1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: obj3d.cxx,v $
10 * $Revision: 1.48.18.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
35 #include "svdglob.hxx"
36 #include <svx/svdview.hxx>
37 #include <svx/svdattr.hxx>
38 #include <svx/svdpage.hxx>
39 #include <svx/svdmodel.hxx>
40 #include "svditer.hxx"
41 #include "globl3d.hxx"
42 #include <svx/camera3d.hxx>
43 #include <svx/scene3d.hxx>
44 #include <svx/polysc3d.hxx>
45 #include <svx/cube3d.hxx>
46 #include <svx/lathe3d.hxx>
47 #include <svx/sphere3d.hxx>
48 #include <svx/extrud3d.hxx>
49 #include <svx/obj3d.hxx>
50 #include <svx/xtable.hxx>
51 #include <svx/xflclit.hxx>
52 #include <vcl/svapp.hxx>
53 #include <vcl/settings.hxx>
54 #include <svx/xlnclit.hxx>
55 #include <svtools/metitem.hxx>
56 #include <svx/xtable.hxx>
57 #include <svx/xfillit.hxx>
58 #include <svx/xlnwtit.hxx>
59 #include <vcl/virdev.hxx>
60 #include <tools/poly.hxx>
61 #include <goodies/b3dtrans.hxx>
62 #include <svx/svxids.hrc>
63 #include <svx/colritem.hxx>
64 #include <svx/e3ditem.hxx>
65 #include <svx/xlntrit.hxx>
66 #include <svx/xfltrit.hxx>
67 #include <svx/svdpagv.hxx>
68 #include <vcl/gradient.hxx>
69 #include <vcl/metaact.hxx>
70 #include <svx/svx3ditems.hxx>
71 #include <svtools/whiter.hxx>
72 #include <svtools/colorcfg.hxx>
73 #include <svx/eeitem.hxx>
74 #include <svx/xgrscit.hxx>
75 #include "svdoimp.hxx"
76 #include <svx/sdr/properties/e3dproperties.hxx>
77 #include <svx/sdr/properties/e3dcompoundproperties.hxx>
78 #include <basegfx/polygon/b3dpolypolygontools.hxx>
79 #include <basegfx/point/b3dpoint.hxx>
80 #include <basegfx/vector/b3dvector.hxx>
81 #include <svx/xlndsit.hxx>
82 #include <basegfx/matrix/b3dhommatrix.hxx>
83 #include <basegfx/polygon/b3dpolygon.hxx>
84 #include <basegfx/matrix/b2dhommatrix.hxx>
85 #include <basegfx/polygon/b2dpolypolygontools.hxx>
86 #include <basegfx/polygon/b3dpolygontools.hxx>
87 #include <svx/helperhittest3d.hxx>
88 #include <svx/sdr/contact/viewcontactofe3d.hxx>
89 #include <drawinglayer/geometry/viewinformation3d.hxx>
90 #include <com/sun/star/uno/Sequence.h>
91 #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
92 #include <basegfx/polygon/b3dpolypolygontools.hxx>
93 #include <svx/e3dsceneupdater.hxx>
95 #define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
97 //////////////////////////////////////////////////////////////////////////////
99 using namespace com::sun::star
;
101 /*************************************************************************
103 |* Liste fuer 3D-Objekte
105 \************************************************************************/
107 TYPEINIT1(E3dObjList
, SdrObjList
);
109 E3dObjList::E3dObjList(SdrModel
* pNewModel
, SdrPage
* pNewPage
, E3dObjList
* pNewUpList
)
110 : SdrObjList(pNewModel
, pNewPage
, pNewUpList
)
114 E3dObjList::E3dObjList(const E3dObjList
& rSrcList
)
115 : SdrObjList(rSrcList
)
119 E3dObjList::~E3dObjList()
123 void E3dObjList::NbcInsertObject(SdrObject
* pObj
, ULONG nPos
, const SdrInsertReason
* pReason
)
126 DBG_ASSERT(GetOwnerObj()->ISA(E3dObject
), "AW: Einfuegen 3DObject in Parent != 3DObject");
128 // Ist es ueberhaupt ein 3D-Objekt?
129 if(pObj
&& pObj
->ISA(E3dObject
))
131 // Normales 3D Objekt, einfuegen mittels
133 SdrObjList::NbcInsertObject(pObj
, nPos
, pReason
);
137 // Kein 3D Objekt, fuege in Seite statt in Szene ein...
138 GetOwnerObj()->GetPage()->InsertObject(pObj
, nPos
);
142 void E3dObjList::InsertObject(SdrObject
* pObj
, ULONG nPos
, const SdrInsertReason
* pReason
)
144 OSL_ENSURE(GetOwnerObj()->ISA(E3dObject
), "Insert 3DObject in non-3D Parent");
145 //E3DModifySceneSnapRectUpdater aUpdater(GetOwnerObj());
148 SdrObjList::InsertObject(pObj
, nPos
, pReason
);
150 E3dScene
* pScene
= ((E3dObject
*)GetOwnerObj())->GetScene();
153 pScene
->Cleanup3DDepthMapper();
157 SdrObject
* E3dObjList::NbcRemoveObject(ULONG nObjNum
)
159 DBG_ASSERT(GetOwnerObj()->ISA(E3dObject
), "AW: Entfernen 3DObject aus Parent != 3DObject");
160 //E3DModifySceneSnapRectUpdater aUpdater(GetOwnerObj());
163 SdrObject
* pRetval
= SdrObjList::NbcRemoveObject(nObjNum
);
165 E3dScene
* pScene
= ((E3dObject
*)GetOwnerObj())->GetScene();
168 pScene
->Cleanup3DDepthMapper();
174 SdrObject
* E3dObjList::RemoveObject(ULONG nObjNum
)
176 OSL_ENSURE(GetOwnerObj()->ISA(E3dObject
), "3DObject is removed from non-3D Parent");
177 //E3DModifySceneSnapRectUpdater aUpdater(GetOwnerObj());
180 SdrObject
* pRetval
= SdrObjList::RemoveObject(nObjNum
);
182 E3dScene
* pScene
= ((E3dObject
*)GetOwnerObj())->GetScene();
185 pScene
->Cleanup3DDepthMapper();
191 /*************************************************************************
195 \************************************************************************/
197 //////////////////////////////////////////////////////////////////////////////
199 sdr::properties::BaseProperties
* E3dObject::CreateObjectSpecificProperties()
201 return new sdr::properties::E3dProperties(*this);
204 ////////////////////////////////////////////////////////////////////////////////////////////////////
206 TYPEINIT1(E3dObject
, SdrAttrObj
);
208 E3dObject::E3dObject()
213 mbTfHasChanged(true),
217 maSubList
.SetOwnerObj(this);
218 maSubList
.SetListKind(SDROBJLIST_GROUPOBJ
);
222 /*************************************************************************
226 \************************************************************************/
228 E3dObject::~E3dObject()
232 /*************************************************************************
234 |* Selektions-Flag setzen
236 \************************************************************************/
238 void E3dObject::SetSelected(bool bNew
)
240 if((bool)mbIsSelected
!= bNew
)
245 for(sal_uInt32
a(0); a
< maSubList
.GetObjCount(); a
++)
247 E3dObject
* pCandidate
= dynamic_cast< E3dObject
* >(maSubList
.GetObj(a
));
251 pCandidate
->SetSelected(bNew
);
256 /*************************************************************************
258 |* Aufbrechen, default-Implementierungen
260 \************************************************************************/
262 BOOL
E3dObject::IsBreakObjPossible()
267 SdrAttrObj
* E3dObject::GetBreakObj()
272 /*************************************************************************
274 |* SetRectsDirty muss ueber die lokale SdrSubList gehen
276 \************************************************************************/
278 void E3dObject::SetRectsDirty(sal_Bool bNotMyself
)
281 SdrAttrObj::SetRectsDirty(bNotMyself
);
283 for(sal_uInt32
a(0); a
< maSubList
.GetObjCount(); a
++)
285 E3dObject
* pCandidate
= dynamic_cast< E3dObject
* >(maSubList
.GetObj(a
));
289 pCandidate
->SetRectsDirty(bNotMyself
);
294 /*************************************************************************
296 |* Inventor zurueckgeben
298 \************************************************************************/
300 UINT32
E3dObject::GetObjInventor() const
305 /*************************************************************************
307 |* Identifier zurueckgeben
309 \************************************************************************/
311 UINT16
E3dObject::GetObjIdentifier() const
313 return E3D_OBJECT_ID
;
316 /*************************************************************************
318 |* Faehigkeiten des Objektes feststellen
320 \************************************************************************/
322 void E3dObject::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
324 rInfo
.bResizeFreeAllowed
= TRUE
;
325 rInfo
.bResizePropAllowed
= TRUE
;
326 rInfo
.bRotateFreeAllowed
= TRUE
;
327 rInfo
.bRotate90Allowed
= TRUE
;
328 rInfo
.bMirrorFreeAllowed
= FALSE
;
329 rInfo
.bMirror45Allowed
= FALSE
;
330 rInfo
.bMirror90Allowed
= FALSE
;
331 rInfo
.bShearAllowed
= FALSE
;
332 rInfo
.bEdgeRadiusAllowed
= FALSE
;
333 rInfo
.bCanConvToPath
= FALSE
;
335 // no transparence for 3d objects
336 rInfo
.bTransparenceAllowed
= FALSE
;
338 // gradient depends on fillstyle
339 // BM *** check if SetItem is NULL ***
340 XFillStyle eFillStyle
= ((XFillStyleItem
&)(GetMergedItem(XATTR_FILLSTYLE
))).GetValue();
341 rInfo
.bGradientAllowed
= (eFillStyle
== XFILL_GRADIENT
);
343 // Umwandeln von 3D-Koerpern in Gruppe von Polygonen:
345 // Erst mal nicht moeglich, da die Erzeugung einer Gruppe von
346 // 2D-Polygonen notwendig waere, die tiefensortiert werden muessten,
347 // also bei Durchdringugnen auch gegeneinander geschnitten werden
348 // muessten. Auch die Texturkoorinaten waeren ein ungeloestes
350 rInfo
.bCanConvToPoly
= FALSE
;
351 rInfo
.bCanConvToContour
= FALSE
;
352 rInfo
.bCanConvToPathLineToArea
= FALSE
;
353 rInfo
.bCanConvToPolyLineToArea
= FALSE
;
356 /*************************************************************************
360 \************************************************************************/
362 void E3dObject::NbcSetLayer(SdrLayerID nLayer
)
364 SdrAttrObj::NbcSetLayer(nLayer
);
366 for(sal_uInt32
a(0); a
< maSubList
.GetObjCount(); a
++)
368 E3dObject
* pCandidate
= dynamic_cast< E3dObject
* >(maSubList
.GetObj(a
));
372 pCandidate
->NbcSetLayer(nLayer
);
377 /*************************************************************************
379 |* ObjList auch an SubList setzen
381 \************************************************************************/
383 void E3dObject::SetObjList(SdrObjList
* pNewObjList
)
385 SdrObject::SetObjList(pNewObjList
);
386 maSubList
.SetUpList(pNewObjList
);
389 /*************************************************************************
393 \************************************************************************/
395 void E3dObject::SetPage(SdrPage
* pNewPage
)
397 SdrAttrObj::SetPage(pNewPage
);
398 maSubList
.SetPage(pNewPage
);
401 /*************************************************************************
405 \************************************************************************/
407 void E3dObject::SetModel(SdrModel
* pNewModel
)
409 SdrAttrObj::SetModel(pNewModel
);
410 maSubList
.SetModel(pNewModel
);
413 /*************************************************************************
415 |* resize object, used from old 2d interfaces, e.g. in Move/Scale dialog
418 \************************************************************************/
419 void E3dObject::NbcResize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
)
421 // Bewegung in X,Y im Augkoordinatensystem
422 E3dScene
* pScene
= GetScene();
426 // transform pos from 2D world to 3D eye
427 const sdr::contact::ViewContactOfE3dScene
& rVCScene
= static_cast< sdr::contact::ViewContactOfE3dScene
& >(pScene
->GetViewContact());
428 const drawinglayer::geometry::ViewInformation3D
aViewInfo3D(rVCScene
.getViewInformation3D());
429 basegfx::B2DPoint
aScaleCenter2D((double)rRef
.X(), (double)rRef
.Y());
430 basegfx::B2DHomMatrix
aInverseSceneTransform(rVCScene
.getObjectTransformation());
432 aInverseSceneTransform
.invert();
433 aScaleCenter2D
= aInverseSceneTransform
* aScaleCenter2D
;
435 basegfx::B3DPoint
aScaleCenter3D(aScaleCenter2D
.getX(), aScaleCenter2D
.getY(), 0.5);
436 basegfx::B3DHomMatrix
aInverseViewToEye(aViewInfo3D
.getDeviceToView() * aViewInfo3D
.getProjection());
438 aInverseViewToEye
.invert();
439 aScaleCenter3D
= aInverseViewToEye
* aScaleCenter3D
;
441 // scale-faktoren holen
442 double fScaleX(xFact
);
443 double fScaleY(yFact
);
446 basegfx::B3DHomMatrix
aInverseOrientation(aViewInfo3D
.getOrientation());
447 aInverseOrientation
.invert();
448 basegfx::B3DHomMatrix
mFullTransform(GetFullTransform());
449 basegfx::B3DHomMatrix
mTrans(mFullTransform
);
451 mTrans
*= aViewInfo3D
.getOrientation();
452 mTrans
.translate(-aScaleCenter3D
.getX(), -aScaleCenter3D
.getY(), -aScaleCenter3D
.getZ());
453 mTrans
.scale(fScaleX
, fScaleY
, 1.0);
454 mTrans
.translate(aScaleCenter3D
.getX(), aScaleCenter3D
.getY(), aScaleCenter3D
.getZ());
455 mTrans
*= aInverseOrientation
;
456 mFullTransform
.invert();
457 mTrans
*= mFullTransform
;
460 basegfx::B3DHomMatrix
mObjTrans(GetTransform());
463 E3DModifySceneSnapRectUpdater
aUpdater(this);
464 SetTransform(mObjTrans
);
468 /*************************************************************************
470 |* Objekt verschieben in 2D, wird bei Cursortasten benoetigt
472 \************************************************************************/
473 void E3dObject::NbcMove(const Size
& rSize
)
475 // Bewegung in X,Y im Augkoordinatensystem
476 E3dScene
* pScene
= GetScene();
480 // Abmessungen der Szene in 3D und 2D als Vergleich
481 Rectangle aRect
= pScene
->GetSnapRect();
483 // Transformation Weltkoordinaten bis eine VOR Objektkoordinaten holen
484 basegfx::B3DHomMatrix mInvDispTransform
;
487 mInvDispTransform
= GetParentObj()->GetFullTransform();
488 mInvDispTransform
.invert();
491 // BoundVolume from 3d world to 3d eye
492 const sdr::contact::ViewContactOfE3dScene
& rVCScene
= static_cast< sdr::contact::ViewContactOfE3dScene
& >(pScene
->GetViewContact());
493 const drawinglayer::geometry::ViewInformation3D
aViewInfo3D(rVCScene
.getViewInformation3D());
494 basegfx::B3DRange
aEyeVol(pScene
->GetBoundVolume());
495 aEyeVol
.transform(aViewInfo3D
.getOrientation());
497 // build relative movement vector in eye coordinates
498 basegfx::B3DPoint
aMove(
499 (double)rSize
.Width() * aEyeVol
.getWidth() / (double)aRect
.GetWidth(),
500 (double)-rSize
.Height() * aEyeVol
.getHeight() / (double)aRect
.GetHeight(),
502 basegfx::B3DPoint
aPos(0.0, 0.0, 0.0);
504 // movement vektor to local coordinates of objects' parent
505 basegfx::B3DHomMatrix
aInverseOrientation(aViewInfo3D
.getOrientation());
506 aInverseOrientation
.invert();
507 basegfx::B3DHomMatrix
aCompleteTrans(mInvDispTransform
* aInverseOrientation
);
509 aMove
= aCompleteTrans
* aMove
;
510 aPos
= aCompleteTrans
* aPos
;
512 // build transformation and apply
513 basegfx::B3DHomMatrix aTranslate
;
514 aTranslate
.translate(aMove
.getX() - aPos
.getX(), aMove
.getY() - aPos
.getY(), aMove
.getZ() - aPos
.getZ());
516 E3DModifySceneSnapRectUpdater
aUpdater(pScene
);
517 SetTransform(aTranslate
* GetTransform());
521 /*************************************************************************
523 |* liefere die Sublist, aber nur dann, wenn darin Objekte enthalten sind !
525 \************************************************************************/
527 SdrObjList
* E3dObject::GetSubList() const
529 return &(const_cast< E3dObjList
& >(maSubList
));
532 /*************************************************************************
534 |* SnapRect berechnen
536 \************************************************************************/
538 void E3dObject::RecalcSnapRect()
540 maSnapRect
= Rectangle();
542 for(sal_uInt32
a(0); a
< maSubList
.GetObjCount(); a
++)
544 E3dObject
* pCandidate
= dynamic_cast< E3dObject
* >(maSubList
.GetObj(a
));
548 maSnapRect
.Union(pCandidate
->GetSnapRect());
553 /*************************************************************************
555 |* Einfuegen eines 3D-Objekts an den Parent weitermelden, damit dieser
556 |* ggf. eine Sonderbehandlung fuer spezielle Objekte durchfuehren kann
557 |* (z.B. Light/Label in E3dScene)
559 \************************************************************************/
561 void E3dObject::NewObjectInserted(const E3dObject
* p3DObj
)
564 GetParentObj()->NewObjectInserted(p3DObj
);
567 /*************************************************************************
569 |* Parent ueber Aenderung der Struktur (z.B. durch Transformation)
570 |* informieren; dabei wird das Objekt, in welchem die Aenderung
571 |* aufgetreten ist, uebergeben
573 \************************************************************************/
575 void E3dObject::StructureChanged()
577 if ( GetParentObj() )
579 GetParentObj()->InvalidateBoundVolume();
580 GetParentObj()->StructureChanged();
584 /*************************************************************************
586 |* 3D-Objekt einfuegen
588 \************************************************************************/
590 void E3dObject::Insert3DObj(E3dObject
* p3DObj
)
592 DBG_ASSERT(p3DObj
, "Insert3DObj mit NULL-Zeiger!");
593 SdrPage
* pPg
= pPage
;
594 maSubList
.InsertObject(p3DObj
);
596 InvalidateBoundVolume();
597 NewObjectInserted(p3DObj
);
601 void E3dObject::Remove3DObj(E3dObject
* p3DObj
)
603 DBG_ASSERT(p3DObj
, "Remove3DObj mit NULL-Zeiger!");
605 if(p3DObj
->GetParentObj() == this)
607 SdrPage
* pPg
= pPage
;
608 maSubList
.RemoveObject(p3DObj
->GetOrdNum());
611 InvalidateBoundVolume();
616 /*************************************************************************
620 \************************************************************************/
622 E3dObject
* E3dObject::GetParentObj() const
624 E3dObject
* pRetval
= NULL
;
627 && GetObjList()->GetOwnerObj()
628 && GetObjList()->GetOwnerObj()->ISA(E3dObject
))
629 pRetval
= ((E3dObject
*)GetObjList()->GetOwnerObj());
633 /*************************************************************************
635 |* Uebergeordnetes Szenenobjekt bestimmen
637 \************************************************************************/
639 E3dScene
* E3dObject::GetScene() const
642 return GetParentObj()->GetScene();
646 /*************************************************************************
648 |* umschliessendes Volumen inklusive aller Kindobjekte berechnen
650 \************************************************************************/
652 basegfx::B3DRange
E3dObject::RecalcBoundVolume() const
654 basegfx::B3DRange aRetval
;
655 const sal_uInt32
nObjCnt(maSubList
.GetObjCount());
659 for(sal_uInt32
a(0); a
< nObjCnt
; a
++)
661 const E3dObject
* p3DObject
= dynamic_cast< const E3dObject
* >(maSubList
.GetObj(a
));
665 basegfx::B3DRange
aLocalRange(p3DObject
->GetBoundVolume());
666 aLocalRange
.transform(p3DObject
->GetTransform());
667 aRetval
.expand(aLocalRange
);
674 const sdr::contact::ViewContactOfE3d
* pVCOfE3D
= dynamic_cast< const sdr::contact::ViewContactOfE3d
* >(&GetViewContact());
678 // BoundVolume is without 3D object transformation, use correct sequence
679 const drawinglayer::primitive3d::Primitive3DSequence
xLocalSequence(pVCOfE3D
->getVIP3DSWithoutObjectTransform());
681 if(xLocalSequence
.hasElements())
683 const uno::Sequence
< beans::PropertyValue
> aEmptyParameters
;
684 const drawinglayer::geometry::ViewInformation3D
aLocalViewInformation3D(aEmptyParameters
);
686 aRetval
= drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
687 xLocalSequence
, aLocalViewInformation3D
);
695 /*************************************************************************
697 |* umschliessendes Volumen zurueckgeben und ggf. neu berechnen
699 \************************************************************************/
701 const basegfx::B3DRange
& E3dObject::GetBoundVolume() const
703 if(maLocalBoundVol
.isEmpty())
705 const_cast< E3dObject
* >(this)->maLocalBoundVol
= RecalcBoundVolume();
708 return maLocalBoundVol
;
711 void E3dObject::InvalidateBoundVolume()
713 maLocalBoundVol
.reset();
716 /*************************************************************************
718 |* Aederung des BoundVolumes an alle Kindobjekte weitergeben
720 \************************************************************************/
722 void E3dObject::SetBoundVolInvalid()
724 InvalidateBoundVolume();
726 for(sal_uInt32
a(0); a
< maSubList
.GetObjCount(); a
++)
728 E3dObject
* pCandidate
= dynamic_cast< E3dObject
* >(maSubList
.GetObj(a
));
732 pCandidate
->SetBoundVolInvalid();
737 /*************************************************************************
739 |* Aederung der Transformation an alle Kindobjekte weitergeben
741 \************************************************************************/
743 void E3dObject::SetTransformChanged()
745 InvalidateBoundVolume();
746 mbTfHasChanged
= true;
748 for(sal_uInt32
a(0); a
< maSubList
.GetObjCount(); a
++)
750 E3dObject
* pCandidate
= dynamic_cast< E3dObject
* >(maSubList
.GetObj(a
));
754 pCandidate
->SetTransformChanged();
759 /*************************************************************************
761 |* hierarchische Transformation ueber alle Parents bestimmen, in
762 |* maFullTransform ablegen und diese zurueckgeben
764 \************************************************************************/
766 const basegfx::B3DHomMatrix
& E3dObject::GetFullTransform() const
770 basegfx::B3DHomMatrix
aNewFullTransformation(maTransformation
);
772 if ( GetParentObj() )
774 aNewFullTransformation
= GetParentObj()->GetFullTransform() * aNewFullTransformation
;
777 const_cast< E3dObject
* >(this)->maFullTransform
= aNewFullTransformation
;
778 const_cast< E3dObject
* >(this)->mbTfHasChanged
= false;
781 return maFullTransform
;
784 /*************************************************************************
786 |* Transformationsmatrix abfragen
788 \************************************************************************/
790 const basegfx::B3DHomMatrix
& E3dObject::GetTransform() const
792 return maTransformation
;
795 /*************************************************************************
797 |* Transformationsmatrix setzen
799 \************************************************************************/
801 void E3dObject::NbcSetTransform(const basegfx::B3DHomMatrix
& rMatrix
)
803 if(maTransformation
!= rMatrix
)
805 maTransformation
= rMatrix
;
806 SetTransformChanged();
811 /*************************************************************************
813 |* Transformationsmatrix setzen mit Repaint-Broadcast
815 \************************************************************************/
817 void E3dObject::SetTransform(const basegfx::B3DHomMatrix
& rMatrix
)
819 if(rMatrix
!= maTransformation
)
821 // #110094#-14 SendRepaintBroadcast();
822 NbcSetTransform(rMatrix
);
824 BroadcastObjectChange();
825 if (pUserCall
!= NULL
) pUserCall
->Changed(*this, SDRUSERCALL_RESIZE
, Rectangle());
829 /*************************************************************************
831 |* Linien fuer die Wireframe-Darstellung des Objekts dem uebergebenen
832 |* basegfx::B3DPolygon hinzufuegen
834 \************************************************************************/
836 basegfx::B3DPolyPolygon
E3dObject::CreateWireframe() const
838 const basegfx::B3DRange
aBoundVolume(GetBoundVolume());
839 return basegfx::tools::createCubePolyPolygonFromB3DRange(aBoundVolume
);
842 /*************************************************************************
844 |* Get the name of the object (singular)
846 \************************************************************************/
848 void E3dObject::TakeObjNameSingul(XubString
& rName
) const
850 rName
=ImpGetResStr(STR_ObjNameSingulObj3d
);
852 String
aName( GetName() );
855 rName
+= sal_Unicode(' ');
856 rName
+= sal_Unicode('\'');
858 rName
+= sal_Unicode('\'');
862 /*************************************************************************
864 |* Get the name of the object (plural)
866 \************************************************************************/
868 void E3dObject::TakeObjNamePlural(XubString
& rName
) const
870 rName
=ImpGetResStr(STR_ObjNamePluralObj3d
);
873 /*************************************************************************
875 |* Zuweisungsoperator
877 \************************************************************************/
879 void E3dObject::operator=(const SdrObject
& rObj
)
881 SdrObject::operator=(rObj
);
883 const E3dObject
& r3DObj
= (const E3dObject
&) rObj
;
884 if (r3DObj
.GetSubList())
886 maSubList
.CopyObjects(*r3DObj
.GetSubList());
889 // BoundVol kann uebernommen werden, da die Childs auch kopiert werden
890 maLocalBoundVol
= r3DObj
.maLocalBoundVol
;
891 maTransformation
= r3DObj
.maTransformation
;
893 // Da sich der Parent geaendert haben kann, Gesamttransformation beim
894 // naechsten Mal auf jeden Fall neu bestimmen
895 SetTransformChanged();
897 // Selektionsstatus kopieren
898 mbIsSelected
= r3DObj
.mbIsSelected
;
901 /*************************************************************************
903 |* erstelle neues GeoData-Objekt
905 \************************************************************************/
907 SdrObjGeoData
*E3dObject::NewGeoData() const
909 // Theoretisch duerfen auch nur Szenen ihre GeoDatas erstellen und verwalten !!
910 // AW: Dies stimmt nicht mehr, diese Stelle ist mit der neuen Engine OK!
911 return new E3DObjGeoData
;
914 /*************************************************************************
916 |* uebergebe aktuelle werte an das GeoData-Objekt
918 \************************************************************************/
920 void E3dObject::SaveGeoData(SdrObjGeoData
& rGeo
) const
922 SdrAttrObj::SaveGeoData (rGeo
);
924 ((E3DObjGeoData
&) rGeo
).maLocalBoundVol
= maLocalBoundVol
;
925 ((E3DObjGeoData
&) rGeo
).maTransformation
= maTransformation
;
928 /*************************************************************************
930 |* uebernehme werte aus dem GeoData-Objekt
932 \************************************************************************/
934 void E3dObject::RestGeoData(const SdrObjGeoData
& rGeo
)
936 maLocalBoundVol
= ((E3DObjGeoData
&) rGeo
).maLocalBoundVol
;
937 E3DModifySceneSnapRectUpdater
aUpdater(this);
938 NbcSetTransform(((E3DObjGeoData
&) rGeo
).maTransformation
);
939 SdrAttrObj::RestGeoData (rGeo
);
942 /*************************************************************************
944 |* Rotation eines 3d-Koerpers
946 \************************************************************************/
947 // 2D-rotation eines 3D-Koerpers, normalerweise macht das die Szene selbst
948 // Ist aber eine korrekte Implementierung, denn alles was passiert ist eine
949 // Rotation um die Achse die senkrecht auf dem Bildschirm steht und zwar
950 // unabhaengig davon, wie die Szene bisher gedreht worden ist.
952 void E3dObject::NbcRotate(const Point
& rRef
, long nWink
, double sn
, double cs
)
954 // Also derzeit sind die Klebepunkte relativ zum aOutRect der Szene definiert. Vor dem Drehen
955 // werden die Klebepunkte relativ zur Seite definiert. Sie nehmen an der Drehung der Szene noch nicht Teil
956 // dafuer gibt es den
957 SetGlueReallyAbsolute(TRUE
);
959 // SendRepaintBroadcast();
960 double fWinkelInRad
= nWink
/100 * F_PI180
;
962 basegfx::B3DHomMatrix aRotateZ
;
963 aRotateZ
.rotate(0.0, 0.0, fWinkelInRad
);
964 NbcSetTransform(aRotateZ
* GetTransform());
966 SetRectsDirty(); // Veranlasst eine Neuberechnung aller BoundRects
967 NbcRotateGluePoints(rRef
,nWink
,sn
,cs
); // Rotiert die Klebepunkte (die haben noch Koordinaten relativ
968 // zum Urpsung des Blattes
969 SetGlueReallyAbsolute(FALSE
); // ab jetzt sind sie wieder relativ zum BoundRect (also dem aOutRect definiert)
972 /*************************************************************************/
974 //////////////////////////////////////////////////////////////////////////////
976 sdr::properties::BaseProperties
* E3dCompoundObject::CreateObjectSpecificProperties()
978 return new sdr::properties::E3dCompoundProperties(*this);
981 ////////////////////////////////////////////////////////////////////////////////////////////////////
983 TYPEINIT1(E3dCompoundObject
, E3dObject
);
985 /*************************************************************************
989 \************************************************************************/
991 E3dCompoundObject::E3dCompoundObject()
993 aMaterialAmbientColor(),
994 bCreateNormals(false),
995 bCreateTexture(false)
998 E3dDefaultAttributes aDefault
;
999 SetDefaultAttributes(aDefault
);
1002 E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes
& rDefault
)
1004 aMaterialAmbientColor(),
1005 bCreateNormals(false),
1006 bCreateTexture(false)
1009 SetDefaultAttributes(rDefault
);
1012 void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes
& rDefault
)
1015 aMaterialAmbientColor
= rDefault
.GetDefaultAmbientColor();
1017 bCreateNormals
= rDefault
.GetDefaultCreateNormals();
1018 bCreateTexture
= rDefault
.GetDefaultCreateTexture();
1021 /*************************************************************************
1025 \************************************************************************/
1027 E3dCompoundObject::~E3dCompoundObject ()
1031 /*************************************************************************
1033 |* Drag-Polygon zurueckgeben
1035 \************************************************************************/
1037 basegfx::B2DPolyPolygon
E3dCompoundObject::TakeXorPoly() const
1039 basegfx::B2DPolyPolygon aRetval
;
1040 const uno::Sequence
< beans::PropertyValue
> aEmptyParameters
;
1041 drawinglayer::geometry::ViewInformation3D
aViewInfo3D(aEmptyParameters
);
1042 E3dScene
* pRootScene
= fillViewInformation3DForCompoundObject(aViewInfo3D
, *this);
1046 const sdr::contact::ViewContactOfE3dScene
& rVCScene
= static_cast< sdr::contact::ViewContactOfE3dScene
& >(pRootScene
->GetViewContact());
1047 const basegfx::B3DPolyPolygon
aCubePolyPolygon(CreateWireframe());
1048 aRetval
= basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCubePolyPolygon
,
1049 aViewInfo3D
.getObjectToView() * GetTransform());
1050 aRetval
.transform(rVCScene
.getObjectTransformation());
1056 /*************************************************************************
1058 |* Anzahl der Handles zurueckgeben
1060 \************************************************************************/
1062 sal_uInt32
E3dCompoundObject::GetHdlCount() const
1064 // 8 Eckpunkte + 1 E3dVolumeMarker (= Wireframe-Darstellung)
1068 /*************************************************************************
1070 |* Handle-Liste fuellen
1072 \************************************************************************/
1074 void E3dCompoundObject::AddToHdlList(SdrHdlList
& rHdlList
) const
1076 const uno::Sequence
< beans::PropertyValue
> aEmptyParameters
;
1077 drawinglayer::geometry::ViewInformation3D
aViewInfo3D(aEmptyParameters
);
1078 E3dScene
* pRootScene
= fillViewInformation3DForCompoundObject(aViewInfo3D
, *this);
1082 const basegfx::B3DRange
aBoundVolume(GetBoundVolume());
1084 if(!aBoundVolume
.isEmpty())
1086 const sdr::contact::ViewContactOfE3dScene
& rVCScene
= static_cast< sdr::contact::ViewContactOfE3dScene
& >(pRootScene
->GetViewContact());
1088 for(sal_uInt32
a(0); a
< 8; a
++)
1090 basegfx::B3DPoint aPos3D
;
1094 case 0 : aPos3D
.setX(aBoundVolume
.getMinX()); aPos3D
.setY(aBoundVolume
.getMinY()); aPos3D
.setZ(aBoundVolume
.getMinZ()); break;
1095 case 1 : aPos3D
.setX(aBoundVolume
.getMinX()); aPos3D
.setY(aBoundVolume
.getMinY()); aPos3D
.setZ(aBoundVolume
.getMaxZ()); break;
1096 case 2 : aPos3D
.setX(aBoundVolume
.getMinX()); aPos3D
.setY(aBoundVolume
.getMaxY()); aPos3D
.setZ(aBoundVolume
.getMinZ()); break;
1097 case 3 : aPos3D
.setX(aBoundVolume
.getMinX()); aPos3D
.setY(aBoundVolume
.getMaxY()); aPos3D
.setZ(aBoundVolume
.getMaxZ()); break;
1098 case 4 : aPos3D
.setX(aBoundVolume
.getMaxX()); aPos3D
.setY(aBoundVolume
.getMinY()); aPos3D
.setZ(aBoundVolume
.getMinZ()); break;
1099 case 5 : aPos3D
.setX(aBoundVolume
.getMaxX()); aPos3D
.setY(aBoundVolume
.getMinY()); aPos3D
.setZ(aBoundVolume
.getMaxZ()); break;
1100 case 6 : aPos3D
.setX(aBoundVolume
.getMaxX()); aPos3D
.setY(aBoundVolume
.getMaxY()); aPos3D
.setZ(aBoundVolume
.getMinZ()); break;
1101 case 7 : aPos3D
.setX(aBoundVolume
.getMaxX()); aPos3D
.setY(aBoundVolume
.getMaxY()); aPos3D
.setZ(aBoundVolume
.getMaxZ()); break;
1105 aPos3D
*= aViewInfo3D
.getObjectToView() * GetTransform();
1107 // create 2d relative scene
1108 basegfx::B2DPoint
aPos2D(aPos3D
.getX(), aPos3D
.getY());
1111 aPos2D
*= rVCScene
.getObjectTransformation();
1113 rHdlList
.AddHdl(new SdrHdl(Point(basegfx::fround(aPos2D
.getX()), basegfx::fround(aPos2D
.getY())), HDL_BWGT
));
1118 const basegfx::B2DPolyPolygon
aPolyPolygon(TakeXorPoly());
1120 if(aPolyPolygon
.count())
1122 E3dVolumeMarker
* pVolMarker
= new E3dVolumeMarker(aPolyPolygon
);
1123 rHdlList
.AddHdl(pVolMarker
);
1127 /*************************************************************************
1129 |* Identifier zurueckgeben
1131 \************************************************************************/
1133 UINT16
E3dCompoundObject::GetObjIdentifier() const
1135 return E3D_COMPOUNDOBJ_ID
;
1138 /*************************************************************************
1140 |* SnapRect berechnen
1142 \************************************************************************/
1144 void E3dCompoundObject::RecalcSnapRect()
1146 const uno::Sequence
< beans::PropertyValue
> aEmptyParameters
;
1147 drawinglayer::geometry::ViewInformation3D
aViewInfo3D(aEmptyParameters
);
1148 E3dScene
* pRootScene
= fillViewInformation3DForCompoundObject(aViewInfo3D
, *this);
1149 maSnapRect
= Rectangle();
1153 // get VC of 3D candidate
1154 const sdr::contact::ViewContactOfE3d
* pVCOfE3D
= dynamic_cast< const sdr::contact::ViewContactOfE3d
* >(&GetViewContact());
1158 // get 3D primitive sequence
1159 const drawinglayer::primitive3d::Primitive3DSequence
xLocalSequence(pVCOfE3D
->getViewIndependentPrimitive3DSequence());
1161 if(xLocalSequence
.hasElements())
1164 basegfx::B3DRange
aBoundVolume(drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
1165 xLocalSequence
, aViewInfo3D
));
1167 // transform bound volume to relative scene coordinates
1168 aBoundVolume
.transform(aViewInfo3D
.getObjectToView());
1170 // build 2d relative scene range
1171 basegfx::B2DRange
aSnapRange(
1172 aBoundVolume
.getMinX(), aBoundVolume
.getMinY(),
1173 aBoundVolume
.getMaxX(), aBoundVolume
.getMaxY());
1175 // transform to 2D world coordiantes
1176 const sdr::contact::ViewContactOfE3dScene
& rVCScene
= static_cast< sdr::contact::ViewContactOfE3dScene
& >(pRootScene
->GetViewContact());
1177 aSnapRange
.transform(rVCScene
.getObjectTransformation());
1180 maSnapRect
= Rectangle(
1181 sal_Int32(floor(aSnapRange
.getMinX())), sal_Int32(floor(aSnapRange
.getMinY())),
1182 sal_Int32(ceil(aSnapRange
.getMaxX())), sal_Int32(ceil(aSnapRange
.getMaxY())));
1188 /*************************************************************************
1192 \************************************************************************/
1194 void E3dCompoundObject::operator=(const SdrObject
& rObj
)
1196 // erstmal alle Childs kopieren
1197 E3dObject::operator=(rObj
);
1199 // weitere Parameter kopieren
1200 const E3dCompoundObject
& r3DObj
= (const E3dCompoundObject
&) rObj
;
1202 bCreateNormals
= r3DObj
.bCreateNormals
;
1203 bCreateTexture
= r3DObj
.bCreateTexture
;
1204 aMaterialAmbientColor
= r3DObj
.aMaterialAmbientColor
;
1207 /*************************************************************************
1209 |* Parameter Geometrieerzeugung setzen
1211 \************************************************************************/
1213 void E3dCompoundObject::SetCreateNormals(BOOL bNew
)
1215 if(bCreateNormals
!= bNew
)
1217 bCreateNormals
= bNew
;
1222 void E3dCompoundObject::SetCreateTexture(BOOL bNew
)
1224 if(bCreateTexture
!= bNew
)
1226 bCreateTexture
= bNew
;
1231 /*************************************************************************
1233 |* Material des Objektes
1235 \************************************************************************/
1237 void E3dCompoundObject::SetMaterialAmbientColor(const Color
& rColor
)
1239 if(aMaterialAmbientColor
!= rColor
)
1241 aMaterialAmbientColor
= rColor
;
1245 /*************************************************************************
1247 |* convert given basegfx::B3DPolyPolygon to screen coor
1249 \************************************************************************/
1251 basegfx::B2DPolyPolygon
E3dCompoundObject::TransformToScreenCoor(const basegfx::B3DPolyPolygon
& rCandidate
)
1253 const uno::Sequence
< beans::PropertyValue
> aEmptyParameters
;
1254 drawinglayer::geometry::ViewInformation3D
aViewInfo3D(aEmptyParameters
);
1255 E3dScene
* pRootScene
= fillViewInformation3DForCompoundObject(aViewInfo3D
, *this);
1256 basegfx::B2DPolyPolygon aRetval
;
1260 aRetval
= basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(rCandidate
,
1261 aViewInfo3D
.getObjectToView() * GetTransform());
1262 const sdr::contact::ViewContactOfE3dScene
& rVCScene
= static_cast< sdr::contact::ViewContactOfE3dScene
& >(pRootScene
->GetViewContact());
1263 aRetval
.transform(rVCScene
.getObjectTransformation());
1269 sal_Bool
E3dCompoundObject::IsAOrdNumRemapCandidate(E3dScene
*& prScene
) const
1272 && GetObjList()->GetOwnerObj()
1273 && GetObjList()->GetOwnerObj()->ISA(E3dScene
))
1275 prScene
= (E3dScene
*)GetObjList()->GetOwnerObj();
1282 //////////////////////////////////////////////////////////////////////////////