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