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/svditer.hxx" 30 31 #if defined( UNX ) || defined( ICC ) 32 #include <stdlib.h> 33 #endif 34 #include "svx/globl3d.hxx" 35 #include <svx/svdpage.hxx> 36 #include <svl/style.hxx> 37 #include <svx/scene3d.hxx> 38 #include <svx/e3dundo.hxx> 39 #include <svx/svdtrans.hxx> 40 #include <svx/svxids.hrc> 41 #include <editeng/colritem.hxx> 42 #include <svx/e3ditem.hxx> 43 #include <svx/xlntrit.hxx> 44 #include <svx/xfltrit.hxx> 45 #include <svx/svx3ditems.hxx> 46 #include <svl/whiter.hxx> 47 #include <svx/xflftrit.hxx> 48 #include <svx/sdr/properties/e3dsceneproperties.hxx> 49 #include <svx/sdr/contact/viewcontactofe3dscene.hxx> 50 #include <svx/svddrag.hxx> 51 #include <helperminimaldepth3d.hxx> 52 #include <algorithm> 53 #include <drawinglayer/geometry/viewinformation3d.hxx> 54 #include <basegfx/polygon/b2dpolypolygontools.hxx> 55 #include <svx/e3dsceneupdater.hxx> 56 #include <svx/svdmodel.hxx> 57 58 #define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue() 59 60 ////////////////////////////////////////////////////////////////////////////// 61 // #110988# 62 63 class ImpRemap3DDepth 64 { 65 sal_uInt32 mnOrdNum; 66 double mfMinimalDepth; 67 68 // bitfield 69 unsigned mbIsScene : 1; 70 71 public: 72 ImpRemap3DDepth(sal_uInt32 nOrdNum, double fMinimalDepth); 73 ImpRemap3DDepth(sal_uInt32 nOrdNum); 74 ~ImpRemap3DDepth(); 75 76 // for ::std::sort 77 bool operator<(const ImpRemap3DDepth& rComp) const; 78 79 sal_uInt32 GetOrdNum() const { return mnOrdNum; } 80 sal_Bool IsScene() const { return mbIsScene; } 81 }; 82 83 ImpRemap3DDepth::ImpRemap3DDepth(sal_uInt32 nOrdNum, double fMinimalDepth) 84 : mnOrdNum(nOrdNum), 85 mfMinimalDepth(fMinimalDepth), 86 mbIsScene(sal_False) 87 { 88 } 89 90 ImpRemap3DDepth::ImpRemap3DDepth(sal_uInt32 nOrdNum) 91 : mnOrdNum(nOrdNum), 92 mbIsScene(sal_True) 93 { 94 } 95 96 ImpRemap3DDepth::~ImpRemap3DDepth() 97 { 98 } 99 100 bool ImpRemap3DDepth::operator<(const ImpRemap3DDepth& rComp) const 101 { 102 if(IsScene()) 103 { 104 return sal_False; 105 } 106 else 107 { 108 if(rComp.IsScene()) 109 { 110 return sal_True; 111 } 112 else 113 { 114 return mfMinimalDepth < rComp.mfMinimalDepth; 115 } 116 } 117 } 118 119 // typedefs for a vector of ImpRemap3DDepths 120 typedef ::std::vector< ImpRemap3DDepth > ImpRemap3DDepthVector; 121 122 ////////////////////////////////////////////////////////////////////////////// 123 // #110988# 124 125 class Imp3DDepthRemapper 126 { 127 ImpRemap3DDepthVector maVector; 128 129 public: 130 Imp3DDepthRemapper(E3dScene& rScene); 131 ~Imp3DDepthRemapper(); 132 133 sal_uInt32 RemapOrdNum(sal_uInt32 nOrdNum) const; 134 }; 135 136 Imp3DDepthRemapper::Imp3DDepthRemapper(E3dScene& rScene) 137 { 138 // only called when rScene.GetSubList() and nObjCount > 1L 139 SdrObjList* pList = rScene.GetSubList(); 140 const sal_uInt32 nObjCount(pList->GetObjCount()); 141 142 for(sal_uInt32 a(0L); a < nObjCount; a++) 143 { 144 SdrObject* pCandidate = pList->GetObj(a); 145 146 if(pCandidate) 147 { 148 if(pCandidate->ISA(E3dCompoundObject)) 149 { 150 // single 3d object, calc depth 151 const double fMinimalDepth(getMinimalDepthInViewCoordinates(static_cast< const E3dCompoundObject& >(*pCandidate))); 152 ImpRemap3DDepth aEntry(a, fMinimalDepth); 153 maVector.push_back(aEntry); 154 } 155 else 156 { 157 // scene, use standard entry for scene 158 ImpRemap3DDepth aEntry(a); 159 maVector.push_back(aEntry); 160 } 161 } 162 } 163 164 // now, we need to sort the maVector by it's members minimal depth. The 165 // smaller, the nearer to the viewer. 166 ::std::sort(maVector.begin(), maVector.end()); 167 } 168 169 Imp3DDepthRemapper::~Imp3DDepthRemapper() 170 { 171 } 172 173 sal_uInt32 Imp3DDepthRemapper::RemapOrdNum(sal_uInt32 nOrdNum) const 174 { 175 if(nOrdNum < maVector.size()) 176 { 177 nOrdNum = maVector[(maVector.size() - 1) - nOrdNum].GetOrdNum(); 178 } 179 180 return nOrdNum; 181 } 182 183 ////////////////////////////////////////////////////////////////////////////// 184 // BaseProperties section 185 186 sdr::properties::BaseProperties* E3dScene::CreateObjectSpecificProperties() 187 { 188 return new sdr::properties::E3dSceneProperties(*this); 189 } 190 191 ////////////////////////////////////////////////////////////////////////////// 192 // #110094# DrawContact section 193 194 sdr::contact::ViewContact* E3dScene::CreateObjectSpecificViewContact() 195 { 196 return new sdr::contact::ViewContactOfE3dScene(*this); 197 } 198 199 //////////////////////////////////////////////////////////////////////////////////////////////////// 200 201 TYPEINIT1(E3dScene, E3dObject); 202 203 /************************************************************************* 204 |* 205 |* E3dScene-Konstruktor 206 |* 207 \************************************************************************/ 208 209 E3dScene::E3dScene() 210 : E3dObject(), 211 aCamera(basegfx::B3DPoint(0.0, 0.0, 4.0), basegfx::B3DPoint()), 212 mp3DDepthRemapper(0L), 213 bDrawOnlySelected(false) 214 { 215 // Defaults setzen 216 E3dDefaultAttributes aDefault; 217 SetDefaultAttributes(aDefault); 218 } 219 220 E3dScene::E3dScene(E3dDefaultAttributes& rDefault) 221 : E3dObject(), 222 aCamera(basegfx::B3DPoint(0.0, 0.0, 4.0), basegfx::B3DPoint()), 223 mp3DDepthRemapper(0L), 224 bDrawOnlySelected(false) 225 { 226 // Defaults setzen 227 SetDefaultAttributes(rDefault); 228 } 229 230 void E3dScene::SetDefaultAttributes(E3dDefaultAttributes& /*rDefault*/) 231 { 232 // Fuer OS/2 die FP-Exceptions abschalten 233 #if defined(OS2) 234 #define SC_FPEXCEPTIONS_ON() _control87( MCW_EM, 0 ) 235 #define SC_FPEXCEPTIONS_OFF() _control87( MCW_EM, MCW_EM ) 236 SC_FPEXCEPTIONS_OFF(); 237 #endif 238 239 // Fuer WIN95/NT die FP-Exceptions abschalten 240 #if defined(WNT) 241 #define SC_FPEXCEPTIONS_ON() _control87( _MCW_EM, 0 ) 242 #define SC_FPEXCEPTIONS_OFF() _control87( _MCW_EM, _MCW_EM ) 243 SC_FPEXCEPTIONS_OFF(); 244 #endif 245 246 // Defaults setzen 247 aCamera.SetViewWindow(-2, -2, 4, 4); 248 aCameraSet.SetDeviceRectangle(-2, 2, -2, 2); 249 aCamera.SetDeviceWindow(Rectangle(0, 0, 10, 10)); 250 Rectangle aRect(0, 0, 10, 10); 251 aCameraSet.SetViewportRectangle(aRect); 252 253 // set defaults for Camera from ItemPool 254 aCamera.SetProjection(GetPerspective()); 255 basegfx::B3DPoint aActualPosition(aCamera.GetPosition()); 256 double fNew = GetDistance(); 257 258 if(fabs(fNew - aActualPosition.getZ()) > 1.0) 259 { 260 aCamera.SetPosition( basegfx::B3DPoint( aActualPosition.getX(), aActualPosition.getY(), fNew) ); 261 } 262 263 fNew = GetFocalLength() / 100.0; 264 aCamera.SetFocalLength(fNew); 265 } 266 267 /************************************************************************* 268 |* 269 |* Destruktor 270 |* 271 \************************************************************************/ 272 273 E3dScene::~E3dScene() 274 { 275 // #110988# 276 ImpCleanup3DDepthMapper(); 277 } 278 279 basegfx::B2DPolyPolygon E3dScene::TakeXorPoly() const 280 { 281 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(GetViewContact()); 282 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); 283 const basegfx::B3DPolyPolygon aCubePolyPolygon(CreateWireframe()); 284 285 basegfx::B2DPolyPolygon aRetval(basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCubePolyPolygon, 286 aViewInfo3D.getObjectToView())); 287 aRetval.transform(rVCScene.getObjectTransformation()); 288 289 return aRetval; 290 } 291 292 // #110988# 293 void E3dScene::ImpCleanup3DDepthMapper() 294 { 295 if(mp3DDepthRemapper) 296 { 297 delete mp3DDepthRemapper; 298 mp3DDepthRemapper = 0L; 299 } 300 } 301 302 // #110988# 303 sal_uInt32 E3dScene::RemapOrdNum(sal_uInt32 nNewOrdNum) const 304 { 305 if(!mp3DDepthRemapper) 306 { 307 const sal_uInt32 nObjCount(GetSubList() ? GetSubList()->GetObjCount() : 0L); 308 309 if(nObjCount > 1L) 310 { 311 ((E3dScene*)this)->mp3DDepthRemapper = new Imp3DDepthRemapper((E3dScene&)(*this)); 312 } 313 } 314 315 if(mp3DDepthRemapper) 316 { 317 return mp3DDepthRemapper->RemapOrdNum(nNewOrdNum); 318 } 319 320 return nNewOrdNum; 321 } 322 323 /************************************************************************* 324 |* 325 |* Identifier zurueckgeben 326 |* 327 \************************************************************************/ 328 329 sal_uInt16 E3dScene::GetObjIdentifier() const 330 { 331 return E3D_SCENE_ID; 332 } 333 334 void E3dScene::SetBoundRectDirty() 335 { 336 E3dScene* pScene = GetScene(); 337 338 if(pScene == this) 339 { 340 // avoid resetting aOutRect which in case of a 3D scene used as 2d object 341 // is model data,not re-creatable view data 342 } 343 else 344 { 345 // if not the outmost scene it is used as group in 3d, call parent 346 E3dObject::SetBoundRectDirty(); 347 } 348 } 349 350 /************************************************************************* 351 |* 352 |* SetSnapRect 353 |* 354 \************************************************************************/ 355 356 void E3dScene::NbcSetSnapRect(const Rectangle& rRect) 357 { 358 SetRectsDirty(); 359 E3dObject::NbcSetSnapRect(rRect); 360 aCamera.SetDeviceWindow(rRect); 361 aCameraSet.SetViewportRectangle((Rectangle&)rRect); 362 363 // #110988# 364 ImpCleanup3DDepthMapper(); 365 } 366 367 /************************************************************************* 368 |* 369 |* Objekt verschieben 370 |* 371 \************************************************************************/ 372 373 void E3dScene::NbcMove(const Size& rSize) 374 { 375 Rectangle aNewSnapRect = GetSnapRect(); 376 MoveRect(aNewSnapRect, rSize); 377 NbcSetSnapRect(aNewSnapRect); 378 } 379 380 /************************************************************************* 381 |* 382 |* Objekt Resizen 383 |* 384 \************************************************************************/ 385 386 void E3dScene::NbcResize(const Point& rRef, const Fraction& rXFact, 387 const Fraction& rYFact) 388 { 389 Rectangle aNewSnapRect = GetSnapRect(); 390 ResizeRect(aNewSnapRect, rRef, rXFact, rYFact); 391 NbcSetSnapRect(aNewSnapRect); 392 } 393 394 /************************************************************************* 395 |* 396 |* Neue Kamera setzen, und dabei die Szene und ggf. das BoundVolume 397 |* als geaendert markieren 398 |* 399 \************************************************************************/ 400 401 void E3dScene::SetCamera(const Camera3D& rNewCamera) 402 { 403 // Alte Kamera setzen 404 aCamera = rNewCamera; 405 ((sdr::properties::E3dSceneProperties&)GetProperties()).SetSceneItemsFromCamera(); 406 407 SetRectsDirty(); 408 409 // Neue Kamera aus alter fuellen 410 Camera3D& rCam = (Camera3D&)GetCamera(); 411 412 // Ratio abschalten 413 if(rCam.GetAspectMapping() == AS_NO_MAPPING) 414 GetCameraSet().SetRatio(0.0); 415 416 // Abbildungsgeometrie setzen 417 basegfx::B3DPoint aVRP(rCam.GetViewPoint()); 418 basegfx::B3DVector aVPN(aVRP - rCam.GetVRP()); 419 basegfx::B3DVector aVUV(rCam.GetVUV()); 420 421 // #91047# use SetViewportValues() to set VRP, VPN and VUV as vectors, too. 422 // Else these values would not be exported/imported correctly. 423 GetCameraSet().SetViewportValues(aVRP, aVPN, aVUV); 424 425 // Perspektive setzen 426 GetCameraSet().SetPerspective(rCam.GetProjection() == PR_PERSPECTIVE); 427 GetCameraSet().SetViewportRectangle((Rectangle&)rCam.GetDeviceWindow()); 428 429 // #110988# 430 ImpCleanup3DDepthMapper(); 431 } 432 433 /************************************************************************* 434 |* 435 |* 3D-Objekt einfuegen 436 |* 437 \************************************************************************/ 438 439 void E3dScene::NewObjectInserted(const E3dObject* p3DObj) 440 { 441 E3dObject::NewObjectInserted(p3DObj); 442 443 if ( p3DObj == this ) 444 return; 445 446 // #110988# 447 ImpCleanup3DDepthMapper(); 448 } 449 450 /************************************************************************* 451 |* 452 |* Parent ueber Aenderung eines Childs informieren 453 |* 454 \************************************************************************/ 455 456 void E3dScene::StructureChanged() 457 { 458 E3dObject::StructureChanged(); 459 460 if(!GetModel() || !GetModel()->isLocked()) 461 { 462 // #123539# optimization for 3D chart object generation: do not reset 463 // already calculated scene projection data every time an object gets 464 // initialized 465 SetRectsDirty(); 466 } 467 468 // #110988# 469 ImpCleanup3DDepthMapper(); 470 } 471 472 /************************************************************************* 473 |* 474 |* Uebergeordnetes Szenenobjekt bestimmen 475 |* 476 \************************************************************************/ 477 478 E3dScene* E3dScene::GetScene() const 479 { 480 if(GetParentObj()) 481 return GetParentObj()->GetScene(); 482 else 483 return (E3dScene*)this; 484 } 485 486 void E3dScene::removeAllNonSelectedObjects() 487 { 488 E3DModifySceneSnapRectUpdater aUpdater(this); 489 490 for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++) 491 { 492 SdrObject* pObj = maSubList.GetObj(a); 493 494 if(pObj) 495 { 496 bool bRemoveObject(false); 497 498 if(pObj->ISA(E3dScene)) 499 { 500 E3dScene* pScene = (E3dScene*)pObj; 501 502 // iterate over this sub-scene 503 pScene->removeAllNonSelectedObjects(); 504 505 // check object count. Empty scenes can be deleted 506 const sal_uInt32 nObjCount(pScene->GetSubList() ? pScene->GetSubList()->GetObjCount() : 0); 507 508 if(!nObjCount) 509 { 510 // all objects removed, scene can be removed, too 511 bRemoveObject = true; 512 } 513 } 514 else if(pObj->ISA(E3dCompoundObject)) 515 { 516 E3dCompoundObject* pCompound = (E3dCompoundObject*)pObj; 517 518 if(!pCompound->GetSelected()) 519 { 520 bRemoveObject = true; 521 } 522 } 523 524 if(bRemoveObject) 525 { 526 maSubList.NbcRemoveObject(pObj->GetOrdNum()); 527 a--; 528 SdrObject::Free(pObj); 529 } 530 } 531 } 532 } 533 534 /************************************************************************* 535 |* 536 |* Zuweisungsoperator 537 |* 538 \************************************************************************/ 539 540 void E3dScene::operator=(const SdrObject& rObj) 541 { 542 E3dObject::operator=(rObj); 543 544 const E3dScene& r3DObj = (const E3dScene&) rObj; 545 aCamera = r3DObj.aCamera; 546 547 // neu ab 377: 548 aCameraSet = r3DObj.aCameraSet; 549 ((sdr::properties::E3dSceneProperties&)GetProperties()).SetSceneItemsFromCamera(); 550 551 // SetSnapRect(r3DObj.GetSnapRect()); 552 InvalidateBoundVolume(); 553 RebuildLists(); 554 SetRectsDirty(); 555 556 // #110988# 557 ImpCleanup3DDepthMapper(); 558 559 // #i101941# 560 // After a Scene as model object is cloned, the used 561 // ViewContactOfE3dScene is created and partially used 562 // to calculate Bound/SnapRects, but - since quite some 563 // values are buffered at the VC - not really well 564 // initialized. It would be possible to always watch for 565 // preconditions of buffered data, but this would be expensive 566 // and would create a lot of short living data structures. 567 // It is currently better to flush that data, e.g. by using 568 // ActionChanged at the VC which will for this class 569 // flush that cached data and initalize it's valid reconstruction 570 GetViewContact().ActionChanged(); 571 } 572 573 /************************************************************************* 574 |* 575 |* Licht- und Labelobjektlisten neu aufbauen (nach Laden, Zuweisung) 576 |* 577 \************************************************************************/ 578 579 void E3dScene::RebuildLists() 580 { 581 // zuerst loeschen 582 SdrLayerID nCurrLayerID = GetLayer(); 583 584 SdrObjListIter a3DIterator(maSubList, IM_FLAT); 585 586 // dann alle Objekte in der Szene pruefen 587 while ( a3DIterator.IsMore() ) 588 { 589 E3dObject* p3DObj = (E3dObject*) a3DIterator.Next(); 590 p3DObj->NbcSetLayer(nCurrLayerID); 591 NewObjectInserted(p3DObj); 592 } 593 } 594 595 /************************************************************************* 596 |* 597 |* erstelle neues GeoData-Objekt 598 |* 599 \************************************************************************/ 600 601 SdrObjGeoData *E3dScene::NewGeoData() const 602 { 603 return new E3DSceneGeoData; 604 } 605 606 /************************************************************************* 607 |* 608 |* uebergebe aktuelle werte an das GeoData-Objekt 609 |* 610 \************************************************************************/ 611 612 void E3dScene::SaveGeoData(SdrObjGeoData& rGeo) const 613 { 614 E3dObject::SaveGeoData (rGeo); 615 616 ((E3DSceneGeoData &) rGeo).aCamera = aCamera; 617 } 618 619 /************************************************************************* 620 |* 621 |* uebernehme werte aus dem GeoData-Objekt 622 |* 623 \************************************************************************/ 624 625 void E3dScene::RestGeoData(const SdrObjGeoData& rGeo) 626 { 627 // #i94832# removed E3DModifySceneSnapRectUpdater here. 628 // It should not be needed, is already part of E3dObject::RestGeoData 629 E3dObject::RestGeoData (rGeo); 630 SetCamera (((E3DSceneGeoData &) rGeo).aCamera); 631 } 632 633 /************************************************************************* 634 |* 635 |* Am StyleSheet wurde etwas geaendert, also Scene aendern 636 |* 637 \************************************************************************/ 638 639 void E3dScene::Notify(SfxBroadcaster &rBC, const SfxHint &rHint) 640 { 641 SetRectsDirty(); 642 E3dObject::Notify(rBC, rHint); 643 } 644 645 /************************************************************************* 646 |* 647 \************************************************************************/ 648 649 void E3dScene::RotateScene (const Point& rRef, long /*nWink*/, double sn, double cs) 650 { 651 Point UpperLeft, LowerRight, Center, NewCenter; 652 653 UpperLeft = aOutRect.TopLeft(); 654 LowerRight = aOutRect.BottomRight(); 655 656 long dxOutRectHalf = labs(UpperLeft.X() - LowerRight.X()); 657 dxOutRectHalf /= 2; 658 long dyOutRectHalf = labs(UpperLeft.Y() - LowerRight.Y()); 659 dyOutRectHalf /= 2; 660 661 Rectangle RectQuelle(aOutRect), RectZiel(aOutRect); 662 663 // Nur der Mittelpunkt wird bewegt. Die Ecken werden von NbcMove bewegt. 664 // Fuer das Drehen wird von mir ein kartesisches Koordinatensystem verwendet in dem der Drehpunkt 665 // der Nullpunkt ist und die Y- Achse nach oben ansteigt, die X-Achse nach rechts. 666 // Dies muss bei den Y-Werten beachtet werden. (Auf dem Blatt zeigt die Y-Achse nach unten 667 Center.X() = (UpperLeft.X() + dxOutRectHalf) - rRef.X(); 668 Center.Y() = -((UpperLeft.Y() + dyOutRectHalf) - rRef.Y()); 669 // Ein paar Spezialfaelle zuerst abhandeln (n*90 Grad n ganzzahlig) 670 if (sn==1.0 && cs==0.0) { // 90deg 671 NewCenter.X() = -Center.Y(); 672 NewCenter.Y() = -Center.X(); 673 } else if (sn==0.0 && cs==-1.0) { // 180deg 674 NewCenter.X() = -Center.X(); 675 NewCenter.Y() = -Center.Y(); 676 } else if (sn==-1.0 && cs==0.0) { // 270deg 677 NewCenter.X() = Center.Y(); 678 NewCenter.Y() = -Center.X(); 679 } 680 else // Hier wird um einen beliebigen Winkel in mathematisch positiver Richtung gedreht! 681 { // xneu = x * cos(alpha) - y * sin(alpha) 682 // yneu = x * sin(alpha) + y * cos(alpha) 683 // Unten Rechts wird nicht gedreht: die Seiten von RectQuelle muessen parallel 684 // zu den Koordinatenachsen bleiben. 685 NewCenter.X() = (long) (Center.X() * cs - Center.Y() * sn); 686 NewCenter.Y() = (long) (Center.X() * sn + Center.Y() * cs); 687 } 688 689 Size Differenz; 690 Point DiffPoint = (NewCenter - Center); 691 Differenz.Width() = DiffPoint.X(); 692 Differenz.Height() = -DiffPoint.Y(); // Man beachte dass die Y-Achse nach unten positiv gezaehlt wird. 693 NbcMove (Differenz); // fuehrt die eigentliche Koordinatentransformation durch. 694 } 695 696 /************************************************************************* 697 |* 698 |* Get the name of the object (singular) 699 |* 700 \************************************************************************/ 701 702 void E3dScene::TakeObjNameSingul(XubString& rName) const 703 { 704 rName=ImpGetResStr(STR_ObjNameSingulScene3d); 705 706 String aName( GetName() ); 707 if(aName.Len()) 708 { 709 rName += sal_Unicode(' '); 710 rName += sal_Unicode('\''); 711 rName += aName; 712 rName += sal_Unicode('\''); 713 } 714 } 715 716 /************************************************************************* 717 |* 718 |* Get the name of the object (plural) 719 |* 720 \************************************************************************/ 721 722 void E3dScene::TakeObjNamePlural(XubString& rName) const 723 { 724 rName=ImpGetResStr(STR_ObjNamePluralScene3d); 725 } 726 727 /************************************************************************* 728 |* 729 |* Die NbcRotate-Routine ueberlaedt die des SdrObject. Die Idee ist die Scene 730 |* drehen zu koennen und relativ zur Lage der Scene dann auch die Objekte 731 |* in der Scene 732 |* 733 \************************************************************************/ 734 735 void E3dScene::NbcSetTransform(const basegfx::B3DHomMatrix& rMatrix) 736 { 737 if(maTransformation != rMatrix) 738 { 739 // call parent 740 E3dObject::NbcSetTransform(rMatrix); 741 } 742 } 743 744 void E3dScene::SetTransform(const basegfx::B3DHomMatrix& rMatrix) 745 { 746 if(rMatrix != maTransformation) 747 { 748 // call parent 749 E3dObject::SetTransform(rMatrix); 750 } 751 } 752 753 void E3dScene::NbcRotate(const Point& rRef, long nWink, double sn, double cs) 754 { 755 // Also derzeit sind die Klebepunkte relativ zum aOutRect der Szene definiert. Vor dem Drehen 756 // werden die Klebepunkte relativ zur Seite definiert. Sie nehmen an der Drehung der Szene noch nicht Teil 757 // dafuer gibt es den 758 SetGlueReallyAbsolute(sal_True); 759 760 // So dass war die Szene, ab jetzt kommen die Objekte in der Szene 761 // 3D-Objekte gibt es nur ein einziges das kann zwar mehrere Flaechen haben aber die Flaechen 762 // muessen ja nicht zusammenhaengend sein 763 // es ermoeglicht den Zugriff auf Kindobjekte 764 // Ich gehe also die gesamte Liste durch und rotiere um die Z-Achse die durch den 765 // Mittelpunkt von aOutRect geht (Satz von Steiner), also RotateZ 766 767 RotateScene (rRef, nWink, sn, cs); // Rotiert die Szene 768 double fWinkelInRad = nWink/100 * F_PI180; 769 770 basegfx::B3DHomMatrix aRotation; 771 aRotation.rotate(0.0, 0.0, fWinkelInRad); 772 NbcSetTransform(aRotation * GetTransform()); 773 774 SetRectsDirty(); // Veranlasst eine Neuberechnung aller BoundRects 775 NbcRotateGluePoints(rRef,nWink,sn,cs); // Rotiert die Klebepunkte (die haben noch Koordinaten relativ 776 // zum Urpsung des Blattes 777 SetGlueReallyAbsolute(sal_False); // ab jetzt sind sie wieder relativ zum BoundRect (also dem aOutRect definiert) 778 SetRectsDirty(); 779 } 780 781 /************************************************************************* 782 |* 783 |* SnapRect berechnen 784 |* 785 \************************************************************************/ 786 787 void E3dScene::RecalcSnapRect() 788 { 789 E3dScene* pScene = GetScene(); 790 791 if(pScene == this) 792 { 793 // Szene wird als 2D-Objekt benutzt, nimm SnapRect aus der 794 // 2D Bildschrimdarstellung 795 Camera3D& rCam = (Camera3D&)pScene->GetCamera(); 796 maSnapRect = rCam.GetDeviceWindow(); 797 } 798 else 799 { 800 // Szene ist selbst Mitglied einer anderen Szene, hole das 801 // SnapRect als zusammengesetztes Objekt 802 E3dObject::RecalcSnapRect(); 803 } 804 } 805 806 /************************************************************************* 807 |* 808 |* Aufbrechen 809 |* 810 \************************************************************************/ 811 812 sal_Bool E3dScene::IsBreakObjPossible() 813 { 814 // Szene ist aufzubrechen, wenn alle Mitglieder aufzubrechen sind 815 SdrObjListIter a3DIterator(maSubList, IM_DEEPWITHGROUPS); 816 817 while ( a3DIterator.IsMore() ) 818 { 819 E3dObject* pObj = (E3dObject*) a3DIterator.Next(); 820 DBG_ASSERT(pObj->ISA(E3dObject), "AW: In Szenen sind nur 3D-Objekte erlaubt!"); 821 if(!pObj->IsBreakObjPossible()) 822 return sal_False; 823 } 824 825 return sal_True; 826 } 827 828 basegfx::B3DVector E3dScene::GetShadowPlaneDirection() const 829 { 830 double fWink = (double)GetShadowSlant() * F_PI180; 831 basegfx::B3DVector aShadowPlaneDir(0.0, sin(fWink), cos(fWink)); 832 aShadowPlaneDir.normalize(); 833 return aShadowPlaneDir; 834 } 835 836 void E3dScene::SetShadowPlaneDirection(const basegfx::B3DVector& rVec) 837 { 838 sal_uInt16 nSceneShadowSlant = (sal_uInt16)((atan2(rVec.getY(), rVec.getZ()) / F_PI180) + 0.5); 839 GetProperties().SetObjectItemDirect(Svx3DShadowSlantItem(nSceneShadowSlant)); 840 } 841 842 basegfx::B2DPolyPolygon E3dScene::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const 843 { 844 return TakeXorPoly(); 845 } 846 847 FASTBOOL E3dScene::BegCreate(SdrDragStat& rStat) 848 { 849 rStat.SetOrtho4Possible(); 850 Rectangle aRect1(rStat.GetStart(), rStat.GetNow()); 851 aRect1.Justify(); 852 rStat.SetActionRect(aRect1); 853 NbcSetSnapRect(aRect1); 854 return sal_True; 855 } 856 857 FASTBOOL E3dScene::MovCreate(SdrDragStat& rStat) 858 { 859 Rectangle aRect1; 860 rStat.TakeCreateRect(aRect1); 861 aRect1.Justify(); 862 rStat.SetActionRect(aRect1); 863 NbcSetSnapRect(aRect1); 864 SetBoundRectDirty(); 865 bSnapRectDirty=sal_True; 866 return sal_True; 867 } 868 869 FASTBOOL E3dScene::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) 870 { 871 Rectangle aRect1; 872 rStat.TakeCreateRect(aRect1); 873 aRect1.Justify(); 874 NbcSetSnapRect(aRect1); 875 SetRectsDirty(); 876 return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2); 877 } 878 879 FASTBOOL E3dScene::BckCreate(SdrDragStat& /*rStat*/) 880 { 881 return sal_False; 882 } 883 884 void E3dScene::BrkCreate(SdrDragStat& /*rStat*/) 885 { 886 } 887 888 // eof 889