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