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 102 E3dObjList::E3dObjList(SdrModel* pNewModel, SdrPage* pNewPage, E3dObjList* pNewUpList) 103 : SdrObjList(pNewModel, pNewPage, pNewUpList) 104 { 105 } 106 107 E3dObjList::E3dObjList(const E3dObjList& rSrcList) 108 : SdrObjList(rSrcList) 109 { 110 } 111 112 E3dObjList::~E3dObjList() 113 { 114 } 115 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 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 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 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 192 sdr::properties::BaseProperties* E3dObject::CreateObjectSpecificProperties() 193 { 194 return new sdr::properties::E3dProperties(*this); 195 } 196 197 //////////////////////////////////////////////////////////////////////////////////////////////////// 198 199 TYPEINIT1(E3dObject, SdrAttrObj); 200 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 221 E3dObject::~E3dObject() 222 { 223 } 224 225 /************************************************************************* 226 |* 227 |* Selektions-Flag setzen 228 |* 229 \************************************************************************/ 230 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 255 sal_Bool E3dObject::IsBreakObjPossible() 256 { 257 return sal_False; 258 } 259 260 SdrAttrObj* E3dObject::GetBreakObj() 261 { 262 return 0L; 263 } 264 265 /************************************************************************* 266 |* 267 |* SetRectsDirty muss ueber die lokale SdrSubList gehen 268 |* 269 \************************************************************************/ 270 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 293 sal_uInt32 E3dObject::GetObjInventor() const 294 { 295 return E3dInventor; 296 } 297 298 /************************************************************************* 299 |* 300 |* Identifier zurueckgeben 301 |* 302 \************************************************************************/ 303 304 sal_uInt16 E3dObject::GetObjIdentifier() const 305 { 306 return E3D_OBJECT_ID; 307 } 308 309 /************************************************************************* 310 |* 311 |* Faehigkeiten des Objektes feststellen 312 |* 313 \************************************************************************/ 314 315 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 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 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 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 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 \************************************************************************/ 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 \************************************************************************/ 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 520 SdrObjList* E3dObject::GetSubList() const 521 { 522 return &(const_cast< E3dObjList& >(maSubList)); 523 } 524 525 /************************************************************************* 526 |* 527 |* SnapRect berechnen 528 |* 529 \************************************************************************/ 530 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 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 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 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 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 615 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 632 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 645 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 694 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 704 void E3dObject::InvalidateBoundVolume() 705 { 706 maLocalBoundVol.reset(); 707 } 708 709 /************************************************************************* 710 |* 711 |* Aederung des BoundVolumes an alle Kindobjekte weitergeben 712 |* 713 \************************************************************************/ 714 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 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 759 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 783 const basegfx::B3DHomMatrix& E3dObject::GetTransform() const 784 { 785 return maTransformation; 786 } 787 788 /************************************************************************* 789 |* 790 |* Transformationsmatrix setzen 791 |* 792 \************************************************************************/ 793 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 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 829 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 841 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 861 void E3dObject::TakeObjNamePlural(XubString& rName) const 862 { 863 rName=ImpGetResStr(STR_ObjNamePluralObj3d); 864 } 865 866 /************************************************************************* 867 |* 868 |* Zuweisungsoperator 869 |* 870 \************************************************************************/ 871 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 900 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 913 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 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 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 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 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 995 E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault) 996 : E3dObject(), 997 aMaterialAmbientColor(), 998 bCreateNormals(false), 999 bCreateTexture(false) 1000 { 1001 // Defaults setzen 1002 SetDefaultAttributes(rDefault); 1003 } 1004 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 1020 E3dCompoundObject::~E3dCompoundObject () 1021 { 1022 } 1023 1024 /************************************************************************* 1025 |* 1026 |* Drag-Polygon zurueckgeben 1027 |* 1028 \************************************************************************/ 1029 1030 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 1055 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 1067 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 1126 sal_uInt16 E3dCompoundObject::GetObjIdentifier() const 1127 { 1128 return E3D_COMPOUNDOBJ_ID; 1129 } 1130 1131 /************************************************************************* 1132 |* 1133 |* SnapRect berechnen 1134 |* 1135 \************************************************************************/ 1136 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 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 1206 void E3dCompoundObject::SetCreateNormals(sal_Bool bNew) 1207 { 1208 if(bCreateNormals != bNew) 1209 { 1210 bCreateNormals = bNew; 1211 ActionChanged(); 1212 } 1213 } 1214 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 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 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 1262 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