xref: /AOO41X/main/svx/source/engine3d/obj3d.cxx (revision f6e50924346d0b8c0b07c91832a97665dd718b0c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #include "svx/svdstr.hrc"
28 #include "svx/svdglob.hxx"
29 #include <svx/svdview.hxx>
30 #include <svx/svdattr.hxx>
31 #include <svx/svdpage.hxx>
32 #include <svx/svdmodel.hxx>
33 #include "svx/svditer.hxx"
34 #include "svx/globl3d.hxx"
35 #include <svx/camera3d.hxx>
36 #include <svx/scene3d.hxx>
37 #include <svx/polysc3d.hxx>
38 #include <svx/cube3d.hxx>
39 #include <svx/lathe3d.hxx>
40 #include <svx/sphere3d.hxx>
41 #include <svx/extrud3d.hxx>
42 #include <svx/obj3d.hxx>
43 #include <svx/xtable.hxx>
44 #include <svx/xflclit.hxx>
45 #include <vcl/svapp.hxx>
46 #include <vcl/settings.hxx>
47 #include <svx/xlnclit.hxx>
48 #include <svl/metitem.hxx>
49 #include <svx/xtable.hxx>
50 #include <svx/xfillit.hxx>
51 #include <svx/xlnwtit.hxx>
52 #include <vcl/virdev.hxx>
53 #include <tools/poly.hxx>
54 #include <tools/b3dtrans.hxx>
55 #include <svx/svxids.hrc>
56 #include <editeng/colritem.hxx>
57 #include <svx/e3ditem.hxx>
58 #include <svx/xlntrit.hxx>
59 #include <svx/xfltrit.hxx>
60 #include <svx/svdpagv.hxx>
61 #include <vcl/gradient.hxx>
62 #include <vcl/metaact.hxx>
63 #include <svx/svx3ditems.hxx>
64 #include <svl/whiter.hxx>
65 #include <svtools/colorcfg.hxx>
66 #include <editeng/eeitem.hxx>
67 #include <svx/xgrscit.hxx>
68 #include "svdoimp.hxx"
69 #include <svx/sdr/properties/e3dproperties.hxx>
70 #include <svx/sdr/properties/e3dcompoundproperties.hxx>
71 #include <basegfx/polygon/b3dpolypolygontools.hxx>
72 #include <basegfx/point/b3dpoint.hxx>
73 #include <basegfx/vector/b3dvector.hxx>
74 #include <svx/xlndsit.hxx>
75 #include <basegfx/matrix/b3dhommatrix.hxx>
76 #include <basegfx/polygon/b3dpolygon.hxx>
77 #include <basegfx/matrix/b2dhommatrix.hxx>
78 #include <basegfx/polygon/b2dpolypolygontools.hxx>
79 #include <basegfx/polygon/b3dpolygontools.hxx>
80 #include <svx/helperhittest3d.hxx>
81 #include <svx/sdr/contact/viewcontactofe3d.hxx>
82 #include <drawinglayer/geometry/viewinformation3d.hxx>
83 #include <com/sun/star/uno/Sequence.h>
84 #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
85 #include <basegfx/polygon/b3dpolypolygontools.hxx>
86 #include <svx/e3dsceneupdater.hxx>
87 
88 #define ITEMVALUE(ItemSet,Id,Cast)  ((const Cast&)(ItemSet).Get(Id)).GetValue()
89 
90 //////////////////////////////////////////////////////////////////////////////
91 
92 using namespace com::sun::star;
93 
94 /*************************************************************************
95 |*
96 |* Liste fuer 3D-Objekte
97 |*
98 \************************************************************************/
99 
100 TYPEINIT1(E3dObjList, SdrObjList);
101 
E3dObjList(SdrModel * pNewModel,SdrPage * pNewPage,E3dObjList * pNewUpList)102 E3dObjList::E3dObjList(SdrModel* pNewModel, SdrPage* pNewPage, E3dObjList* pNewUpList)
103 :   SdrObjList(pNewModel, pNewPage, pNewUpList)
104 {
105 }
106 
E3dObjList(const E3dObjList & rSrcList)107 E3dObjList::E3dObjList(const E3dObjList& rSrcList)
108 :   SdrObjList(rSrcList)
109 {
110 }
111 
~E3dObjList()112 E3dObjList::~E3dObjList()
113 {
114 }
115 
NbcInsertObject(SdrObject * pObj,sal_uIntPtr nPos,const SdrInsertReason * pReason)116 void E3dObjList::NbcInsertObject(SdrObject* pObj, sal_uIntPtr nPos, const SdrInsertReason* pReason)
117 {
118     // Owner holen
119     DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "AW: Einfuegen 3DObject in Parent != 3DObject");
120 
121     // Ist es ueberhaupt ein 3D-Objekt?
122     if(pObj && pObj->ISA(E3dObject))
123     {
124         // Normales 3D Objekt, einfuegen mittels
125         // call parent
126         SdrObjList::NbcInsertObject(pObj, nPos, pReason);
127     }
128     else
129     {
130         // Kein 3D Objekt, fuege in Seite statt in Szene ein...
131         GetOwnerObj()->GetPage()->InsertObject(pObj, nPos);
132     }
133 }
134 
InsertObject(SdrObject * pObj,sal_uIntPtr nPos,const SdrInsertReason * pReason)135 void E3dObjList::InsertObject(SdrObject* pObj, sal_uIntPtr nPos, const SdrInsertReason* pReason)
136 {
137     OSL_ENSURE(GetOwnerObj()->ISA(E3dObject), "Insert 3DObject in non-3D Parent");
138     //E3DModifySceneSnapRectUpdater aUpdater(GetOwnerObj());
139 
140     // call parent
141     SdrObjList::InsertObject(pObj, nPos, pReason);
142 
143     E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene();
144     if(pScene)
145     {
146         pScene->Cleanup3DDepthMapper();
147     }
148 }
149 
NbcRemoveObject(sal_uIntPtr nObjNum)150 SdrObject* E3dObjList::NbcRemoveObject(sal_uIntPtr nObjNum)
151 {
152     DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "AW: Entfernen 3DObject aus Parent != 3DObject");
153     //E3DModifySceneSnapRectUpdater aUpdater(GetOwnerObj());
154 
155     // call parent
156     SdrObject* pRetval = SdrObjList::NbcRemoveObject(nObjNum);
157 
158     E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene();
159     if(pScene)
160     {
161         pScene->Cleanup3DDepthMapper();
162     }
163 
164     return pRetval;
165 }
166 
RemoveObject(sal_uIntPtr nObjNum)167 SdrObject* E3dObjList::RemoveObject(sal_uIntPtr nObjNum)
168 {
169     OSL_ENSURE(GetOwnerObj()->ISA(E3dObject), "3DObject is removed from non-3D Parent");
170     //E3DModifySceneSnapRectUpdater aUpdater(GetOwnerObj());
171 
172     // call parent
173     SdrObject* pRetval = SdrObjList::RemoveObject(nObjNum);
174 
175     E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene();
176     if(pScene)
177     {
178         pScene->Cleanup3DDepthMapper();
179     }
180 
181     return pRetval;
182 }
183 
184 /*************************************************************************
185 |*
186 |* Konstruktor
187 |*
188 \************************************************************************/
189 
190 //////////////////////////////////////////////////////////////////////////////
191 
CreateObjectSpecificProperties()192 sdr::properties::BaseProperties* E3dObject::CreateObjectSpecificProperties()
193 {
194     return new sdr::properties::E3dProperties(*this);
195 }
196 
197 ////////////////////////////////////////////////////////////////////////////////////////////////////
198 
199 TYPEINIT1(E3dObject, SdrAttrObj);
200 
E3dObject()201 E3dObject::E3dObject()
202 :   maSubList(),
203     maLocalBoundVol(),
204     maTransformation(),
205     maFullTransform(),
206     mbTfHasChanged(true),
207     mbIsSelected(false)
208 {
209     bIs3DObj = true;
210     maSubList.SetOwnerObj(this);
211     maSubList.SetListKind(SDROBJLIST_GROUPOBJ);
212     bClosedObj = true;
213 }
214 
215 /*************************************************************************
216 |*
217 |* Destruktor
218 |*
219 \************************************************************************/
220 
~E3dObject()221 E3dObject::~E3dObject()
222 {
223 }
224 
225 /*************************************************************************
226 |*
227 |* Selektions-Flag setzen
228 |*
229 \************************************************************************/
230 
SetSelected(bool bNew)231 void E3dObject::SetSelected(bool bNew)
232 {
233     if((bool)mbIsSelected != bNew)
234     {
235         mbIsSelected = bNew;
236     }
237 
238     for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
239     {
240         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
241 
242         if(pCandidate)
243         {
244             pCandidate->SetSelected(bNew);
245         }
246     }
247 }
248 
249 /*************************************************************************
250 |*
251 |* Aufbrechen, default-Implementierungen
252 |*
253 \************************************************************************/
254 
IsBreakObjPossible()255 sal_Bool E3dObject::IsBreakObjPossible()
256 {
257     return sal_False;
258 }
259 
GetBreakObj()260 SdrAttrObj* E3dObject::GetBreakObj()
261 {
262     return 0L;
263 }
264 
265 /*************************************************************************
266 |*
267 |* SetRectsDirty muss ueber die lokale SdrSubList gehen
268 |*
269 \************************************************************************/
270 
SetRectsDirty(sal_Bool bNotMyself)271 void E3dObject::SetRectsDirty(sal_Bool bNotMyself)
272 {
273     // call parent
274     SdrAttrObj::SetRectsDirty(bNotMyself);
275 
276     for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
277     {
278         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
279 
280         if(pCandidate)
281         {
282             pCandidate->SetRectsDirty(bNotMyself);
283         }
284     }
285 }
286 
287 /*************************************************************************
288 |*
289 |* Inventor zurueckgeben
290 |*
291 \************************************************************************/
292 
GetObjInventor() const293 sal_uInt32 E3dObject::GetObjInventor() const
294 {
295     return E3dInventor;
296 }
297 
298 /*************************************************************************
299 |*
300 |* Identifier zurueckgeben
301 |*
302 \************************************************************************/
303 
GetObjIdentifier() const304 sal_uInt16 E3dObject::GetObjIdentifier() const
305 {
306     return E3D_OBJECT_ID;
307 }
308 
309 /*************************************************************************
310 |*
311 |* Faehigkeiten des Objektes feststellen
312 |*
313 \************************************************************************/
314 
TakeObjInfo(SdrObjTransformInfoRec & rInfo) const315 void E3dObject::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
316 {
317     rInfo.bResizeFreeAllowed    = sal_True;
318     rInfo.bResizePropAllowed    = sal_True;
319     rInfo.bRotateFreeAllowed    = sal_True;
320     rInfo.bRotate90Allowed      = sal_True;
321     rInfo.bMirrorFreeAllowed    = sal_False;
322     rInfo.bMirror45Allowed      = sal_False;
323     rInfo.bMirror90Allowed      = sal_False;
324     rInfo.bShearAllowed         = sal_False;
325     rInfo.bEdgeRadiusAllowed    = sal_False;
326     rInfo.bCanConvToPath        = sal_False;
327 
328     // no transparence for 3d objects
329     rInfo.bTransparenceAllowed = sal_False;
330 
331     // gradient depends on fillstyle
332     // BM *** check if SetItem is NULL ***
333     XFillStyle eFillStyle = ((XFillStyleItem&)(GetMergedItem(XATTR_FILLSTYLE))).GetValue();
334     rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
335 
336     // Umwandeln von 3D-Koerpern in Gruppe von Polygonen:
337     //
338     // Erst mal nicht moeglich, da die Erzeugung einer Gruppe von
339     // 2D-Polygonen notwendig waere, die tiefensortiert werden muessten,
340     // also bei Durchdringugnen auch gegeneinander geschnitten werden
341     // muessten. Auch die Texturkoorinaten waeren ein ungeloestes
342     // Problem.
343     rInfo.bCanConvToPoly = sal_False;
344     rInfo.bCanConvToContour = sal_False;
345     rInfo.bCanConvToPathLineToArea = sal_False;
346     rInfo.bCanConvToPolyLineToArea = sal_False;
347 }
348 
349 /*************************************************************************
350 |*
351 |* Layer setzen
352 |*
353 \************************************************************************/
354 
NbcSetLayer(SdrLayerID nLayer)355 void E3dObject::NbcSetLayer(SdrLayerID nLayer)
356 {
357     SdrAttrObj::NbcSetLayer(nLayer);
358 
359     for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
360     {
361         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
362 
363         if(pCandidate)
364         {
365             pCandidate->NbcSetLayer(nLayer);
366         }
367     }
368 }
369 
370 /*************************************************************************
371 |*
372 |* ObjList auch an SubList setzen
373 |*
374 \************************************************************************/
375 
SetObjList(SdrObjList * pNewObjList)376 void E3dObject::SetObjList(SdrObjList* pNewObjList)
377 {
378     SdrObject::SetObjList(pNewObjList);
379     maSubList.SetUpList(pNewObjList);
380 }
381 
382 /*************************************************************************
383 |*
384 |* Layer setzen
385 |*
386 \************************************************************************/
387 
SetPage(SdrPage * pNewPage)388 void E3dObject::SetPage(SdrPage* pNewPage)
389 {
390     SdrAttrObj::SetPage(pNewPage);
391     maSubList.SetPage(pNewPage);
392 }
393 
394 /*************************************************************************
395 |*
396 |* Layer setzen
397 |*
398 \************************************************************************/
399 
SetModel(SdrModel * pNewModel)400 void E3dObject::SetModel(SdrModel* pNewModel)
401 {
402     SdrAttrObj::SetModel(pNewModel);
403     maSubList.SetModel(pNewModel);
404 }
405 
406 /*************************************************************************
407 |*
408 |* resize object, used from old 2d interfaces, e.g. in Move/Scale dialog
409 |* (F4)
410 |*
411 \************************************************************************/
NbcResize(const Point & rRef,const Fraction & xFact,const Fraction & yFact)412 void E3dObject::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
413 {
414     // Bewegung in X,Y im Augkoordinatensystem
415     E3dScene* pScene = GetScene();
416 
417     if(pScene)
418     {
419         // transform pos from 2D world to 3D eye
420         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
421         const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
422         basegfx::B2DPoint aScaleCenter2D((double)rRef.X(), (double)rRef.Y());
423         basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());
424 
425         aInverseSceneTransform.invert();
426         aScaleCenter2D = aInverseSceneTransform * aScaleCenter2D;
427 
428         basegfx::B3DPoint aScaleCenter3D(aScaleCenter2D.getX(), aScaleCenter2D.getY(), 0.5);
429         basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
430 
431         aInverseViewToEye.invert();
432         aScaleCenter3D = aInverseViewToEye * aScaleCenter3D;
433 
434         // scale-faktoren holen
435         double fScaleX(xFact);
436         double fScaleY(yFact);
437 
438         // build transform
439         basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
440         aInverseOrientation.invert();
441         basegfx::B3DHomMatrix mFullTransform(GetFullTransform());
442         basegfx::B3DHomMatrix mTrans(mFullTransform);
443 
444         mTrans *= aViewInfo3D.getOrientation();
445         mTrans.translate(-aScaleCenter3D.getX(), -aScaleCenter3D.getY(), -aScaleCenter3D.getZ());
446         mTrans.scale(fScaleX, fScaleY, 1.0);
447         mTrans.translate(aScaleCenter3D.getX(), aScaleCenter3D.getY(), aScaleCenter3D.getZ());
448         mTrans *= aInverseOrientation;
449         mFullTransform.invert();
450         mTrans *= mFullTransform;
451 
452         // anwenden
453         basegfx::B3DHomMatrix mObjTrans(GetTransform());
454         mObjTrans *= mTrans;
455 
456         E3DModifySceneSnapRectUpdater aUpdater(this);
457         SetTransform(mObjTrans);
458     }
459 }
460 
461 /*************************************************************************
462 |*
463 |* Objekt verschieben in 2D, wird bei Cursortasten benoetigt
464 |*
465 \************************************************************************/
NbcMove(const Size & rSize)466 void E3dObject::NbcMove(const Size& rSize)
467 {
468     // Bewegung in X,Y im Augkoordinatensystem
469     E3dScene* pScene = GetScene();
470 
471     if(pScene)
472     {
473         // Abmessungen der Szene in 3D und 2D als Vergleich
474         Rectangle aRect = pScene->GetSnapRect();
475 
476         // Transformation Weltkoordinaten bis eine VOR Objektkoordinaten holen
477         basegfx::B3DHomMatrix mInvDispTransform;
478         if(GetParentObj())
479         {
480             mInvDispTransform = GetParentObj()->GetFullTransform();
481             mInvDispTransform.invert();
482         }
483 
484         // BoundVolume from 3d world to 3d eye
485         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
486         const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
487         basegfx::B3DRange aEyeVol(pScene->GetBoundVolume());
488         aEyeVol.transform(aViewInfo3D.getOrientation());
489 
490         // build relative movement vector in eye coordinates
491         basegfx::B3DPoint aMove(
492             (double)rSize.Width() * aEyeVol.getWidth() / (double)aRect.GetWidth(),
493             (double)-rSize.Height() * aEyeVol.getHeight() / (double)aRect.GetHeight(),
494             0.0);
495         basegfx::B3DPoint aPos(0.0, 0.0, 0.0);
496 
497         // movement vektor to local coordinates of objects' parent
498         basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
499         aInverseOrientation.invert();
500         basegfx::B3DHomMatrix aCompleteTrans(mInvDispTransform * aInverseOrientation);
501 
502         aMove = aCompleteTrans * aMove;
503         aPos = aCompleteTrans * aPos;
504 
505         // build transformation and apply
506         basegfx::B3DHomMatrix aTranslate;
507         aTranslate.translate(aMove.getX() - aPos.getX(), aMove.getY() - aPos.getY(), aMove.getZ() - aPos.getZ());
508 
509         E3DModifySceneSnapRectUpdater aUpdater(pScene);
510         SetTransform(aTranslate * GetTransform());
511     }
512 }
513 
514 /*************************************************************************
515 |*
516 |* liefere die Sublist, aber nur dann, wenn darin Objekte enthalten sind !
517 |*
518 \************************************************************************/
519 
GetSubList() const520 SdrObjList* E3dObject::GetSubList() const
521 {
522     return &(const_cast< E3dObjList& >(maSubList));
523 }
524 
525 /*************************************************************************
526 |*
527 |* SnapRect berechnen
528 |*
529 \************************************************************************/
530 
RecalcSnapRect()531 void E3dObject::RecalcSnapRect()
532 {
533     maSnapRect = Rectangle();
534 
535     for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
536     {
537         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
538 
539         if(pCandidate)
540         {
541             maSnapRect.Union(pCandidate->GetSnapRect());
542         }
543     }
544 }
545 
546 /*************************************************************************
547 |*
548 |* Einfuegen eines 3D-Objekts an den Parent weitermelden, damit dieser
549 |* ggf. eine Sonderbehandlung fuer spezielle Objekte durchfuehren kann
550 |* (z.B. Light/Label in E3dScene)
551 |*
552 \************************************************************************/
553 
NewObjectInserted(const E3dObject * p3DObj)554 void E3dObject::NewObjectInserted(const E3dObject* p3DObj)
555 {
556     if(GetParentObj())
557         GetParentObj()->NewObjectInserted(p3DObj);
558 }
559 
560 /*************************************************************************
561 |*
562 |* Parent ueber Aenderung der Struktur (z.B. durch Transformation)
563 |* informieren; dabei wird das Objekt, in welchem die Aenderung
564 |* aufgetreten ist, uebergeben
565 |*
566 \************************************************************************/
567 
StructureChanged()568 void E3dObject::StructureChanged()
569 {
570     if ( GetParentObj() )
571     {
572         GetParentObj()->InvalidateBoundVolume();
573         GetParentObj()->StructureChanged();
574     }
575 }
576 
577 /*************************************************************************
578 |*
579 |* 3D-Objekt einfuegen
580 |*
581 \************************************************************************/
582 
Insert3DObj(E3dObject * p3DObj)583 void E3dObject::Insert3DObj(E3dObject* p3DObj)
584 {
585     DBG_ASSERT(p3DObj, "Insert3DObj mit NULL-Zeiger!");
586     SdrPage* pPg = pPage;
587     maSubList.InsertObject(p3DObj);
588     pPage = pPg;
589     InvalidateBoundVolume();
590     NewObjectInserted(p3DObj);
591     StructureChanged();
592 }
593 
Remove3DObj(E3dObject * p3DObj)594 void E3dObject::Remove3DObj(E3dObject* p3DObj)
595 {
596     DBG_ASSERT(p3DObj, "Remove3DObj mit NULL-Zeiger!");
597 
598     if(p3DObj->GetParentObj() == this)
599     {
600         SdrPage* pPg = pPage;
601         maSubList.RemoveObject(p3DObj->GetOrdNum());
602         pPage = pPg;
603 
604         InvalidateBoundVolume();
605         StructureChanged();
606     }
607 }
608 
609 /*************************************************************************
610 |*
611 |* Parent holen
612 |*
613 \************************************************************************/
614 
GetParentObj() const615 E3dObject* E3dObject::GetParentObj() const
616 {
617     E3dObject* pRetval = NULL;
618 
619     if(GetObjList()
620         && GetObjList()->GetOwnerObj()
621         && GetObjList()->GetOwnerObj()->ISA(E3dObject))
622         pRetval = ((E3dObject*)GetObjList()->GetOwnerObj());
623     return pRetval;
624 }
625 
626 /*************************************************************************
627 |*
628 |* Uebergeordnetes Szenenobjekt bestimmen
629 |*
630 \************************************************************************/
631 
GetScene() const632 E3dScene* E3dObject::GetScene() const
633 {
634     if(GetParentObj())
635         return GetParentObj()->GetScene();
636     return NULL;
637 }
638 
639 /*************************************************************************
640 |*
641 |* umschliessendes Volumen inklusive aller Kindobjekte berechnen
642 |*
643 \************************************************************************/
644 
RecalcBoundVolume() const645 basegfx::B3DRange E3dObject::RecalcBoundVolume() const
646 {
647     basegfx::B3DRange aRetval;
648     const sal_uInt32 nObjCnt(maSubList.GetObjCount());
649 
650     if(nObjCnt)
651     {
652         for(sal_uInt32 a(0); a < nObjCnt; a++)
653         {
654             const E3dObject* p3DObject = dynamic_cast< const E3dObject* >(maSubList.GetObj(a));
655 
656             if(p3DObject)
657             {
658                 basegfx::B3DRange aLocalRange(p3DObject->GetBoundVolume());
659                 aLocalRange.transform(p3DObject->GetTransform());
660                 aRetval.expand(aLocalRange);
661             }
662         }
663     }
664     else
665     {
666         // single 3D object
667         const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
668 
669         if(pVCOfE3D)
670         {
671             // BoundVolume is without 3D object transformation, use correct sequence
672             const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getVIP3DSWithoutObjectTransform());
673 
674             if(xLocalSequence.hasElements())
675             {
676                 const uno::Sequence< beans::PropertyValue > aEmptyParameters;
677                 const drawinglayer::geometry::ViewInformation3D aLocalViewInformation3D(aEmptyParameters);
678 
679                 aRetval = drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
680                     xLocalSequence, aLocalViewInformation3D);
681             }
682         }
683     }
684 
685     return aRetval;
686 }
687 
688 /*************************************************************************
689 |*
690 |* umschliessendes Volumen zurueckgeben und ggf. neu berechnen
691 |*
692 \************************************************************************/
693 
GetBoundVolume() const694 const basegfx::B3DRange& E3dObject::GetBoundVolume() const
695 {
696     if(maLocalBoundVol.isEmpty())
697     {
698         const_cast< E3dObject* >(this)->maLocalBoundVol = RecalcBoundVolume();
699     }
700 
701     return maLocalBoundVol;
702 }
703 
InvalidateBoundVolume()704 void E3dObject::InvalidateBoundVolume()
705 {
706     maLocalBoundVol.reset();
707 }
708 
709 /*************************************************************************
710 |*
711 |* Aederung des BoundVolumes an alle Kindobjekte weitergeben
712 |*
713 \************************************************************************/
714 
SetBoundVolInvalid()715 void E3dObject::SetBoundVolInvalid()
716 {
717     InvalidateBoundVolume();
718 
719     for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
720     {
721         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
722 
723         if(pCandidate)
724         {
725             pCandidate->SetBoundVolInvalid();
726         }
727     }
728 }
729 
730 /*************************************************************************
731 |*
732 |* Aederung der Transformation an alle Kindobjekte weitergeben
733 |*
734 \************************************************************************/
735 
SetTransformChanged()736 void E3dObject::SetTransformChanged()
737 {
738     InvalidateBoundVolume();
739     mbTfHasChanged = true;
740 
741     for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
742     {
743         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
744 
745         if(pCandidate)
746         {
747             pCandidate->SetTransformChanged();
748         }
749     }
750 }
751 
752 /*************************************************************************
753 |*
754 |* hierarchische Transformation ueber alle Parents bestimmen, in
755 |* maFullTransform ablegen und diese zurueckgeben
756 |*
757 \************************************************************************/
758 
GetFullTransform() const759 const basegfx::B3DHomMatrix& E3dObject::GetFullTransform() const
760 {
761     if(mbTfHasChanged)
762     {
763         basegfx::B3DHomMatrix aNewFullTransformation(maTransformation);
764 
765         if ( GetParentObj() )
766         {
767             aNewFullTransformation = GetParentObj()->GetFullTransform() * aNewFullTransformation;
768         }
769 
770         const_cast< E3dObject* >(this)->maFullTransform = aNewFullTransformation;
771         const_cast< E3dObject* >(this)->mbTfHasChanged = false;
772     }
773 
774     return maFullTransform;
775 }
776 
777 /*************************************************************************
778 |*
779 |* Transformationsmatrix abfragen
780 |*
781 \************************************************************************/
782 
GetTransform() const783 const basegfx::B3DHomMatrix& E3dObject::GetTransform() const
784 {
785     return maTransformation;
786 }
787 
788 /*************************************************************************
789 |*
790 |* Transformationsmatrix setzen
791 |*
792 \************************************************************************/
793 
NbcSetTransform(const basegfx::B3DHomMatrix & rMatrix)794 void E3dObject::NbcSetTransform(const basegfx::B3DHomMatrix& rMatrix)
795 {
796     if(maTransformation != rMatrix)
797     {
798         maTransformation = rMatrix;
799         SetTransformChanged();
800         StructureChanged();
801     }
802 }
803 
804 /*************************************************************************
805 |*
806 |* Transformationsmatrix setzen mit Repaint-Broadcast
807 |*
808 \************************************************************************/
809 
SetTransform(const basegfx::B3DHomMatrix & rMatrix)810 void E3dObject::SetTransform(const basegfx::B3DHomMatrix& rMatrix)
811 {
812     if(rMatrix != maTransformation)
813     {
814         // #110094#-14 SendRepaintBroadcast();
815         NbcSetTransform(rMatrix);
816         SetChanged();
817         BroadcastObjectChange();
818         if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
819     }
820 }
821 
822 /*************************************************************************
823 |*
824 |* Linien fuer die Wireframe-Darstellung des Objekts dem uebergebenen
825 |* basegfx::B3DPolygon hinzufuegen
826 |*
827 \************************************************************************/
828 
CreateWireframe() const829 basegfx::B3DPolyPolygon E3dObject::CreateWireframe() const
830 {
831     const basegfx::B3DRange aBoundVolume(GetBoundVolume());
832     return basegfx::tools::createCubePolyPolygonFromB3DRange(aBoundVolume);
833 }
834 
835 /*************************************************************************
836 |*
837 |* Get the name of the object (singular)
838 |*
839 \************************************************************************/
840 
TakeObjNameSingul(XubString & rName) const841 void E3dObject::TakeObjNameSingul(XubString& rName) const
842 {
843     rName=ImpGetResStr(STR_ObjNameSingulObj3d);
844 
845     String aName( GetName() );
846     if(aName.Len())
847     {
848         rName += sal_Unicode(' ');
849         rName += sal_Unicode('\'');
850         rName += aName;
851         rName += sal_Unicode('\'');
852     }
853 }
854 
855 /*************************************************************************
856 |*
857 |* Get the name of the object (plural)
858 |*
859 \************************************************************************/
860 
TakeObjNamePlural(XubString & rName) const861 void E3dObject::TakeObjNamePlural(XubString& rName) const
862 {
863     rName=ImpGetResStr(STR_ObjNamePluralObj3d);
864 }
865 
866 /*************************************************************************
867 |*
868 |* Zuweisungsoperator
869 |*
870 \************************************************************************/
871 
operator =(const SdrObject & rObj)872 void E3dObject::operator=(const SdrObject& rObj)
873 {
874     SdrObject::operator=(rObj);
875 
876     const E3dObject& r3DObj = (const E3dObject&) rObj;
877     if (r3DObj.GetSubList())
878     {
879         maSubList.CopyObjects(*r3DObj.GetSubList());
880     }
881 
882     // BoundVol kann uebernommen werden, da die Childs auch kopiert werden
883     maLocalBoundVol  = r3DObj.maLocalBoundVol;
884     maTransformation = r3DObj.maTransformation;
885 
886     // Da sich der Parent geaendert haben kann, Gesamttransformation beim
887     // naechsten Mal auf jeden Fall neu bestimmen
888     SetTransformChanged();
889 
890     // Selektionsstatus kopieren
891     mbIsSelected = r3DObj.mbIsSelected;
892 }
893 
894 /*************************************************************************
895 |*
896 |* erstelle neues GeoData-Objekt
897 |*
898 \************************************************************************/
899 
NewGeoData() const900 SdrObjGeoData *E3dObject::NewGeoData() const
901 {
902     // Theoretisch duerfen auch nur Szenen ihre GeoDatas erstellen und verwalten !!
903     // AW: Dies stimmt nicht mehr, diese Stelle ist mit der neuen Engine OK!
904     return new E3DObjGeoData;
905 }
906 
907 /*************************************************************************
908 |*
909 |* uebergebe aktuelle werte an das GeoData-Objekt
910 |*
911 \************************************************************************/
912 
SaveGeoData(SdrObjGeoData & rGeo) const913 void E3dObject::SaveGeoData(SdrObjGeoData& rGeo) const
914 {
915     SdrAttrObj::SaveGeoData (rGeo);
916 
917     ((E3DObjGeoData &) rGeo).maLocalBoundVol  = maLocalBoundVol;
918     ((E3DObjGeoData &) rGeo).maTransformation = maTransformation;
919 }
920 
921 /*************************************************************************
922 |*
923 |* uebernehme werte aus dem GeoData-Objekt
924 |*
925 \************************************************************************/
926 
RestGeoData(const SdrObjGeoData & rGeo)927 void E3dObject::RestGeoData(const SdrObjGeoData& rGeo)
928 {
929     maLocalBoundVol = ((E3DObjGeoData &) rGeo).maLocalBoundVol;
930     E3DModifySceneSnapRectUpdater aUpdater(this);
931     NbcSetTransform(((E3DObjGeoData &) rGeo).maTransformation);
932     SdrAttrObj::RestGeoData (rGeo);
933 }
934 
935 /*************************************************************************
936 |*
937 |* Rotation eines 3d-Koerpers
938 |*
939 \************************************************************************/
940 // 2D-rotation eines 3D-Koerpers, normalerweise macht das die Szene selbst
941 // Ist aber eine korrekte Implementierung, denn alles was passiert ist eine
942 // Rotation um die Achse die senkrecht auf dem Bildschirm steht und zwar
943 // unabhaengig davon, wie die Szene bisher gedreht worden ist.
944 
NbcRotate(const Point & rRef,long nWink,double sn,double cs)945 void E3dObject::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
946 {
947     // Also derzeit sind die Klebepunkte relativ zum aOutRect der Szene definiert. Vor dem Drehen
948     // werden die Klebepunkte relativ zur Seite definiert. Sie nehmen an der Drehung der Szene noch nicht Teil
949     // dafuer gibt es den
950     SetGlueReallyAbsolute(sal_True);
951 
952     // SendRepaintBroadcast();
953     double fWinkelInRad = nWink/100 * F_PI180;
954 
955     basegfx::B3DHomMatrix aRotateZ;
956     aRotateZ.rotate(0.0, 0.0, fWinkelInRad);
957     NbcSetTransform(aRotateZ * GetTransform());
958 
959     SetRectsDirty();    // Veranlasst eine Neuberechnung aller BoundRects
960     NbcRotateGluePoints(rRef,nWink,sn,cs);  // Rotiert die Klebepunkte (die haben noch Koordinaten relativ
961                                             // zum Urpsung des Blattes
962     SetGlueReallyAbsolute(sal_False);  // ab jetzt sind sie wieder relativ zum BoundRect (also dem aOutRect definiert)
963 }
964 
965 /*************************************************************************/
966 
967 //////////////////////////////////////////////////////////////////////////////
968 
CreateObjectSpecificProperties()969 sdr::properties::BaseProperties* E3dCompoundObject::CreateObjectSpecificProperties()
970 {
971     return new sdr::properties::E3dCompoundProperties(*this);
972 }
973 
974 ////////////////////////////////////////////////////////////////////////////////////////////////////
975 
976 TYPEINIT1(E3dCompoundObject, E3dObject);
977 
978 /*************************************************************************
979 |*
980 |* Konstruktor
981 |*
982 \************************************************************************/
983 
E3dCompoundObject()984 E3dCompoundObject::E3dCompoundObject()
985 :   E3dObject(),
986     aMaterialAmbientColor(),
987     bCreateNormals(false),
988     bCreateTexture(false)
989 {
990     // Defaults setzen
991     E3dDefaultAttributes aDefault;
992     SetDefaultAttributes(aDefault);
993 }
994 
E3dCompoundObject(E3dDefaultAttributes & rDefault)995 E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault)
996 :   E3dObject(),
997     aMaterialAmbientColor(),
998     bCreateNormals(false),
999     bCreateTexture(false)
1000 {
1001     // Defaults setzen
1002     SetDefaultAttributes(rDefault);
1003 }
1004 
SetDefaultAttributes(E3dDefaultAttributes & rDefault)1005 void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault)
1006 {
1007     // Defaults setzen
1008     aMaterialAmbientColor = rDefault.GetDefaultAmbientColor();
1009 
1010     bCreateNormals = rDefault.GetDefaultCreateNormals();
1011     bCreateTexture = rDefault.GetDefaultCreateTexture();
1012 }
1013 
1014 /*************************************************************************
1015 |*
1016 |* Destruktor
1017 |*
1018 \************************************************************************/
1019 
~E3dCompoundObject()1020 E3dCompoundObject::~E3dCompoundObject ()
1021 {
1022 }
1023 
1024 /*************************************************************************
1025 |*
1026 |* Drag-Polygon zurueckgeben
1027 |*
1028 \************************************************************************/
1029 
TakeXorPoly() const1030 basegfx::B2DPolyPolygon E3dCompoundObject::TakeXorPoly() const
1031 {
1032     basegfx::B2DPolyPolygon aRetval;
1033     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
1034     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
1035     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
1036 
1037     if(pRootScene)
1038     {
1039         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
1040         const basegfx::B3DPolyPolygon aCubePolyPolygon(CreateWireframe());
1041         aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCubePolyPolygon,
1042             aViewInfo3D.getObjectToView() * GetTransform());
1043         aRetval.transform(rVCScene.getObjectTransformation());
1044     }
1045 
1046     return aRetval;
1047 }
1048 
1049 /*************************************************************************
1050 |*
1051 |* Anzahl der Handles zurueckgeben
1052 |*
1053 \************************************************************************/
1054 
GetHdlCount() const1055 sal_uInt32 E3dCompoundObject::GetHdlCount() const
1056 {
1057     // 8 Eckpunkte + 1 E3dVolumeMarker (= Wireframe-Darstellung)
1058     return 9L;
1059 }
1060 
1061 /*************************************************************************
1062 |*
1063 |* Handle-Liste fuellen
1064 |*
1065 \************************************************************************/
1066 
AddToHdlList(SdrHdlList & rHdlList) const1067 void E3dCompoundObject::AddToHdlList(SdrHdlList& rHdlList) const
1068 {
1069     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
1070     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
1071     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
1072 
1073     if(pRootScene)
1074     {
1075         const basegfx::B3DRange aBoundVolume(GetBoundVolume());
1076 
1077         if(!aBoundVolume.isEmpty())
1078         {
1079             const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
1080 
1081             for(sal_uInt32 a(0); a < 8; a++)
1082             {
1083                 basegfx::B3DPoint aPos3D;
1084 
1085                 switch(a)
1086                 {
1087                     case 0 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
1088                     case 1 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
1089                     case 2 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
1090                     case 3 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
1091                     case 4 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
1092                     case 5 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
1093                     case 6 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
1094                     case 7 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
1095                 }
1096 
1097                 // to 3d view coor
1098                 aPos3D *= aViewInfo3D.getObjectToView() * GetTransform();
1099 
1100                 // create 2d relative scene
1101                 basegfx::B2DPoint aPos2D(aPos3D.getX(), aPos3D.getY());
1102 
1103                 // to 2d world coor
1104                 aPos2D *= rVCScene.getObjectTransformation();
1105 
1106                 rHdlList.AddHdl(new SdrHdl(Point(basegfx::fround(aPos2D.getX()), basegfx::fround(aPos2D.getY())), HDL_BWGT));
1107             }
1108         }
1109     }
1110 
1111     const basegfx::B2DPolyPolygon aPolyPolygon(TakeXorPoly());
1112 
1113     if(aPolyPolygon.count())
1114     {
1115         E3dVolumeMarker* pVolMarker = new E3dVolumeMarker(aPolyPolygon);
1116         rHdlList.AddHdl(pVolMarker);
1117     }
1118 }
1119 
1120 /*************************************************************************
1121 |*
1122 |* Identifier zurueckgeben
1123 |*
1124 \************************************************************************/
1125 
GetObjIdentifier() const1126 sal_uInt16 E3dCompoundObject::GetObjIdentifier() const
1127 {
1128     return E3D_COMPOUNDOBJ_ID;
1129 }
1130 
1131 /*************************************************************************
1132 |*
1133 |* SnapRect berechnen
1134 |*
1135 \************************************************************************/
1136 
RecalcSnapRect()1137 void E3dCompoundObject::RecalcSnapRect()
1138 {
1139     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
1140     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
1141     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
1142     maSnapRect = Rectangle();
1143 
1144     if(pRootScene)
1145     {
1146         // get VC of 3D candidate
1147         const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
1148 
1149         if(pVCOfE3D)
1150         {
1151             // get 3D primitive sequence
1152             const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getViewIndependentPrimitive3DSequence());
1153 
1154             if(xLocalSequence.hasElements())
1155             {
1156                 // get BoundVolume
1157                 basegfx::B3DRange aBoundVolume(drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
1158                     xLocalSequence, aViewInfo3D));
1159 
1160                 // transform bound volume to relative scene coordinates
1161                 aBoundVolume.transform(aViewInfo3D.getObjectToView());
1162 
1163                 // build 2d relative scene range
1164                 basegfx::B2DRange aSnapRange(
1165                     aBoundVolume.getMinX(), aBoundVolume.getMinY(),
1166                     aBoundVolume.getMaxX(), aBoundVolume.getMaxY());
1167 
1168                 // transform to 2D world coordiantes
1169                 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
1170                 aSnapRange.transform(rVCScene.getObjectTransformation());
1171 
1172                 // snap to integer
1173                 maSnapRect = Rectangle(
1174                     sal_Int32(floor(aSnapRange.getMinX())), sal_Int32(floor(aSnapRange.getMinY())),
1175                     sal_Int32(ceil(aSnapRange.getMaxX())), sal_Int32(ceil(aSnapRange.getMaxY())));
1176             }
1177         }
1178     }
1179 }
1180 
1181 /*************************************************************************
1182 |*
1183 |* Copy-Operator
1184 |*
1185 \************************************************************************/
1186 
operator =(const SdrObject & rObj)1187 void E3dCompoundObject::operator=(const SdrObject& rObj)
1188 {
1189     // erstmal alle Childs kopieren
1190     E3dObject::operator=(rObj);
1191 
1192     // weitere Parameter kopieren
1193     const E3dCompoundObject& r3DObj = (const E3dCompoundObject&) rObj;
1194 
1195     bCreateNormals = r3DObj.bCreateNormals;
1196     bCreateTexture = r3DObj.bCreateTexture;
1197     aMaterialAmbientColor = r3DObj.aMaterialAmbientColor;
1198 }
1199 
1200 /*************************************************************************
1201 |*
1202 |* Parameter Geometrieerzeugung setzen
1203 |*
1204 \************************************************************************/
1205 
SetCreateNormals(sal_Bool bNew)1206 void E3dCompoundObject::SetCreateNormals(sal_Bool bNew)
1207 {
1208     if(bCreateNormals != bNew)
1209     {
1210         bCreateNormals = bNew;
1211         ActionChanged();
1212     }
1213 }
1214 
SetCreateTexture(sal_Bool bNew)1215 void E3dCompoundObject::SetCreateTexture(sal_Bool bNew)
1216 {
1217     if(bCreateTexture != bNew)
1218     {
1219         bCreateTexture = bNew;
1220         ActionChanged();
1221     }
1222 }
1223 
1224 /*************************************************************************
1225 |*
1226 |* Material des Objektes
1227 |*
1228 \************************************************************************/
1229 
SetMaterialAmbientColor(const Color & rColor)1230 void E3dCompoundObject::SetMaterialAmbientColor(const Color& rColor)
1231 {
1232     if(aMaterialAmbientColor != rColor)
1233     {
1234         aMaterialAmbientColor = rColor;
1235     }
1236 }
1237 
1238 /*************************************************************************
1239 |*
1240 |* convert given basegfx::B3DPolyPolygon to screen coor
1241 |*
1242 \************************************************************************/
1243 
TransformToScreenCoor(const basegfx::B3DPolyPolygon & rCandidate)1244 basegfx::B2DPolyPolygon E3dCompoundObject::TransformToScreenCoor(const basegfx::B3DPolyPolygon& rCandidate)
1245 {
1246     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
1247     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
1248     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
1249     basegfx::B2DPolyPolygon aRetval;
1250 
1251     if(pRootScene)
1252     {
1253         aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(rCandidate,
1254             aViewInfo3D.getObjectToView() * GetTransform());
1255         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
1256         aRetval.transform(rVCScene.getObjectTransformation());
1257     }
1258 
1259     return aRetval;
1260 }
1261 
IsAOrdNumRemapCandidate(E3dScene * & prScene) const1262 sal_Bool E3dCompoundObject::IsAOrdNumRemapCandidate(E3dScene*& prScene) const
1263 {
1264     if(GetObjList()
1265         && GetObjList()->GetOwnerObj()
1266         && GetObjList()->GetOwnerObj()->ISA(E3dScene))
1267     {
1268         prScene = (E3dScene*)GetObjList()->GetOwnerObj();
1269         return sal_True;
1270     }
1271 
1272     return sal_False;
1273 }
1274 
1275 //////////////////////////////////////////////////////////////////////////////
1276 // eof
1277