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