2000-09-18 16:07:07 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
|
|
|
* $RCSfile: obj3d.cxx,v $
|
|
|
|
*
|
2004-04-02 13:06:42 +00:00
|
|
|
* $Revision: 1.32 $
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2004-04-02 13:06:42 +00:00
|
|
|
* last change: $Author: rt $ $Date: 2004-04-02 14:06:42 $
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
|
|
|
* 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 _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
|
|
|
|
|
2002-03-06 10:19:16 +00:00
|
|
|
#ifndef _SVAPP_HXX
|
|
|
|
#include <vcl/svapp.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SETTINGS_HXX
|
|
|
|
#include <vcl/settings.hxx>
|
|
|
|
#endif
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
#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
|
|
|
|
|
2004-01-06 14:31:12 +00:00
|
|
|
#ifndef _TL_POLY_HXX
|
|
|
|
#include <tools/poly.hxx>
|
2000-09-18 16:07:07 +00:00
|
|
|
#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
|
|
|
|
|
2000-10-30 10:00:01 +00:00
|
|
|
#ifndef _SVX3DITEMS_HXX
|
|
|
|
#include "svx3ditems.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SFX_WHITER_HXX
|
|
|
|
#include <svtools/whiter.hxx>
|
|
|
|
#endif
|
|
|
|
|
2003-03-27 14:06:05 +00:00
|
|
|
#ifndef INCLUDED_SVTOOLS_COLORCFG_HXX
|
|
|
|
#include <svtools/colorcfg.hxx>
|
|
|
|
#endif
|
|
|
|
|
2000-10-30 10:00:01 +00:00
|
|
|
#ifndef _EEITEM_HXX
|
|
|
|
#include "eeitem.hxx"
|
|
|
|
#endif
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
#ifndef _SVX_XGRSCIT_HXX
|
2001-07-31 10:56:47 +00:00
|
|
|
#include "xgrscit.hxx"
|
2001-06-26 13:04:27 +00:00
|
|
|
#endif
|
|
|
|
|
2002-08-22 08:46:27 +00:00
|
|
|
#ifndef _SVX_SVDOIMP_HXX
|
|
|
|
#include "svdoimp.hxx"
|
|
|
|
#endif
|
|
|
|
|
2003-11-24 15:36:54 +00:00
|
|
|
#ifndef _SDR_PROPERTIES_E3DPROPERTIES_HXX
|
|
|
|
#include <svx/sdr/properties/e3dproperties.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SDR_PROPERTIES_E3DCOMPOUNDPROPERTIES_HXX
|
|
|
|
#include <svx/sdr/properties/e3dcompoundproperties.hxx>
|
|
|
|
#endif
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
#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
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2003-11-24 15:36:54 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
sdr::properties::BaseProperties* E3dObject::CreateObjectSpecificProperties()
|
|
|
|
{
|
|
|
|
return new sdr::properties::E3dProperties(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
TYPEINIT1(E3dObject, SdrAttrObj);
|
|
|
|
|
|
|
|
E3dObject::E3dObject() :
|
|
|
|
nLogicalGroup(0),
|
|
|
|
nObjTreeLevel(0),
|
|
|
|
eDragDetail(E3DDETAIL_ONEBOX),
|
|
|
|
nPartOfParent(0),
|
|
|
|
bTfHasChanged(TRUE),
|
|
|
|
bBoundVolValid(TRUE),
|
2000-10-30 10:00:01 +00:00
|
|
|
bIsSelected(FALSE)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2003-11-24 15:36:54 +00:00
|
|
|
void E3dObject::SetRectsDirty(sal_Bool bNotMyself)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
// 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;
|
2001-02-15 15:11:33 +00:00
|
|
|
rInfo.bEdgeRadiusAllowed = FALSE;
|
2000-09-18 16:07:07 +00:00
|
|
|
rInfo.bCanConvToPath = FALSE;
|
|
|
|
|
|
|
|
// no transparence for 3d objects
|
|
|
|
rInfo.bTransparenceAllowed = FALSE;
|
|
|
|
|
|
|
|
// gradient depends on fillstyle
|
|
|
|
// BM *** check if SetItem is NULL ***
|
2003-11-24 15:36:54 +00:00
|
|
|
XFillStyle eFillStyle = ((XFillStyleItem&)(GetMergedItem(XATTR_FILLSTYLE))).GetValue();
|
2000-09-18 16:07:07 +00:00
|
|
|
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.
|
2000-10-30 10:00:01 +00:00
|
|
|
rInfo.bCanConvToPoly = FALSE;
|
2000-09-18 16:07:07 +00:00
|
|
|
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)
|
|
|
|
{
|
2001-07-17 06:04:31 +00:00
|
|
|
#ifndef SVX_LIGHT
|
2000-09-18 16:07:07 +00:00
|
|
|
// SdrAttrObj::NbcResize(rRef, xFact, yFact);
|
|
|
|
|
|
|
|
// Bewegung in X,Y im Augkoordinatensystem
|
|
|
|
E3dScene* pScene = GetScene();
|
|
|
|
|
|
|
|
if(pScene)
|
|
|
|
{
|
|
|
|
// pos ermitteln
|
2001-07-19 15:59:49 +00:00
|
|
|
B3dTransformationSet& rTransSet = pScene->GetCameraSet();
|
2000-09-18 16:07:07 +00:00
|
|
|
Vector3D aScaleCenter((double)rRef.X(), (double)rRef.Y(), 32768.0);
|
2001-07-19 15:59:49 +00:00
|
|
|
aScaleCenter = rTransSet.ViewToEyeCoor(aScaleCenter);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// scale-faktoren holen
|
|
|
|
double fScaleX = xFact;
|
|
|
|
double fScaleY = yFact;
|
|
|
|
|
|
|
|
// build transform
|
|
|
|
Matrix4D mFullTransform(GetFullTransform());
|
|
|
|
Matrix4D mTrans(mFullTransform);
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
mTrans *= rTransSet.GetOrientation();
|
2000-09-18 16:07:07 +00:00
|
|
|
mTrans.Translate(-aScaleCenter);
|
|
|
|
mTrans.Scale(fScaleX, fScaleY, 1.0);
|
|
|
|
mTrans.Translate(aScaleCenter);
|
2001-07-19 15:59:49 +00:00
|
|
|
mTrans *= rTransSet.GetInvOrientation();
|
2000-09-18 16:07:07 +00:00
|
|
|
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();
|
|
|
|
}
|
2001-07-17 06:04:31 +00:00
|
|
|
#endif
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Objekt verschieben in 2D, wird bei Cursortasten benoetigt
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
void E3dObject::NbcMove(const Size& rSize)
|
|
|
|
{
|
2001-07-17 06:04:31 +00:00
|
|
|
#ifndef SVX_LIGHT
|
2000-09-18 16:07:07 +00:00
|
|
|
// 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
|
2001-07-19 15:59:49 +00:00
|
|
|
B3dTransformationSet& rTransSet = pScene->GetCameraSet();
|
2000-09-18 16:07:07 +00:00
|
|
|
const Volume3D& rVol = pScene->GetBoundVolume();
|
2001-07-19 15:59:49 +00:00
|
|
|
Volume3D aEyeVol = rVol.GetTransformVolume(rTransSet.GetOrientation());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// 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;
|
2001-07-19 15:59:49 +00:00
|
|
|
aMove = rTransSet.EyeToWorldCoor(aMove);
|
2000-09-18 16:07:07 +00:00
|
|
|
aMove *= mInvDispTransform;
|
2001-07-19 15:59:49 +00:00
|
|
|
aPos = rTransSet.EyeToWorldCoor(aPos);
|
2000-09-18 16:07:07 +00:00
|
|
|
aPos *= mInvDispTransform;
|
|
|
|
aMove = aMove - aPos;
|
|
|
|
|
|
|
|
// Transformieren
|
|
|
|
Translate(aMove);
|
|
|
|
|
|
|
|
// force new camera and SnapRect on scene, geometry may have really
|
|
|
|
// changed
|
|
|
|
pScene->CorrectSceneDimensions();
|
|
|
|
}
|
2001-07-17 06:04:31 +00:00
|
|
|
#endif
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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())
|
2001-06-26 13:04:27 +00:00
|
|
|
|| ((rInfoRec.nPaintMode & SDRPAINTMODE_MASTERPAGE) != 0))
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
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()
|
|
|
|
{
|
2000-10-30 10:00:01 +00:00
|
|
|
maSnapRect = Rectangle();
|
2000-09-18 16:07:07 +00:00
|
|
|
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();
|
2000-10-30 10:00:01 +00:00
|
|
|
maSnapRect.Union(aSubRect);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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!");
|
2003-11-24 15:36:54 +00:00
|
|
|
Rectangle aSubRect = ((E3dObject*)pObj)->GetCurrentBoundRect();
|
2000-09-18 16:07:07 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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)
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
// #110094#-14 SendRepaintBroadcast();
|
2000-09-18 16:07:07 +00:00
|
|
|
NbcSetTransform(rMatrix);
|
|
|
|
SetChanged();
|
2003-11-24 15:36:54 +00:00
|
|
|
BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Transformationsmatrix zuruecksetzen mit Repaint-Broadcast
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dObject::ResetTransform()
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
// #110094#-14 SendRepaintBroadcast();
|
2000-09-18 16:07:07 +00:00
|
|
|
NbcResetTransform();
|
|
|
|
SetChanged();
|
2003-11-24 15:36:54 +00:00
|
|
|
BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
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)
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
// #110094#-14 SendRepaintBroadcast();
|
2000-09-18 16:07:07 +00:00
|
|
|
NbcTranslate(rTrans);
|
|
|
|
SetChanged();
|
2003-11-24 15:36:54 +00:00
|
|
|
BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
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)
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
// #110094#-14 SendRepaintBroadcast();
|
2000-09-18 16:07:07 +00:00
|
|
|
NbcScaleX(fSx);
|
|
|
|
SetChanged();
|
2003-11-24 15:36:54 +00:00
|
|
|
BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
|
|
|
|
void E3dObject::ScaleY(double fSy)
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
// #110094#-14 SendRepaintBroadcast();
|
2000-09-18 16:07:07 +00:00
|
|
|
NbcScaleY(fSy);
|
|
|
|
SetChanged();
|
2003-11-24 15:36:54 +00:00
|
|
|
BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
|
|
|
|
void E3dObject::ScaleZ(double fSz)
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
// #110094#-14 SendRepaintBroadcast();
|
2000-09-18 16:07:07 +00:00
|
|
|
NbcScaleZ(fSz);
|
|
|
|
SetChanged();
|
2003-11-24 15:36:54 +00:00
|
|
|
BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
|
|
|
|
void E3dObject::Scale(double fSx, double fSy, double fSz)
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
// #110094#-14 SendRepaintBroadcast();
|
2000-09-18 16:07:07 +00:00
|
|
|
NbcScale(fSx, fSy, fSz);
|
|
|
|
SetChanged();
|
2003-11-24 15:36:54 +00:00
|
|
|
BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
|
|
|
|
void E3dObject::Scale(double fS)
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
// #110094#-14 SendRepaintBroadcast();
|
2000-09-18 16:07:07 +00:00
|
|
|
NbcScale(fS);
|
|
|
|
SetChanged();
|
2003-11-24 15:36:54 +00:00
|
|
|
BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
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)
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
// #110094#-14 SendRepaintBroadcast();
|
2000-09-18 16:07:07 +00:00
|
|
|
NbcRotateX(fAng);
|
|
|
|
SetChanged();
|
2003-11-24 15:36:54 +00:00
|
|
|
BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
|
|
|
|
void E3dObject::RotateY(double fAng)
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
// #110094#-14 SendRepaintBroadcast();
|
2000-09-18 16:07:07 +00:00
|
|
|
NbcRotateY(fAng);
|
|
|
|
SetChanged();
|
2003-11-24 15:36:54 +00:00
|
|
|
BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
|
|
|
|
void E3dObject::RotateZ(double fAng)
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
// #110094#-14 SendRepaintBroadcast();
|
2000-09-18 16:07:07 +00:00
|
|
|
NbcRotateZ(fAng);
|
|
|
|
SetChanged();
|
2003-11-24 15:36:54 +00:00
|
|
|
BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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);
|
2002-06-07 11:08:48 +00:00
|
|
|
|
|
|
|
String aName( GetName() );
|
|
|
|
if(aName.Len())
|
|
|
|
{
|
|
|
|
rName += sal_Unicode(' ');
|
|
|
|
rName += sal_Unicode('\'');
|
|
|
|
rName += aName;
|
|
|
|
rName += sal_Unicode('\'');
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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)
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
SdrObject::operator=(rObj);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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)
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2001-07-17 06:04:31 +00:00
|
|
|
#ifndef SVX_LIGHT
|
2000-09-18 16:07:07 +00:00
|
|
|
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);
|
|
|
|
}
|
2001-07-17 06:04:31 +00:00
|
|
|
#endif
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Objektdaten in Stream speichern
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dObject::WriteData(SvStream& rOut) const
|
|
|
|
{
|
2001-07-17 06:04:31 +00:00
|
|
|
#ifndef SVX_LIGHT
|
2000-09-18 16:07:07 +00:00
|
|
|
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();
|
2001-07-17 06:04:31 +00:00
|
|
|
#endif
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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();
|
2000-10-30 10:00:01 +00:00
|
|
|
}
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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)
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
|
2003-11-24 15:36:54 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
sdr::properties::BaseProperties* E3dCompoundObject::CreateObjectSpecificProperties()
|
|
|
|
{
|
|
|
|
return new sdr::properties::E3dCompoundProperties(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
TYPEINIT1(E3dCompoundObject, E3dObject);
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Konstruktor
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
E3dCompoundObject::E3dCompoundObject() : E3dObject()
|
|
|
|
{
|
|
|
|
// Defaults setzen
|
|
|
|
E3dDefaultAttributes aDefault;
|
|
|
|
SetDefaultAttributes(aDefault);
|
|
|
|
|
|
|
|
bBytesLeft = FALSE;
|
|
|
|
bCreateE3dPolyObj = FALSE;
|
|
|
|
bGeometryValid = FALSE;
|
2004-04-02 13:06:42 +00:00
|
|
|
bFullTfIsPositive = TRUE;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault) : E3dObject()
|
|
|
|
{
|
|
|
|
// Defaults setzen
|
|
|
|
SetDefaultAttributes(rDefault);
|
|
|
|
|
|
|
|
bBytesLeft = FALSE;
|
|
|
|
bCreateE3dPolyObj = FALSE;
|
|
|
|
bGeometryValid = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault)
|
|
|
|
{
|
|
|
|
// Defaults setzen
|
2000-11-07 11:58:28 +00:00
|
|
|
aMaterialAmbientColor = rDefault.GetDefaultAmbientColor();
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
aBackMaterial = rDefault.GetDefaultBackMaterial();
|
|
|
|
bCreateNormals = rDefault.GetDefaultCreateNormals();
|
|
|
|
bCreateTexture = rDefault.GetDefaultCreateTexture();
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* SnapRect berechnen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dCompoundObject::RecalcSnapRect()
|
|
|
|
{
|
|
|
|
E3dScene* pScene = GetScene();
|
|
|
|
if(pScene)
|
|
|
|
{
|
|
|
|
// Objekttransformation uebernehmen
|
|
|
|
const Volume3D& rBoundVol = GetBoundVolume();
|
2000-10-30 10:00:01 +00:00
|
|
|
maSnapRect = Rectangle();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
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));
|
2000-10-30 10:00:01 +00:00
|
|
|
maSnapRect.Union(Rectangle(aPoint, aPoint));
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
2001-07-19 15:59:49 +00:00
|
|
|
PolyPolygon3D aShadowPoly3D;
|
|
|
|
ImpGetShadowPolygon(aShadowPoly3D);
|
|
|
|
|
|
|
|
// invert Y coor cause of GetPolyPolygon() later
|
|
|
|
Matrix4D aTransMat;
|
|
|
|
aTransMat.Scale(1.0, -1.0, 1.0);
|
|
|
|
aShadowPoly3D.Transform(aTransMat);
|
|
|
|
|
|
|
|
PolyPolygon aShadowPoly(aShadowPoly3D.GetPolyPolygon());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Hinzufuegen
|
|
|
|
aOutRect.Union(aShadowPoly.GetBoundRect());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Linienbreite beruecksichtigen
|
2003-11-24 15:36:54 +00:00
|
|
|
INT32 nLineWidth = ((const XLineWidthItem&)(GetObjectItem(XATTR_LINEWIDTH))).GetValue();
|
2000-10-30 10:00:01 +00:00
|
|
|
if(nLineWidth)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2000-10-30 10:00:01 +00:00
|
|
|
Rectangle aShadowRect = aOutRect;
|
|
|
|
aShadowRect.Left() -= nLineWidth;
|
|
|
|
aShadowRect.Right() += nLineWidth;
|
|
|
|
aShadowRect.Top() -= nLineWidth;
|
|
|
|
aShadowRect.Bottom() += nLineWidth;
|
|
|
|
aOutRect.Union(aShadowRect);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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
|
|
|
|
{
|
2001-07-17 06:04:31 +00:00
|
|
|
#ifndef SVX_LIGHT
|
2000-09-18 16:07:07 +00:00
|
|
|
#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
|
2000-11-07 11:58:28 +00:00
|
|
|
rOut << BOOL(GetDoubleSided());
|
2000-09-18 16:07:07 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// neue Parameter zur Geometrieerzeugung
|
|
|
|
rOut << BOOL(bCreateNormals);
|
|
|
|
rOut << BOOL(bCreateTexture);
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
sal_uInt16 nVal = GetNormalsKind();
|
|
|
|
rOut << BOOL(nVal > 0);
|
|
|
|
rOut << BOOL(nVal > 1);
|
|
|
|
|
|
|
|
nVal = GetTextureProjectionX();
|
|
|
|
rOut << BOOL(nVal > 0);
|
|
|
|
rOut << BOOL(nVal > 1);
|
|
|
|
|
|
|
|
nVal = GetTextureProjectionY();
|
|
|
|
rOut << BOOL(nVal > 0);
|
|
|
|
rOut << BOOL(nVal > 1);
|
|
|
|
|
|
|
|
rOut << BOOL(GetShadow3D());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// neu al 384:
|
2000-11-07 11:58:28 +00:00
|
|
|
rOut << GetMaterialAmbientColor();
|
|
|
|
rOut << GetMaterialColor();
|
|
|
|
rOut << GetMaterialSpecular();
|
|
|
|
rOut << GetMaterialEmission();
|
|
|
|
rOut << GetMaterialSpecularIntensity();
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
aBackMaterial.WriteData(rOut);
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
rOut << (UINT16)GetTextureKind();
|
|
|
|
|
|
|
|
rOut << (UINT16)GetTextureMode();
|
|
|
|
|
|
|
|
rOut << BOOL(GetNormalsInvert());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// neu ab 534: (hat noch gefehlt)
|
2000-11-07 11:58:28 +00:00
|
|
|
rOut << BOOL(GetTextureFilter());
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
2001-07-17 06:04:31 +00:00
|
|
|
#endif
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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))
|
|
|
|
{
|
2000-11-07 11:58:28 +00:00
|
|
|
BOOL bTmp, bTmp2;
|
|
|
|
sal_uInt16 nTmp;
|
|
|
|
|
|
|
|
rIn >> bTmp;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DDoubleSidedItem(bTmp));
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// neue Parameter zur Geometrieerzeugung
|
|
|
|
if (aCompat.GetBytesLeft () >= sizeof (BOOL))
|
|
|
|
{
|
2000-11-07 11:58:28 +00:00
|
|
|
rIn >> bTmp;
|
|
|
|
bCreateNormals = bTmp;
|
|
|
|
|
|
|
|
rIn >> bTmp;
|
|
|
|
bCreateTexture = bTmp;
|
|
|
|
|
|
|
|
rIn >> bTmp;
|
|
|
|
rIn >> bTmp2;
|
|
|
|
if(bTmp == FALSE && bTmp2 == FALSE)
|
|
|
|
nTmp = 0;
|
|
|
|
else if(bTmp == TRUE && bTmp2 == FALSE)
|
|
|
|
nTmp = 1;
|
|
|
|
else
|
|
|
|
nTmp = 2;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DNormalsKindItem(nTmp));
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
rIn >> bTmp;
|
|
|
|
rIn >> bTmp2;
|
|
|
|
if(bTmp == FALSE && bTmp2 == FALSE)
|
|
|
|
nTmp = 0;
|
|
|
|
else if(bTmp == TRUE && bTmp2 == FALSE)
|
|
|
|
nTmp = 1;
|
|
|
|
else
|
|
|
|
nTmp = 2;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DTextureProjectionXItem(nTmp));
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
rIn >> bTmp;
|
|
|
|
rIn >> bTmp2;
|
|
|
|
if(bTmp == FALSE && bTmp2 == FALSE)
|
|
|
|
nTmp = 0;
|
|
|
|
else if(bTmp == TRUE && bTmp2 == FALSE)
|
|
|
|
nTmp = 1;
|
|
|
|
else
|
|
|
|
nTmp = 2;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DTextureProjectionYItem(nTmp));
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
rIn >> bTmp;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DShadow3DItem(bTmp));
|
2000-11-07 11:58:28 +00:00
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
// Setze ein Flag fuer den Aufrufer, dass neues Format
|
|
|
|
// zu lesen ist
|
|
|
|
bBytesLeft = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// neu al 384:
|
|
|
|
if (aCompat.GetBytesLeft () >= sizeof (B3dMaterial))
|
|
|
|
{
|
|
|
|
UINT16 nTmp;
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
Color aCol;
|
|
|
|
|
|
|
|
rIn >> aCol;
|
|
|
|
SetMaterialAmbientColor(aCol);
|
|
|
|
|
|
|
|
rIn >> aCol;
|
|
|
|
// do NOT use, this is the old 3D-Color(!)
|
|
|
|
// SetItem(XFillColorItem(String(), aCol));
|
|
|
|
|
|
|
|
rIn >> aCol;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DMaterialSpecularItem(aCol));
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
rIn >> aCol;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DMaterialEmissionItem(aCol));
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
rIn >> nTmp;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DMaterialSpecularIntensityItem(nTmp));
|
2000-11-07 11:58:28 +00:00
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
aBackMaterial.ReadData(rIn);
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
rIn >> nTmp;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DTextureKindItem(nTmp));
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
rIn >> nTmp;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DTextureModeItem(nTmp));
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
rIn >> bTmp;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DNormalsInvertItem(bTmp));
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// neu ab 534: (hat noch gefehlt)
|
|
|
|
if (aCompat.GetBytesLeft () >= sizeof (BOOL))
|
|
|
|
{
|
2000-11-07 11:58:28 +00:00
|
|
|
rIn >> bTmp;
|
2003-11-24 15:36:54 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DTextureFilterItem(bTmp));
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Bitmaps fuer 3D-Darstellung von Gradients und Hatches holen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
AlphaMask E3dCompoundObject::GetAlphaMask(const SfxItemSet& rSet, const Size& rSizePixel)
|
|
|
|
{
|
|
|
|
const XFillFloatTransparenceItem& rFloatTrans = ((const XFillFloatTransparenceItem&)(rSet.Get(XATTR_FILLFLOATTRANSPARENCE)));
|
|
|
|
VirtualDevice *pVD = new VirtualDevice();
|
|
|
|
pVD->SetOutputSizePixel( rSizePixel );
|
|
|
|
XOutputDevice *pXOut = new XOutputDevice( pVD );
|
|
|
|
SfxItemSet aFillSet(*rSet.GetPool());
|
|
|
|
|
|
|
|
XGradient aNewGradient(rFloatTrans.GetValue());
|
|
|
|
|
|
|
|
Color aStartCol(aNewGradient.GetStartColor());
|
|
|
|
if(aNewGradient.GetStartIntens() != 100)
|
|
|
|
{
|
|
|
|
double fFact = (double)aNewGradient.GetStartIntens() / 100.0;
|
|
|
|
aStartCol = (B3dColor)aStartCol * fFact;
|
|
|
|
}
|
|
|
|
aNewGradient.SetStartColor(aStartCol);
|
|
|
|
aNewGradient.SetStartIntens(100);
|
|
|
|
|
|
|
|
Color aEndCol(aNewGradient.GetEndColor());
|
|
|
|
if(aNewGradient.GetEndIntens() != 100)
|
|
|
|
{
|
|
|
|
double fFact = (double)aNewGradient.GetEndIntens() / 100.0;
|
|
|
|
aEndCol = (B3dColor)aEndCol * fFact;
|
|
|
|
}
|
|
|
|
aNewGradient.SetEndColor(aEndCol);
|
|
|
|
aNewGradient.SetEndIntens(100);
|
|
|
|
|
|
|
|
aFillSet.Put( XFillStyleItem( XFILL_GRADIENT ) );
|
|
|
|
aFillSet.Put( XFillGradientItem( String(), aNewGradient ) );
|
|
|
|
aFillSet.Put( XGradientStepCountItem( aNewGradient.GetSteps() ) );
|
|
|
|
pXOut->SetFillAttr( aFillSet );
|
|
|
|
|
|
|
|
aFillSet.Put( XLineStyleItem( XLINE_NONE ) );
|
|
|
|
pXOut->SetLineAttr( aFillSet );
|
|
|
|
|
|
|
|
pXOut->DrawRect( Rectangle( Point(), rSizePixel ) );
|
|
|
|
Bitmap aGradientBitmap = pVD->GetBitmap( Point(), rSizePixel );
|
|
|
|
|
|
|
|
if( pVD )
|
|
|
|
delete pVD;
|
|
|
|
if( pXOut )
|
|
|
|
delete pXOut;
|
|
|
|
|
|
|
|
return AlphaMask(aGradientBitmap);
|
|
|
|
}
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
Bitmap E3dCompoundObject::GetGradientBitmap(const SfxItemSet& rSet)
|
|
|
|
{
|
|
|
|
VirtualDevice *pVD = new VirtualDevice();
|
|
|
|
Size aVDSize(256, 256);
|
|
|
|
pVD->SetOutputSizePixel( aVDSize );
|
|
|
|
XOutputDevice *pXOut = new XOutputDevice( pVD );
|
2000-10-30 10:00:01 +00:00
|
|
|
SfxItemSet aFillSet(*rSet.GetPool());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2000-10-30 10:00:01 +00:00
|
|
|
aFillSet.Put( XFillStyleItem( XFILL_GRADIENT ) );
|
|
|
|
aFillSet.Put( rSet.Get(XATTR_FILLGRADIENT) );
|
|
|
|
aFillSet.Put( rSet.Get(XATTR_GRADIENTSTEPCOUNT) );
|
|
|
|
pXOut->SetFillAttr( aFillSet );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2000-10-30 10:00:01 +00:00
|
|
|
aFillSet.Put( XLineStyleItem( XLINE_NONE ) );
|
|
|
|
pXOut->SetLineAttr( aFillSet );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
pXOut->DrawRect( Rectangle( Point(), aVDSize ) );
|
|
|
|
Bitmap aGradientBitmap = pVD->GetBitmap( Point(), aVDSize );
|
|
|
|
|
|
|
|
if( pVD )
|
|
|
|
delete pVD;
|
|
|
|
if( pXOut )
|
|
|
|
delete pXOut;
|
|
|
|
|
|
|
|
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 );
|
2000-10-30 10:00:01 +00:00
|
|
|
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 );
|
2000-09-18 16:07:07 +00:00
|
|
|
pXOut->DrawRect( Rectangle( Point(), pVD->PixelToLogic(aVDSize) ) );
|
|
|
|
|
2000-10-30 10:00:01 +00:00
|
|
|
aFillSet.Put( XFillStyleItem( XFILL_HATCH ) );
|
|
|
|
aFillSet.Put( rSet.Get(XATTR_FILLHATCH) );
|
|
|
|
pXOut->SetFillAttr( aFillSet );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
Size aLogicalSize = pVD->PixelToLogic(aVDSize);
|
2003-05-22 09:27:01 +00:00
|
|
|
|
|
|
|
// #109483#
|
|
|
|
// If nDistance was 0 (the init value from the API), nDistanceX/Y
|
|
|
|
// may be zero, too, which is not a valid value for a fraction. The
|
|
|
|
// best value then is 1 since this simply takes the logical size as
|
|
|
|
// scaling. A distance of 0 in a hatch makes no sense anyways.
|
|
|
|
if(!nDistanceX)
|
|
|
|
{
|
|
|
|
nDistanceX = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!nDistanceY)
|
|
|
|
{
|
|
|
|
nDistanceY = 1;
|
|
|
|
}
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
return aHatchBitmap;
|
|
|
|
}
|
|
|
|
|
2001-07-10 09:09:51 +00:00
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Give out simple line geometry
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dCompoundObject::GetLineGeometry(PolyPolygon3D& rLinePolyPolygon) const
|
|
|
|
{
|
|
|
|
// use basic implementation here. Maybe optimized later.
|
|
|
|
rLinePolyPolygon.Clear();
|
|
|
|
B3dEntityBucket& rEntityBucket = ((E3dCompoundObject*)this)->GetDisplayGeometry().GetEntityBucket();
|
|
|
|
GeometryIndexValueBucket& rIndexBucket = ((E3dCompoundObject*)this)->GetDisplayGeometry().GetIndexBucket();
|
|
|
|
sal_uInt32 nPolyCounter(0);
|
|
|
|
sal_uInt32 nEntityCounter(0);
|
|
|
|
|
|
|
|
while(nPolyCounter < rIndexBucket.Count())
|
|
|
|
{
|
|
|
|
// next primitive
|
|
|
|
sal_uInt32 nUpperBound(rIndexBucket[nPolyCounter++].GetIndex());
|
|
|
|
Vector3D aLastPoint;
|
|
|
|
|
|
|
|
BOOL bLastLineVisible = rEntityBucket[nUpperBound - 1].IsEdgeVisible();
|
|
|
|
if(bLastLineVisible)
|
|
|
|
aLastPoint = rEntityBucket[nUpperBound - 1].Point().GetVector3D();
|
|
|
|
|
|
|
|
while(nEntityCounter < nUpperBound)
|
|
|
|
{
|
|
|
|
Vector3D aNewPoint = rEntityBucket[nEntityCounter].Point().GetVector3D();
|
|
|
|
|
|
|
|
if(bLastLineVisible)
|
|
|
|
{
|
|
|
|
if(aLastPoint != aNewPoint)
|
|
|
|
{
|
|
|
|
// fill polygon
|
|
|
|
Polygon3D aNewPoly(2);
|
|
|
|
aNewPoly[0] = aLastPoint;
|
|
|
|
aNewPoly[1] = aNewPoint;
|
|
|
|
|
|
|
|
// create line geometry for polygon in eye coor to
|
|
|
|
// have it always orthogonal to camera plane
|
|
|
|
rLinePolyPolygon.Insert(aNewPoly);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bLastLineVisible = rEntityBucket[nEntityCounter++].IsEdgeVisible();
|
|
|
|
aLastPoint = aNewPoint;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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)
|
|
|
|
{
|
2000-11-07 11:58:28 +00:00
|
|
|
if(GetNormalsKind() > 1)
|
2000-09-18 16:07:07 +00:00
|
|
|
GetDisplayGeometry().CreateDefaultNormalsSphere();
|
2000-11-07 11:58:28 +00:00
|
|
|
if(GetNormalsInvert())
|
2000-09-18 16:07:07 +00:00
|
|
|
GetDisplayGeometry().InvertNormals();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(bCreateTexture)
|
|
|
|
{
|
|
|
|
GetDisplayGeometry().CreateDefaultTexture(
|
2000-11-07 11:58:28 +00:00
|
|
|
((GetTextureProjectionX() > 0) ? B3D_CREATE_DEFAULT_X : FALSE)
|
|
|
|
|((GetTextureProjectionY() > 0) ? B3D_CREATE_DEFAULT_Y : FALSE),
|
|
|
|
GetTextureProjectionX() > 1);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
}
|
|
|
|
|
2004-04-02 13:06:42 +00:00
|
|
|
void E3dCompoundObject::GetFullTransform(Matrix4D& rMatrix) const
|
|
|
|
{
|
|
|
|
E3dObject::GetFullTransform( rMatrix );
|
|
|
|
}
|
|
|
|
const Matrix4D& E3dCompoundObject::GetFullTransform()
|
|
|
|
{
|
|
|
|
if ( bTfHasChanged )
|
|
|
|
{
|
|
|
|
aFullTfMatrix = aTfMatrix;
|
|
|
|
|
|
|
|
if ( GetParentObj() )
|
|
|
|
aFullTfMatrix *= GetParentObj()->GetFullTransform();
|
|
|
|
|
|
|
|
bTfHasChanged = FALSE;
|
|
|
|
|
|
|
|
// THB: Temporary fix for SJ's flipping problem
|
|
|
|
// TODO: Clarify with AW
|
|
|
|
// Check whether matrix mirrors
|
|
|
|
const bool bIsPositive( aFullTfMatrix.Determinant() >= 0.0 );
|
|
|
|
if( bIsPositive != bFullTfIsPositive )
|
|
|
|
{
|
|
|
|
bGeometryValid = FALSE; // force geometry recreation, which then takes care of flipping
|
|
|
|
bFullTfIsPositive = bIsPositive;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return aFullTfMatrix;
|
|
|
|
}
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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(
|
2000-11-07 11:58:28 +00:00
|
|
|
rPolyPolygon3D, GetDoubleSided(), TRUE);
|
2000-09-18 16:07:07 +00:00
|
|
|
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(
|
2000-11-07 11:58:28 +00:00
|
|
|
rPolyPolygon3D, rPolyNormal3D, GetDoubleSided(), TRUE);
|
2000-09-18 16:07:07 +00:00
|
|
|
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,
|
2000-11-07 11:58:28 +00:00
|
|
|
rPolyTexture3D, GetDoubleSided(), TRUE);
|
2000-09-18 16:07:07 +00:00
|
|
|
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;
|
|
|
|
bCreateNormals = r3DObj.bCreateNormals;
|
|
|
|
bCreateTexture = r3DObj.bCreateTexture;
|
|
|
|
bGeometryValid = r3DObj.bGeometryValid;
|
|
|
|
bBytesLeft = r3DObj.bBytesLeft;
|
|
|
|
bCreateE3dPolyObj = r3DObj.bCreateE3dPolyObj;
|
|
|
|
|
|
|
|
// neu ab 383:
|
2000-11-07 11:58:28 +00:00
|
|
|
aMaterialAmbientColor = r3DObj.aMaterialAmbientColor;
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
aBackMaterial = r3DObj.aBackMaterial;
|
|
|
|
bUseDifferentBackMaterial = r3DObj.bUseDifferentBackMaterial;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Ausgabeparameter an 3D-Kontext setzen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
void E3dCompoundObject::ImpSet3DParForFill(ExtOutputDevice& rOut, Base3D* pBase3D,
|
|
|
|
BOOL& bDrawObject, UINT16 nDrawFlags, BOOL bGhosted, BOOL bIsFillDraft)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
if(bIsFillDraft)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
bDrawObject = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
const SfxItemSet& rSet = GetObjectItemSet();
|
2001-06-26 13:04:27 +00:00
|
|
|
const XFillStyle eFillStyle = ((const XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
if(eFillStyle == XFILL_NONE)
|
|
|
|
{
|
|
|
|
bDrawObject = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sal_uInt16 nFillTrans = ((const XFillTransparenceItem&)(rSet.Get(XATTR_FILLTRANSPARENCE))).GetValue();
|
|
|
|
const XFillFloatTransparenceItem& rFloatTrans = ((const XFillFloatTransparenceItem&)(rSet.Get(XATTR_FILLFLOATTRANSPARENCE)));
|
|
|
|
BOOL bFillTransparence = (nFillTrans != 0);
|
|
|
|
BOOL bFloatTransparence = rFloatTrans.IsEnabled();
|
|
|
|
BOOL bAnyTransparence = (bFillTransparence || bFloatTransparence);
|
|
|
|
BOOL bDrawTransparence = ((nDrawFlags & E3D_DRAWFLAG_TRANSPARENT) != 0);
|
|
|
|
|
|
|
|
// force no fill transparence when float transparence
|
|
|
|
if(bFloatTransparence)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
bFillTransparence = FALSE;
|
|
|
|
nFillTrans = 0;
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
if(bAnyTransparence != bDrawTransparence)
|
|
|
|
{
|
|
|
|
bDrawObject = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// get base color
|
|
|
|
Color aColorSolid = ((const XFillColorItem&) (rSet.Get(XATTR_FILLCOLOR))).GetValue();
|
2000-09-18 16:07:07 +00:00
|
|
|
if(bGhosted)
|
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
aColorSolid = Color(
|
|
|
|
(aColorSolid.GetRed() >> 1) + 0x80,
|
|
|
|
(aColorSolid.GetGreen() >> 1) + 0x80,
|
|
|
|
(aColorSolid.GetBlue() >> 1) + 0x80);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
// prepare custom colors for linear transparency and black/white mode
|
|
|
|
Color aColorSolidWithTransparency(aColorSolid);
|
2000-09-18 16:07:07 +00:00
|
|
|
aColorSolidWithTransparency.SetTransparency((UINT8)(nFillTrans * 255 / 100));
|
|
|
|
Color aColorWhite(COL_WHITE);
|
|
|
|
Color aColorWhiteWithTransparency(COL_WHITE);
|
|
|
|
aColorWhiteWithTransparency.SetTransparency((UINT8)(nFillTrans * 255 / 100));
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
// set base materials (if no drawmode is set)
|
2000-09-18 16:07:07 +00:00
|
|
|
pBase3D->SetMaterial(aColorWhite, Base3DMaterialAmbient);
|
|
|
|
pBase3D->SetMaterial(aColorWhiteWithTransparency, Base3DMaterialDiffuse);
|
2000-11-07 11:58:28 +00:00
|
|
|
pBase3D->SetMaterial(GetMaterialSpecular(), Base3DMaterialSpecular);
|
|
|
|
pBase3D->SetMaterial(GetMaterialEmission(), Base3DMaterialEmission);
|
|
|
|
pBase3D->SetShininess(GetMaterialSpecularIntensity());
|
2000-09-18 16:07:07 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
// prepare some more later used texture parameters
|
|
|
|
B3dTexture* pTexture = NULL;
|
|
|
|
Base3DTextureWrap eWrapX(Base3DTextureRepeat);
|
|
|
|
Base3DTextureWrap eWrapY(Base3DTextureRepeat);
|
2000-09-18 16:07:07 +00:00
|
|
|
Matrix4D mTexture;
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
// now test the different draw modes and cases
|
|
|
|
if((pBase3D->GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL) != 0)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
// set material to black and white mode
|
|
|
|
pBase3D->SetMaterial(aColorWhite, Base3DMaterialAmbient);
|
|
|
|
pBase3D->SetMaterial(aColorWhiteWithTransparency, Base3DMaterialDiffuse);
|
|
|
|
if(GetUseDifferentBackMaterial())
|
|
|
|
{
|
|
|
|
pBase3D->SetMaterial(aColorWhite, Base3DMaterialAmbient, Base3DMaterialBack);
|
|
|
|
pBase3D->SetMaterial(aColorWhiteWithTransparency, Base3DMaterialDiffuse, Base3DMaterialBack);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Color stays white, just set render mode
|
2000-09-18 16:07:07 +00:00
|
|
|
pBase3D->SetRenderMode(Base3DRenderFill);
|
|
|
|
}
|
2002-03-06 10:19:16 +00:00
|
|
|
else if((pBase3D->GetOutputDevice()->GetDrawMode() & DRAWMODE_SETTINGSFILL) != 0)
|
|
|
|
{
|
|
|
|
Color aColorFill(Application::GetSettings().GetStyleSettings().GetWindowColor());
|
|
|
|
Color aColorFillWithTransparency(aColorFill);
|
|
|
|
aColorFillWithTransparency.SetTransparency((UINT8)(nFillTrans * 255 / 100));
|
|
|
|
|
|
|
|
// set material to black and white mode
|
|
|
|
pBase3D->SetMaterial(aColorFill, Base3DMaterialAmbient);
|
|
|
|
pBase3D->SetMaterial(aColorFillWithTransparency, Base3DMaterialDiffuse);
|
|
|
|
if(GetUseDifferentBackMaterial())
|
|
|
|
{
|
|
|
|
pBase3D->SetMaterial(aColorFill, Base3DMaterialAmbient, Base3DMaterialBack);
|
|
|
|
pBase3D->SetMaterial(aColorFillWithTransparency, Base3DMaterialDiffuse, Base3DMaterialBack);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Color stays solid, just set render mode
|
|
|
|
pBase3D->SetRenderMode(Base3DRenderFill);
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
else if(eFillStyle == XFILL_BITMAP)
|
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
// bitmap fill, use bitmap texture from 2D defines
|
|
|
|
BitmapEx aBmpEx;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
if(SFX_ITEM_SET == rSet.GetItemState(XATTR_FILLBITMAP, TRUE))
|
|
|
|
{
|
|
|
|
// EIndeutige Bitmap, benutze diese
|
2001-06-26 13:04:27 +00:00
|
|
|
aBmpEx = BitmapEx((((const XFillBitmapItem&) (rSet.Get(XATTR_FILLBITMAP))).GetValue()).GetBitmap());
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Keine eindeutige Bitmap. benutze default
|
|
|
|
//
|
|
|
|
// DIES IST EINE NOTLOESUNG, BIS MAN IRGENDWO AN DIE
|
|
|
|
// DEAULT-BITMAP RANKOMMT (IST VON KA IN VORBEREITUNG)
|
|
|
|
//
|
2001-06-26 13:04:27 +00:00
|
|
|
aBmpEx = BitmapEx(Bitmap(Size(4,4), 8));
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Texturattribute bilden
|
2001-06-26 13:04:27 +00:00
|
|
|
TextureAttributesBitmap aTexAttr(
|
|
|
|
bGhosted,
|
|
|
|
(void*)&rSet.Get(XATTR_FILLFLOATTRANSPARENCE),
|
|
|
|
aBmpEx.GetBitmap());
|
2000-09-18 16:07:07 +00:00
|
|
|
pTexture = pBase3D->ObtainTexture(aTexAttr);
|
|
|
|
if(!pTexture)
|
2000-11-14 12:34:45 +00:00
|
|
|
{
|
|
|
|
if(bGhosted)
|
2001-06-26 13:04:27 +00:00
|
|
|
aBmpEx.Adjust( 50 );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
if(bFloatTransparence)
|
|
|
|
// add alpha channel to bitmap
|
|
|
|
aBmpEx = BitmapEx(aBmpEx.GetBitmap(), GetAlphaMask(rSet, aBmpEx.GetSizePixel()));
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
pTexture = pBase3D->ObtainTexture(aTexAttr, aBmpEx);
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
sal_uInt16 nOffX = ((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_TILEOFFSETX))).GetValue();
|
|
|
|
sal_uInt16 nOffY = ((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_TILEOFFSETY))).GetValue();
|
|
|
|
sal_uInt16 nOffPosX = ((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_POSOFFSETX))).GetValue();
|
|
|
|
sal_uInt16 nOffPosY = ((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_POSOFFSETY))).GetValue();
|
|
|
|
RECT_POINT eRectPoint = (RECT_POINT)((const SfxEnumItem&) (rSet.Get(XATTR_FILLBMP_POS))).GetValue();
|
|
|
|
BOOL bTile = ((const SfxBoolItem&) (rSet.Get(XATTR_FILLBMP_TILE))).GetValue();
|
|
|
|
BOOL bStretch = ((const SfxBoolItem&) (rSet.Get(XATTR_FILLBMP_STRETCH))).GetValue();
|
|
|
|
BOOL bLogSize = ((const SfxBoolItem&) (rSet.Get(XATTR_FILLBMP_SIZELOG))).GetValue();
|
|
|
|
Size aSize(
|
|
|
|
labs(((const SfxMetricItem&)(rSet.Get(XATTR_FILLBMP_SIZEX))).GetValue()),
|
|
|
|
labs(((const SfxMetricItem&)(rSet.Get(XATTR_FILLBMP_SIZEY))).GetValue()));
|
2000-09-18 16:07:07 +00:00
|
|
|
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
|
2001-06-26 13:04:27 +00:00
|
|
|
Size aLogicalSize = aBmpEx.GetPrefSize();
|
2000-09-18 16:07:07 +00:00
|
|
|
const Volume3D& rVol = GetBoundVolume();
|
|
|
|
if(aLogicalSize.Width() == 0 || aLogicalSize.Height() == 0)
|
|
|
|
{
|
|
|
|
// Keine logische Groesse, nimm Pixelgroesse
|
|
|
|
// und wandle diese um
|
2001-06-26 13:04:27 +00:00
|
|
|
aLogicalSize = Application::GetDefaultDevice()->PixelToLogic(aBmpEx.GetSizePixel(), MAP_100TH_MM);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-03-27 14:06:05 +00:00
|
|
|
if ( aBmpEx.GetPrefMapMode() == MAP_PIXEL )
|
|
|
|
aLogicalSize = Application::GetDefaultDevice()->PixelToLogic( aLogicalSize, MAP_100TH_MM );
|
|
|
|
else
|
|
|
|
aLogicalSize = OutputDevice::LogicToLogic( aLogicalSize, aBmpEx.GetPrefMapMode(), MAP_100TH_MM );
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(bLogSize)
|
|
|
|
{
|
|
|
|
// logische Groesse
|
|
|
|
if(aSize.Width() == 0 && aSize.Height() == 0)
|
|
|
|
{
|
2003-03-27 14:06:05 +00:00
|
|
|
// Originalgroesse benutzen, Original flagy
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// 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
|
2001-06-26 13:04:27 +00:00
|
|
|
double fLeftBound = (rVol.GetWidth() / 2.0) - ((double)aLogicalSize.Width() / 2.0);
|
|
|
|
double fTopBound = (rVol.GetHeight() / 2.0) - ((double)aLogicalSize.Height() / 2.0);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// 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)
|
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
// gradient fill. Create texture and set.
|
2000-09-18 16:07:07 +00:00
|
|
|
TextureAttributesGradient aTexAttr(
|
2001-06-26 13:04:27 +00:00
|
|
|
bGhosted,
|
|
|
|
(void*)&rSet.Get(XATTR_FILLFLOATTRANSPARENCE),
|
2000-09-18 16:07:07 +00:00
|
|
|
(void*)&rSet.Get(XATTR_FILLGRADIENT),
|
2001-06-26 13:04:27 +00:00
|
|
|
(void*)&rSet.Get(XATTR_GRADIENTSTEPCOUNT));
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
pTexture = pBase3D->ObtainTexture(aTexAttr);
|
|
|
|
if(!pTexture)
|
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
BitmapEx aBmpEx = BitmapEx(GetGradientBitmap(rSet));
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
if(bFloatTransparence)
|
|
|
|
// add alpha channel to bitmap
|
|
|
|
aBmpEx = BitmapEx(aBmpEx.GetBitmap(), GetAlphaMask(rSet, aBmpEx.GetSizePixel()));
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
if(bGhosted)
|
|
|
|
aBmpEx.Adjust( 50 );
|
|
|
|
pTexture = pBase3D->ObtainTexture(aTexAttr, aBmpEx);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(eFillStyle == XFILL_HATCH)
|
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
// hatch fill. Create texture and set.
|
2000-09-18 16:07:07 +00:00
|
|
|
TextureAttributesHatch aTexAttr(
|
2001-06-26 13:04:27 +00:00
|
|
|
bGhosted,
|
|
|
|
(void*)&rSet.Get(XATTR_FILLFLOATTRANSPARENCE),
|
|
|
|
(void*)&rSet.Get(XATTR_FILLHATCH));
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
pTexture = pBase3D->ObtainTexture(aTexAttr);
|
|
|
|
if(!pTexture)
|
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
BitmapEx aBmpEx = GetHatchBitmap(rSet);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
if(bFloatTransparence)
|
|
|
|
// add alpha channel to bitmap
|
|
|
|
aBmpEx = BitmapEx(aBmpEx.GetBitmap(), GetAlphaMask(rSet, aBmpEx.GetSizePixel()));
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
if(bGhosted)
|
|
|
|
aBmpEx.Adjust( 50 );
|
|
|
|
pTexture = pBase3D->ObtainTexture(aTexAttr, aBmpEx);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
// set different texture transformation
|
2000-09-18 16:07:07 +00:00
|
|
|
mTexture.Scale(Vector3D(20.0, 20.0, 20.0));
|
|
|
|
}
|
2001-06-26 13:04:27 +00:00
|
|
|
else if(eFillStyle == XFILL_SOLID)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
if(bFloatTransparence)
|
|
|
|
{
|
|
|
|
// Texturattribute bilden
|
|
|
|
TextureAttributesColor aTexAttr(
|
|
|
|
bGhosted,
|
|
|
|
(void*)&rSet.Get(XATTR_FILLFLOATTRANSPARENCE),
|
|
|
|
aColorSolid);
|
|
|
|
|
|
|
|
pTexture = pBase3D->ObtainTexture(aTexAttr);
|
|
|
|
if(!pTexture)
|
|
|
|
{
|
|
|
|
// build single colored bitmap with draw color and add transparence bitmap
|
|
|
|
Size aSizeBitmap(128, 128);
|
|
|
|
Bitmap aForeground(aSizeBitmap, 24);
|
|
|
|
aForeground.Erase(aColorSolid);
|
|
|
|
|
|
|
|
if(bGhosted)
|
|
|
|
aForeground.Adjust( 50 );
|
|
|
|
|
|
|
|
// add alpha channel to bitmap
|
|
|
|
BitmapEx aBmpEx(aForeground, GetAlphaMask(rSet, aSizeBitmap));
|
|
|
|
|
|
|
|
pTexture = pBase3D->ObtainTexture(aTexAttr, aBmpEx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
// set material to base color
|
|
|
|
pBase3D->SetMaterial(aColorSolid, Base3DMaterialAmbient);
|
|
|
|
pBase3D->SetMaterial(aColorSolidWithTransparency, Base3DMaterialDiffuse);
|
|
|
|
if(GetUseDifferentBackMaterial())
|
|
|
|
{
|
|
|
|
pBase3D->SetMaterial(aBackMaterial.GetMaterial(Base3DMaterialAmbient), Base3DMaterialAmbient, Base3DMaterialBack);
|
|
|
|
pBase3D->SetMaterial(aBackMaterial.GetMaterial(Base3DMaterialDiffuse), Base3DMaterialDiffuse, Base3DMaterialBack);
|
|
|
|
}
|
|
|
|
|
|
|
|
// and at last, the render mode.
|
|
|
|
pBase3D->SetRenderMode(Base3DRenderFill);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
2001-06-26 13:04:27 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DBG_ERROR("unknown drawing mode (!)");
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
// use texture?
|
2000-09-18 16:07:07 +00:00
|
|
|
if(pTexture)
|
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
// set values for texture modes
|
2000-11-07 11:58:28 +00:00
|
|
|
pTexture->SetTextureKind(GetTextureKind());
|
|
|
|
pTexture->SetTextureMode(GetTextureMode());
|
2001-06-26 13:04:27 +00:00
|
|
|
pTexture->SetTextureFilter(GetTextureFilter() ? Base3DTextureLinear : Base3DTextureNearest);
|
2000-09-18 16:07:07 +00:00
|
|
|
pTexture->SetTextureWrapS(eWrapX);
|
|
|
|
pTexture->SetTextureWrapT(eWrapY);
|
|
|
|
pTexture->SetBlendColor(aColorSolid);
|
|
|
|
pTexture->SetTextureColor(aColorSolid);
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
// activate texture
|
2000-09-18 16:07:07 +00:00
|
|
|
pBase3D->SetActiveTexture(pTexture);
|
|
|
|
pBase3D->SetRenderMode(Base3DRenderFill);
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
// set texture transformation
|
2000-09-18 16:07:07 +00:00
|
|
|
GetScene()->GetCameraSet().SetTexture(mTexture);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
// switch it off.texture usage
|
2000-09-18 16:07:07 +00:00
|
|
|
pBase3D->SetActiveTexture();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-06-26 13:04:27 +00:00
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
void E3dCompoundObject::ImpSet3DParForLine(ExtOutputDevice& rOut, Base3D* pBase3D,
|
|
|
|
BOOL& bDrawOutline, UINT16 nDrawFlags, BOOL bGhosted, BOOL bIsLineDraft)
|
|
|
|
{
|
|
|
|
// do drawflags allow line drawing at all?
|
2003-11-24 15:36:54 +00:00
|
|
|
const SfxItemSet& rSet = GetObjectItemSet();
|
2001-06-26 13:04:27 +00:00
|
|
|
sal_uInt16 nLineTransparence = ((const XLineTransparenceItem&)(rSet.Get(XATTR_LINETRANSPARENCE))).GetValue();
|
|
|
|
BOOL bLineTransparence = (nLineTransparence != 0);
|
|
|
|
BOOL bDrawTransparence = ((nDrawFlags & E3D_DRAWFLAG_TRANSPARENT) != 0);
|
2002-03-08 14:28:48 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
if(bLineTransparence != bDrawTransparence)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
bDrawOutline = FALSE;
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
// if no linestyle, draw no outline
|
|
|
|
XLineStyle aLineStyle(XLINE_NONE);
|
|
|
|
if(bDrawOutline)
|
|
|
|
{
|
|
|
|
aLineStyle = ((const XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue();
|
|
|
|
bDrawOutline = (aLineStyle != XLINE_NONE);
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2002-03-08 14:28:48 +00:00
|
|
|
// special mode for black/white drawing or high contrast mode
|
|
|
|
// Linecolor is set to black before (Base3d::SetColor())
|
|
|
|
if((!bDrawOutline) && ((pBase3D->GetOutputDevice()->GetDrawMode() & (DRAWMODE_WHITEFILL|DRAWMODE_SETTINGSLINE)) != 0))
|
2001-06-26 13:04:27 +00:00
|
|
|
{
|
|
|
|
bDrawOutline = TRUE;
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
// does the outdev use linestyle?
|
|
|
|
if(bDrawOutline && !rOut.GetIgnoreLineStyle())
|
|
|
|
{
|
|
|
|
Color aColorLine = ((const XLineColorItem&)(rSet.Get(XATTR_LINECOLOR))).GetValue();
|
|
|
|
sal_Int32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2002-03-08 14:28:48 +00:00
|
|
|
if(pBase3D->GetOutputDevice()->GetDrawMode() & DRAWMODE_SETTINGSLINE)
|
|
|
|
{
|
2003-03-27 14:06:05 +00:00
|
|
|
svtools::ColorConfig aColorConfig;
|
|
|
|
aColorLine = Color( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
|
2002-03-08 14:28:48 +00:00
|
|
|
}
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
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);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
// Material setzen
|
|
|
|
pBase3D->SetColor(aColorLine);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
2001-06-26 13:04:27 +00:00
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
void E3dCompoundObject::SetBase3DParams(ExtOutputDevice& rOut, Base3D* pBase3D,
|
|
|
|
BOOL& bDrawObject, BOOL& bDrawOutline, UINT16 nDrawFlags, BOOL bGhosted,
|
|
|
|
BOOL bIsLineDraft, BOOL bIsFillDraft)
|
|
|
|
{
|
|
|
|
bDrawObject = ((nDrawFlags & E3D_DRAWFLAG_FILLED) != 0);
|
|
|
|
if(bDrawObject)
|
|
|
|
ImpSet3DParForFill(rOut, pBase3D, bDrawObject, nDrawFlags, bGhosted, bIsFillDraft);
|
|
|
|
|
|
|
|
bDrawOutline = ((nDrawFlags & E3D_DRAWFLAG_OUTLINE) != 0);
|
|
|
|
if(bDrawOutline)
|
|
|
|
ImpSet3DParForLine(rOut, pBase3D, bDrawOutline, nDrawFlags, bGhosted, bIsLineDraft);
|
|
|
|
|
|
|
|
// Set ObjectTrans if line or fill is still set (maybe retet by upper calls)
|
2000-09-18 16:07:07 +00:00
|
|
|
if(bDrawObject || bDrawOutline)
|
|
|
|
{
|
|
|
|
Matrix4D mTransform = GetFullTransform();
|
|
|
|
GetScene()->GetCameraSet().SetObjectTrans(mTransform);
|
|
|
|
pBase3D->SetTransformationSet(&(GetScene()->GetCameraSet()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Hittest fuer 3D-Objekte, wird an Geometrie weitergegeben
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2004-02-26 16:45:55 +00:00
|
|
|
// #110988# test if given hit candidate point is inside bound volume of object
|
|
|
|
sal_Bool E3dCompoundObject::ImpIsInsideBoundVolume(const Vector3D& rFront, const Vector3D& rBack, const Point& rPnt) const
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2004-02-26 16:45:55 +00:00
|
|
|
const Volume3D& rBoundVol = ((E3dCompoundObject*)this)->GetBoundVolume();
|
|
|
|
|
|
|
|
if(rBoundVol.IsValid())
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2004-02-26 16:45:55 +00:00
|
|
|
double fXMax = rFront.X();
|
|
|
|
double fXMin = rBack.X();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2004-02-26 16:45:55 +00:00
|
|
|
if(fXMax < fXMin)
|
|
|
|
{
|
|
|
|
fXMax = rBack.X();
|
|
|
|
fXMin = rFront.X();
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2004-02-26 16:45:55 +00:00
|
|
|
if(rBoundVol.MinVec().X() <= fXMax && rBoundVol.MaxVec().X() >= fXMin)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2004-02-26 16:45:55 +00:00
|
|
|
double fYMax = rFront.Y();
|
|
|
|
double fYMin = rBack.Y();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2004-02-26 16:45:55 +00:00
|
|
|
if(fYMax < fYMin)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2004-02-26 16:45:55 +00:00
|
|
|
fYMax = rBack.Y();
|
|
|
|
fYMin = rFront.Y();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2004-02-26 16:45:55 +00:00
|
|
|
if(rBoundVol.MinVec().Y() <= fYMax && rBoundVol.MaxVec().Y() >= fYMin)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2004-02-26 16:45:55 +00:00
|
|
|
double fZMax = rFront.Z();
|
|
|
|
double fZMin = rBack.Z();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2004-02-26 16:45:55 +00:00
|
|
|
if(fZMax < fZMin)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2004-02-26 16:45:55 +00:00
|
|
|
fZMax = rBack.Z();
|
|
|
|
fZMin = rFront.Z();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2004-02-26 16:45:55 +00:00
|
|
|
if(rBoundVol.MinVec().Z() <= fZMax && rBoundVol.MaxVec().Z() >= fZMin)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2004-02-26 16:45:55 +00:00
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2004-02-26 16:45:55 +00:00
|
|
|
return sal_False;
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2004-02-26 16:45:55 +00:00
|
|
|
SdrObject* E3dCompoundObject::CheckHit(const Point& rPnt, USHORT nTol, const SetOfByte* pVisiLayer) const
|
|
|
|
{
|
|
|
|
E3dPolyScene* pScene = (E3dPolyScene*)GetScene();
|
|
|
|
|
|
|
|
if(pScene)
|
|
|
|
{
|
|
|
|
// get HitLine in ObjectKoordinates
|
|
|
|
// set ObjectTrans
|
|
|
|
Matrix4D mTransform = ((E3dCompoundObject*)this)->GetFullTransform();
|
|
|
|
pScene->GetCameraSet().SetObjectTrans(mTransform);
|
|
|
|
|
|
|
|
// create HitPoint Front und Back, transform to object coordinates
|
|
|
|
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);
|
|
|
|
|
|
|
|
if(ImpIsInsideBoundVolume(aFront, aBack, rPnt))
|
|
|
|
{
|
|
|
|
// 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))
|
|
|
|
{
|
|
|
|
return ((E3dCompoundObject*)this);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-02-26 16:45:55 +00:00
|
|
|
|
|
|
|
return 0L;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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);
|
2003-10-27 12:26:17 +00:00
|
|
|
SetTransform(aTransMat * GetTransform()); // #112587#
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Schattenattribute holen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
Color E3dCompoundObject::GetShadowColor()
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
return ((SdrShadowColorItem&)(GetObjectItem(SDRATTR_SHADOWCOLOR))).GetValue();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL E3dCompoundObject::DrawShadowAsOutline()
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
const SfxItemSet& rSet = GetObjectItemSet();
|
2000-10-30 10:00:01 +00:00
|
|
|
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);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
INT32 E3dCompoundObject::GetShadowXDistance()
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
return (long)((SdrShadowXDistItem&)(GetObjectItem(SDRATTR_SHADOWXDIST))).GetValue();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
INT32 E3dCompoundObject::GetShadowYDistance()
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
return (long)((SdrShadowYDistItem&)(GetObjectItem(SDRATTR_SHADOWYDIST))).GetValue();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
UINT16 E3dCompoundObject::GetShadowTransparence()
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
return (UINT16)((SdrShadowTransparenceItem&)(GetObjectItem(SDRATTR_SHADOWTRANSPARENCE))).GetValue();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL E3dCompoundObject::DoDrawShadow()
|
|
|
|
{
|
2003-11-24 15:36:54 +00:00
|
|
|
const SfxItemSet& rSet = GetObjectItemSet();
|
2000-10-30 10:00:01 +00:00
|
|
|
BOOL bRetval(FALSE);
|
|
|
|
BOOL bShadOn = ((SdrShadowItem&)(rSet.Get(SDRATTR_SHADOW))).GetValue();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2000-10-30 10:00:01 +00:00
|
|
|
if(bShadOn)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2000-10-30 10:00:01 +00:00
|
|
|
bRetval = TRUE;
|
|
|
|
|
|
|
|
if(((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue() == XFILL_NONE)
|
|
|
|
{
|
|
|
|
if(((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue() == XLINE_NONE)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2000-10-30 10:00:01 +00:00
|
|
|
bRetval = FALSE;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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();
|
2001-07-19 15:59:49 +00:00
|
|
|
B3dTransformationSet& rTransSet = GetScene()->GetCameraSet();
|
2000-09-18 16:07:07 +00:00
|
|
|
BOOL bDrawLine, bLastDrawLine;
|
|
|
|
Vector3D aPoint;
|
|
|
|
|
|
|
|
while(nPolyCounter < rIndexBucket.Count())
|
|
|
|
{
|
|
|
|
// Naechstes Primitiv
|
|
|
|
nUpperBound = rIndexBucket[nPolyCounter++].GetIndex();
|
|
|
|
bDrawLine = bLastDrawLine = rEntityBucket[nEntityCounter].IsEdgeVisible();
|
2001-07-19 15:59:49 +00:00
|
|
|
aPoint = rTransSet.ObjectToViewCoor(rEntityBucket[nEntityCounter++].Point().GetVector3D());
|
2000-09-18 16:07:07 +00:00
|
|
|
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();
|
2001-07-19 15:59:49 +00:00
|
|
|
aPoint = rTransSet.ObjectToViewCoor(rEntityBucket[nEntityCounter++].Point().GetVector3D());
|
2000-09-18 16:07:07 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Create vertical polygons for line polygon
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
// #78972#
|
|
|
|
void E3dCompoundObject::ImpCompleteLinePolygon(PolyPolygon3D& rLinePolyPoly,
|
|
|
|
sal_uInt16 nPolysPerRun, BOOL bClosed)
|
|
|
|
{
|
|
|
|
if(rLinePolyPoly.Count() && nPolysPerRun)
|
|
|
|
{
|
|
|
|
// get number of layers
|
|
|
|
sal_uInt16 nLayers(rLinePolyPoly.Count() / nPolysPerRun);
|
|
|
|
sal_uInt16 a, b, c;
|
|
|
|
|
|
|
|
// add vertical Polygons if at least two horizontal ones exist
|
|
|
|
if(nLayers > 1)
|
|
|
|
{
|
|
|
|
for(a = 0; a < nPolysPerRun; a++)
|
|
|
|
{
|
|
|
|
const sal_uInt16 nPntCnt = rLinePolyPoly[a].GetPointCount();
|
|
|
|
|
|
|
|
for(b = 0; b < nPntCnt; b++)
|
|
|
|
{
|
|
|
|
Polygon3D aNewVerPoly(bClosed ? nLayers + 1 : nLayers);
|
|
|
|
|
|
|
|
for(c = 0; c < nLayers; c++)
|
|
|
|
aNewVerPoly[c] = rLinePolyPoly[(c * nPolysPerRun) + a][b];
|
|
|
|
|
|
|
|
// evtl. set first point again to close polygon
|
|
|
|
if(bClosed)
|
|
|
|
aNewVerPoly[aNewVerPoly.GetPointCount()] = aNewVerPoly[0];
|
|
|
|
|
|
|
|
// insert
|
|
|
|
rLinePolyPoly.Insert(aNewVerPoly);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// open closed polygons
|
|
|
|
for(a = 0; a < rLinePolyPoly.Count(); a++)
|
|
|
|
{
|
|
|
|
if(rLinePolyPoly[a].IsClosed())
|
|
|
|
{
|
|
|
|
rLinePolyPoly[a][rLinePolyPoly[a].GetPointCount()] = rLinePolyPoly[a][0];
|
|
|
|
rLinePolyPoly[a].SetClosed(FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Ein Segment fuer Extrude oder Lathe erzeugen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
void E3dCompoundObject::ImpCreateSegment(
|
2000-09-18 16:07:07 +00:00
|
|
|
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
|
2001-07-19 15:59:49 +00:00
|
|
|
BOOL bRotateTexture90, // Textur der Seitenflaechen um 90 Grad kippen
|
|
|
|
PolyPolygon3D* pLineGeometry // For creation of line geometry
|
2000-09-18 16:07:07 +00:00
|
|
|
)
|
|
|
|
{
|
|
|
|
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);
|
2001-07-19 15:59:49 +00:00
|
|
|
|
|
|
|
// #78972#
|
|
|
|
if(pLineGeometry)
|
|
|
|
{
|
|
|
|
pLineGeometry->Insert(rFront);
|
|
|
|
if(bCreateBack)
|
|
|
|
pLineGeometry->Insert(rBack);
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
PolyPolygon3D aOuterFront;
|
|
|
|
PolyPolygon3D aOuterBack;
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
if(bCreateFront)
|
|
|
|
{
|
|
|
|
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
|
2001-07-11 07:48:20 +00:00
|
|
|
//GrowPoly(aLocalFront, aNormalsOuterFront, -fDiagLen);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Neue Groesse inneres Polygon feststellen
|
|
|
|
Volume3D aNewSize(aLocalFront.GetPolySize());
|
|
|
|
|
|
|
|
// Skalierung feststellen (nur X,Y)
|
2001-07-11 07:23:05 +00:00
|
|
|
Vector3D aScaleVec(
|
|
|
|
(aNewSize.GetWidth() != 0.0) ? aOldSize.GetWidth() / aNewSize.GetWidth() : 1.0,
|
|
|
|
(aNewSize.GetHeight() != 0.0) ? aOldSize.GetHeight() / aNewSize.GetHeight() : 1.0,
|
|
|
|
(aNewSize.GetDepth() != 0.0) ? aOldSize.GetDepth() / aNewSize.GetDepth() : 1.0);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// 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
|
2001-07-11 07:23:05 +00:00
|
|
|
Vector3D aTransVec(
|
|
|
|
aOldSize.MinVec().X() - aNewSize.MinVec().X(),
|
2000-09-18 16:07:07 +00:00
|
|
|
aOldSize.MinVec().Y() - aNewSize.MinVec().Y(),
|
2001-07-11 07:23:05 +00:00
|
|
|
aOldSize.MinVec().Z() - aNewSize.MinVec().Z());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Transformation bilden
|
|
|
|
aTransMat.Identity();
|
|
|
|
aTransMat.Translate(aTransVec);
|
|
|
|
|
|
|
|
// aeusseres und inneres Polygon skalieren
|
|
|
|
aLocalFront.Transform(aTransMat);
|
|
|
|
aOuterFront.Transform(aTransMat);
|
2001-07-11 07:23:05 +00:00
|
|
|
|
|
|
|
// move aLocalFront again, scale and translate has moved it back
|
|
|
|
GrowPoly(aLocalFront, aNormalsOuterFront, -fDiagLen);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
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 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
|
2001-07-11 07:48:20 +00:00
|
|
|
//GrowPoly(aLocalBack, aNormalsOuterBack, -fDiagLen);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Neue Groesse inneres Polygon feststellen
|
|
|
|
Volume3D aNewSize(aLocalBack.GetPolySize());
|
|
|
|
|
|
|
|
// Skalierung feststellen (nur X,Y)
|
2001-07-11 07:23:05 +00:00
|
|
|
Vector3D aScaleVec(
|
|
|
|
(aNewSize.GetWidth() != 0.0) ? aOldSize.GetWidth() / aNewSize.GetWidth() : 1.0,
|
|
|
|
(aNewSize.GetHeight() != 0.0) ? aOldSize.GetHeight() / aNewSize.GetHeight() : 1.0,
|
|
|
|
(aNewSize.GetDepth() != 0.0) ? aOldSize.GetDepth() / aNewSize.GetDepth() : 1.0);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// 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
|
2001-07-11 07:23:05 +00:00
|
|
|
Vector3D aTransVec(
|
|
|
|
aOldSize.MinVec().X() - aNewSize.MinVec().X(),
|
2000-09-18 16:07:07 +00:00
|
|
|
aOldSize.MinVec().Y() - aNewSize.MinVec().Y(),
|
2001-07-11 07:23:05 +00:00
|
|
|
aOldSize.MinVec().Z() - aNewSize.MinVec().Z());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Transformation bilden
|
|
|
|
aTransMat.Identity();
|
|
|
|
aTransMat.Translate(aTransVec);
|
|
|
|
|
|
|
|
// aeusseres und inneres Polygon skalieren
|
|
|
|
aLocalBack.Transform(aTransMat);
|
|
|
|
aOuterBack.Transform(aTransMat);
|
2001-07-11 07:23:05 +00:00
|
|
|
|
|
|
|
// move aLocalBack again, scale and translate has moved it back
|
|
|
|
GrowPoly(aLocalBack, aNormalsOuterBack, -fDiagLen);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
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);
|
2001-07-19 15:59:49 +00:00
|
|
|
|
|
|
|
// #78972#
|
|
|
|
if(pLineGeometry)
|
|
|
|
{
|
|
|
|
if(bCreateFront)
|
|
|
|
pLineGeometry->Insert(aOuterFront);
|
|
|
|
pLineGeometry->Insert(aLocalFront);
|
|
|
|
if(bCreateBack)
|
|
|
|
{
|
|
|
|
pLineGeometry->Insert(aLocalBack);
|
|
|
|
pLineGeometry->Insert(aOuterBack);
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 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
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2000-11-07 11:58:28 +00:00
|
|
|
void E3dCompoundObject::SetMaterialAmbientColor(const Color& rColor)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2000-11-07 11:58:28 +00:00
|
|
|
if(aMaterialAmbientColor != rColor)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2000-11-07 11:58:28 +00:00
|
|
|
aMaterialAmbientColor = rColor;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2001-06-26 13:04:27 +00:00
|
|
|
BOOL bIsLineDraft((rInfoRec.nPaintMode & SDRPAINTMODE_DRAFTLINE) != 0);
|
|
|
|
BOOL bIsFillDraft((rInfoRec.nPaintMode & SDRPAINTMODE_DRAFTFILL) != 0);
|
2000-09-18 16:07:07 +00:00
|
|
|
SetBase3DParams(rOut, pBase3D, bDrawObject, bDrawOutline, nDrawFlags,
|
2000-09-27 13:03:58 +00:00
|
|
|
(rInfoRec.pPV && rInfoRec.pPV->GetView().DoVisualizeEnteredGroup()) ? rInfoRec.bNotActive : FALSE,
|
|
|
|
bIsLineDraft, bIsFillDraft);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Culling?
|
2000-11-07 11:58:28 +00:00
|
|
|
pBase3D->SetCullMode(GetDoubleSided() ? Base3DCullNone : Base3DCullBack);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Objekt flat darstellen?
|
2000-11-07 11:58:28 +00:00
|
|
|
BOOL bForceFlat = ((GetNormalsKind() > 0) && !(GetNormalsKind() > 1));
|
2000-09-18 16:07:07 +00:00
|
|
|
pBase3D->SetForceFlat(bForceFlat);
|
|
|
|
|
|
|
|
// Geometrie ausgeben
|
|
|
|
if(bDrawObject)
|
2001-09-20 15:33:33 +00:00
|
|
|
{
|
|
|
|
// #92030# for E3dPolygonObj, take flag at created DisplayGeometry into account
|
|
|
|
// which may not allow this object to be drawn filled
|
|
|
|
if(!GetDisplayGeometry().IsOutline())
|
|
|
|
{
|
|
|
|
pBase3D->DrawPolygonGeometry(GetDisplayGeometry());
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Outline ausgeben
|
|
|
|
if(bDrawOutline && pBase3D->GetLightGroup())
|
|
|
|
{
|
|
|
|
BOOL bLightingWasEnabled = pBase3D->GetLightGroup()->IsLightingEnabled();
|
|
|
|
pBase3D->GetLightGroup()->EnableLighting(FALSE);
|
|
|
|
pBase3D->SetLightGroup(pBase3D->GetLightGroup());
|
2000-10-31 11:43:34 +00:00
|
|
|
|
2000-11-14 12:34:45 +00:00
|
|
|
// #79585#
|
2000-10-31 11:43:34 +00:00
|
|
|
pBase3D->SetActiveTexture();
|
|
|
|
|
2001-07-10 09:09:51 +00:00
|
|
|
// #78972#
|
|
|
|
// detect if lines need to be drawn specifically
|
2003-11-24 15:36:54 +00:00
|
|
|
const SfxItemSet& rSet = GetObjectItemSet();
|
2001-07-10 09:09:51 +00:00
|
|
|
sal_Int32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue();
|
|
|
|
XLineStyle aLineStyle = ((const XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue();
|
|
|
|
BOOL bDrawLineSolidHair = (aLineStyle == XLINE_SOLID && nLineWidth == 0);
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// get line geometry
|
|
|
|
PolyPolygon3D aLinePolyPolygon;
|
|
|
|
GetLineGeometry(aLinePolyPolygon);
|
|
|
|
|
2001-07-10 09:09:51 +00:00
|
|
|
if(bDrawLineSolidHair)
|
|
|
|
{
|
|
|
|
// simply draw the object geometry as line (as done before)
|
2001-07-19 15:59:49 +00:00
|
|
|
// pBase3D->DrawPolygonGeometry(GetDisplayGeometry(), TRUE);
|
|
|
|
if(aLinePolyPolygon.Count())
|
|
|
|
{
|
|
|
|
// draw the line geometry as 3d lines
|
|
|
|
pBase3D->SetRenderMode(Base3DRenderLine);
|
|
|
|
pBase3D->SetPolygonOffset(Base3DPolygonOffsetLine, TRUE);
|
|
|
|
|
|
|
|
for(sal_uInt32 a(0); a < aLinePolyPolygon.Count(); a++)
|
|
|
|
{
|
|
|
|
// start new primitive
|
|
|
|
const Polygon3D& rPolygon = aLinePolyPolygon[(sal_uInt16)a];
|
|
|
|
pBase3D->StartPrimitive(Base3DLineStrip);
|
|
|
|
|
|
|
|
for(sal_uInt32 b(0); b < rPolygon.GetPointCount(); b++)
|
|
|
|
{
|
|
|
|
Vector3D aVec = rPolygon[sal_uInt16(b)];
|
|
|
|
pBase3D->AddVertex(aVec);
|
|
|
|
}
|
|
|
|
|
|
|
|
// draw primitive
|
|
|
|
pBase3D->EndPrimitive();
|
|
|
|
}
|
|
|
|
|
|
|
|
pBase3D->SetPolygonOffset(Base3DPolygonOffsetLine, FALSE);
|
|
|
|
}
|
2001-07-10 09:09:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// convert object geometry to line geometry and draw as polygons
|
|
|
|
// in 3D space
|
|
|
|
PolyPolygon3D aPolyPoly3D;
|
|
|
|
PolyPolygon3D aLinePoly3D;
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// get ImpLineStyleParameterPack
|
|
|
|
ImpLineStyleParameterPack aLineAttr(rSet, FALSE, rOut.GetOutDev());
|
|
|
|
aLineAttr.ForceNoArrowsLeft(TRUE);
|
|
|
|
aLineAttr.ForceNoArrowsRight(TRUE);
|
|
|
|
ImpLineGeometryCreator aLineCreator(aLineAttr, aPolyPoly3D, aLinePoly3D, FALSE);
|
2001-07-10 09:09:51 +00:00
|
|
|
|
|
|
|
// get camera set
|
|
|
|
B3dTransformationSet* pTransSet = pBase3D->GetTransformationSet();
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// get transform object geometry in eye coor
|
2001-07-10 09:09:51 +00:00
|
|
|
Matrix4D aMatObjectToEye = pTransSet->GetObjectTrans();
|
|
|
|
aMatObjectToEye *= pTransSet->GetOrientation();
|
|
|
|
|
|
|
|
for(sal_uInt16 nInd(0); nInd < aLinePolyPolygon.Count(); nInd++)
|
|
|
|
{
|
|
|
|
// create line geometry for polygon in eye coor to
|
|
|
|
// have it always orthogonal to camera plane
|
|
|
|
Polygon3D aLinePoly = aLinePolyPolygon.GetObject(nInd);
|
|
|
|
aLinePoly.Transform(aMatObjectToEye);
|
|
|
|
aLineCreator.AddPolygon3D(aLinePoly);
|
|
|
|
}
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// put together
|
|
|
|
aLinePoly3D.Insert(aPolyPoly3D);
|
2001-07-10 09:09:51 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
if(aLinePoly3D.Count())
|
|
|
|
{
|
|
|
|
pBase3D->SetCullMode(Base3DCullNone);
|
|
|
|
for(sal_uInt32 a(0); a < aLinePoly3D.Count(); a++)
|
2001-07-10 09:09:51 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
// start new primitive
|
|
|
|
const Polygon3D& rPolygon = aLinePoly3D[(sal_uInt16)a];
|
2001-07-10 09:09:51 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
if(rPolygon.IsClosed())
|
2001-07-10 09:09:51 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
pBase3D->SetRenderMode(Base3DRenderFill);
|
|
|
|
pBase3D->StartPrimitive(Base3DPolygon);
|
2001-07-10 09:09:51 +00:00
|
|
|
}
|
2001-07-19 15:59:49 +00:00
|
|
|
else
|
2001-07-10 09:09:51 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
pBase3D->SetRenderMode(Base3DRenderLine);
|
|
|
|
pBase3D->SetPolygonOffset(Base3DPolygonOffsetLine, TRUE);
|
|
|
|
pBase3D->StartPrimitive(Base3DLineStrip);
|
2001-07-10 09:09:51 +00:00
|
|
|
}
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
for(sal_uInt32 b(0); b < rPolygon.GetPointCount(); b++)
|
2001-07-10 09:09:51 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
Vector3D aVec = rPolygon[sal_uInt16(b)];
|
|
|
|
aVec = pTransSet->EyeToObjectCoor(aVec);
|
|
|
|
pBase3D->AddVertex(aVec);
|
|
|
|
}
|
2001-07-10 09:09:51 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// draw primitive
|
|
|
|
pBase3D->EndPrimitive();
|
2001-07-10 09:09:51 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
if(!rPolygon.IsClosed())
|
|
|
|
{
|
|
|
|
pBase3D->SetPolygonOffset(Base3DPolygonOffsetLine, FALSE);
|
2001-07-10 09:09:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
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
|
2003-11-24 15:36:54 +00:00
|
|
|
aTempRect = GetCurrentBoundRect();
|
2000-09-18 16:07:07 +00:00
|
|
|
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();
|
2001-07-19 15:59:49 +00:00
|
|
|
B3dTransformationSet& rTransSet = GetScene()->GetCameraSet();
|
2000-09-18 16:07:07 +00:00
|
|
|
Vector3D aPoint;
|
|
|
|
Point aNewPoint;
|
|
|
|
|
|
|
|
// ObjectTrans setzen
|
|
|
|
Matrix4D mTransform = GetFullTransform();
|
2001-07-19 15:59:49 +00:00
|
|
|
rTransSet.SetObjectTrans(mTransform);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
while(nPolyCounter < rIndexBucket.Count())
|
|
|
|
{
|
|
|
|
// Naechstes Primitiv
|
|
|
|
nUpperBound = rIndexBucket[nPolyCounter++].GetIndex();
|
|
|
|
XPolygon aNewPart(UINT16(nUpperBound - nEntityCounter));
|
|
|
|
UINT16 nIndex = 0;
|
|
|
|
|
|
|
|
while(nEntityCounter < nUpperBound)
|
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
aPoint = rTransSet.ObjectToViewCoor(rEntityBucket[nEntityCounter++].Point().GetVector3D());
|
2000-09-18 16:07:07 +00:00
|
|
|
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#)
|
2001-07-19 15:59:49 +00:00
|
|
|
PolyPolygon3D aShadowPolyPoly;
|
|
|
|
ImpGetShadowPolygon(aShadowPolyPoly);
|
|
|
|
|
|
|
|
// invert Y coor cause of GetPolygon() later
|
|
|
|
Matrix4D aTransMat;
|
|
|
|
aTransMat.Scale(1.0, -1.0, 1.0);
|
|
|
|
aShadowPolyPoly.Transform(aTransMat);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
for(UINT16 a = 0; a < aShadowPolyPoly.Count(); a++)
|
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
XPolygon aNewPart(aShadowPolyPoly[a].GetPolygon());
|
2000-09-18 16:07:07 +00:00
|
|
|
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
|
2001-07-19 15:59:49 +00:00
|
|
|
PolyPolygon3D aShadowPoly;
|
|
|
|
ImpGetShadowPolygon(aShadowPoly);
|
|
|
|
|
|
|
|
// invert Y coor cause of GetPolyPolygon() in ImpDrawShadowPolygon() later
|
|
|
|
Matrix4D aTransMat;
|
|
|
|
aTransMat.Scale(1.0, -1.0, 1.0);
|
|
|
|
aShadowPoly.Transform(aTransMat);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// ...und Zeichnen
|
2001-07-19 15:59:49 +00:00
|
|
|
ImpDrawShadowPolygon(aShadowPoly, rXOut);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
void E3dCompoundObject::ImpGetShadowPolygon(PolyPolygon3D& rPoly)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
// #79585#
|
|
|
|
sal_Int32 nXDist(GetShadowXDistance());
|
|
|
|
sal_Int32 nYDist(GetShadowYDistance());
|
|
|
|
BOOL bDrawAsOutline(DrawShadowAsOutline());
|
|
|
|
PolyPolygon3D aLinePolyPolygon;
|
|
|
|
B3dTransformationSet& rTransSet = GetScene()->GetCameraSet();
|
2003-11-24 15:36:54 +00:00
|
|
|
const SfxItemSet& rSet = GetObjectItemSet();
|
2001-07-19 15:59:49 +00:00
|
|
|
XLineStyle aLineStyle = ((const XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue();
|
|
|
|
sal_Int32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
if(!bDrawAsOutline)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
// add basic polygon geometry, generate from 3D bucket
|
|
|
|
B3dEntityBucket& rEntityBucket = ((E3dCompoundObject*)this)->GetDisplayGeometry().GetEntityBucket();
|
|
|
|
GeometryIndexValueBucket& rIndexBucket = ((E3dCompoundObject*)this)->GetDisplayGeometry().GetIndexBucket();
|
|
|
|
sal_uInt32 nPolyCounter(0);
|
|
|
|
sal_uInt32 nEntityCounter(0);
|
|
|
|
|
|
|
|
while(nPolyCounter < rIndexBucket.Count())
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
// next primitive
|
|
|
|
sal_uInt32 nUpperBound(rIndexBucket[nPolyCounter++].GetIndex());
|
|
|
|
Polygon3D aNewPolygon((sal_uInt16)(nUpperBound - nEntityCounter));
|
|
|
|
sal_uInt16 nIndex(0);
|
|
|
|
|
|
|
|
while(nEntityCounter < nUpperBound)
|
|
|
|
aNewPolygon[nIndex++] = rEntityBucket[nEntityCounter++].Point().GetVector3D();
|
|
|
|
|
|
|
|
aNewPolygon.SetClosed(TRUE);
|
|
|
|
aLinePolyPolygon.Insert(aNewPolygon);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
2001-07-19 15:59:49 +00:00
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
if(bDrawAsOutline || (nLineWidth != 0))
|
|
|
|
{
|
|
|
|
// add 3D line drawing geometry
|
|
|
|
PolyPolygon3D aBasicLinePolyPoly;
|
|
|
|
GetLineGeometry(aBasicLinePolyPoly);
|
|
|
|
|
|
|
|
// #78972# detect if lines need to be drawn with pattern
|
|
|
|
if(aLineStyle == XLINE_DASH || (aLineStyle == XLINE_SOLID && nLineWidth != 0))
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
PolyPolygon3D aPolyPoly3D;
|
|
|
|
PolyPolygon3D aLinePoly3D;
|
|
|
|
|
|
|
|
// get ImpLineStyleParameterPack, bForceHair==FALSE to create polygons
|
|
|
|
ImpLineStyleParameterPack aLineAttr(rSet, FALSE, NULL);
|
|
|
|
aLineAttr.ForceNoArrowsLeft(TRUE);
|
|
|
|
aLineAttr.ForceNoArrowsRight(TRUE);
|
|
|
|
ImpLineGeometryCreator aLineCreator(aLineAttr, aPolyPoly3D, aLinePoly3D, FALSE);
|
|
|
|
|
|
|
|
// get camera set and transform to eye coor
|
|
|
|
Matrix4D aMatObjectToEye = rTransSet.GetObjectTrans();
|
|
|
|
aMatObjectToEye *= rTransSet.GetOrientation();
|
|
|
|
|
|
|
|
for(sal_uInt16 nInd(0); nInd < aBasicLinePolyPoly.Count(); nInd++)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
Polygon3D aLinePoly = aBasicLinePolyPoly.GetObject(nInd);
|
|
|
|
aLinePoly.Transform(aMatObjectToEye);
|
|
|
|
aLineCreator.AddPolygon3D(aLinePoly);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
2001-07-19 15:59:49 +00:00
|
|
|
|
|
|
|
// prepare transform back to object coor
|
|
|
|
if(aLinePoly3D.Count() || aPolyPoly3D.Count())
|
|
|
|
aMatObjectToEye.Invert();
|
|
|
|
|
|
|
|
if(aLinePoly3D.Count())
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
// transform and add all generated line polygons
|
|
|
|
aLinePoly3D.Transform(aMatObjectToEye);
|
|
|
|
aLinePolyPolygon.Insert(aLinePoly3D);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
if(aPolyPoly3D.Count())
|
|
|
|
{
|
|
|
|
// transform and add all generated polygons
|
|
|
|
aPolyPoly3D.Transform(aMatObjectToEye);
|
|
|
|
aLinePolyPolygon.Insert(aPolyPoly3D);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// simply add basic line geometry
|
|
|
|
aLinePolyPolygon.Insert(aBasicLinePolyPoly);
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
if(aLinePolyPolygon.Count())
|
|
|
|
{
|
|
|
|
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)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
if(rLightGroup.IsEnabled(aLightNumber))
|
|
|
|
bLightNumberValid = TRUE;
|
|
|
|
else
|
|
|
|
aLightNumber = (Base3DLightNumber)((UINT16)aLightNumber + 1);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
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;
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// Ebene holen, Richtung in Augkoordinaten
|
|
|
|
aGroundDirection = -GetScene()->GetShadowPlaneDirection();
|
|
|
|
aGroundDirection.Normalize();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// Ist die Lampe auch vor der Ebene?
|
|
|
|
Vector3D aLightNormal = aLampPositionOrDirection;
|
|
|
|
if(!bDirectionalSource)
|
|
|
|
{
|
|
|
|
// Nur Position vorhanden, berechne einen Lichtvektor
|
|
|
|
aLightNormal = aLinePolyPolygon[0][0] - aLampPositionOrDirection;
|
|
|
|
aLightNormal.Normalize();
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
double fLightAndNormal = aLightNormal.Scalar(aGroundDirection);
|
|
|
|
B3dVolume aVolume = rTransSet.GetDeviceVolume();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// auf Augkoordinaten umstellen
|
|
|
|
double fTemp = aVolume.MinVec().Z();
|
|
|
|
aVolume.MinVec().Z() = -aVolume.MaxVec().Z();
|
|
|
|
aVolume.MaxVec().Z() = -fTemp;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
if(fLightAndNormal > 0.0)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
// 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);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// Skalar der Ebenengleichung holen
|
|
|
|
double fGroundScalar = -aGroundPosition.Scalar(aGroundDirection);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// ObjectTrans setzen
|
|
|
|
BOOL bPolygonVisible(TRUE);
|
|
|
|
Matrix4D mTransform = GetFullTransform();
|
|
|
|
rTransSet.SetObjectTrans(mTransform);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
for(sal_uInt16 a(0); a < aLinePolyPolygon.Count(); a++)
|
|
|
|
{
|
|
|
|
Polygon3D& rLinePoly = aLinePolyPolygon[a];
|
|
|
|
Polygon3D aPoly(rLinePoly.GetPointCount());
|
|
|
|
sal_uInt16 nPolyPos(0);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
for(sal_uInt16 b(0); b < rLinePoly.GetPointCount(); b++)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
// Naechsten Punkt holen
|
|
|
|
Vector3D aPoint = rLinePoly[b];
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// Auf Augkoordinaten umrechnen
|
|
|
|
aPoint = rTransSet.ObjectToEyeCoor(aPoint);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// Richtung bestimmen
|
|
|
|
Vector3D aDirection = aLampPositionOrDirection;
|
|
|
|
if(!bDirectionalSource)
|
|
|
|
{
|
|
|
|
aDirection = aPoint - aLampPositionOrDirection;
|
|
|
|
aDirection.Normalize();
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// 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;
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// Punkt normal transformieren
|
|
|
|
if(bPolygonVisible)
|
|
|
|
{
|
|
|
|
// Auf ViewKoordinaten
|
|
|
|
Vector3D aShadowPoint = rTransSet.EyeToViewCoor(aPoint);
|
|
|
|
aPoly[nPolyPos++] = Vector3D(
|
|
|
|
aShadowPoint.X() + (double)nXDist,
|
|
|
|
aShadowPoint.Y() + (double)nYDist,
|
|
|
|
0.0);
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// Teilpolygon einfuegen
|
|
|
|
if(nPolyPos)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
aPoly.SetClosed(rLinePoly.IsClosed());
|
|
|
|
rPoly.Insert(aPoly);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
// ObjectTrans setzen
|
|
|
|
Matrix4D mTransform = GetFullTransform();
|
|
|
|
rTransSet.SetObjectTrans(mTransform);
|
|
|
|
|
|
|
|
for(sal_uInt16 a(0); a < aLinePolyPolygon.Count(); a++)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
Polygon3D& rLinePoly = aLinePolyPolygon[a];
|
|
|
|
Polygon3D aPoly(rLinePoly.GetPointCount());
|
|
|
|
sal_uInt16 nPolyPos(0);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Polygon fuellen
|
2001-07-19 15:59:49 +00:00
|
|
|
for(sal_uInt16 b(0); b < rLinePoly.GetPointCount(); b++)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
// Naechsten Punkt holen
|
|
|
|
Vector3D aPoint = rLinePoly[b];
|
|
|
|
aPoint = rTransSet.ObjectToViewCoor(aPoint);
|
|
|
|
aPoly[nPolyPos++] = Vector3D(
|
|
|
|
aPoint.X() + (double)nXDist,
|
|
|
|
aPoint.Y() + (double)nYDist,
|
|
|
|
0.0);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
// open/close
|
|
|
|
aPoly.SetClosed(rLinePoly.IsClosed());
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
// Teilpolygon einfuegen
|
|
|
|
rPoly.Insert(aPoly);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
void E3dCompoundObject::ImpDrawShadowPolygon(PolyPolygon3D& rPoly, ExtOutputDevice& rXOut)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
Color aCol = GetShadowColor();
|
|
|
|
OutputDevice *pDevice = rXOut.GetOutDev();
|
|
|
|
BOOL bDrawAsOutline(DrawShadowAsOutline());
|
|
|
|
UINT16 nTransparence = GetShadowTransparence();
|
2001-07-19 15:59:49 +00:00
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
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
|
2001-07-19 15:59:49 +00:00
|
|
|
PolyPolygon aPolyPolygon(rPoly.GetPolyPolygon());
|
|
|
|
Rectangle aBound(aPolyPolygon.GetBoundRect());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// prepare VDev and MetaFile
|
|
|
|
aVDev.EnableOutput(FALSE);
|
|
|
|
aVDev.SetMapMode(rXOut.GetOutDev()->GetMapMode());
|
|
|
|
aMetaFile.Record(&aVDev);
|
|
|
|
|
|
|
|
aVDev.SetFont(rXOut.GetOutDev()->GetFont());
|
|
|
|
aVDev.SetDrawMode(rXOut.GetOutDev()->GetDrawMode());
|
|
|
|
aVDev.SetRefPoint(rXOut.GetOutDev()->GetRefPoint());
|
|
|
|
|
|
|
|
// create output
|
2001-07-19 15:59:49 +00:00
|
|
|
for(UINT16 a(0); a < aPolyPolygon.Count(); a++)
|
|
|
|
{
|
|
|
|
if(rPoly[a].IsClosed())
|
|
|
|
{
|
|
|
|
aVDev.SetLineColor();
|
|
|
|
aVDev.SetFillColor(aCol);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aVDev.SetLineColor(aCol);
|
|
|
|
aVDev.SetFillColor();
|
|
|
|
}
|
|
|
|
|
|
|
|
aMetaFile.AddAction(new MetaPolygonAction(aPolyPolygon[a]));
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
// no transparence, draw all single polys directly
|
|
|
|
for(UINT16 a(0); a < rPoly.Count(); a++)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
if(rPoly[a].IsClosed())
|
|
|
|
{
|
|
|
|
pDevice->SetLineColor();
|
|
|
|
pDevice->SetFillColor(aCol);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pDevice->SetLineColor(aCol);
|
|
|
|
pDevice->SetFillColor();
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2001-07-19 15:59:49 +00:00
|
|
|
pDevice->DrawPolygon(rPoly[a].GetPolygon());
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* convert given PolyPolygon3D to screen coor
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
XPolyPolygon E3dCompoundObject::TransformToScreenCoor(const PolyPolygon3D &rExtrudePoly)
|
|
|
|
{
|
|
|
|
XPolyPolygon aNewPolyPolygon;
|
2001-07-19 15:59:49 +00:00
|
|
|
B3dTransformationSet& rTransSet = GetScene()->GetCameraSet();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// set ObjectTrans
|
|
|
|
Matrix4D mTransform = GetFullTransform();
|
2001-07-19 15:59:49 +00:00
|
|
|
rTransSet.SetObjectTrans(mTransform);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// 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++)
|
|
|
|
{
|
2001-07-19 15:59:49 +00:00
|
|
|
Vector3D aPoint = rTransSet.ObjectToViewCoor(rExtPoly[b]);
|
2000-09-18 16:07:07 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2004-02-26 16:45:55 +00:00
|
|
|
// #110988#
|
|
|
|
double E3dCompoundObject::GetMinimalDepthInViewCoor(E3dScene& rScene) const
|
|
|
|
{
|
|
|
|
double fRetval(DBL_MAX);
|
|
|
|
B3dTransformationSet& rTransSet = rScene.GetCameraSet();
|
|
|
|
Matrix4D mTransform = ((E3dCompoundObject*)this)->GetFullTransform();
|
|
|
|
rTransSet.SetObjectTrans(mTransform);
|
|
|
|
B3dEntityBucket& rEntityBucket = ((E3dCompoundObject*)this)->GetDisplayGeometry().GetEntityBucket();
|
|
|
|
GeometryIndexValueBucket& rIndexBucket = ((E3dCompoundObject*)this)->GetDisplayGeometry().GetIndexBucket();
|
|
|
|
sal_uInt32 nPolyCounter(0L);
|
|
|
|
sal_uInt32 nEntityCounter(0L);
|
|
|
|
|
|
|
|
while(nPolyCounter < rIndexBucket.Count())
|
|
|
|
{
|
|
|
|
sal_uInt32 nUpperBound(rIndexBucket[nPolyCounter++].GetIndex());
|
|
|
|
|
|
|
|
while(nEntityCounter < nUpperBound)
|
|
|
|
{
|
|
|
|
Vector3D aNewPoint = rEntityBucket[nEntityCounter++].Point().GetVector3D();
|
|
|
|
aNewPoint = rTransSet.ObjectToViewCoor(aNewPoint);
|
|
|
|
|
|
|
|
if(aNewPoint.Z() < fRetval)
|
|
|
|
{
|
|
|
|
fRetval = aNewPoint.Z();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return fRetval;
|
|
|
|
}
|
|
|
|
|
|
|
|
// #110988#
|
|
|
|
sal_Bool E3dCompoundObject::IsAOrdNumRemapCandidate(E3dScene*& prScene) const
|
|
|
|
{
|
|
|
|
if(GetObjList()
|
|
|
|
&& GetObjList()->GetOwnerObj()
|
|
|
|
&& GetObjList()->GetOwnerObj()->ISA(E3dScene))
|
|
|
|
{
|
|
|
|
prScene = (E3dScene*)GetObjList()->GetOwnerObj();
|
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sal_False;
|
|
|
|
}
|
|
|
|
|
2000-10-30 10:00:01 +00:00
|
|
|
// EOF
|