Update ooo320-m1
[ooovba.git] / svx / source / engine3d / obj3d.cxx
blob85c35f03cb1bc860226885d91773a65fe0a28bbb
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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"
34 #include "svdstr.hrc"
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)
125 // Owner holen
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
132 // call parent
133 SdrObjList::NbcInsertObject(pObj, nPos, pReason);
135 else
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());
147 // call parent
148 SdrObjList::InsertObject(pObj, nPos, pReason);
150 E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene();
151 if(pScene)
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());
162 // call parent
163 SdrObject* pRetval = SdrObjList::NbcRemoveObject(nObjNum);
165 E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene();
166 if(pScene)
168 pScene->Cleanup3DDepthMapper();
171 return pRetval;
174 SdrObject* E3dObjList::RemoveObject(ULONG nObjNum)
176 OSL_ENSURE(GetOwnerObj()->ISA(E3dObject), "3DObject is removed from non-3D Parent");
177 //E3DModifySceneSnapRectUpdater aUpdater(GetOwnerObj());
179 // call parent
180 SdrObject* pRetval = SdrObjList::RemoveObject(nObjNum);
182 E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene();
183 if(pScene)
185 pScene->Cleanup3DDepthMapper();
188 return pRetval;
191 /*************************************************************************
193 |* Konstruktor
195 \************************************************************************/
197 //////////////////////////////////////////////////////////////////////////////
199 sdr::properties::BaseProperties* E3dObject::CreateObjectSpecificProperties()
201 return new sdr::properties::E3dProperties(*this);
204 ////////////////////////////////////////////////////////////////////////////////////////////////////
206 TYPEINIT1(E3dObject, SdrAttrObj);
208 E3dObject::E3dObject()
209 : maSubList(),
210 maLocalBoundVol(),
211 maTransformation(),
212 maFullTransform(),
213 mbTfHasChanged(true),
214 mbIsSelected(false)
216 bIs3DObj = true;
217 maSubList.SetOwnerObj(this);
218 maSubList.SetListKind(SDROBJLIST_GROUPOBJ);
219 bClosedObj = true;
222 /*************************************************************************
224 |* Destruktor
226 \************************************************************************/
228 E3dObject::~E3dObject()
232 /*************************************************************************
234 |* Selektions-Flag setzen
236 \************************************************************************/
238 void E3dObject::SetSelected(bool bNew)
240 if((bool)mbIsSelected != bNew)
242 mbIsSelected = bNew;
245 for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
247 E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
249 if(pCandidate)
251 pCandidate->SetSelected(bNew);
256 /*************************************************************************
258 |* Aufbrechen, default-Implementierungen
260 \************************************************************************/
262 BOOL E3dObject::IsBreakObjPossible()
264 return FALSE;
267 SdrAttrObj* E3dObject::GetBreakObj()
269 return 0L;
272 /*************************************************************************
274 |* SetRectsDirty muss ueber die lokale SdrSubList gehen
276 \************************************************************************/
278 void E3dObject::SetRectsDirty(sal_Bool bNotMyself)
280 // call parent
281 SdrAttrObj::SetRectsDirty(bNotMyself);
283 for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
285 E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
287 if(pCandidate)
289 pCandidate->SetRectsDirty(bNotMyself);
294 /*************************************************************************
296 |* Inventor zurueckgeben
298 \************************************************************************/
300 UINT32 E3dObject::GetObjInventor() const
302 return E3dInventor;
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
349 // Problem.
350 rInfo.bCanConvToPoly = FALSE;
351 rInfo.bCanConvToContour = FALSE;
352 rInfo.bCanConvToPathLineToArea = FALSE;
353 rInfo.bCanConvToPolyLineToArea = FALSE;
356 /*************************************************************************
358 |* Layer setzen
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));
370 if(pCandidate)
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 /*************************************************************************
391 |* Layer setzen
393 \************************************************************************/
395 void E3dObject::SetPage(SdrPage* pNewPage)
397 SdrAttrObj::SetPage(pNewPage);
398 maSubList.SetPage(pNewPage);
401 /*************************************************************************
403 |* Layer setzen
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
416 |* (F4)
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();
424 if(pScene)
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);
445 // build transform
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;
459 // anwenden
460 basegfx::B3DHomMatrix mObjTrans(GetTransform());
461 mObjTrans *= mTrans;
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();
478 if(pScene)
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;
485 if(GetParentObj())
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(),
501 0.0);
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));
546 if(pCandidate)
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)
563 if(GetParentObj())
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);
595 pPage = pPg;
596 InvalidateBoundVolume();
597 NewObjectInserted(p3DObj);
598 StructureChanged();
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());
609 pPage = pPg;
611 InvalidateBoundVolume();
612 StructureChanged();
616 /*************************************************************************
618 |* Parent holen
620 \************************************************************************/
622 E3dObject* E3dObject::GetParentObj() const
624 E3dObject* pRetval = NULL;
626 if(GetObjList()
627 && GetObjList()->GetOwnerObj()
628 && GetObjList()->GetOwnerObj()->ISA(E3dObject))
629 pRetval = ((E3dObject*)GetObjList()->GetOwnerObj());
630 return pRetval;
633 /*************************************************************************
635 |* Uebergeordnetes Szenenobjekt bestimmen
637 \************************************************************************/
639 E3dScene* E3dObject::GetScene() const
641 if(GetParentObj())
642 return GetParentObj()->GetScene();
643 return NULL;
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());
657 if(nObjCnt)
659 for(sal_uInt32 a(0); a < nObjCnt; a++)
661 const E3dObject* p3DObject = dynamic_cast< const E3dObject* >(maSubList.GetObj(a));
663 if(p3DObject)
665 basegfx::B3DRange aLocalRange(p3DObject->GetBoundVolume());
666 aLocalRange.transform(p3DObject->GetTransform());
667 aRetval.expand(aLocalRange);
671 else
673 // single 3D object
674 const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
676 if(pVCOfE3D)
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);
692 return aRetval;
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));
730 if(pCandidate)
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));
752 if(pCandidate)
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
768 if(mbTfHasChanged)
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();
807 StructureChanged();
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);
823 SetChanged();
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() );
853 if(aName.Len())
855 rName += sal_Unicode(' ');
856 rName += sal_Unicode('\'');
857 rName += aName;
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 /*************************************************************************
987 |* Konstruktor
989 \************************************************************************/
991 E3dCompoundObject::E3dCompoundObject()
992 : E3dObject(),
993 aMaterialAmbientColor(),
994 bCreateNormals(false),
995 bCreateTexture(false)
997 // Defaults setzen
998 E3dDefaultAttributes aDefault;
999 SetDefaultAttributes(aDefault);
1002 E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault)
1003 : E3dObject(),
1004 aMaterialAmbientColor(),
1005 bCreateNormals(false),
1006 bCreateTexture(false)
1008 // Defaults setzen
1009 SetDefaultAttributes(rDefault);
1012 void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault)
1014 // Defaults setzen
1015 aMaterialAmbientColor = rDefault.GetDefaultAmbientColor();
1017 bCreateNormals = rDefault.GetDefaultCreateNormals();
1018 bCreateTexture = rDefault.GetDefaultCreateTexture();
1021 /*************************************************************************
1023 |* Destruktor
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);
1044 if(pRootScene)
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());
1053 return aRetval;
1056 /*************************************************************************
1058 |* Anzahl der Handles zurueckgeben
1060 \************************************************************************/
1062 sal_uInt32 E3dCompoundObject::GetHdlCount() const
1064 // 8 Eckpunkte + 1 E3dVolumeMarker (= Wireframe-Darstellung)
1065 return 9L;
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);
1080 if(pRootScene)
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;
1092 switch(a)
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;
1104 // to 3d view coor
1105 aPos3D *= aViewInfo3D.getObjectToView() * GetTransform();
1107 // create 2d relative scene
1108 basegfx::B2DPoint aPos2D(aPos3D.getX(), aPos3D.getY());
1110 // to 2d world coor
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();
1151 if(pRootScene)
1153 // get VC of 3D candidate
1154 const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
1156 if(pVCOfE3D)
1158 // get 3D primitive sequence
1159 const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getViewIndependentPrimitive3DSequence());
1161 if(xLocalSequence.hasElements())
1163 // get BoundVolume
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());
1179 // snap to integer
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 /*************************************************************************
1190 |* Copy-Operator
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;
1218 ActionChanged();
1222 void E3dCompoundObject::SetCreateTexture(BOOL bNew)
1224 if(bCreateTexture != bNew)
1226 bCreateTexture = bNew;
1227 ActionChanged();
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;
1258 if(pRootScene)
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());
1266 return aRetval;
1269 sal_Bool E3dCompoundObject::IsAOrdNumRemapCandidate(E3dScene*& prScene) const
1271 if(GetObjList()
1272 && GetObjList()->GetOwnerObj()
1273 && GetObjList()->GetOwnerObj()->ISA(E3dScene))
1275 prScene = (E3dScene*)GetObjList()->GetOwnerObj();
1276 return sal_True;
1279 return sal_False;
1282 //////////////////////////////////////////////////////////////////////////////
1283 // eof