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 <vcl/wrkwin.hxx> 28 #include <svx/svdogrp.hxx> 29 #include <svx/svdopath.hxx> 30 #include <tools/shl.hxx> 31 #include "svx/svditer.hxx" 32 #include <svx/svdpool.hxx> 33 #include <svx/svdorect.hxx> 34 #include <svx/svdmodel.hxx> 35 #include <svx/svdpagv.hxx> 36 #include <svx/svxids.hrc> 37 #include <editeng/colritem.hxx> 38 #include <svx/xtable.hxx> 39 #include <svx/svdview.hxx> 40 #include <svx/dialogs.hrc> 41 #include <svx/dialmgr.hxx> 42 #include "svx/globl3d.hxx" 43 #include <svx/obj3d.hxx> 44 #include <svx/lathe3d.hxx> 45 #include <svx/sphere3d.hxx> 46 #include <svx/extrud3d.hxx> 47 #include <svx/cube3d.hxx> 48 #include <svx/polysc3d.hxx> 49 #include "dragmt3d.hxx" 50 #include <svx/view3d.hxx> 51 #include <svx/svdundo.hxx> 52 #include <svx/xflclit.hxx> 53 #include <svx/xlnclit.hxx> 54 #include <svx/svdograf.hxx> 55 #include <svx/xbtmpit.hxx> 56 #include <svx/xflbmtit.hxx> 57 #include <basegfx/range/b2drange.hxx> 58 #include <basegfx/polygon/b2dpolygontools.hxx> 59 #include <basegfx/polygon/b2dpolypolygontools.hxx> 60 #include <svx/xlnwtit.hxx> 61 #include <svx/sdr/overlay/overlaypolypolygon.hxx> 62 #include <svx/sdr/overlay/overlaymanager.hxx> 63 #include <svx/sdrpaintwindow.hxx> 64 #include <svx/sdr/contact/viewcontactofe3dscene.hxx> 65 #include <drawinglayer/geometry/viewinformation3d.hxx> 66 #include <svx/sdrpagewindow.hxx> 67 #include <svx/sdr/contact/displayinfo.hxx> 68 #include <svx/sdr/contact/objectcontact.hxx> 69 #include <svx/sdr/contact/viewobjectcontact.hxx> 70 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 71 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx> 72 #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 73 #include <basegfx/matrix/b2dhommatrixtools.hxx> 74 #include <basegfx/polygon/b2dpolypolygoncutter.hxx> 75 76 #define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue() 77 78 TYPEINIT1(E3dView, SdrView); 79 80 //////////////////////////////////////////////////////////////////////////////////////////////////// 81 // Migrate Marking 82 83 class Impl3DMirrorConstructOverlay 84 { 85 // The OverlayObjects 86 ::sdr::overlay::OverlayObjectList maObjects; 87 88 // the view 89 const E3dView& mrView; 90 91 // the object count 92 sal_uInt32 mnCount; 93 94 // the unmirrored polygons 95 basegfx::B2DPolyPolygon* mpPolygons; 96 97 // the overlay geometry from selected objects 98 drawinglayer::primitive2d::Primitive2DSequence maFullOverlay; 99 100 public: 101 Impl3DMirrorConstructOverlay(const E3dView& rView); 102 ~Impl3DMirrorConstructOverlay(); 103 104 void SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB); 105 }; 106 107 Impl3DMirrorConstructOverlay::Impl3DMirrorConstructOverlay(const E3dView& rView) 108 : maObjects(), 109 mrView(rView), 110 mnCount(rView.GetMarkedObjectCount()), 111 mpPolygons(0), 112 maFullOverlay() 113 { 114 if(mnCount) 115 { 116 if(mrView.IsSolidDragging()) 117 { 118 SdrPageView* pPV = rView.GetSdrPageView(); 119 120 if(pPV && pPV->PageWindowCount()) 121 { 122 sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact(); 123 sdr::contact::DisplayInfo aDisplayInfo; 124 125 // Do not use the last ViewPort set at the OC at the last ProcessDisplay() 126 rOC.resetViewPort(); 127 128 for(sal_uInt32 a(0);a < mnCount;a++) 129 { 130 SdrObject* pObject = mrView.GetMarkedObjectByIndex(a); 131 132 if(pObject) 133 { 134 sdr::contact::ViewContact& rVC = pObject->GetViewContact(); 135 sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rOC); 136 137 const drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo)); 138 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(maFullOverlay, aNewSequence); 139 } 140 } 141 } 142 } 143 else 144 { 145 mpPolygons = new basegfx::B2DPolyPolygon[mnCount]; 146 147 for(sal_uInt32 a(0); a < mnCount; a++) 148 { 149 SdrObject* pObject = mrView.GetMarkedObjectByIndex(a); 150 mpPolygons[mnCount - (a + 1)] = pObject->TakeXorPoly(); 151 } 152 } 153 } 154 } 155 156 Impl3DMirrorConstructOverlay::~Impl3DMirrorConstructOverlay() 157 { 158 // The OverlayObjects are cleared using the destructor of OverlayObjectList. 159 // That destructor calls clear() at the list which removes all objects from the 160 // OverlayManager and deletes them. 161 if(!mrView.IsSolidDragging()) 162 { 163 delete[] mpPolygons; 164 } 165 } 166 167 void Impl3DMirrorConstructOverlay::SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB) 168 { 169 // get rid of old overlay objects 170 maObjects.clear(); 171 172 // create new ones 173 for(sal_uInt32 a(0); a < mrView.PaintWindowCount(); a++) 174 { 175 SdrPaintWindow* pCandidate = mrView.GetPaintWindow(a); 176 ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager(); 177 178 if(pTargetOverlay) 179 { 180 // buld transfoprmation: translate and rotate so that given edge is 181 // on x axis, them mirror in y and translate back 182 const basegfx::B2DVector aEdge(aMirrorAxisB.X() - aMirrorAxisA.X(), aMirrorAxisB.Y() - aMirrorAxisA.Y()); 183 basegfx::B2DHomMatrix aMatrixTransform(basegfx::tools::createTranslateB2DHomMatrix( 184 -aMirrorAxisA.X(), -aMirrorAxisA.Y())); 185 aMatrixTransform.rotate(-atan2(aEdge.getY(), aEdge.getX())); 186 aMatrixTransform.scale(1.0, -1.0); 187 aMatrixTransform.rotate(atan2(aEdge.getY(), aEdge.getX())); 188 aMatrixTransform.translate(aMirrorAxisA.X(), aMirrorAxisA.Y()); 189 190 if(mrView.IsSolidDragging()) 191 { 192 if(maFullOverlay.hasElements()) 193 { 194 drawinglayer::primitive2d::Primitive2DSequence aContent(maFullOverlay); 195 196 if(!aMatrixTransform.isIdentity()) 197 { 198 // embed in transformation group 199 drawinglayer::primitive2d::Primitive2DReference aTransformPrimitive2D(new drawinglayer::primitive2d::TransformPrimitive2D(aMatrixTransform, aContent)); 200 aContent = drawinglayer::primitive2d::Primitive2DSequence(&aTransformPrimitive2D, 1); 201 } 202 203 // if we have full overlay from selected objects, embed with 50% transparence, the 204 // transformation is added to the OverlayPrimitive2DSequenceObject 205 drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aContent, 0.5)); 206 aContent = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparencePrimitive2D, 1); 207 208 sdr::overlay::OverlayPrimitive2DSequenceObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aContent); 209 210 pTargetOverlay->add(*pNew); 211 maObjects.append(*pNew); 212 } 213 } 214 else 215 { 216 for(sal_uInt32 b(0); b < mnCount; b++) 217 { 218 // apply to polygon 219 basegfx::B2DPolyPolygon aPolyPolygon(mpPolygons[b]); 220 aPolyPolygon.transform(aMatrixTransform); 221 222 ::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(aPolyPolygon); 223 pTargetOverlay->add(*pNew); 224 maObjects.append(*pNew); 225 } 226 } 227 } 228 } 229 } 230 231 /************************************************************************* 232 |* 233 |* Konstruktor 1 234 |* 235 \************************************************************************/ 236 237 E3dView::E3dView(SdrModel* pModel, OutputDevice* pOut) : 238 SdrView(pModel, pOut) 239 { 240 InitView (); 241 } 242 243 /************************************************************************* 244 |* 245 |* DrawMarkedObj ueberladen, da eventuell nur einzelne 3D-Objekte 246 |* gezeichnet werden sollen 247 |* 248 \************************************************************************/ 249 250 void E3dView::DrawMarkedObj(OutputDevice& rOut) const 251 { 252 // Existieren 3D-Objekte, deren Szenen nicht selektiert sind? 253 sal_Bool bSpecialHandling = sal_False; 254 E3dScene *pScene = NULL; 255 256 long nCnt = GetMarkedObjectCount(); 257 for(long nObjs = 0;nObjs < nCnt;nObjs++) 258 { 259 SdrObject *pObj = GetMarkedObjectByIndex(nObjs); 260 if(pObj && pObj->ISA(E3dCompoundObject)) 261 { 262 // zugehoerige Szene 263 pScene = ((E3dCompoundObject*)pObj)->GetScene(); 264 if(pScene && !IsObjMarked(pScene)) 265 bSpecialHandling = sal_True; 266 } 267 // Alle SelectionFlags zuruecksetzen 268 if(pObj && pObj->ISA(E3dObject)) 269 { 270 pScene = ((E3dObject*)pObj)->GetScene(); 271 if(pScene) 272 pScene->SetSelected(sal_False); 273 } 274 } 275 276 if(bSpecialHandling) 277 { 278 // SelectionFlag bei allen zu 3D Objekten gehoerigen 279 // Szenen und deren Objekten auf nicht selektiert setzen 280 long nObjs; 281 for(nObjs = 0;nObjs < nCnt;nObjs++) 282 { 283 SdrObject *pObj = GetMarkedObjectByIndex(nObjs); 284 if(pObj && pObj->ISA(E3dCompoundObject)) 285 { 286 // zugehoerige Szene 287 pScene = ((E3dCompoundObject*)pObj)->GetScene(); 288 if(pScene) 289 pScene->SetSelected(sal_False); 290 } 291 } 292 293 // bei allen direkt selektierten Objekten auf selektiert setzen 294 SdrMark* pM = NULL; 295 296 for(nObjs = 0;nObjs < nCnt;nObjs++) 297 { 298 SdrObject *pObj = GetMarkedObjectByIndex(nObjs); 299 if(pObj && pObj->ISA(E3dObject)) 300 { 301 // Objekt markieren 302 E3dObject* p3DObj = (E3dObject*)pObj; 303 p3DObj->SetSelected(sal_True); 304 pScene = p3DObj->GetScene(); 305 pM = GetSdrMarkByIndex(nObjs); 306 } 307 } 308 309 if(pScene) 310 { 311 // code from parent 312 SortMarkedObjects(); 313 314 pScene->SetDrawOnlySelected(sal_True); 315 pScene->SingleObjectPainter(rOut); // #110094#-17 316 pScene->SetDrawOnlySelected(sal_False); 317 } 318 319 // SelectionFlag zuruecksetzen 320 for(nObjs = 0;nObjs < nCnt;nObjs++) 321 { 322 SdrObject *pObj = GetMarkedObjectByIndex(nObjs); 323 if(pObj && pObj->ISA(E3dCompoundObject)) 324 { 325 // zugehoerige Szene 326 pScene = ((E3dCompoundObject*)pObj)->GetScene(); 327 if(pScene) 328 pScene->SetSelected(sal_False); 329 } 330 } 331 } 332 else 333 { 334 // call parent 335 SdrExchangeView::DrawMarkedObj(rOut); 336 } 337 } 338 339 /************************************************************************* 340 |* 341 |* Model holen ueberladen, da bei einzelnen 3D Objekten noch eine Szene 342 |* untergeschoben werden muss 343 |* 344 \************************************************************************/ 345 346 SdrModel* E3dView::GetMarkedObjModel() const 347 { 348 // Existieren 3D-Objekte, deren Szenen nicht selektiert sind? 349 bool bSpecialHandling(false); 350 const sal_uInt32 nCount(GetMarkedObjectCount()); 351 sal_uInt32 nObjs(0); 352 E3dScene *pScene = 0; 353 354 for(nObjs = 0; nObjs < nCount; nObjs++) 355 { 356 const SdrObject* pObj = GetMarkedObjectByIndex(nObjs); 357 358 if(!bSpecialHandling && pObj && pObj->ISA(E3dCompoundObject)) 359 { 360 // if the object is selected, but it's scene not, 361 // we need special handling 362 pScene = ((E3dCompoundObject*)pObj)->GetScene(); 363 364 if(pScene && !IsObjMarked(pScene)) 365 { 366 bSpecialHandling = true; 367 } 368 } 369 370 if(pObj && pObj->ISA(E3dObject)) 371 { 372 // reset all selection flags at 3D objects 373 pScene = ((E3dObject*)pObj)->GetScene(); 374 375 if(pScene) 376 { 377 pScene->SetSelected(false); 378 } 379 } 380 } 381 382 if(!bSpecialHandling) 383 { 384 // call parent 385 return SdrView::GetMarkedObjModel(); 386 } 387 388 SdrModel* pNewModel = 0; 389 Rectangle aSelectedSnapRect; 390 391 // set 3d selection flags at all directly selected objects 392 // and collect SnapRect of selected objects 393 for(nObjs = 0; nObjs < nCount; nObjs++) 394 { 395 SdrObject *pObj = GetMarkedObjectByIndex(nObjs); 396 397 if(pObj && pObj->ISA(E3dCompoundObject)) 398 { 399 // mark object, but not scenes 400 E3dCompoundObject* p3DObj = (E3dCompoundObject*)pObj; 401 p3DObj->SetSelected(true); 402 aSelectedSnapRect.Union(p3DObj->GetSnapRect()); 403 } 404 } 405 406 // create new mark list which contains all indirectly selected3d 407 // scenes as selected objects 408 SdrMarkList aOldML(GetMarkedObjectList()); 409 SdrMarkList aNewML; 410 SdrMarkList& rCurrentMarkList = ((E3dView*)this)->GetMarkedObjectListWriteAccess(); 411 rCurrentMarkList = aNewML; 412 413 for(nObjs = 0; nObjs < nCount; nObjs++) 414 { 415 SdrObject *pObj = aOldML.GetMark(nObjs)->GetMarkedSdrObj(); 416 417 if(pObj && pObj->ISA(E3dObject)) 418 { 419 pScene = ((E3dObject*)pObj)->GetScene(); 420 421 if(pScene && !IsObjMarked(pScene) && GetSdrPageView()) 422 { 423 ((E3dView*)this)->MarkObj(pScene, GetSdrPageView(), sal_False, sal_True); 424 } 425 } 426 } 427 428 // call parent. This will copy all scenes and the selection flags at the 3d objectss. So 429 // it will be possible to delete all non-selected 3d objects from the cloned 3d scenes 430 pNewModel = SdrView::GetMarkedObjModel(); 431 432 if(pNewModel) 433 { 434 for(sal_uInt16 nPg(0); nPg < pNewModel->GetPageCount(); nPg++) 435 { 436 const SdrPage* pSrcPg=pNewModel->GetPage(nPg); 437 const sal_uInt32 nObAnz(pSrcPg->GetObjCount()); 438 439 for(sal_uInt32 nOb(0); nOb < nObAnz; nOb++) 440 { 441 const SdrObject* pSrcOb=pSrcPg->GetObj(nOb); 442 443 if(pSrcOb->ISA(E3dScene)) 444 { 445 pScene = (E3dScene*)pSrcOb; 446 447 // delete all not intentionally cloned 3d objects 448 pScene->removeAllNonSelectedObjects(); 449 450 // reset select flags and set SnapRect of all selected objects 451 pScene->SetSelected(false); 452 pScene->SetSnapRect(aSelectedSnapRect); 453 } 454 } 455 } 456 } 457 458 // restore old selection 459 rCurrentMarkList = aOldML; 460 461 // model zurueckgeben 462 return pNewModel; 463 } 464 465 /************************************************************************* 466 |* 467 |* Bei Paste muss - falls in eine Scene eingefuegt wird - die 468 |* Objekte der Szene eingefuegt werden, die Szene selbst aber nicht 469 |* 470 \************************************************************************/ 471 472 sal_Bool E3dView::Paste(const SdrModel& rMod, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions) 473 { 474 sal_Bool bRetval = sal_False; 475 476 // Liste holen 477 Point aPos(rPos); 478 SdrObjList* pDstList = pLst; 479 ImpGetPasteObjList(aPos, pDstList); 480 481 if(!pDstList) 482 return sal_False; 483 484 // Owner der Liste holen 485 SdrObject* pOwner = pDstList->GetOwnerObj(); 486 if(pOwner && pOwner->ISA(E3dScene)) 487 { 488 E3dScene* pDstScene = (E3dScene*)pOwner; 489 BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_EXCHANGE_PASTE)); 490 491 // Alle Objekte aus E3dScenes kopieren und direkt einfuegen 492 for(sal_uInt16 nPg(0); nPg < rMod.GetPageCount(); nPg++) 493 { 494 const SdrPage* pSrcPg=rMod.GetPage(nPg); 495 sal_uInt32 nObAnz(pSrcPg->GetObjCount()); 496 497 // calculate offset for paste 498 Rectangle aR = pSrcPg->GetAllObjBoundRect(); 499 Point aDist(aPos - aR.Center()); 500 501 // Unterobjekte von Szenen einfuegen 502 for(sal_uInt32 nOb(0); nOb < nObAnz; nOb++) 503 { 504 const SdrObject* pSrcOb = pSrcPg->GetObj(nOb); 505 if(pSrcOb->ISA(E3dScene)) 506 { 507 E3dScene* pSrcScene = (E3dScene*)pSrcOb; 508 ImpCloneAll3DObjectsToDestScene(pSrcScene, pDstScene, aDist); 509 } 510 } 511 } 512 EndUndo(); 513 } 514 else 515 { 516 // call parent 517 bRetval = SdrView::Paste(rMod, rPos, pLst, nOptions); 518 } 519 520 // und Rueckgabewert liefern 521 return bRetval; 522 } 523 524 // #83403# Service routine used from local Clone() and from SdrCreateView::EndCreateObj(...) 525 sal_Bool E3dView::ImpCloneAll3DObjectsToDestScene(E3dScene* pSrcScene, E3dScene* pDstScene, Point /*aOffset*/) 526 { 527 sal_Bool bRetval(sal_False); 528 529 if(pSrcScene && pDstScene) 530 { 531 const sdr::contact::ViewContactOfE3dScene& rVCSceneDst = static_cast< sdr::contact::ViewContactOfE3dScene& >(pDstScene->GetViewContact()); 532 const drawinglayer::geometry::ViewInformation3D aViewInfo3DDst(rVCSceneDst.getViewInformation3D()); 533 const sdr::contact::ViewContactOfE3dScene& rVCSceneSrc = static_cast< sdr::contact::ViewContactOfE3dScene& >(pSrcScene->GetViewContact()); 534 const drawinglayer::geometry::ViewInformation3D aViewInfo3DSrc(rVCSceneSrc.getViewInformation3D()); 535 536 for(sal_uInt32 i(0); i < pSrcScene->GetSubList()->GetObjCount(); i++) 537 { 538 E3dCompoundObject* pCompoundObj = dynamic_cast< E3dCompoundObject* >(pSrcScene->GetSubList()->GetObj(i)); 539 540 if(pCompoundObj) 541 { 542 // #116235# 543 E3dCompoundObject* pNewCompoundObj = dynamic_cast< E3dCompoundObject* >(pCompoundObj->Clone()); 544 545 if(pNewCompoundObj) 546 { 547 // get dest scene's current range in 3D world coordinates 548 const basegfx::B3DHomMatrix aSceneToWorldTrans(pDstScene->GetFullTransform()); 549 basegfx::B3DRange aSceneRange(pDstScene->GetBoundVolume()); 550 aSceneRange.transform(aSceneToWorldTrans); 551 552 // get new object's implied object transformation 553 const basegfx::B3DHomMatrix aNewObjectTrans(pNewCompoundObj->GetTransform()); 554 555 // get new object's range in 3D world coordinates in dest scene 556 // as if it were already added 557 const basegfx::B3DHomMatrix aObjectToWorldTrans(aSceneToWorldTrans * aNewObjectTrans); 558 basegfx::B3DRange aObjectRange(pNewCompoundObj->GetBoundVolume()); 559 aObjectRange.transform(aObjectToWorldTrans); 560 561 // get scale adaption 562 const basegfx::B3DVector aSceneScale(aSceneRange.getRange()); 563 const basegfx::B3DVector aObjectScale(aObjectRange.getRange()); 564 double fScale(1.0); 565 566 // if new object's size in X,Y or Z is bigger that 80% of dest scene, adapt scale 567 // to not change the scene by the inserted object 568 const double fSizeFactor(0.5); 569 570 if(aObjectScale.getX() * fScale > aSceneScale.getX() * fSizeFactor) 571 { 572 const double fObjSize(aObjectScale.getX() * fScale); 573 const double fFactor((aSceneScale.getX() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize)); 574 fScale *= fFactor; 575 } 576 577 if(aObjectScale.getY() * fScale > aSceneScale.getY() * fSizeFactor) 578 { 579 const double fObjSize(aObjectScale.getY() * fScale); 580 const double fFactor((aSceneScale.getY() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize)); 581 fScale *= fFactor; 582 } 583 584 if(aObjectScale.getZ() * fScale > aSceneScale.getZ() * fSizeFactor) 585 { 586 const double fObjSize(aObjectScale.getZ() * fScale); 587 const double fFactor((aSceneScale.getZ() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize)); 588 fScale *= fFactor; 589 } 590 591 // get translation adaption 592 const basegfx::B3DPoint aSceneCenter(aSceneRange.getCenter()); 593 const basegfx::B3DPoint aObjectCenter(aObjectRange.getCenter()); 594 595 // build full modification transform. The object's transformation 596 // shall be modified, so start at object coordinates; transform to 3d world coor 597 basegfx::B3DHomMatrix aModifyingTransform(aObjectToWorldTrans); 598 599 // translate to absolute center in 3d world coor 600 aModifyingTransform.translate(-aObjectCenter.getX(), -aObjectCenter.getY(), -aObjectCenter.getZ()); 601 602 // scale to dest size in 3d world coor 603 aModifyingTransform.scale(fScale, fScale, fScale); 604 605 // translate to dest scene center in 3d world coor 606 aModifyingTransform.translate(aSceneCenter.getX(), aSceneCenter.getY(), aSceneCenter.getZ()); 607 608 // transform from 3d world to dest object coordinates 609 basegfx::B3DHomMatrix aWorldToObject(aObjectToWorldTrans); 610 aWorldToObject.invert(); 611 aModifyingTransform = aWorldToObject * aModifyingTransform; 612 613 // correct implied object transform by applying changing one in object coor 614 pNewCompoundObj->SetTransform(aModifyingTransform * aNewObjectTrans); 615 616 // fill and insert new object 617 pNewCompoundObj->SetModel(pDstScene->GetModel()); 618 pNewCompoundObj->SetPage(pDstScene->GetPage()); 619 pNewCompoundObj->NbcSetLayer(pCompoundObj->GetLayer()); 620 pNewCompoundObj->NbcSetStyleSheet(pCompoundObj->GetStyleSheet(), sal_True); 621 pDstScene->Insert3DObj(pNewCompoundObj); 622 bRetval = sal_True; 623 624 // Undo anlegen 625 if( GetModel()->IsUndoEnabled() ) 626 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNewCompoundObj)); 627 } 628 } 629 } 630 } 631 632 return bRetval; 633 } 634 635 /************************************************************************* 636 |* 637 |* 3D-Konvertierung moeglich? 638 |* 639 \************************************************************************/ 640 641 sal_Bool E3dView::IsConvertTo3DObjPossible() const 642 { 643 sal_Bool bAny3D(sal_False); 644 sal_Bool bGroupSelected(sal_False); 645 sal_Bool bRetval(sal_True); 646 647 for(sal_uInt32 a=0;!bAny3D && a<GetMarkedObjectCount();a++) 648 { 649 SdrObject *pObj = GetMarkedObjectByIndex(a); 650 if(pObj) 651 { 652 ImpIsConvertTo3DPossible(pObj, bAny3D, bGroupSelected); 653 } 654 } 655 656 bRetval = !bAny3D 657 && ( 658 IsConvertToPolyObjPossible(sal_False) 659 || IsConvertToPathObjPossible(sal_False) 660 || IsImportMtfPossible()); 661 return bRetval; 662 } 663 664 void E3dView::ImpIsConvertTo3DPossible(SdrObject* pObj, sal_Bool& rAny3D, 665 sal_Bool& rGroupSelected) const 666 { 667 if(pObj) 668 { 669 if(pObj->ISA(E3dObject)) 670 { 671 rAny3D = sal_True; 672 } 673 else 674 { 675 if(pObj->IsGroupObject()) 676 { 677 SdrObjListIter aIter(*pObj, IM_DEEPNOGROUPS); 678 while(aIter.IsMore()) 679 { 680 SdrObject* pNewObj = aIter.Next(); 681 ImpIsConvertTo3DPossible(pNewObj, rAny3D, rGroupSelected); 682 } 683 rGroupSelected = sal_True; 684 } 685 } 686 } 687 } 688 689 /************************************************************************* 690 |* 691 |* 3D-Konvertierung zu Extrude ausfuehren 692 |* 693 \************************************************************************/ 694 #include <editeng/eeitem.hxx> 695 696 void E3dView::ImpChangeSomeAttributesFor3DConversion(SdrObject* pObj) 697 { 698 if(pObj->ISA(SdrTextObj)) 699 { 700 const SfxItemSet& rSet = pObj->GetMergedItemSet(); 701 const SvxColorItem& rTextColorItem = (const SvxColorItem&)rSet.Get(EE_CHAR_COLOR); 702 if(rTextColorItem.GetValue() == RGB_Color(COL_BLACK)) 703 { 704 // Bei schwarzen Textobjekten wird die Farbe auf grau gesetzt 705 if(pObj->GetPage()) 706 { 707 // #84864# if black is only default attribute from 708 // pattern set it hard so that it is used in undo. 709 pObj->SetMergedItem(SvxColorItem(RGB_Color(COL_BLACK), EE_CHAR_COLOR)); 710 711 // add undo now 712 if( GetModel()->IsUndoEnabled() ) 713 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj, false, false)); 714 } 715 716 pObj->SetMergedItem(SvxColorItem(RGB_Color(COL_GRAY), EE_CHAR_COLOR)); 717 } 718 } 719 } 720 721 void E3dView::ImpChangeSomeAttributesFor3DConversion2(SdrObject* pObj) 722 { 723 if(pObj->ISA(SdrPathObj)) 724 { 725 const SfxItemSet& rSet = pObj->GetMergedItemSet(); 726 sal_Int32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue(); 727 XLineStyle eLineStyle = (XLineStyle)((const XLineStyleItem&)rSet.Get(XATTR_LINESTYLE)).GetValue(); 728 XFillStyle eFillStyle = ITEMVALUE(rSet, XATTR_FILLSTYLE, XFillStyleItem); 729 730 if(((SdrPathObj*)pObj)->IsClosed() 731 && eLineStyle == XLINE_SOLID 732 && !nLineWidth 733 && eFillStyle != XFILL_NONE) 734 { 735 if(pObj->GetPage() && GetModel()->IsUndoEnabled() ) 736 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj, false, false)); 737 pObj->SetMergedItem(XLineStyleItem(XLINE_NONE)); 738 pObj->SetMergedItem(XLineWidthItem(0L)); 739 } 740 } 741 } 742 743 void E3dView::ImpCreateSingle3DObjectFlat(E3dScene* pScene, SdrObject* pObj, sal_Bool bExtrude, double fDepth, basegfx::B2DHomMatrix& rLatheMat) 744 { 745 // Einzelnes PathObject, dieses umwanden 746 SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj); 747 748 if(pPath) 749 { 750 E3dDefaultAttributes aDefault = Get3DDefaultAttributes(); 751 if(bExtrude) 752 aDefault.SetDefaultExtrudeCharacterMode(sal_True); 753 else 754 aDefault.SetDefaultLatheCharacterMode(sal_True); 755 756 // ItemSet des Ursprungsobjektes holen 757 SfxItemSet aSet(pObj->GetMergedItemSet()); 758 759 XFillStyle eFillStyle = ITEMVALUE(aSet, XATTR_FILLSTYLE, XFillStyleItem); 760 761 // Linienstil ausschalten 762 aSet.Put(XLineStyleItem(XLINE_NONE)); 763 764 // Feststellen, ob ein FILL_Attribut gesetzt ist. 765 if(!pPath->IsClosed() || eFillStyle == XFILL_NONE) 766 { 767 // Das SdrPathObj ist nicht gefuellt, lasse die 768 // vordere und hintere Flaeche weg. Ausserdem ist 769 // eine beidseitige Darstellung notwendig. 770 aDefault.SetDefaultExtrudeCloseFront(sal_False); 771 aDefault.SetDefaultExtrudeCloseBack(sal_False); 772 773 aSet.Put(Svx3DDoubleSidedItem(sal_True)); 774 775 // Fuellattribut setzen 776 aSet.Put(XFillStyleItem(XFILL_SOLID)); 777 778 // Fuellfarbe muss auf Linienfarbe, da das Objekt vorher 779 // nur eine Linie war 780 Color aColorLine = ((const XLineColorItem&)(aSet.Get(XATTR_LINECOLOR))).GetColorValue(); 781 aSet.Put(XFillColorItem(String(), aColorLine)); 782 } 783 784 // Neues Extrude-Objekt erzeugen 785 E3dObject* p3DObj = NULL; 786 if(bExtrude) 787 { 788 p3DObj = new E3dExtrudeObj(aDefault, pPath->GetPathPoly(), fDepth); 789 } 790 else 791 { 792 basegfx::B2DPolyPolygon aPolyPoly2D(pPath->GetPathPoly()); 793 aPolyPoly2D.transform(rLatheMat); 794 p3DObj = new E3dLatheObj(aDefault, aPolyPoly2D); 795 } 796 797 // Attribute setzen 798 if(p3DObj) 799 { 800 p3DObj->NbcSetLayer(pObj->GetLayer()); 801 802 p3DObj->SetMergedItemSet(aSet); 803 804 p3DObj->NbcSetStyleSheet(pObj->GetStyleSheet(), sal_True); 805 806 // Neues 3D-Objekt einfuegen 807 pScene->Insert3DObj(p3DObj); 808 } 809 } 810 } 811 812 void E3dView::ImpCreate3DObject(E3dScene* pScene, SdrObject* pObj, sal_Bool bExtrude, double fDepth, basegfx::B2DHomMatrix& rLatheMat) 813 { 814 if(pObj) 815 { 816 // change text color attribute for not so dark colors 817 if(pObj->IsGroupObject()) 818 { 819 SdrObjListIter aIter(*pObj, IM_DEEPWITHGROUPS); 820 while(aIter.IsMore()) 821 { 822 SdrObject* pGroupMember = aIter.Next(); 823 ImpChangeSomeAttributesFor3DConversion(pGroupMember); 824 } 825 } 826 else 827 ImpChangeSomeAttributesFor3DConversion(pObj); 828 829 // convert completely to path objects 830 SdrObject* pNewObj1 = pObj->ConvertToPolyObj(sal_False, sal_False); 831 832 if(pNewObj1) 833 { 834 // change text color attribute for not so dark colors 835 if(pNewObj1->IsGroupObject()) 836 { 837 SdrObjListIter aIter(*pNewObj1, IM_DEEPWITHGROUPS); 838 while(aIter.IsMore()) 839 { 840 SdrObject* pGroupMember = aIter.Next(); 841 ImpChangeSomeAttributesFor3DConversion2(pGroupMember); 842 } 843 } 844 else 845 ImpChangeSomeAttributesFor3DConversion2(pNewObj1); 846 847 // convert completely to path objects 848 SdrObject* pNewObj2 = pObj->ConvertToContourObj(pNewObj1, sal_True); 849 850 if(pNewObj2) 851 { 852 // add all to flat scene 853 if(pNewObj2->IsGroupObject()) 854 { 855 SdrObjListIter aIter(*pNewObj2, IM_DEEPWITHGROUPS); 856 while(aIter.IsMore()) 857 { 858 SdrObject* pGroupMember = aIter.Next(); 859 ImpCreateSingle3DObjectFlat(pScene, pGroupMember, bExtrude, fDepth, rLatheMat); 860 } 861 } 862 else 863 ImpCreateSingle3DObjectFlat(pScene, pNewObj2, bExtrude, fDepth, rLatheMat); 864 865 // delete zwi object 866 if(pNewObj2 != pObj && pNewObj2 != pNewObj1 && pNewObj2) 867 SdrObject::Free( pNewObj2 ); 868 } 869 870 // delete zwi object 871 if(pNewObj1 != pObj && pNewObj1) 872 SdrObject::Free( pNewObj1 ); 873 } 874 } 875 } 876 877 /************************************************************************* 878 |* 879 |* 3D-Konvertierung zu Extrude steuern 880 |* 881 \************************************************************************/ 882 883 void E3dView::ConvertMarkedObjTo3D(sal_Bool bExtrude, basegfx::B2DPoint aPnt1, basegfx::B2DPoint aPnt2) 884 { 885 if(AreObjectsMarked()) 886 { 887 // Undo anlegen 888 if(bExtrude) 889 BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_EXTRUDE)); 890 else 891 BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_LATHE)); 892 893 // Neue Szene fuer zu erzeugende 3D-Objekte anlegen 894 E3dScene* pScene = new E3dPolyScene(Get3DDefaultAttributes()); 895 896 // Rechteck bestimmen und evtl. korrigieren 897 Rectangle aRect = GetAllMarkedRect(); 898 if(aRect.GetWidth() <= 1) 899 aRect.SetSize(Size(500, aRect.GetHeight())); 900 if(aRect.GetHeight() <= 1) 901 aRect.SetSize(Size(aRect.GetWidth(), 500)); 902 903 // Tiefe relativ zur Groesse der Selektion bestimmen 904 double fDepth = 0.0; 905 double fRot3D = 0.0; 906 basegfx::B2DHomMatrix aLatheMat; 907 908 if(bExtrude) 909 { 910 double fW = (double)aRect.GetWidth(); 911 double fH = (double)aRect.GetHeight(); 912 fDepth = sqrt(fW*fW + fH*fH) / 6.0; 913 } 914 if(!bExtrude) 915 { 916 // Transformation fuer Polygone Rotationskoerper erstellen 917 if(aPnt1 != aPnt2) 918 { 919 // Rotation um Kontrollpunkt1 mit eigestelltem Winkel 920 // fuer 3D Koordinaten 921 basegfx::B2DPoint aDiff(aPnt1 - aPnt2); 922 fRot3D = atan2(aDiff.getY(), aDiff.getX()) - F_PI2; 923 924 if(basegfx::fTools::equalZero(fabs(fRot3D))) 925 fRot3D = 0.0; 926 927 if(fRot3D != 0.0) 928 { 929 aLatheMat = basegfx::tools::createRotateAroundPoint(aPnt2, -fRot3D) 930 * aLatheMat; 931 } 932 } 933 934 if(aPnt2.getX() != 0.0) 935 { 936 // Translation auf Y=0 - Achse 937 aLatheMat.translate(-aPnt2.getX(), 0.0); 938 } 939 else 940 { 941 aLatheMat.translate((double)-aRect.Left(), 0.0); 942 } 943 944 // Inverse Matrix bilden, um die Zielausdehnung zu bestimmen 945 basegfx::B2DHomMatrix aInvLatheMat(aLatheMat); 946 aInvLatheMat.invert(); 947 948 // SnapRect Ausdehnung mittels Spiegelung an der Rotationsachse 949 // erweitern 950 for(sal_uInt32 a=0;a<GetMarkedObjectCount();a++) 951 { 952 SdrMark* pMark = GetSdrMarkByIndex(a); 953 SdrObject* pObj = pMark->GetMarkedSdrObj(); 954 Rectangle aTurnRect = pObj->GetSnapRect(); 955 basegfx::B2DPoint aRot; 956 Point aRotPnt; 957 958 aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Top()); 959 aRot *= aLatheMat; 960 aRot.setX(-aRot.getX()); 961 aRot *= aInvLatheMat; 962 aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5)); 963 aRect.Union(Rectangle(aRotPnt, aRotPnt)); 964 965 aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Bottom()); 966 aRot *= aLatheMat; 967 aRot.setX(-aRot.getX()); 968 aRot *= aInvLatheMat; 969 aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5)); 970 aRect.Union(Rectangle(aRotPnt, aRotPnt)); 971 972 aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Top()); 973 aRot *= aLatheMat; 974 aRot.setX(-aRot.getX()); 975 aRot *= aInvLatheMat; 976 aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5)); 977 aRect.Union(Rectangle(aRotPnt, aRotPnt)); 978 979 aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Bottom()); 980 aRot *= aLatheMat; 981 aRot.setX(-aRot.getX()); 982 aRot *= aInvLatheMat; 983 aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5)); 984 aRect.Union(Rectangle(aRotPnt, aRotPnt)); 985 } 986 } 987 988 // Ueber die Selektion gehen und in 3D wandeln, komplett mit 989 // Umwandeln in SdrPathObject, auch Schriften 990 for(sal_uInt32 a=0;a<GetMarkedObjectCount();a++) 991 { 992 SdrMark* pMark = GetSdrMarkByIndex(a); 993 SdrObject* pObj = pMark->GetMarkedSdrObj(); 994 995 ImpCreate3DObject(pScene, pObj, bExtrude, fDepth, aLatheMat); 996 } 997 998 if(pScene->GetSubList() && pScene->GetSubList()->GetObjCount() != 0) 999 { 1000 // Alle angelegten Objekte Tiefenarrangieren 1001 if(bExtrude) 1002 DoDepthArrange(pScene, fDepth); 1003 1004 // 3D-Objekte auf die Mitte des Gesamtrechtecks zentrieren 1005 basegfx::B3DPoint aCenter(pScene->GetBoundVolume().getCenter()); 1006 basegfx::B3DHomMatrix aMatrix; 1007 1008 aMatrix.translate(-aCenter.getX(), -aCenter.getY(), -aCenter.getZ()); 1009 pScene->SetTransform(aMatrix * pScene->GetTransform()); // #112587# 1010 1011 // Szene initialisieren 1012 pScene->NbcSetSnapRect(aRect); 1013 basegfx::B3DRange aBoundVol = pScene->GetBoundVolume(); 1014 InitScene(pScene, (double)aRect.GetWidth(), (double)aRect.GetHeight(), aBoundVol.getDepth()); 1015 1016 // Szene anstelle des ersten selektierten Objektes einfuegen 1017 // und alle alten Objekte weghauen 1018 SdrObject* pRepObj = GetMarkedObjectByIndex(0); 1019 SdrPageView* pPV = GetSdrPageViewOfMarkedByIndex(0); 1020 MarkObj(pRepObj, pPV, sal_True); 1021 ReplaceObjectAtView(pRepObj, *pPV, pScene, sal_False); 1022 DeleteMarked(); 1023 MarkObj(pScene, pPV); 1024 1025 // Rotationskoerper um Rotationsachse drehen 1026 basegfx::B3DHomMatrix aRotate; 1027 1028 if(!bExtrude && fRot3D != 0.0) 1029 { 1030 aRotate.rotate(0.0, 0.0, fRot3D); 1031 } 1032 1033 // Default-Rotation setzen 1034 { 1035 double XRotateDefault = 20; 1036 aRotate.rotate(DEG2RAD(XRotateDefault), 0.0, 0.0); 1037 } 1038 1039 if(!aRotate.isIdentity()) 1040 { 1041 pScene->SetTransform(aRotate * pScene->GetTransform()); 1042 } 1043 1044 // SnapRects der Objekte ungueltig 1045 pScene->SetSnapRect(aRect); 1046 } 1047 else 1048 { 1049 // Es wurden keine 3D Objekte erzeugt, schmeiss alles weg 1050 delete pScene; 1051 } 1052 1053 // Undo abschliessen 1054 EndUndo(); 1055 } 1056 } 1057 1058 /************************************************************************* 1059 |* 1060 |* Alle enthaltenen Extrude-Objekte Tiefenarrangieren 1061 |* 1062 \************************************************************************/ 1063 1064 struct E3dDepthNeighbour 1065 { 1066 E3dDepthNeighbour* mpNext; 1067 E3dExtrudeObj* mpObj; 1068 basegfx::B2DPolyPolygon maPreparedPolyPolygon; 1069 1070 E3dDepthNeighbour() 1071 : mpNext(0), 1072 mpObj(0), 1073 maPreparedPolyPolygon() 1074 { 1075 } 1076 }; 1077 1078 struct E3dDepthLayer 1079 { 1080 E3dDepthLayer* mpDown; 1081 E3dDepthNeighbour* mpNext; 1082 1083 E3dDepthLayer() 1084 : mpDown(0), 1085 mpNext(0) 1086 { 1087 } 1088 1089 ~E3dDepthLayer() 1090 { 1091 while(mpNext) 1092 { 1093 E3dDepthNeighbour* pSucc = mpNext->mpNext; 1094 delete mpNext; 1095 mpNext = pSucc; 1096 } 1097 } 1098 }; 1099 1100 void E3dView::DoDepthArrange(E3dScene* pScene, double fDepth) 1101 { 1102 if(pScene && pScene->GetSubList() && pScene->GetSubList()->GetObjCount() > 1) 1103 { 1104 SdrObjList* pSubList = pScene->GetSubList(); 1105 SdrObjListIter aIter(*pSubList, IM_FLAT); 1106 E3dDepthLayer* pBaseLayer = NULL; 1107 E3dDepthLayer* pLayer = NULL; 1108 sal_Int32 nNumLayers = 0; 1109 1110 while(aIter.IsMore()) 1111 { 1112 E3dExtrudeObj* pExtrudeObj = dynamic_cast< E3dExtrudeObj* >(aIter.Next()); 1113 1114 if(pExtrudeObj) 1115 { 1116 const basegfx::B2DPolyPolygon aExtrudePoly( 1117 basegfx::tools::prepareForPolygonOperation(pExtrudeObj->GetExtrudePolygon())); 1118 const SfxItemSet& rLocalSet = pExtrudeObj->GetMergedItemSet(); 1119 const XFillStyle eLocalFillStyle = ITEMVALUE(rLocalSet, XATTR_FILLSTYLE, XFillStyleItem); 1120 const Color aLocalColor = ((const XFillColorItem&)(rLocalSet.Get(XATTR_FILLCOLOR))).GetColorValue(); 1121 1122 // sort in ExtrudeObj 1123 if(pLayer) 1124 { 1125 // do we have overlap with an object of this layer? 1126 bool bOverlap(false); 1127 E3dDepthNeighbour* pAct = pLayer->mpNext; 1128 1129 while(!bOverlap && pAct) 1130 { 1131 // do pAct->mpObj and pExtrudeObj overlap? Check by 1132 // using logical AND clipping 1133 const basegfx::B2DPolyPolygon aAndPolyPolygon( 1134 basegfx::tools::solvePolygonOperationAnd( 1135 aExtrudePoly, 1136 pAct->maPreparedPolyPolygon)); 1137 1138 bOverlap = (0 != aAndPolyPolygon.count()); 1139 1140 if(bOverlap) 1141 { 1142 // second ciriteria: is another fillstyle or color used? 1143 const SfxItemSet& rCompareSet = pAct->mpObj->GetMergedItemSet(); 1144 1145 XFillStyle eCompareFillStyle = ITEMVALUE(rCompareSet, XATTR_FILLSTYLE, XFillStyleItem); 1146 1147 if(eLocalFillStyle == eCompareFillStyle) 1148 { 1149 if(eLocalFillStyle == XFILL_SOLID) 1150 { 1151 Color aCompareColor = ((const XFillColorItem&)(rCompareSet.Get(XATTR_FILLCOLOR))).GetColorValue(); 1152 1153 if(aCompareColor == aLocalColor) 1154 { 1155 bOverlap = sal_False; 1156 } 1157 } 1158 else if(eLocalFillStyle == XFILL_NONE) 1159 { 1160 bOverlap = sal_False; 1161 } 1162 } 1163 } 1164 1165 pAct = pAct->mpNext; 1166 } 1167 1168 if(bOverlap) 1169 { 1170 // yes, start a new layer 1171 pLayer->mpDown = new E3dDepthLayer; 1172 pLayer = pLayer->mpDown; 1173 nNumLayers++; 1174 pLayer->mpNext = new E3dDepthNeighbour; 1175 pLayer->mpNext->mpObj = pExtrudeObj; 1176 pLayer->mpNext->maPreparedPolyPolygon = aExtrudePoly; 1177 } 1178 else 1179 { 1180 // no, add to current layer 1181 E3dDepthNeighbour* pNewNext = new E3dDepthNeighbour; 1182 pNewNext->mpObj = pExtrudeObj; 1183 pNewNext->maPreparedPolyPolygon = aExtrudePoly; 1184 pNewNext->mpNext = pLayer->mpNext; 1185 pLayer->mpNext = pNewNext; 1186 } 1187 } 1188 else 1189 { 1190 // first layer ever 1191 pBaseLayer = new E3dDepthLayer; 1192 pLayer = pBaseLayer; 1193 nNumLayers++; 1194 pLayer->mpNext = new E3dDepthNeighbour; 1195 pLayer->mpNext->mpObj = pExtrudeObj; 1196 pLayer->mpNext->maPreparedPolyPolygon = aExtrudePoly; 1197 } 1198 } 1199 } 1200 1201 // number of layers is done 1202 if(nNumLayers > 1) 1203 { 1204 // need to be arranged 1205 double fMinDepth = fDepth * 0.8; 1206 double fStep = (fDepth - fMinDepth) / (double)nNumLayers; 1207 pLayer = pBaseLayer; 1208 1209 while(pLayer) 1210 { 1211 // move along layer 1212 E3dDepthNeighbour* pAct = pLayer->mpNext; 1213 1214 while(pAct) 1215 { 1216 // adapt extrude value 1217 pAct->mpObj->SetMergedItem(SfxUInt32Item(SDRATTR_3DOBJ_DEPTH, sal_uInt32(fMinDepth + 0.5))); 1218 1219 // next 1220 pAct = pAct->mpNext; 1221 } 1222 1223 // next layer 1224 pLayer = pLayer->mpDown; 1225 fMinDepth += fStep; 1226 } 1227 } 1228 1229 // cleanup 1230 while(pBaseLayer) 1231 { 1232 pLayer = pBaseLayer->mpDown; 1233 delete pBaseLayer; 1234 pBaseLayer = pLayer; 1235 } 1236 } 1237 } 1238 1239 /************************************************************************* 1240 |* 1241 |* Drag beginnen, vorher ggf. Drag-Methode fuer 3D-Objekte erzeugen 1242 |* 1243 \************************************************************************/ 1244 1245 sal_Bool E3dView::BegDragObj(const Point& rPnt, OutputDevice* pOut, 1246 SdrHdl* pHdl, short nMinMov, 1247 SdrDragMethod* pForcedMeth) 1248 { 1249 if(Is3DRotationCreationActive() && GetMarkedObjectCount()) 1250 { 1251 // bestimme alle selektierten Polygone und gebe die gespiegelte Hilfsfigur aus 1252 mpMirrorOverlay->SetMirrorAxis(aRef1, aRef2); 1253 } 1254 else 1255 { 1256 sal_Bool bOwnActionNecessary; 1257 if (pHdl == NULL) 1258 { 1259 bOwnActionNecessary = sal_True; 1260 } 1261 else if (pHdl->IsVertexHdl() || pHdl->IsCornerHdl()) 1262 { 1263 bOwnActionNecessary = sal_True; 1264 } 1265 else 1266 { 1267 bOwnActionNecessary = sal_False; 1268 } 1269 1270 if(bOwnActionNecessary && GetMarkedObjectCount() >= 1) 1271 { 1272 E3dDragConstraint eConstraint = E3DDRAG_CONSTR_XYZ; 1273 sal_Bool bThereAreRootScenes = sal_False; 1274 sal_Bool bThereAre3DObjects = sal_False; 1275 long nCnt = GetMarkedObjectCount(); 1276 for(long nObjs = 0;nObjs < nCnt;nObjs++) 1277 { 1278 SdrObject *pObj = GetMarkedObjectByIndex(nObjs); 1279 if(pObj) 1280 { 1281 if(pObj->ISA(E3dScene) && ((E3dScene*)pObj)->GetScene() == pObj) 1282 bThereAreRootScenes = sal_True; 1283 if(pObj->ISA(E3dObject)) 1284 bThereAre3DObjects = sal_True; 1285 } 1286 } 1287 if( bThereAre3DObjects ) 1288 { 1289 eDragHdl = ( pHdl == NULL ? HDL_MOVE : pHdl->GetKind() ); 1290 switch ( eDragMode ) 1291 { 1292 case SDRDRAG_ROTATE: 1293 case SDRDRAG_SHEAR: 1294 { 1295 switch ( eDragHdl ) 1296 { 1297 case HDL_LEFT: 1298 case HDL_RIGHT: 1299 { 1300 eConstraint = E3DDRAG_CONSTR_X; 1301 } 1302 break; 1303 1304 case HDL_UPPER: 1305 case HDL_LOWER: 1306 { 1307 eConstraint = E3DDRAG_CONSTR_Y; 1308 } 1309 break; 1310 1311 case HDL_UPLFT: 1312 case HDL_UPRGT: 1313 case HDL_LWLFT: 1314 case HDL_LWRGT: 1315 { 1316 eConstraint = E3DDRAG_CONSTR_Z; 1317 } 1318 break; 1319 default: break; 1320 } 1321 1322 // die nicht erlaubten Rotationen ausmaskieren 1323 eConstraint = E3dDragConstraint(eConstraint& eDragConstraint); 1324 pForcedMeth = new E3dDragRotate(*this, GetMarkedObjectList(), eConstraint, IsSolidDragging()); 1325 } 1326 break; 1327 1328 case SDRDRAG_MOVE: 1329 { 1330 if(!bThereAreRootScenes) 1331 { 1332 pForcedMeth = new E3dDragMove(*this, GetMarkedObjectList(), eDragHdl, eConstraint, IsSolidDragging()); 1333 } 1334 } 1335 break; 1336 1337 // spaeter mal 1338 case SDRDRAG_MIRROR: 1339 case SDRDRAG_CROOK: 1340 case SDRDRAG_DISTORT: 1341 case SDRDRAG_TRANSPARENCE: 1342 case SDRDRAG_GRADIENT: 1343 default: 1344 { 1345 } 1346 break; 1347 } 1348 } 1349 } 1350 } 1351 return SdrView::BegDragObj(rPnt, pOut, pHdl, nMinMov, pForcedMeth); 1352 } 1353 1354 /************************************************************************* 1355 |* 1356 |* Pruefen, obj 3D-Szene markiert ist 1357 |* 1358 \************************************************************************/ 1359 1360 sal_Bool E3dView::HasMarkedScene() 1361 { 1362 return (GetMarkedScene() != NULL); 1363 } 1364 1365 /************************************************************************* 1366 |* 1367 |* Pruefen, obj 3D-Szene markiert ist 1368 |* 1369 \************************************************************************/ 1370 1371 E3dScene* E3dView::GetMarkedScene() 1372 { 1373 sal_uIntPtr nCnt = GetMarkedObjectCount(); 1374 1375 for ( sal_uIntPtr i = 0; i < nCnt; i++ ) 1376 if ( GetMarkedObjectByIndex(i)->ISA(E3dScene) ) 1377 return (E3dScene*) GetMarkedObjectByIndex(i); 1378 1379 return NULL; 1380 } 1381 1382 /************************************************************************* 1383 |* 1384 |* aktuelles 3D-Zeichenobjekt setzen, dafuer Szene erzeugen 1385 |* 1386 \************************************************************************/ 1387 1388 E3dScene* E3dView::SetCurrent3DObj(E3dObject* p3DObj) 1389 { 1390 DBG_ASSERT(p3DObj != NULL, "Nana, wer steckt denn hier 'nen NULL-Zeiger rein?"); 1391 E3dScene* pScene = NULL; 1392 1393 // get transformed BoundVolume of the object 1394 basegfx::B3DRange aVolume(p3DObj->GetBoundVolume()); 1395 aVolume.transform(p3DObj->GetTransform()); 1396 double fW(aVolume.getWidth()); 1397 double fH(aVolume.getHeight()); 1398 1399 Rectangle aRect(0,0, (long) fW, (long) fH); 1400 1401 pScene = new E3dPolyScene(Get3DDefaultAttributes()); 1402 1403 InitScene(pScene, fW, fH, aVolume.getMaxZ() + ((fW + fH) / 4.0)); 1404 1405 pScene->Insert3DObj(p3DObj); 1406 pScene->NbcSetSnapRect(aRect); 1407 1408 return pScene; 1409 } 1410 1411 /************************************************************************* 1412 |* 1413 |* neu erzeugte Szene initialisieren 1414 |* 1415 \************************************************************************/ 1416 1417 void E3dView::InitScene(E3dScene* pScene, double fW, double fH, double fCamZ) 1418 { 1419 Camera3D aCam(pScene->GetCamera()); 1420 1421 aCam.SetAutoAdjustProjection(sal_False); 1422 aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH); 1423 basegfx::B3DPoint aLookAt; 1424 1425 double fDefaultCamPosZ = GetDefaultCamPosZ(); 1426 basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ); 1427 1428 aCam.SetPosAndLookAt(aCamPos, aLookAt); 1429 aCam.SetFocalLength(GetDefaultCamFocal()); 1430 aCam.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, GetDefaultCamFocal()); 1431 pScene->SetCamera(aCam); 1432 } 1433 1434 /************************************************************************* 1435 |* 1436 |* startsequenz fuer die erstellung eines 3D-Rotationskoerpers 1437 |* 1438 \************************************************************************/ 1439 1440 void E3dView::Start3DCreation() 1441 { 1442 if (GetMarkedObjectCount()) 1443 { 1444 // irgendwelche Markierungen ermitteln und ausschalten 1445 //HMHBOOL bVis = IsMarkHdlShown(); 1446 1447 //HMHif (bVis) HideMarkHdl(); 1448 1449 // bestimme die koordinaten fuer JOEs Mirrorachse 1450 // entgegen der normalen Achse wird diese an die linke Seite des Objektes 1451 // positioniert 1452 long nOutMin = 0; 1453 long nOutMax = 0; 1454 long nMinLen = 0; 1455 long nObjDst = 0; 1456 long nOutHgt = 0; 1457 OutputDevice* pOut = GetFirstOutputDevice(); //GetWin(0); 1458 1459 // erstmal Darstellungsgrenzen bestimmen 1460 if (pOut != NULL) 1461 { 1462 nMinLen = pOut->PixelToLogic(Size(0,50)).Height(); 1463 nObjDst = pOut->PixelToLogic(Size(0,20)).Height(); 1464 1465 long nDst = pOut->PixelToLogic(Size(0,10)).Height(); 1466 1467 nOutMin = -pOut->GetMapMode().GetOrigin().Y(); 1468 nOutMax = pOut->GetOutputSize().Height() - 1 + nOutMin; 1469 nOutMin += nDst; 1470 nOutMax -= nDst; 1471 1472 if (nOutMax - nOutMin < nDst) 1473 { 1474 nOutMin += nOutMax + 1; 1475 nOutMin /= 2; 1476 nOutMin -= (nDst + 1) / 2; 1477 nOutMax = nOutMin + nDst; 1478 } 1479 1480 nOutHgt = nOutMax - nOutMin; 1481 1482 long nTemp = nOutHgt / 4; 1483 if (nTemp > nMinLen) nMinLen = nTemp; 1484 } 1485 1486 // und dann die Markierungen oben und unten an das Objekt heften 1487 basegfx::B2DRange aR; 1488 for(sal_uInt32 nMark(0L); nMark < GetMarkedObjectCount(); nMark++) 1489 { 1490 SdrObject* pMark = GetMarkedObjectByIndex(nMark); 1491 basegfx::B2DPolyPolygon aXPP(pMark->TakeXorPoly()); 1492 aR.expand(basegfx::tools::getRange(aXPP)); 1493 } 1494 1495 basegfx::B2DPoint aCenter(aR.getCenter()); 1496 long nMarkHgt = basegfx::fround(aR.getHeight()) - 1; 1497 long nHgt = nMarkHgt + nObjDst * 2; 1498 1499 if (nHgt < nMinLen) nHgt = nMinLen; 1500 1501 long nY1 = basegfx::fround(aCenter.getY()) - (nHgt + 1) / 2; 1502 long nY2 = nY1 + nHgt; 1503 1504 if (pOut && (nMinLen > nOutHgt)) nMinLen = nOutHgt; 1505 if (pOut) 1506 { 1507 if (nY1 < nOutMin) 1508 { 1509 nY1 = nOutMin; 1510 if (nY2 < nY1 + nMinLen) nY2 = nY1 + nMinLen; 1511 } 1512 if (nY2 > nOutMax) 1513 { 1514 nY2 = nOutMax; 1515 if (nY1 > nY2 - nMinLen) nY1 = nY2 - nMinLen; 1516 } 1517 } 1518 1519 aRef1.X() = basegfx::fround(aR.getMinX()); // Initial Achse um 2/100mm nach links 1520 aRef1.Y() = nY1; 1521 aRef2.X() = aRef1.X(); 1522 aRef2.Y() = nY2; 1523 1524 // Markierungen einschalten 1525 SetMarkHandles(); 1526 1527 //HMHif (bVis) ShowMarkHdl(); 1528 if (AreObjectsMarked()) MarkListHasChanged(); 1529 1530 // SpiegelPolygone SOFORT zeigen 1531 const SdrHdlList &aHdlList = GetHdlList(); 1532 mpMirrorOverlay = new Impl3DMirrorConstructOverlay(*this); 1533 mpMirrorOverlay->SetMirrorAxis(aHdlList.GetHdl(HDL_REF1)->GetPos(), aHdlList.GetHdl(HDL_REF2)->GetPos()); 1534 //CreateMirrorPolygons (); 1535 //ShowMirrorPolygons (aHdlList.GetHdl (HDL_REF1)->GetPos (), 1536 // aHdlList.GetHdl (HDL_REF2)->GetPos ()); 1537 } 1538 } 1539 1540 /************************************************************************* 1541 |* 1542 |* was passiert bei einer Mausbewegung, wenn das Objekt erstellt wird ? 1543 |* 1544 \************************************************************************/ 1545 1546 void E3dView::MovAction(const Point& rPnt) 1547 { 1548 if(Is3DRotationCreationActive()) 1549 { 1550 SdrHdl* pHdl = GetDragHdl(); 1551 1552 if (pHdl) 1553 { 1554 SdrHdlKind eHdlKind = pHdl->GetKind(); 1555 1556 // reagiere nur bei einer spiegelachse 1557 if ((eHdlKind == HDL_REF1) || 1558 (eHdlKind == HDL_REF2) || 1559 (eHdlKind == HDL_MIRX)) 1560 { 1561 const SdrHdlList &aHdlList = GetHdlList (); 1562 1563 // loesche das gespiegelte Polygon, spiegele das Original und zeichne es neu 1564 //ShowMirrored (); 1565 SdrView::MovAction (rPnt); 1566 mpMirrorOverlay->SetMirrorAxis( 1567 aHdlList.GetHdl (HDL_REF1)->GetPos(), 1568 aHdlList.GetHdl (HDL_REF2)->GetPos()); 1569 } 1570 } 1571 else 1572 { 1573 SdrView::MovAction (rPnt); 1574 } 1575 } 1576 else 1577 { 1578 SdrView::MovAction (rPnt); 1579 } 1580 } 1581 1582 /************************************************************************* 1583 |* 1584 |* Schluss. Objekt und evtl. Unterobjekte ueber ImpCreate3DLathe erstellen 1585 |* [FG] Mit dem Parameterwert sal_True (SDefault: sal_False) wird einfach ein 1586 |* Rotationskoerper erzeugt, ohne den Benutzer die Lage der 1587 |* Achse fetlegen zu lassen. Es reicht dieser Aufruf, falls 1588 |* ein Objekt selektiert ist. (keine Initialisierung noetig) 1589 |* 1590 \************************************************************************/ 1591 1592 void E3dView::End3DCreation(sal_Bool bUseDefaultValuesForMirrorAxes) 1593 { 1594 ResetCreationActive(); 1595 1596 if(AreObjectsMarked()) 1597 { 1598 if(bUseDefaultValuesForMirrorAxes) 1599 { 1600 Rectangle aRect = GetAllMarkedRect(); 1601 if(aRect.GetWidth() <= 1) 1602 aRect.SetSize(Size(500, aRect.GetHeight())); 1603 if(aRect.GetHeight() <= 1) 1604 aRect.SetSize(Size(aRect.GetWidth(), 500)); 1605 1606 basegfx::B2DPoint aPnt1(aRect.Left(), -aRect.Top()); 1607 basegfx::B2DPoint aPnt2(aRect.Left(), -aRect.Bottom()); 1608 1609 ConvertMarkedObjTo3D(sal_False, aPnt1, aPnt2); 1610 } 1611 else 1612 { 1613 // Hilfsfigur ausschalten 1614 // bestimme aus den Handlepositionen und den Versatz der Punkte 1615 const SdrHdlList &aHdlList = GetHdlList(); 1616 Point aMirrorRef1 = aHdlList.GetHdl(HDL_REF1)->GetPos(); 1617 Point aMirrorRef2 = aHdlList.GetHdl(HDL_REF2)->GetPos(); 1618 1619 basegfx::B2DPoint aPnt1(aMirrorRef1.X(), -aMirrorRef1.Y()); 1620 basegfx::B2DPoint aPnt2(aMirrorRef2.X(), -aMirrorRef2.Y()); 1621 1622 ConvertMarkedObjTo3D(sal_False, aPnt1, aPnt2); 1623 } 1624 } 1625 } 1626 1627 /************************************************************************* 1628 |* 1629 |* Destruktor 1630 |* 1631 \************************************************************************/ 1632 1633 E3dView::~E3dView () 1634 { 1635 } 1636 1637 /************************************************************************* 1638 |* 1639 |* beende das erzeugen und loesche die polygone 1640 |* 1641 \************************************************************************/ 1642 1643 void E3dView::ResetCreationActive () 1644 { 1645 if(mpMirrorOverlay) 1646 { 1647 delete mpMirrorOverlay; 1648 mpMirrorOverlay = 0L; 1649 } 1650 } 1651 1652 /************************************************************************* 1653 |* 1654 |* Klasse initialisieren 1655 |* 1656 \************************************************************************/ 1657 1658 void E3dView::InitView () 1659 { 1660 eDragConstraint = E3DDRAG_CONSTR_XYZ; 1661 fDefaultScaleX = 1662 fDefaultScaleY = 1663 fDefaultScaleZ = 1.0; 1664 fDefaultRotateX = 1665 fDefaultRotateY = 1666 fDefaultRotateZ = 0.0; 1667 fDefaultExtrusionDeepth = 1000; // old: 2000; 1668 fDefaultLightIntensity = 0.8; // old: 0.6; 1669 fDefaultAmbientIntensity = 0.4; 1670 nHDefaultSegments = 12; 1671 nVDefaultSegments = 12; 1672 aDefaultLightColor = RGB_Color(COL_WHITE); 1673 aDefaultAmbientColor = RGB_Color(COL_BLACK); 1674 bDoubleSided = sal_False; 1675 mpMirrorOverlay = 0L; 1676 } 1677 1678 /************************************************************************* 1679 |* 1680 |* Koennen die selektierten Objekte aufgebrochen werden? 1681 |* 1682 \************************************************************************/ 1683 1684 sal_Bool E3dView::IsBreak3DObjPossible() const 1685 { 1686 sal_uIntPtr nCount = GetMarkedObjectCount(); 1687 1688 if (nCount > 0) 1689 { 1690 sal_uIntPtr i = 0; 1691 1692 while (i < nCount) 1693 { 1694 SdrObject* pObj = GetMarkedObjectByIndex(i); 1695 1696 if (pObj && pObj->ISA(E3dObject)) 1697 { 1698 if(!(((E3dObject*)pObj)->IsBreakObjPossible())) 1699 return sal_False; 1700 } 1701 else 1702 { 1703 return sal_False; 1704 } 1705 1706 i++; 1707 } 1708 } 1709 else 1710 { 1711 return sal_False; 1712 } 1713 1714 return sal_True; 1715 } 1716 1717 /************************************************************************* 1718 |* 1719 |* Selektierte Lathe-Objekte aufbrechen 1720 |* 1721 \************************************************************************/ 1722 1723 void E3dView::Break3DObj() 1724 { 1725 if(IsBreak3DObjPossible()) 1726 { 1727 // ALLE selektierten Objekte werden gewandelt 1728 sal_uInt32 nCount = GetMarkedObjectCount(); 1729 1730 BegUndo(String(SVX_RESSTR(RID_SVX_3D_UNDO_BREAK_LATHE))); 1731 for(sal_uInt32 a=0;a<nCount;a++) 1732 { 1733 E3dObject* pObj = (E3dObject*)GetMarkedObjectByIndex(a); 1734 BreakSingle3DObj(pObj); 1735 } 1736 DeleteMarked(); 1737 EndUndo(); 1738 } 1739 } 1740 1741 void E3dView::BreakSingle3DObj(E3dObject* pObj) 1742 { 1743 if(pObj->ISA(E3dScene)) 1744 { 1745 SdrObjList* pSubList = pObj->GetSubList(); 1746 SdrObjListIter aIter(*pSubList, IM_FLAT); 1747 1748 while(aIter.IsMore()) 1749 { 1750 E3dObject* pSubObj = (E3dObject*)aIter.Next(); 1751 BreakSingle3DObj(pSubObj); 1752 } 1753 } 1754 else 1755 { 1756 SdrAttrObj* pNewObj = pObj->GetBreakObj(); 1757 if(pNewObj) 1758 { 1759 InsertObjectAtView(pNewObj, *GetSdrPageView(), SDRINSERT_DONTMARK); 1760 pNewObj->SetChanged(); 1761 pNewObj->BroadcastObjectChange(); 1762 } 1763 } 1764 } 1765 1766 /************************************************************************* 1767 |* 1768 |* Szenen mischen 1769 |* 1770 \************************************************************************/ 1771 1772 void E3dView::MergeScenes () 1773 { 1774 sal_uIntPtr nCount = GetMarkedObjectCount(); 1775 1776 if (nCount > 0) 1777 { 1778 sal_uIntPtr nObj = 0; 1779 SdrObject *pObj = GetMarkedObjectByIndex(nObj); 1780 E3dScene *pScene = new E3dPolyScene(Get3DDefaultAttributes()); 1781 basegfx::B3DRange aBoundVol; 1782 Rectangle aAllBoundRect (GetMarkedObjBoundRect ()); 1783 Point aCenter (aAllBoundRect.Center()); 1784 1785 while (pObj) 1786 { 1787 if (pObj->ISA(E3dScene)) 1788 { 1789 /********************************************************** 1790 * Es ist eine 3D-Scene oder 3D-PolyScene 1791 **********************************************************/ 1792 SdrObjList* pSubList = ((E3dObject*) pObj)->GetSubList(); 1793 1794 SdrObjListIter aIter(*pSubList, IM_FLAT); 1795 1796 while (aIter.IsMore()) 1797 { 1798 /****************************************************** 1799 * LatheObjekte suchen 1800 ******************************************************/ 1801 SdrObject* pSubObj = aIter.Next(); 1802 1803 E3dObject *pNewObj = 0; 1804 1805 switch (pSubObj->GetObjIdentifier()) 1806 { 1807 case E3D_CUBEOBJ_ID : 1808 pNewObj = new E3dCubeObj; 1809 *(E3dCubeObj*)pNewObj = *(E3dCubeObj*)pSubObj; 1810 break; 1811 1812 case E3D_SPHEREOBJ_ID: 1813 pNewObj = new E3dSphereObj; 1814 *(E3dSphereObj*)pNewObj = *(E3dSphereObj*)pSubObj; 1815 break; 1816 1817 case E3D_EXTRUDEOBJ_ID: 1818 pNewObj = new E3dExtrudeObj; 1819 *(E3dExtrudeObj*)pNewObj = *(E3dExtrudeObj*)pSubObj; 1820 break; 1821 1822 case E3D_LATHEOBJ_ID: 1823 pNewObj = new E3dLatheObj; 1824 *(E3dLatheObj*)pNewObj = *(E3dLatheObj*)pSubObj; 1825 break; 1826 1827 case E3D_COMPOUNDOBJ_ID: 1828 pNewObj = new E3dCompoundObject; 1829 *(E3dCompoundObject*)pNewObj = *(E3dCompoundObject*)pSubObj; 1830 break; 1831 } 1832 1833 Rectangle aBoundRect = pSubObj->GetCurrentBoundRect(); 1834 1835 basegfx::B3DHomMatrix aMatrix; 1836 aMatrix.translate(aBoundRect.Left() - aCenter.getX(), aCenter.getY(), 0.0); 1837 pNewObj->SetTransform(aMatrix * pNewObj->GetTransform()); // #112587# 1838 1839 if (pNewObj) aBoundVol.expand(pNewObj->GetBoundVolume()); 1840 pScene->Insert3DObj (pNewObj); 1841 } 1842 } 1843 1844 nObj++; 1845 1846 if (nObj < nCount) 1847 { 1848 pObj = GetMarkedObjectByIndex(nObj); 1849 } 1850 else 1851 { 1852 pObj = NULL; 1853 } 1854 } 1855 1856 double fW = aAllBoundRect.GetWidth(); 1857 double fH = aAllBoundRect.GetHeight(); 1858 Rectangle aRect(0,0, (long) fW, (long) fH); 1859 1860 InitScene(pScene, fW, fH, aBoundVol.getMaxZ() + + ((fW + fH) / 4.0)); 1861 pScene->NbcSetSnapRect(aRect); 1862 1863 Camera3D &aCamera = (Camera3D&) pScene->GetCamera (); 1864 basegfx::B3DPoint aMinVec(aBoundVol.getMinimum()); 1865 basegfx::B3DPoint aMaxVec(aBoundVol.getMaximum()); 1866 double fDeepth(fabs(aMaxVec.getZ() - aMinVec.getZ())); 1867 1868 aCamera.SetPRP(basegfx::B3DPoint(0.0, 0.0, 1000.0)); 1869 double fDefaultCamPosZ(GetDefaultCamPosZ()); 1870 aCamera.SetPosition(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ + fDeepth / 2.0)); 1871 aCamera.SetFocalLength(GetDefaultCamFocal()); 1872 pScene->SetCamera (aCamera); 1873 1874 // SnapRects der Objekte ungueltig 1875 pScene->SetRectsDirty(); 1876 1877 InsertObjectAtView(pScene, *(GetSdrPageViewOfMarkedByIndex(0))); 1878 1879 // SnapRects der Objekte ungueltig 1880 pScene->SetRectsDirty(); 1881 } 1882 } 1883 1884 /************************************************************************* 1885 |* 1886 |* Possibilities, hauptsaechlich gruppieren/ungruppieren 1887 |* 1888 \************************************************************************/ 1889 void E3dView::CheckPossibilities() 1890 { 1891 // call parent 1892 SdrView::CheckPossibilities(); 1893 1894 // Weitere Flags bewerten 1895 if(bGroupPossible || bUnGroupPossible || bGrpEnterPossible) 1896 { 1897 sal_Int32 nMarkCnt = GetMarkedObjectCount(); 1898 sal_Bool bCoumpound = sal_False; 1899 sal_Bool b3DObject = sal_False; 1900 for(sal_Int32 nObjs = 0L; (nObjs < nMarkCnt) && !bCoumpound; nObjs++) 1901 { 1902 SdrObject *pObj = GetMarkedObjectByIndex(nObjs); 1903 if(pObj && pObj->ISA(E3dCompoundObject)) 1904 bCoumpound = sal_True; 1905 if(pObj && pObj->ISA(E3dObject)) 1906 b3DObject = sal_True; 1907 } 1908 1909 // Bisher: Es sind ZWEI oder mehr beliebiger Objekte selektiert. 1910 // Nachsehen, ob CompoundObjects beteiligt sind. Falls ja, 1911 // das Gruppieren verbieten. 1912 if(bGroupPossible && bCoumpound) 1913 bGroupPossible = sal_False; 1914 1915 if(bUnGroupPossible && b3DObject) 1916 bUnGroupPossible = sal_False; 1917 1918 if(bGrpEnterPossible && bCoumpound) 1919 bGrpEnterPossible = sal_False; 1920 } 1921 } 1922 1923 // eof 1924