LCOV - code coverage report
Current view: top level - svx/source/engine3d - view3d.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 58 745 7.8 %
Date: 2014-11-03 Functions: 14 41 34.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <vcl/wrkwin.hxx>
      22             : #include <svx/svdogrp.hxx>
      23             : #include <svx/svdopath.hxx>
      24             : #include "svx/svditer.hxx"
      25             : #include <svx/svdpool.hxx>
      26             : #include <svx/svdorect.hxx>
      27             : #include <svx/svdmodel.hxx>
      28             : #include <svx/svdpagv.hxx>
      29             : #include <svx/svxids.hrc>
      30             : #include <editeng/colritem.hxx>
      31             : #include <svx/xtable.hxx>
      32             : #include <svx/svdview.hxx>
      33             : #include <svx/dialogs.hrc>
      34             : #include <svx/dialmgr.hxx>
      35             : #include "svx/globl3d.hxx"
      36             : #include <svx/obj3d.hxx>
      37             : #include <svx/lathe3d.hxx>
      38             : #include <svx/sphere3d.hxx>
      39             : #include <svx/extrud3d.hxx>
      40             : #include <svx/cube3d.hxx>
      41             : #include <svx/polysc3d.hxx>
      42             : #include "dragmt3d.hxx"
      43             : #include <svx/view3d.hxx>
      44             : #include <svx/svdundo.hxx>
      45             : #include <svx/xflclit.hxx>
      46             : #include <svx/xlnclit.hxx>
      47             : #include <svx/svdograf.hxx>
      48             : #include <svx/xbtmpit.hxx>
      49             : #include <svx/xflbmtit.hxx>
      50             : #include <basegfx/range/b2drange.hxx>
      51             : #include <basegfx/polygon/b2dpolygontools.hxx>
      52             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      53             : #include <svx/xlnwtit.hxx>
      54             : #include <svx/sdr/overlay/overlaypolypolygon.hxx>
      55             : #include <svx/sdr/overlay/overlaymanager.hxx>
      56             : #include <svx/sdrpaintwindow.hxx>
      57             : #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
      58             : #include <drawinglayer/geometry/viewinformation3d.hxx>
      59             : #include <svx/sdrpagewindow.hxx>
      60             : #include <svx/sdr/contact/displayinfo.hxx>
      61             : #include <svx/sdr/contact/objectcontact.hxx>
      62             : #include <svx/sdr/contact/viewobjectcontact.hxx>
      63             : #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
      64             : #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
      65             : #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
      66             : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      67             : #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
      68             : 
      69             : using namespace com::sun::star;
      70             : 
      71             : #define ITEMVALUE(ItemSet,Id,Cast)  (static_cast<const Cast&>((ItemSet).Get(Id))).GetValue()
      72             : 
      73       20145 : TYPEINIT1(E3dView, SdrView);
      74             : 
      75             : 
      76             : // Migrate Marking
      77             : 
      78             : class Impl3DMirrorConstructOverlay
      79             : {
      80             :     // The OverlayObjects
      81             :     ::sdr::overlay::OverlayObjectList               maObjects;
      82             : 
      83             :     // the view
      84             :     const E3dView&                                  mrView;
      85             : 
      86             :     // the object count
      87             :     size_t mnCount;
      88             : 
      89             :     // the unmirrored polygons
      90             :     basegfx::B2DPolyPolygon*                        mpPolygons;
      91             : 
      92             :     // the overlay geometry from selected objects
      93             :     drawinglayer::primitive2d::Primitive2DSequence  maFullOverlay;
      94             : 
      95             : public:
      96             :     Impl3DMirrorConstructOverlay(const E3dView& rView);
      97             :     ~Impl3DMirrorConstructOverlay();
      98             : 
      99             :     void SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB);
     100             : };
     101             : 
     102           0 : Impl3DMirrorConstructOverlay::Impl3DMirrorConstructOverlay(const E3dView& rView)
     103             : :   maObjects(),
     104             :     mrView(rView),
     105           0 :     mnCount(rView.GetMarkedObjectCount()),
     106             :     mpPolygons(0),
     107           0 :     maFullOverlay()
     108             : {
     109           0 :     if(mnCount)
     110             :     {
     111           0 :         if(mrView.IsSolidDragging())
     112             :         {
     113           0 :             SdrPageView* pPV = rView.GetSdrPageView();
     114             : 
     115           0 :             if(pPV && pPV->PageWindowCount())
     116             :             {
     117           0 :                 sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
     118           0 :                 sdr::contact::DisplayInfo aDisplayInfo;
     119             : 
     120             :                 // Do not use the last ViewPort set at the OC at the last ProcessDisplay()
     121           0 :                 rOC.resetViewPort();
     122             : 
     123           0 :                 for(size_t a = 0; a < mnCount; ++a)
     124             :                 {
     125           0 :                     SdrObject* pObject = mrView.GetMarkedObjectByIndex(a);
     126             : 
     127           0 :                     if(pObject)
     128             :                     {
     129           0 :                         sdr::contact::ViewContact& rVC = pObject->GetViewContact();
     130           0 :                         sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rOC);
     131             : 
     132           0 :                         const drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo));
     133           0 :                         drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(maFullOverlay, aNewSequence);
     134             :                     }
     135           0 :                 }
     136             :             }
     137             :         }
     138             :         else
     139             :         {
     140           0 :             mpPolygons = new basegfx::B2DPolyPolygon[mnCount];
     141             : 
     142           0 :             for(size_t a = 0; a < mnCount; ++a)
     143             :             {
     144           0 :                 SdrObject* pObject = mrView.GetMarkedObjectByIndex(a);
     145           0 :                 mpPolygons[mnCount - (a + 1)] = pObject->TakeXorPoly();
     146             :             }
     147             :         }
     148             :     }
     149           0 : }
     150             : 
     151           0 : Impl3DMirrorConstructOverlay::~Impl3DMirrorConstructOverlay()
     152             : {
     153             :     // The OverlayObjects are cleared using the destructor of OverlayObjectList.
     154             :     // That destructor calls clear() at the list which removes all objects from the
     155             :     // OverlayManager and deletes them.
     156           0 :     if(!mrView.IsSolidDragging())
     157             :     {
     158           0 :         delete[] mpPolygons;
     159             :     }
     160           0 : }
     161             : 
     162           0 : void Impl3DMirrorConstructOverlay::SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB)
     163             : {
     164             :     // get rid of old overlay objects
     165           0 :     maObjects.clear();
     166             : 
     167             :     // create new ones
     168           0 :     for(sal_uInt32 a(0); a < mrView.PaintWindowCount(); a++)
     169             :     {
     170           0 :         SdrPaintWindow* pCandidate = mrView.GetPaintWindow(a);
     171           0 :         rtl::Reference< ::sdr::overlay::OverlayManager > xTargetOverlay = pCandidate->GetOverlayManager();
     172             : 
     173           0 :         if(xTargetOverlay.is())
     174             :         {
     175             :             // buld transfoprmation: translate and rotate so that given edge is
     176             :             // on x axis, them mirror in y and translate back
     177           0 :             const basegfx::B2DVector aEdge(aMirrorAxisB.X() - aMirrorAxisA.X(), aMirrorAxisB.Y() - aMirrorAxisA.Y());
     178             :             basegfx::B2DHomMatrix aMatrixTransform(basegfx::tools::createTranslateB2DHomMatrix(
     179           0 :                 -aMirrorAxisA.X(), -aMirrorAxisA.Y()));
     180           0 :             aMatrixTransform.rotate(-atan2(aEdge.getY(), aEdge.getX()));
     181           0 :             aMatrixTransform.scale(1.0, -1.0);
     182           0 :             aMatrixTransform.rotate(atan2(aEdge.getY(), aEdge.getX()));
     183           0 :             aMatrixTransform.translate(aMirrorAxisA.X(), aMirrorAxisA.Y());
     184             : 
     185           0 :             if(mrView.IsSolidDragging())
     186             :             {
     187           0 :                 if(maFullOverlay.hasElements())
     188             :                 {
     189           0 :                     drawinglayer::primitive2d::Primitive2DSequence aContent(maFullOverlay);
     190             : 
     191           0 :                     if(!aMatrixTransform.isIdentity())
     192             :                     {
     193             :                         // embed in transformation group
     194           0 :                         drawinglayer::primitive2d::Primitive2DReference aTransformPrimitive2D(new drawinglayer::primitive2d::TransformPrimitive2D(aMatrixTransform, aContent));
     195           0 :                         aContent = drawinglayer::primitive2d::Primitive2DSequence(&aTransformPrimitive2D, 1);
     196             :                     }
     197             : 
     198             :                     // if we have full overlay from selected objects, embed with 50% transparence, the
     199             :                     // transformation is added to the OverlayPrimitive2DSequenceObject
     200           0 :                     drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aContent, 0.5));
     201           0 :                     aContent = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparencePrimitive2D, 1);
     202             : 
     203           0 :                     sdr::overlay::OverlayPrimitive2DSequenceObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aContent);
     204             : 
     205           0 :                     xTargetOverlay->add(*pNew);
     206           0 :                     maObjects.append(*pNew);
     207             :                 }
     208             :             }
     209             :             else
     210             :             {
     211           0 :                 for(size_t b = 0; b < mnCount; ++b)
     212             :                 {
     213             :                     // apply to polygon
     214           0 :                     basegfx::B2DPolyPolygon aPolyPolygon(mpPolygons[b]);
     215           0 :                     aPolyPolygon.transform(aMatrixTransform);
     216             : 
     217             :                     ::sdr::overlay::OverlayPolyPolygonStripedAndFilled* pNew = new ::sdr::overlay::OverlayPolyPolygonStripedAndFilled(
     218           0 :                         aPolyPolygon);
     219           0 :                     xTargetOverlay->add(*pNew);
     220           0 :                     maObjects.append(*pNew);
     221           0 :                 }
     222           0 :             }
     223             :         }
     224           0 :     }
     225           0 : }
     226             : 
     227        7010 : E3dView::E3dView(SdrModel* pModel, OutputDevice* pOut) :
     228        7010 :     SdrView(pModel, pOut)
     229             : {
     230        7010 :     InitView ();
     231        7010 : }
     232             : 
     233             : // DrawMarkedObj overloaded, since possibly only a single 3D object is to be
     234             : // drawn
     235             : 
     236         516 : void E3dView::DrawMarkedObj(OutputDevice& rOut) const
     237             : {
     238             :     // Does 3D objects exist which scenes are not selected?
     239         516 :     bool bSpecialHandling = false;
     240         516 :     E3dScene *pScene = NULL;
     241             : 
     242         516 :     const size_t nCnt = GetMarkedObjectCount();
     243        1032 :     for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
     244             :     {
     245         516 :         SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
     246         516 :         if(pObj && pObj->ISA(E3dCompoundObject))
     247             :         {
     248             :             // related scene
     249           0 :             pScene = static_cast<E3dCompoundObject*>(pObj)->GetScene();
     250           0 :             if(pScene && !IsObjMarked(pScene))
     251           0 :                 bSpecialHandling = true;
     252             :         }
     253             :         // Reset all selection flags
     254         516 :         if(pObj && pObj->ISA(E3dObject))
     255             :         {
     256           0 :             pScene = static_cast<E3dObject*>(pObj)->GetScene();
     257           0 :             if(pScene)
     258           0 :                 pScene->SetSelected(false);
     259             :         }
     260             :     }
     261             : 
     262         516 :     if(bSpecialHandling)
     263             :     {
     264             :         // Set selection flag to "not selected" for scenes related to all 3D
     265             :         // objects
     266           0 :         for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
     267             :         {
     268           0 :             SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
     269           0 :             if(pObj && pObj->ISA(E3dCompoundObject))
     270             :             {
     271             :                 // relatated scene
     272           0 :                 pScene = static_cast<E3dCompoundObject*>(pObj)->GetScene();
     273           0 :                 if(pScene)
     274           0 :                     pScene->SetSelected(false);
     275             :             }
     276             :         }
     277             : 
     278           0 :         for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
     279             :         {
     280           0 :             SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
     281           0 :             if(pObj && pObj->ISA(E3dObject))
     282             :             {
     283             :                 // Select object
     284           0 :                 E3dObject* p3DObj = static_cast<E3dObject*>(pObj);
     285           0 :                 p3DObj->SetSelected(true);
     286           0 :                 pScene = p3DObj->GetScene();
     287             :             }
     288             :         }
     289             : 
     290           0 :         if(pScene)
     291             :         {
     292             :             // code from parent
     293           0 :             SortMarkedObjects();
     294             : 
     295           0 :             pScene->SetDrawOnlySelected(true);
     296           0 :             pScene->SingleObjectPainter(rOut);
     297           0 :             pScene->SetDrawOnlySelected(false);
     298             :         }
     299             : 
     300             :         // Reset selection flag
     301           0 :         for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
     302             :         {
     303           0 :             SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
     304           0 :             if(pObj && pObj->ISA(E3dCompoundObject))
     305             :             {
     306             :                 // releated scene
     307           0 :                 pScene = static_cast<E3dCompoundObject*>(pObj)->GetScene();
     308           0 :                 if(pScene)
     309           0 :                     pScene->SetSelected(false);
     310             :             }
     311             :         }
     312             :     }
     313             :     else
     314             :     {
     315             :         // call parent
     316         516 :         SdrExchangeView::DrawMarkedObj(rOut);
     317             :     }
     318         516 : }
     319             : 
     320             : // Get overloaded model, since in some 3D objects an additional scene
     321             : // must be pushed in
     322             : 
     323           0 : SdrModel* E3dView::GetMarkedObjModel() const
     324             : {
     325             :     // Does 3D objects exist which scenes are not selected?
     326           0 :     bool bSpecialHandling(false);
     327           0 :     const size_t nCount(GetMarkedObjectCount());
     328           0 :     E3dScene *pScene = 0;
     329             : 
     330           0 :     for(size_t nObjs = 0; nObjs < nCount; ++nObjs)
     331             :     {
     332           0 :         const SdrObject* pObj = GetMarkedObjectByIndex(nObjs);
     333             : 
     334           0 :         if(!bSpecialHandling && pObj && pObj->ISA(E3dCompoundObject))
     335             :         {
     336             :             // if the object is selected, but it's scene not,
     337             :             // we need special handling
     338           0 :             pScene = static_cast<const E3dCompoundObject*>(pObj)->GetScene();
     339             : 
     340           0 :             if(pScene && !IsObjMarked(pScene))
     341             :             {
     342           0 :                 bSpecialHandling = true;
     343             :             }
     344             :         }
     345             : 
     346           0 :         if(pObj && pObj->ISA(E3dObject))
     347             :         {
     348             :             // reset all selection flags at 3D objects
     349           0 :             pScene = static_cast<const E3dObject*>(pObj)->GetScene();
     350             : 
     351           0 :             if(pScene)
     352             :             {
     353           0 :                 pScene->SetSelected(false);
     354             :             }
     355             :         }
     356             :     }
     357             : 
     358           0 :     if(!bSpecialHandling)
     359             :     {
     360             :         // call parent
     361           0 :         return SdrView::GetMarkedObjModel();
     362             :     }
     363             : 
     364           0 :     SdrModel* pNewModel = 0;
     365           0 :     Rectangle aSelectedSnapRect;
     366             : 
     367             :     // set 3d selection flags at all directly selected objects
     368             :     // and collect SnapRect of selected objects
     369           0 :     for(size_t nObjs = 0; nObjs < nCount; ++nObjs)
     370             :     {
     371           0 :         SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
     372             : 
     373           0 :         if(pObj && pObj->ISA(E3dCompoundObject))
     374             :         {
     375             :             // mark object, but not scenes
     376           0 :             E3dCompoundObject* p3DObj = static_cast<E3dCompoundObject*>(pObj);
     377           0 :             p3DObj->SetSelected(true);
     378           0 :             aSelectedSnapRect.Union(p3DObj->GetSnapRect());
     379             :         }
     380             :     }
     381             : 
     382             :     // create new mark list which contains all indirectly selected3d
     383             :     // scenes as selected objects
     384           0 :     SdrMarkList aOldML(GetMarkedObjectList());
     385           0 :     SdrMarkList aNewML;
     386           0 :     SdrMarkList& rCurrentMarkList = ((E3dView*)this)->GetMarkedObjectListWriteAccess();
     387           0 :     rCurrentMarkList = aNewML;
     388             : 
     389           0 :     for(size_t nObjs = 0; nObjs < nCount; ++nObjs)
     390             :     {
     391           0 :         SdrObject *pObj = aOldML.GetMark(nObjs)->GetMarkedSdrObj();
     392             : 
     393           0 :         if(pObj && pObj->ISA(E3dObject))
     394             :         {
     395           0 :             pScene = static_cast<E3dObject*>(pObj)->GetScene();
     396             : 
     397           0 :             if(pScene && !IsObjMarked(pScene) && GetSdrPageView())
     398             :             {
     399           0 :                 ((E3dView*)this)->MarkObj(pScene, GetSdrPageView(), false, true);
     400             :             }
     401             :         }
     402             :     }
     403             : 
     404             :     // call parent. This will copy all scenes and the selection flags at the 3d objectss. So
     405             :     // it will be possible to delete all non-selected 3d objects from the cloned 3d scenes
     406           0 :     pNewModel = SdrView::GetMarkedObjModel();
     407             : 
     408           0 :     if(pNewModel)
     409             :     {
     410           0 :         for(sal_uInt16 nPg(0); nPg < pNewModel->GetPageCount(); nPg++)
     411             :         {
     412           0 :             const SdrPage* pSrcPg=pNewModel->GetPage(nPg);
     413           0 :             const size_t nObAnz(pSrcPg->GetObjCount());
     414             : 
     415           0 :             for(size_t nOb = 0; nOb < nObAnz; ++nOb)
     416             :             {
     417           0 :                 const SdrObject* pSrcOb=pSrcPg->GetObj(nOb);
     418             : 
     419           0 :                 if(pSrcOb->ISA(E3dScene))
     420             :                 {
     421           0 :                     pScene = const_cast<E3dScene*>(static_cast<const E3dScene*>(pSrcOb));
     422             : 
     423             :                     // delete all not intentionally cloned 3d objects
     424           0 :                     pScene->removeAllNonSelectedObjects();
     425             : 
     426             :                     // reset select flags and set SnapRect of all selected objects
     427           0 :                     pScene->SetSelected(false);
     428           0 :                     pScene->SetSnapRect(aSelectedSnapRect);
     429             :                 }
     430             :             }
     431             :         }
     432             :     }
     433             : 
     434             :     // restore old selection
     435           0 :     rCurrentMarkList = aOldML;
     436             : 
     437           0 :     return pNewModel;
     438             : }
     439             : 
     440             : // When pasting objects have to integrated if a scene is inserted, but
     441             : // not the scene itself
     442             : 
     443           0 : bool E3dView::Paste(
     444             :     const SdrModel& rMod, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions,
     445             :     const OUString& rSrcShellID, const OUString& rDestShellID )
     446             : {
     447           0 :     bool bRetval = false;
     448             : 
     449             :     // Get list
     450           0 :     Point aPos(rPos);
     451           0 :     SdrObjList* pDstList = pLst;
     452           0 :     ImpGetPasteObjList(aPos, pDstList);
     453             : 
     454           0 :     if(!pDstList)
     455           0 :         return false;
     456             : 
     457             :     // Get owner of the list
     458           0 :     SdrObject* pOwner = pDstList->GetOwnerObj();
     459           0 :     if(pOwner && pOwner->ISA(E3dScene))
     460             :     {
     461           0 :         E3dScene* pDstScene = static_cast<E3dScene*>(pOwner);
     462           0 :         BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_EXCHANGE_PASTE));
     463             : 
     464             :         // Copy all objects from E3dScenes and insert them directly
     465           0 :         for(sal_uInt16 nPg(0); nPg < rMod.GetPageCount(); nPg++)
     466             :         {
     467           0 :             const SdrPage* pSrcPg=rMod.GetPage(nPg);
     468           0 :             const size_t nObAnz(pSrcPg->GetObjCount());
     469             : 
     470             :             // calculate offset for paste
     471           0 :             Rectangle aR = pSrcPg->GetAllObjBoundRect();
     472           0 :             Point aDist(aPos - aR.Center());
     473             : 
     474             :             // Insert sub-objects for scenes
     475           0 :             for(size_t nOb = 0; nOb < nObAnz; ++nOb)
     476             :             {
     477           0 :                 const SdrObject* pSrcOb = pSrcPg->GetObj(nOb);
     478           0 :                 if(pSrcOb->ISA(E3dScene))
     479             :                 {
     480           0 :                     E3dScene* pSrcScene = const_cast<E3dScene*>(static_cast<const E3dScene*>(pSrcOb));
     481           0 :                     ImpCloneAll3DObjectsToDestScene(pSrcScene, pDstScene, aDist);
     482             :                 }
     483             :             }
     484             :         }
     485           0 :         EndUndo();
     486             :     }
     487             :     else
     488             :     {
     489             :         // call parent
     490           0 :         bRetval = SdrView::Paste(rMod, rPos, pLst, nOptions, rSrcShellID, rDestShellID);
     491             :     }
     492             : 
     493           0 :     return bRetval;
     494             : }
     495             : 
     496             : // Service routine used from local Clone() and from SdrCreateView::EndCreateObj(...)
     497           0 : bool E3dView::ImpCloneAll3DObjectsToDestScene(E3dScene* pSrcScene, E3dScene* pDstScene, Point /*aOffset*/)
     498             : {
     499           0 :     bool bRetval(false);
     500             : 
     501           0 :     if(pSrcScene && pDstScene)
     502             :     {
     503           0 :         const sdr::contact::ViewContactOfE3dScene& rVCSceneDst = static_cast< sdr::contact::ViewContactOfE3dScene& >(pDstScene->GetViewContact());
     504           0 :         const drawinglayer::geometry::ViewInformation3D aViewInfo3DDst(rVCSceneDst.getViewInformation3D());
     505           0 :         const sdr::contact::ViewContactOfE3dScene& rVCSceneSrc = static_cast< sdr::contact::ViewContactOfE3dScene& >(pSrcScene->GetViewContact());
     506           0 :         const drawinglayer::geometry::ViewInformation3D aViewInfo3DSrc(rVCSceneSrc.getViewInformation3D());
     507             : 
     508           0 :         for(size_t i = 0; i < pSrcScene->GetSubList()->GetObjCount(); ++i)
     509             :         {
     510           0 :             E3dCompoundObject* pCompoundObj = dynamic_cast< E3dCompoundObject* >(pSrcScene->GetSubList()->GetObj(i));
     511             : 
     512           0 :             if(pCompoundObj)
     513             :             {
     514           0 :                 E3dCompoundObject* pNewCompoundObj = dynamic_cast< E3dCompoundObject* >(pCompoundObj->Clone());
     515             : 
     516           0 :                 if(pNewCompoundObj)
     517             :                 {
     518             :                     // get dest scene's current range in 3D world coordinates
     519           0 :                     const basegfx::B3DHomMatrix aSceneToWorldTrans(pDstScene->GetFullTransform());
     520           0 :                     basegfx::B3DRange aSceneRange(pDstScene->GetBoundVolume());
     521           0 :                     aSceneRange.transform(aSceneToWorldTrans);
     522             : 
     523             :                     // get new object's implied object transformation
     524           0 :                     const basegfx::B3DHomMatrix aNewObjectTrans(pNewCompoundObj->GetTransform());
     525             : 
     526             :                     // get new object's range in 3D world coordinates in dest scene
     527             :                     // as if it were already added
     528           0 :                     const basegfx::B3DHomMatrix aObjectToWorldTrans(aSceneToWorldTrans * aNewObjectTrans);
     529           0 :                     basegfx::B3DRange aObjectRange(pNewCompoundObj->GetBoundVolume());
     530           0 :                     aObjectRange.transform(aObjectToWorldTrans);
     531             : 
     532             :                     // get scale adaption
     533           0 :                     const basegfx::B3DVector aSceneScale(aSceneRange.getRange());
     534           0 :                     const basegfx::B3DVector aObjectScale(aObjectRange.getRange());
     535           0 :                     double fScale(1.0);
     536             : 
     537             :                     // if new object's size in X,Y or Z is bigger that 80% of dest scene, adapt scale
     538             :                     // to not change the scene by the inserted object
     539           0 :                     const double fSizeFactor(0.5);
     540             : 
     541           0 :                     if(aObjectScale.getX() * fScale > aSceneScale.getX() * fSizeFactor)
     542             :                     {
     543           0 :                         const double fObjSize(aObjectScale.getX() * fScale);
     544           0 :                         const double fFactor((aSceneScale.getX() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
     545           0 :                         fScale *= fFactor;
     546             :                     }
     547             : 
     548           0 :                     if(aObjectScale.getY() * fScale > aSceneScale.getY() * fSizeFactor)
     549             :                     {
     550           0 :                         const double fObjSize(aObjectScale.getY() * fScale);
     551           0 :                         const double fFactor((aSceneScale.getY() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
     552           0 :                         fScale *= fFactor;
     553             :                     }
     554             : 
     555           0 :                     if(aObjectScale.getZ() * fScale > aSceneScale.getZ() * fSizeFactor)
     556             :                     {
     557           0 :                         const double fObjSize(aObjectScale.getZ() * fScale);
     558           0 :                         const double fFactor((aSceneScale.getZ() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
     559           0 :                         fScale *= fFactor;
     560             :                     }
     561             : 
     562             :                     // get translation adaption
     563           0 :                     const basegfx::B3DPoint aSceneCenter(aSceneRange.getCenter());
     564           0 :                     const basegfx::B3DPoint aObjectCenter(aObjectRange.getCenter());
     565             : 
     566             :                     // build full modification transform. The object's transformation
     567             :                     // shall be modified, so start at object coordinates; transform to 3d world coor
     568           0 :                     basegfx::B3DHomMatrix aModifyingTransform(aObjectToWorldTrans);
     569             : 
     570             :                     // translate to absolute center in 3d world coor
     571           0 :                     aModifyingTransform.translate(-aObjectCenter.getX(), -aObjectCenter.getY(), -aObjectCenter.getZ());
     572             : 
     573             :                     // scale to dest size in 3d world coor
     574           0 :                     aModifyingTransform.scale(fScale, fScale, fScale);
     575             : 
     576             :                     // translate to dest scene center in 3d world coor
     577           0 :                     aModifyingTransform.translate(aSceneCenter.getX(), aSceneCenter.getY(), aSceneCenter.getZ());
     578             : 
     579             :                     // transform from 3d world to dest object coordinates
     580           0 :                     basegfx::B3DHomMatrix aWorldToObject(aObjectToWorldTrans);
     581           0 :                     aWorldToObject.invert();
     582           0 :                     aModifyingTransform = aWorldToObject * aModifyingTransform;
     583             : 
     584             :                     // correct implied object transform by applying changing one in object coor
     585           0 :                     pNewCompoundObj->SetTransform(aModifyingTransform * aNewObjectTrans);
     586             : 
     587             :                     // fill and insert new object
     588           0 :                     pNewCompoundObj->SetModel(pDstScene->GetModel());
     589           0 :                     pNewCompoundObj->SetPage(pDstScene->GetPage());
     590           0 :                     pNewCompoundObj->NbcSetLayer(pCompoundObj->GetLayer());
     591           0 :                     pNewCompoundObj->NbcSetStyleSheet(pCompoundObj->GetStyleSheet(), true);
     592           0 :                     pDstScene->Insert3DObj(pNewCompoundObj);
     593           0 :                     bRetval = true;
     594             : 
     595             :                     // Create undo
     596           0 :                     if( GetModel()->IsUndoEnabled() )
     597           0 :                         AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNewCompoundObj));
     598             :                 }
     599             :             }
     600           0 :         }
     601             :     }
     602             : 
     603           0 :     return bRetval;
     604             : }
     605             : 
     606        4221 : bool E3dView::IsConvertTo3DObjPossible() const
     607             : {
     608        4221 :     bool bAny3D(false);
     609        4221 :     bool bGroupSelected(false);
     610        4221 :     bool bRetval(true);
     611             : 
     612        4223 :     for(size_t a=0; !bAny3D && a<GetMarkedObjectCount(); ++a)
     613             :     {
     614           2 :         SdrObject *pObj = GetMarkedObjectByIndex(a);
     615           2 :         if(pObj)
     616             :         {
     617           2 :             ImpIsConvertTo3DPossible(pObj, bAny3D, bGroupSelected);
     618             :         }
     619             :     }
     620             : 
     621        4221 :     bRetval = !bAny3D
     622        8444 :         && (
     623        4221 :            IsConvertToPolyObjPossible(false)
     624        4219 :         || IsConvertToPathObjPossible(false)
     625        8440 :         || IsImportMtfPossible());
     626        4221 :     return bRetval;
     627             : }
     628             : 
     629           2 : void E3dView::ImpIsConvertTo3DPossible(SdrObject* pObj, bool& rAny3D,
     630             :     bool& rGroupSelected) const
     631             : {
     632           2 :     if(pObj)
     633             :     {
     634           2 :         if(pObj->ISA(E3dObject))
     635             :         {
     636           0 :             rAny3D = true;
     637             :         }
     638             :         else
     639             :         {
     640           2 :             if(pObj->IsGroupObject())
     641             :             {
     642           0 :                 SdrObjListIter aIter(*pObj, IM_DEEPNOGROUPS);
     643           0 :                 while(aIter.IsMore())
     644             :                 {
     645           0 :                     SdrObject* pNewObj = aIter.Next();
     646           0 :                     ImpIsConvertTo3DPossible(pNewObj, rAny3D, rGroupSelected);
     647             :                 }
     648           0 :                 rGroupSelected = true;
     649             :             }
     650             :         }
     651             :     }
     652           2 : }
     653             : 
     654             : #include <editeng/eeitem.hxx>
     655             : 
     656           0 : void E3dView::ImpChangeSomeAttributesFor3DConversion(SdrObject* pObj)
     657             : {
     658           0 :     if(pObj->ISA(SdrTextObj))
     659             :     {
     660           0 :         const SfxItemSet& rSet = pObj->GetMergedItemSet();
     661           0 :         const SvxColorItem& rTextColorItem = static_cast<const SvxColorItem&>(rSet.Get(EE_CHAR_COLOR));
     662           0 :         if(rTextColorItem.GetValue() == RGB_Color(COL_BLACK))
     663             :         {
     664             :             //For black text objects, the color set to gray
     665           0 :             if(pObj->GetPage())
     666             :             {
     667             :                 // if black is only default attribute from
     668             :                 // pattern set it hard so that it is used in undo.
     669           0 :                 pObj->SetMergedItem(SvxColorItem(RGB_Color(COL_BLACK), EE_CHAR_COLOR));
     670             : 
     671             :                 // add undo now
     672           0 :                 if( GetModel()->IsUndoEnabled() )
     673           0 :                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj, false, false));
     674             :             }
     675             : 
     676           0 :             pObj->SetMergedItem(SvxColorItem(RGB_Color(COL_GRAY), EE_CHAR_COLOR));
     677             :         }
     678             :     }
     679           0 : }
     680             : 
     681           0 : void E3dView::ImpChangeSomeAttributesFor3DConversion2(SdrObject* pObj)
     682             : {
     683           0 :     if(pObj->ISA(SdrPathObj))
     684             :     {
     685           0 :         const SfxItemSet& rSet = pObj->GetMergedItemSet();
     686           0 :         sal_Int32 nLineWidth = static_cast<const XLineWidthItem&>(rSet.Get(XATTR_LINEWIDTH)).GetValue();
     687           0 :         XLineStyle eLineStyle = (XLineStyle)static_cast<const XLineStyleItem&>(rSet.Get(XATTR_LINESTYLE)).GetValue();
     688           0 :         drawing::FillStyle eFillStyle = ITEMVALUE(rSet, XATTR_FILLSTYLE, XFillStyleItem);
     689             : 
     690           0 :         if(static_cast<SdrPathObj*>(pObj)->IsClosed()
     691           0 :             && eLineStyle == XLINE_SOLID
     692           0 :             && !nLineWidth
     693           0 :             && eFillStyle != drawing::FillStyle_NONE)
     694             :         {
     695           0 :             if(pObj->GetPage() && GetModel()->IsUndoEnabled() )
     696           0 :                 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj, false, false));
     697           0 :             pObj->SetMergedItem(XLineStyleItem(XLINE_NONE));
     698           0 :             pObj->SetMergedItem(XLineWidthItem(0L));
     699             :         }
     700             :     }
     701           0 : }
     702             : 
     703           0 : void E3dView::ImpCreateSingle3DObjectFlat(E3dScene* pScene, SdrObject* pObj, bool bExtrude, double fDepth, basegfx::B2DHomMatrix& rLatheMat)
     704             : {
     705             :     // Single PathObject, transform this
     706           0 :     SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj);
     707             : 
     708           0 :     if(pPath)
     709             :     {
     710           0 :         E3dDefaultAttributes aDefault = Get3DDefaultAttributes();
     711           0 :         if(bExtrude)
     712           0 :             aDefault.SetDefaultExtrudeCharacterMode(true);
     713             :         else
     714           0 :             aDefault.SetDefaultLatheCharacterMode(true);
     715             : 
     716             :         // Get Itemset of the original object
     717           0 :         SfxItemSet aSet(pObj->GetMergedItemSet());
     718             : 
     719           0 :         drawing::FillStyle eFillStyle = ITEMVALUE(aSet, XATTR_FILLSTYLE, XFillStyleItem);
     720             : 
     721             :         // line style turned off
     722           0 :         aSet.Put(XLineStyleItem(XLINE_NONE));
     723             : 
     724             :         //Determining if FILL_Attribut is set.
     725           0 :         if(!pPath->IsClosed() || eFillStyle == drawing::FillStyle_NONE)
     726             :         {
     727             :             // This SdrPathObj is not filled, leave the front and rear face out.
     728             :             // Moreover, a two-sided representation necessary.
     729           0 :             aDefault.SetDefaultExtrudeCloseFront(false);
     730           0 :             aDefault.SetDefaultExtrudeCloseBack(false);
     731             : 
     732           0 :             aSet.Put(makeSvx3DDoubleSidedItem(true));
     733             : 
     734             :             // Set fill attribute
     735           0 :             aSet.Put(XFillStyleItem(drawing::FillStyle_SOLID));
     736             : 
     737             :             // Fill color must be the color line, because the object was
     738             :             // previously just a line
     739           0 :             Color aColorLine = static_cast<const XLineColorItem&>(aSet.Get(XATTR_LINECOLOR)).GetColorValue();
     740           0 :             aSet.Put(XFillColorItem(OUString(), aColorLine));
     741             :         }
     742             : 
     743             :         // Create a new extrude object
     744           0 :         E3dObject* p3DObj = NULL;
     745           0 :         if(bExtrude)
     746             :         {
     747           0 :             p3DObj = new E3dExtrudeObj(aDefault, pPath->GetPathPoly(), fDepth);
     748             :         }
     749             :         else
     750             :         {
     751           0 :             basegfx::B2DPolyPolygon aPolyPoly2D(pPath->GetPathPoly());
     752           0 :             aPolyPoly2D.transform(rLatheMat);
     753           0 :             p3DObj = new E3dLatheObj(aDefault, aPolyPoly2D);
     754             :         }
     755             : 
     756             :         // Set attribute
     757           0 :         if(p3DObj)
     758             :         {
     759           0 :             p3DObj->NbcSetLayer(pObj->GetLayer());
     760             : 
     761           0 :             p3DObj->SetMergedItemSet(aSet);
     762             : 
     763           0 :             p3DObj->NbcSetStyleSheet(pObj->GetStyleSheet(), true);
     764             : 
     765             :             // Insert a new extrude object
     766           0 :             pScene->Insert3DObj(p3DObj);
     767           0 :         }
     768             :     }
     769           0 : }
     770             : 
     771           0 : void E3dView::ImpCreate3DObject(E3dScene* pScene, SdrObject* pObj, bool bExtrude, double fDepth, basegfx::B2DHomMatrix& rLatheMat)
     772             : {
     773           0 :     if(pObj)
     774             :     {
     775             :         // change text color attribute for not so dark colors
     776           0 :         if(pObj->IsGroupObject())
     777             :         {
     778           0 :             SdrObjListIter aIter(*pObj, IM_DEEPWITHGROUPS);
     779           0 :             while(aIter.IsMore())
     780             :             {
     781           0 :                 SdrObject* pGroupMember = aIter.Next();
     782           0 :                 ImpChangeSomeAttributesFor3DConversion(pGroupMember);
     783           0 :             }
     784             :         }
     785             :         else
     786           0 :             ImpChangeSomeAttributesFor3DConversion(pObj);
     787             : 
     788             :         // convert completely to path objects
     789           0 :         SdrObject* pNewObj1 = pObj->ConvertToPolyObj(false, false);
     790             : 
     791           0 :         if(pNewObj1)
     792             :         {
     793             :             // change text color attribute for not so dark colors
     794           0 :             if(pNewObj1->IsGroupObject())
     795             :             {
     796           0 :                 SdrObjListIter aIter(*pNewObj1, IM_DEEPWITHGROUPS);
     797           0 :                 while(aIter.IsMore())
     798             :                 {
     799           0 :                     SdrObject* pGroupMember = aIter.Next();
     800           0 :                     ImpChangeSomeAttributesFor3DConversion2(pGroupMember);
     801           0 :                 }
     802             :             }
     803             :             else
     804           0 :                 ImpChangeSomeAttributesFor3DConversion2(pNewObj1);
     805             : 
     806             :             // convert completely to path objects
     807           0 :             SdrObject* pNewObj2 = pObj->ConvertToContourObj(pNewObj1, true);
     808             : 
     809           0 :             if(pNewObj2)
     810             :             {
     811             :                 // add all to flat scene
     812           0 :                 if(pNewObj2->IsGroupObject())
     813             :                 {
     814           0 :                     SdrObjListIter aIter(*pNewObj2, IM_DEEPWITHGROUPS);
     815           0 :                     while(aIter.IsMore())
     816             :                     {
     817           0 :                         SdrObject* pGroupMember = aIter.Next();
     818           0 :                         ImpCreateSingle3DObjectFlat(pScene, pGroupMember, bExtrude, fDepth, rLatheMat);
     819           0 :                     }
     820             :                 }
     821             :                 else
     822           0 :                     ImpCreateSingle3DObjectFlat(pScene, pNewObj2, bExtrude, fDepth, rLatheMat);
     823             : 
     824             :                 // delete object in between
     825           0 :                 if(pNewObj2 != pObj && pNewObj2 != pNewObj1 && pNewObj2)
     826           0 :                     SdrObject::Free( pNewObj2 );
     827             :             }
     828             : 
     829             :             // delete object in between
     830           0 :             if(pNewObj1 != pObj && pNewObj1)
     831           0 :                 SdrObject::Free( pNewObj1 );
     832             :         }
     833             :     }
     834           0 : }
     835             : 
     836           0 : void E3dView::ConvertMarkedObjTo3D(bool bExtrude, basegfx::B2DPoint aPnt1, basegfx::B2DPoint aPnt2)
     837             : {
     838           0 :     if(AreObjectsMarked())
     839             :     {
     840             :         // Create undo
     841           0 :         if(bExtrude)
     842           0 :             BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_EXTRUDE));
     843             :         else
     844           0 :             BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_LATHE));
     845             : 
     846             :         // Create a new scene for the created 3D object
     847           0 :         E3dScene* pScene = new E3dPolyScene(Get3DDefaultAttributes());
     848             : 
     849             :         // Determine rectangle and possibly correct it
     850           0 :         Rectangle aRect = GetAllMarkedRect();
     851           0 :         if(aRect.GetWidth() <= 1)
     852           0 :             aRect.SetSize(Size(500, aRect.GetHeight()));
     853           0 :         if(aRect.GetHeight() <= 1)
     854           0 :             aRect.SetSize(Size(aRect.GetWidth(), 500));
     855             : 
     856             :         // Determine the depth relative to the size of the selection
     857           0 :         double fDepth = 0.0;
     858           0 :         double fRot3D = 0.0;
     859           0 :         basegfx::B2DHomMatrix aLatheMat;
     860             : 
     861           0 :         if(bExtrude)
     862             :         {
     863           0 :             double fW = (double)aRect.GetWidth();
     864           0 :             double fH = (double)aRect.GetHeight();
     865           0 :             fDepth = sqrt(fW*fW + fH*fH) / 6.0;
     866             :         }
     867           0 :         if(!bExtrude)
     868             :         {
     869             :             // Create transformation for the polygons rotating body
     870           0 :             if(aPnt1 != aPnt2)
     871             :             {
     872             :                 // Rotation around control point #1 with set angle
     873             :                 // for 3D coordinates
     874           0 :                 basegfx::B2DPoint aDiff(aPnt1 - aPnt2);
     875           0 :                 fRot3D = atan2(aDiff.getY(), aDiff.getX()) - F_PI2;
     876             : 
     877           0 :                 if(basegfx::fTools::equalZero(fabs(fRot3D)))
     878           0 :                     fRot3D = 0.0;
     879             : 
     880           0 :                 if(fRot3D != 0.0)
     881             :                 {
     882             :                     aLatheMat = basegfx::tools::createRotateAroundPoint(aPnt2, -fRot3D)
     883           0 :                         * aLatheMat;
     884           0 :                 }
     885             :             }
     886             : 
     887           0 :             if(aPnt2.getX() != 0.0)
     888             :             {
     889             :                 // Translation to Y=0 - axis
     890           0 :                 aLatheMat.translate(-aPnt2.getX(), 0.0);
     891             :             }
     892             :             else
     893             :             {
     894           0 :                 aLatheMat.translate((double)-aRect.Left(), 0.0);
     895             :             }
     896             : 
     897             :             // Form the inverse matrix to determine the target expansion
     898           0 :             basegfx::B2DHomMatrix aInvLatheMat(aLatheMat);
     899           0 :             aInvLatheMat.invert();
     900             : 
     901             :             // SnapRect extension enables mirroring in the axis of rotation
     902           0 :             for(size_t a=0; a<GetMarkedObjectCount(); ++a)
     903             :             {
     904           0 :                 SdrMark* pMark = GetSdrMarkByIndex(a);
     905           0 :                 SdrObject* pObj = pMark->GetMarkedSdrObj();
     906           0 :                 Rectangle aTurnRect = pObj->GetSnapRect();
     907           0 :                 basegfx::B2DPoint aRot;
     908           0 :                 Point aRotPnt;
     909             : 
     910           0 :                 aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Top());
     911           0 :                 aRot *= aLatheMat;
     912           0 :                 aRot.setX(-aRot.getX());
     913           0 :                 aRot *= aInvLatheMat;
     914           0 :                 aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
     915           0 :                 aRect.Union(Rectangle(aRotPnt, aRotPnt));
     916             : 
     917           0 :                 aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Bottom());
     918           0 :                 aRot *= aLatheMat;
     919           0 :                 aRot.setX(-aRot.getX());
     920           0 :                 aRot *= aInvLatheMat;
     921           0 :                 aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
     922           0 :                 aRect.Union(Rectangle(aRotPnt, aRotPnt));
     923             : 
     924           0 :                 aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Top());
     925           0 :                 aRot *= aLatheMat;
     926           0 :                 aRot.setX(-aRot.getX());
     927           0 :                 aRot *= aInvLatheMat;
     928           0 :                 aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
     929           0 :                 aRect.Union(Rectangle(aRotPnt, aRotPnt));
     930             : 
     931           0 :                 aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Bottom());
     932           0 :                 aRot *= aLatheMat;
     933           0 :                 aRot.setX(-aRot.getX());
     934           0 :                 aRot *= aInvLatheMat;
     935           0 :                 aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
     936           0 :                 aRect.Union(Rectangle(aRotPnt, aRotPnt));
     937           0 :             }
     938             :         }
     939             : 
     940             :         // Walk through the selection and convert it into 3D, complete with
     941             :         // Conversion to SdrPathObject, also fonts
     942           0 :         for(size_t a=0; a<GetMarkedObjectCount(); ++a)
     943             :         {
     944           0 :             SdrMark* pMark = GetSdrMarkByIndex(a);
     945           0 :             SdrObject* pObj = pMark->GetMarkedSdrObj();
     946             : 
     947           0 :             ImpCreate3DObject(pScene, pObj, bExtrude, fDepth, aLatheMat);
     948             :         }
     949             : 
     950           0 :         if(pScene->GetSubList() && pScene->GetSubList()->GetObjCount() != 0)
     951             :         {
     952             :             // Arrange all created objects by depth
     953           0 :             if(bExtrude)
     954           0 :                 DoDepthArrange(pScene, fDepth);
     955             : 
     956             :             // Center 3D objects in the middle of the overall rectangle
     957           0 :             basegfx::B3DPoint aCenter(pScene->GetBoundVolume().getCenter());
     958           0 :             basegfx::B3DHomMatrix aMatrix;
     959             : 
     960           0 :             aMatrix.translate(-aCenter.getX(), -aCenter.getY(), -aCenter.getZ());
     961           0 :             pScene->SetTransform(aMatrix * pScene->GetTransform());
     962             : 
     963             :             // Initialize scene
     964           0 :             pScene->NbcSetSnapRect(aRect);
     965           0 :             basegfx::B3DRange aBoundVol = pScene->GetBoundVolume();
     966           0 :             InitScene(pScene, (double)aRect.GetWidth(), (double)aRect.GetHeight(), aBoundVol.getDepth());
     967             : 
     968             :             // Insert scene instead of the first selected object and throw away
     969             :             // all the old objects
     970           0 :             SdrObject* pRepObj = GetMarkedObjectByIndex(0);
     971           0 :             SdrPageView* pPV = GetSdrPageViewOfMarkedByIndex(0);
     972           0 :             MarkObj(pRepObj, pPV, true);
     973           0 :             ReplaceObjectAtView(pRepObj, *pPV, pScene, false);
     974           0 :             DeleteMarked();
     975           0 :             MarkObj(pScene, pPV);
     976             : 
     977             :             // Rotate Rotation body around the axis of rotation
     978           0 :             basegfx::B3DHomMatrix aRotate;
     979             : 
     980           0 :             if(!bExtrude && fRot3D != 0.0)
     981             :             {
     982           0 :                 aRotate.rotate(0.0, 0.0, fRot3D);
     983             :             }
     984             : 
     985             :             // Set default rotation
     986             :             {
     987           0 :                 double XRotateDefault = 20;
     988           0 :                 aRotate.rotate(DEG2RAD(XRotateDefault), 0.0, 0.0);
     989             :             }
     990             : 
     991           0 :             if(!aRotate.isIdentity())
     992             :             {
     993           0 :                 pScene->SetTransform(aRotate * pScene->GetTransform());
     994             :             }
     995             : 
     996             :             // Invalid SnapRects of objects
     997           0 :             pScene->SetSnapRect(aRect);
     998             :         }
     999             :         else
    1000             :         {
    1001             :             // No 3D object was created, throw away everything
    1002           0 :             delete pScene;
    1003             :         }
    1004             : 
    1005           0 :         EndUndo();
    1006             :     }
    1007           0 : }
    1008             : 
    1009             : //Arrange all created extrude objects by depth
    1010             : 
    1011           0 : struct E3dDepthNeighbour
    1012             : {
    1013             :     E3dDepthNeighbour*          mpNext;
    1014             :     E3dExtrudeObj*              mpObj;
    1015             :     basegfx::B2DPolyPolygon     maPreparedPolyPolygon;
    1016             : 
    1017           0 :     E3dDepthNeighbour()
    1018             :     :   mpNext(0),
    1019             :         mpObj(0),
    1020           0 :         maPreparedPolyPolygon()
    1021             :     {
    1022           0 :     }
    1023             : };
    1024             : 
    1025             : struct E3dDepthLayer
    1026             : {
    1027             :     E3dDepthLayer*              mpDown;
    1028             :     E3dDepthNeighbour*          mpNext;
    1029             : 
    1030           0 :     E3dDepthLayer()
    1031             :     :   mpDown(0),
    1032           0 :         mpNext(0)
    1033             :     {
    1034           0 :     }
    1035             : 
    1036           0 :     ~E3dDepthLayer()
    1037             :     {
    1038           0 :         while(mpNext)
    1039             :         {
    1040           0 :             E3dDepthNeighbour* pSucc = mpNext->mpNext;
    1041           0 :             delete mpNext;
    1042           0 :             mpNext = pSucc;
    1043             :         }
    1044           0 :     }
    1045             : };
    1046             : 
    1047           0 : void E3dView::DoDepthArrange(E3dScene* pScene, double fDepth)
    1048             : {
    1049           0 :     if(pScene && pScene->GetSubList() && pScene->GetSubList()->GetObjCount() > 1)
    1050             :     {
    1051           0 :         SdrObjList* pSubList = pScene->GetSubList();
    1052           0 :         SdrObjListIter aIter(*pSubList, IM_FLAT);
    1053           0 :         E3dDepthLayer* pBaseLayer = NULL;
    1054           0 :         E3dDepthLayer* pLayer = NULL;
    1055           0 :         sal_Int32 nNumLayers = 0;
    1056             : 
    1057           0 :         while(aIter.IsMore())
    1058             :         {
    1059           0 :             E3dExtrudeObj* pExtrudeObj = dynamic_cast< E3dExtrudeObj* >(aIter.Next());
    1060             : 
    1061           0 :             if(pExtrudeObj)
    1062             :             {
    1063             :                 const basegfx::B2DPolyPolygon aExtrudePoly(
    1064           0 :                     basegfx::tools::prepareForPolygonOperation(pExtrudeObj->GetExtrudePolygon()));
    1065           0 :                 const SfxItemSet& rLocalSet = pExtrudeObj->GetMergedItemSet();
    1066           0 :                 const drawing::FillStyle eLocalFillStyle = ITEMVALUE(rLocalSet, XATTR_FILLSTYLE, XFillStyleItem);
    1067           0 :                 const Color aLocalColor = static_cast<const XFillColorItem&>(rLocalSet.Get(XATTR_FILLCOLOR)).GetColorValue();
    1068             : 
    1069             :                 // sort in ExtrudeObj
    1070           0 :                 if(pLayer)
    1071             :                 {
    1072             :                     // do we have overlap with an object of this layer?
    1073           0 :                     bool bOverlap(false);
    1074           0 :                     E3dDepthNeighbour* pAct = pLayer->mpNext;
    1075             : 
    1076           0 :                     while(!bOverlap && pAct)
    1077             :                     {
    1078             :                         // do pAct->mpObj and pExtrudeObj overlap? Check by
    1079             :                         // using logical AND clipping
    1080             :                         const basegfx::B2DPolyPolygon aAndPolyPolygon(
    1081             :                             basegfx::tools::solvePolygonOperationAnd(
    1082             :                                 aExtrudePoly,
    1083           0 :                                 pAct->maPreparedPolyPolygon));
    1084             : 
    1085           0 :                         bOverlap = (0 != aAndPolyPolygon.count());
    1086             : 
    1087           0 :                         if(bOverlap)
    1088             :                         {
    1089             :                             // second ciriteria: is another fillstyle or color used?
    1090           0 :                             const SfxItemSet& rCompareSet = pAct->mpObj->GetMergedItemSet();
    1091             : 
    1092           0 :                             drawing::FillStyle eCompareFillStyle = ITEMVALUE(rCompareSet, XATTR_FILLSTYLE, XFillStyleItem);
    1093             : 
    1094           0 :                             if(eLocalFillStyle == eCompareFillStyle)
    1095             :                             {
    1096           0 :                                 if(eLocalFillStyle == drawing::FillStyle_SOLID)
    1097             :                                 {
    1098           0 :                                     Color aCompareColor = static_cast<const XFillColorItem&>(rCompareSet.Get(XATTR_FILLCOLOR)).GetColorValue();
    1099             : 
    1100           0 :                                     if(aCompareColor == aLocalColor)
    1101             :                                     {
    1102           0 :                                         bOverlap = false;
    1103             :                                     }
    1104             :                                 }
    1105           0 :                                 else if(eLocalFillStyle == drawing::FillStyle_NONE)
    1106             :                                 {
    1107           0 :                                     bOverlap = false;
    1108             :                                 }
    1109             :                             }
    1110             :                         }
    1111             : 
    1112           0 :                         pAct = pAct->mpNext;
    1113           0 :                     }
    1114             : 
    1115           0 :                     if(bOverlap)
    1116             :                     {
    1117             :                         // yes, start a new layer
    1118           0 :                         pLayer->mpDown = new E3dDepthLayer;
    1119           0 :                         pLayer = pLayer->mpDown;
    1120           0 :                         nNumLayers++;
    1121           0 :                         pLayer->mpNext = new E3dDepthNeighbour;
    1122           0 :                         pLayer->mpNext->mpObj = pExtrudeObj;
    1123           0 :                         pLayer->mpNext->maPreparedPolyPolygon = aExtrudePoly;
    1124             :                     }
    1125             :                     else
    1126             :                     {
    1127             :                         // no, add to current layer
    1128           0 :                         E3dDepthNeighbour* pNewNext = new E3dDepthNeighbour;
    1129           0 :                         pNewNext->mpObj = pExtrudeObj;
    1130           0 :                         pNewNext->maPreparedPolyPolygon = aExtrudePoly;
    1131           0 :                         pNewNext->mpNext = pLayer->mpNext;
    1132           0 :                         pLayer->mpNext = pNewNext;
    1133             :                     }
    1134             :                 }
    1135             :                 else
    1136             :                 {
    1137             :                     // first layer ever
    1138           0 :                     pBaseLayer = new E3dDepthLayer;
    1139           0 :                     pLayer = pBaseLayer;
    1140           0 :                     nNumLayers++;
    1141           0 :                     pLayer->mpNext = new E3dDepthNeighbour;
    1142           0 :                     pLayer->mpNext->mpObj = pExtrudeObj;
    1143           0 :                     pLayer->mpNext->maPreparedPolyPolygon = aExtrudePoly;
    1144           0 :                 }
    1145             :             }
    1146             :         }
    1147             : 
    1148             :         // number of layers is done
    1149           0 :         if(nNumLayers > 1)
    1150             :         {
    1151             :             // need to be arranged
    1152           0 :             double fMinDepth = fDepth * 0.8;
    1153           0 :             double fStep = (fDepth - fMinDepth) / (double)nNumLayers;
    1154           0 :             pLayer = pBaseLayer;
    1155             : 
    1156           0 :             while(pLayer)
    1157             :             {
    1158             :                 // move along layer
    1159           0 :                 E3dDepthNeighbour* pAct = pLayer->mpNext;
    1160             : 
    1161           0 :                 while(pAct)
    1162             :                 {
    1163             :                     // adapt extrude value
    1164           0 :                     pAct->mpObj->SetMergedItem(SfxUInt32Item(SDRATTR_3DOBJ_DEPTH, sal_uInt32(fMinDepth + 0.5)));
    1165             : 
    1166             :                     // next
    1167           0 :                     pAct = pAct->mpNext;
    1168             :                 }
    1169             : 
    1170             :                 // next layer
    1171           0 :                 pLayer = pLayer->mpDown;
    1172           0 :                 fMinDepth += fStep;
    1173             :             }
    1174             :         }
    1175             : 
    1176             :         // cleanup
    1177           0 :         while(pBaseLayer)
    1178             :         {
    1179           0 :             pLayer = pBaseLayer->mpDown;
    1180           0 :             delete pBaseLayer;
    1181           0 :             pBaseLayer = pLayer;
    1182           0 :         }
    1183             :     }
    1184           0 : }
    1185             : 
    1186             : // Start drag, create for 3D objects before possibly drag method
    1187             : 
    1188           0 : bool E3dView::BegDragObj(const Point& rPnt, OutputDevice* pOut,
    1189             :     SdrHdl* pHdl, short nMinMov,
    1190             :     SdrDragMethod* pForcedMeth)
    1191             : {
    1192           0 :     if(Is3DRotationCreationActive() && GetMarkedObjectCount())
    1193             :     {
    1194             :         // Determine all selected polygons and return the mirrored helper overlay
    1195           0 :         mpMirrorOverlay->SetMirrorAxis(aRef1, aRef2);
    1196             :     }
    1197             :     else
    1198             :     {
    1199             :         bool bOwnActionNecessary;
    1200           0 :         if (pHdl == NULL)
    1201             :         {
    1202           0 :            bOwnActionNecessary = true;
    1203             :         }
    1204           0 :         else if (pHdl->IsVertexHdl() || pHdl->IsCornerHdl())
    1205             :         {
    1206           0 :            bOwnActionNecessary = true;
    1207             :         }
    1208             :         else
    1209             :         {
    1210           0 :            bOwnActionNecessary = false;
    1211             :         }
    1212             : 
    1213           0 :         if(bOwnActionNecessary && GetMarkedObjectCount() > 0)
    1214             :         {
    1215           0 :             E3dDragConstraint eConstraint = E3DDRAG_CONSTR_XYZ;
    1216           0 :             bool bThereAreRootScenes = false;
    1217           0 :             bool bThereAre3DObjects = false;
    1218           0 :             const size_t nCnt = GetMarkedObjectCount();
    1219           0 :             for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
    1220             :             {
    1221           0 :                 SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
    1222           0 :                 if(pObj)
    1223             :                 {
    1224           0 :                     if(pObj->ISA(E3dScene) && static_cast<E3dScene*>(pObj)->GetScene() == pObj)
    1225           0 :                         bThereAreRootScenes = true;
    1226           0 :                     if(pObj->ISA(E3dObject))
    1227           0 :                         bThereAre3DObjects = true;
    1228             :                 }
    1229             :             }
    1230           0 :             if( bThereAre3DObjects )
    1231             :             {
    1232           0 :                 eDragHdl = ( pHdl == NULL ? HDL_MOVE : pHdl->GetKind() );
    1233           0 :                 switch ( eDragMode )
    1234             :                 {
    1235             :                     case SDRDRAG_ROTATE:
    1236             :                     case SDRDRAG_SHEAR:
    1237             :                     {
    1238           0 :                         switch ( eDragHdl )
    1239             :                         {
    1240             :                             case HDL_LEFT:
    1241             :                             case HDL_RIGHT:
    1242             :                             {
    1243           0 :                                 eConstraint = E3DDRAG_CONSTR_X;
    1244             :                             }
    1245           0 :                             break;
    1246             : 
    1247             :                             case HDL_UPPER:
    1248             :                             case HDL_LOWER:
    1249             :                             {
    1250           0 :                                 eConstraint = E3DDRAG_CONSTR_Y;
    1251             :                             }
    1252           0 :                             break;
    1253             : 
    1254             :                             case HDL_UPLFT:
    1255             :                             case HDL_UPRGT:
    1256             :                             case HDL_LWLFT:
    1257             :                             case HDL_LWRGT:
    1258             :                             {
    1259           0 :                                 eConstraint = E3DDRAG_CONSTR_Z;
    1260             :                             }
    1261           0 :                             break;
    1262           0 :                             default: break;
    1263             :                         }
    1264             : 
    1265             :                         // do not mask the allowed rotations
    1266           0 :                         eConstraint = E3dDragConstraint(eConstraint& eDragConstraint);
    1267           0 :                         pForcedMeth = new E3dDragRotate(*this, GetMarkedObjectList(), eConstraint, IsSolidDragging());
    1268             :                     }
    1269           0 :                     break;
    1270             : 
    1271             :                     case SDRDRAG_MOVE:
    1272             :                     {
    1273           0 :                         if(!bThereAreRootScenes)
    1274             :                         {
    1275           0 :                             pForcedMeth = new E3dDragMove(*this, GetMarkedObjectList(), eDragHdl, eConstraint, IsSolidDragging());
    1276             :                         }
    1277             :                     }
    1278           0 :                     break;
    1279             : 
    1280             :                     // later on
    1281             :                     case SDRDRAG_MIRROR:
    1282             :                     case SDRDRAG_CROOK:
    1283             :                     case SDRDRAG_DISTORT:
    1284             :                     case SDRDRAG_TRANSPARENCE:
    1285             :                     case SDRDRAG_GRADIENT:
    1286             :                     default:
    1287             :                     {
    1288             :                     }
    1289           0 :                     break;
    1290             :                 }
    1291             :             }
    1292             :         }
    1293             :     }
    1294           0 :     return SdrView::BegDragObj(rPnt, pOut, pHdl, nMinMov, pForcedMeth);
    1295             : }
    1296             : 
    1297             : // Set current 3D drawing object, create the scene for this
    1298             : 
    1299           0 : E3dScene* E3dView::SetCurrent3DObj(E3dObject* p3DObj)
    1300             : {
    1301             :     DBG_ASSERT(p3DObj != NULL, "Who puts in a NULL-pointer here");
    1302           0 :     E3dScene* pScene = NULL;
    1303             : 
    1304             :     // get transformed BoundVolume of the object
    1305           0 :     basegfx::B3DRange aVolume(p3DObj->GetBoundVolume());
    1306           0 :     aVolume.transform(p3DObj->GetTransform());
    1307           0 :     double fW(aVolume.getWidth());
    1308           0 :     double fH(aVolume.getHeight());
    1309             : 
    1310           0 :     Rectangle aRect(0,0, (long) fW, (long) fH);
    1311             : 
    1312           0 :     pScene = new E3dPolyScene(Get3DDefaultAttributes());
    1313             : 
    1314           0 :     InitScene(pScene, fW, fH, aVolume.getMaxZ() + ((fW + fH) / 4.0));
    1315             : 
    1316           0 :     pScene->Insert3DObj(p3DObj);
    1317           0 :     pScene->NbcSetSnapRect(aRect);
    1318             : 
    1319           0 :     return pScene;
    1320             : }
    1321             : 
    1322           0 : void E3dView::InitScene(E3dScene* pScene, double fW, double fH, double fCamZ)
    1323             : {
    1324           0 :     Camera3D aCam(pScene->GetCamera());
    1325             : 
    1326           0 :     aCam.SetAutoAdjustProjection(false);
    1327           0 :     aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
    1328           0 :     basegfx::B3DPoint aLookAt;
    1329             : 
    1330           0 :     double fDefaultCamPosZ = GetDefaultCamPosZ();
    1331           0 :     basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
    1332             : 
    1333           0 :     aCam.SetPosAndLookAt(aCamPos, aLookAt);
    1334           0 :     aCam.SetFocalLength(GetDefaultCamFocal());
    1335           0 :     aCam.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, GetDefaultCamFocal());
    1336           0 :     pScene->SetCamera(aCam);
    1337           0 : }
    1338             : 
    1339           0 : void E3dView::Start3DCreation()
    1340             : {
    1341           0 :     if (GetMarkedObjectCount())
    1342             :     {
    1343             :         //positioned
    1344           0 :         long          nOutMin = 0;
    1345           0 :         long          nOutMax = 0;
    1346           0 :         long          nMinLen = 0;
    1347           0 :         long          nObjDst = 0;
    1348           0 :         long          nOutHgt = 0;
    1349           0 :         OutputDevice* pOut    = GetFirstOutputDevice();
    1350             : 
    1351             :         // first determine representation boundaries
    1352           0 :         if (pOut != NULL)
    1353             :         {
    1354           0 :             nMinLen = pOut->PixelToLogic(Size(0,50)).Height();
    1355           0 :             nObjDst = pOut->PixelToLogic(Size(0,20)).Height();
    1356             : 
    1357           0 :             long nDst = pOut->PixelToLogic(Size(0,10)).Height();
    1358             : 
    1359           0 :             nOutMin =  -pOut->GetMapMode().GetOrigin().Y();
    1360           0 :             nOutMax =  pOut->GetOutputSize().Height() - 1 + nOutMin;
    1361           0 :             nOutMin += nDst;
    1362           0 :             nOutMax -= nDst;
    1363             : 
    1364           0 :             if (nOutMax - nOutMin < nDst)
    1365             :             {
    1366           0 :                 nOutMin += nOutMax + 1;
    1367           0 :                 nOutMin /= 2;
    1368           0 :                 nOutMin -= (nDst + 1) / 2;
    1369           0 :                 nOutMax  = nOutMin + nDst;
    1370             :             }
    1371             : 
    1372           0 :             nOutHgt = nOutMax - nOutMin;
    1373             : 
    1374           0 :             long nTemp = nOutHgt / 4;
    1375           0 :             if (nTemp > nMinLen) nMinLen = nTemp;
    1376             :         }
    1377             : 
    1378             :         // and then attach the marks at the top and bottom of the object
    1379           0 :         basegfx::B2DRange aR;
    1380           0 :         for(size_t nMark = 0; nMark < GetMarkedObjectCount(); ++nMark)
    1381             :         {
    1382           0 :             SdrObject* pMark = GetMarkedObjectByIndex(nMark);
    1383           0 :             basegfx::B2DPolyPolygon aXPP(pMark->TakeXorPoly());
    1384           0 :             aR.expand(basegfx::tools::getRange(aXPP));
    1385           0 :         }
    1386             : 
    1387           0 :         basegfx::B2DPoint aCenter(aR.getCenter());
    1388           0 :         long      nMarkHgt = basegfx::fround(aR.getHeight()) - 1;
    1389           0 :         long      nHgt     = nMarkHgt + nObjDst * 2;
    1390             : 
    1391           0 :         if (nHgt < nMinLen) nHgt = nMinLen;
    1392             : 
    1393           0 :         long nY1 = basegfx::fround(aCenter.getY()) - (nHgt + 1) / 2;
    1394           0 :         long nY2 = nY1 + nHgt;
    1395             : 
    1396           0 :         if (pOut && (nMinLen > nOutHgt)) nMinLen = nOutHgt;
    1397           0 :         if (pOut)
    1398             :         {
    1399           0 :             if (nY1 < nOutMin)
    1400             :             {
    1401           0 :                 nY1 = nOutMin;
    1402           0 :                 if (nY2 < nY1 + nMinLen) nY2 = nY1 + nMinLen;
    1403             :             }
    1404           0 :             if (nY2 > nOutMax)
    1405             :             {
    1406           0 :                 nY2 = nOutMax;
    1407           0 :                 if (nY1 > nY2 - nMinLen) nY1 = nY2 - nMinLen;
    1408             :             }
    1409             :         }
    1410             : 
    1411           0 :         aRef1.X() = basegfx::fround(aR.getMinX());    // Initial move axis 2/100mm to the left
    1412           0 :         aRef1.Y() = nY1;
    1413           0 :         aRef2.X() = aRef1.X();
    1414           0 :         aRef2.Y() = nY2;
    1415             : 
    1416             :         // Turn on marks
    1417           0 :         SetMarkHandles();
    1418             : 
    1419             :         //HMHif (bVis) ShowMarkHdl();
    1420           0 :         if (AreObjectsMarked()) MarkListHasChanged();
    1421             : 
    1422             :         // Show mirror polygon IMMEDIATELY
    1423           0 :         const SdrHdlList &aHdlList = GetHdlList();
    1424           0 :         mpMirrorOverlay = new Impl3DMirrorConstructOverlay(*this);
    1425           0 :         mpMirrorOverlay->SetMirrorAxis(aHdlList.GetHdl(HDL_REF1)->GetPos(), aHdlList.GetHdl(HDL_REF2)->GetPos());
    1426             :     }
    1427           0 : }
    1428             : 
    1429             : // what happens with a mouse movement when the object is created?
    1430             : 
    1431           0 : void E3dView::MovAction(const Point& rPnt)
    1432             : {
    1433           0 :     if(Is3DRotationCreationActive())
    1434             :     {
    1435           0 :         SdrHdl* pHdl = GetDragHdl();
    1436             : 
    1437           0 :         if (pHdl)
    1438             :         {
    1439           0 :             SdrHdlKind eHdlKind = pHdl->GetKind();
    1440             : 
    1441             :             // reacts only due to a mirror axis
    1442           0 :             if ((eHdlKind == HDL_REF1) ||
    1443           0 :                 (eHdlKind == HDL_REF2) ||
    1444             :                 (eHdlKind == HDL_MIRX))
    1445             :             {
    1446           0 :                 const SdrHdlList &aHdlList = GetHdlList ();
    1447             : 
    1448             :                 // delete the mirroed polygon, mirrors the original and draws
    1449             :                 // it anew
    1450           0 :                 SdrView::MovAction (rPnt);
    1451             :                 mpMirrorOverlay->SetMirrorAxis(
    1452           0 :                     aHdlList.GetHdl (HDL_REF1)->GetPos(),
    1453           0 :                     aHdlList.GetHdl (HDL_REF2)->GetPos());
    1454             :             }
    1455             :         }
    1456             :         else
    1457             :         {
    1458           0 :             SdrView::MovAction (rPnt);
    1459             :         }
    1460             :     }
    1461             :     else
    1462             :     {
    1463           0 :         SdrView::MovAction (rPnt);
    1464             :     }
    1465           0 : }
    1466             : 
    1467             : // The End. Create object and any child objects through ImpCreate3DLathe.
    1468             : // With the parameter value sal_True (SDefault: sal_False) is simply a
    1469             : // rotation body  created, without letting the user set the position of the
    1470             : // axis. It is sufficient with this call, if an object is selected.
    1471             : // (No initialization necessary)
    1472             : 
    1473           0 : void E3dView::End3DCreation(bool bUseDefaultValuesForMirrorAxes)
    1474             : {
    1475           0 :     ResetCreationActive();
    1476             : 
    1477           0 :     if(AreObjectsMarked())
    1478             :     {
    1479           0 :         if(bUseDefaultValuesForMirrorAxes)
    1480             :         {
    1481           0 :             Rectangle aRect = GetAllMarkedRect();
    1482           0 :             if(aRect.GetWidth() <= 1)
    1483           0 :                 aRect.SetSize(Size(500, aRect.GetHeight()));
    1484           0 :             if(aRect.GetHeight() <= 1)
    1485           0 :                 aRect.SetSize(Size(aRect.GetWidth(), 500));
    1486             : 
    1487           0 :             basegfx::B2DPoint aPnt1(aRect.Left(), -aRect.Top());
    1488           0 :             basegfx::B2DPoint aPnt2(aRect.Left(), -aRect.Bottom());
    1489             : 
    1490           0 :             ConvertMarkedObjTo3D(false, aPnt1, aPnt2);
    1491             :         }
    1492             :         else
    1493             :         {
    1494             :             // Turn off helper overlay
    1495             :             // Determine from the handle positions and the displacement of
    1496             :             // the points
    1497           0 :             const SdrHdlList &aHdlList = GetHdlList();
    1498           0 :             Point aMirrorRef1 = aHdlList.GetHdl(HDL_REF1)->GetPos();
    1499           0 :             Point aMirrorRef2 = aHdlList.GetHdl(HDL_REF2)->GetPos();
    1500             : 
    1501           0 :             basegfx::B2DPoint aPnt1(aMirrorRef1.X(), -aMirrorRef1.Y());
    1502           0 :             basegfx::B2DPoint aPnt2(aMirrorRef2.X(), -aMirrorRef2.Y());
    1503             : 
    1504           0 :             ConvertMarkedObjTo3D(false, aPnt1, aPnt2);
    1505             :         }
    1506             :     }
    1507           0 : }
    1508             : 
    1509        7492 : E3dView::~E3dView ()
    1510             : {
    1511        7492 : }
    1512             : 
    1513         762 : void E3dView::ResetCreationActive ()
    1514             : {
    1515         762 :     if(mpMirrorOverlay)
    1516             :     {
    1517           0 :         delete mpMirrorOverlay;
    1518           0 :         mpMirrorOverlay = 0L;
    1519             :     }
    1520         762 : }
    1521             : 
    1522        7010 : void E3dView::InitView ()
    1523             : {
    1524        7010 :     eDragConstraint          = E3DDRAG_CONSTR_XYZ;
    1525             :     fDefaultScaleX           =
    1526             :     fDefaultScaleY           =
    1527        7010 :     fDefaultScaleZ           = 1.0;
    1528             :     fDefaultRotateX          =
    1529             :     fDefaultRotateY          =
    1530        7010 :     fDefaultRotateZ          = 0.0;
    1531        7010 :     fDefaultExtrusionDeepth  = 1000; // old: 2000;
    1532        7010 :     fDefaultLightIntensity   = 0.8; // old: 0.6;
    1533        7010 :     fDefaultAmbientIntensity = 0.4;
    1534        7010 :     nHDefaultSegments        = 12;
    1535        7010 :     nVDefaultSegments        = 12;
    1536        7010 :     aDefaultLightColor       = RGB_Color(COL_WHITE);
    1537        7010 :     aDefaultAmbientColor     = RGB_Color(COL_BLACK);
    1538        7010 :     bDoubleSided             = false;
    1539        7010 :     mpMirrorOverlay          = 0L;
    1540        7010 : }
    1541             : 
    1542           0 : bool E3dView::IsBreak3DObjPossible() const
    1543             : {
    1544           0 :     const size_t nCount = GetMarkedObjectCount();
    1545             : 
    1546           0 :     if (nCount > 0)
    1547             :     {
    1548           0 :         for (size_t i = 0; i < nCount; ++i)
    1549             :         {
    1550           0 :             SdrObject* pObj = GetMarkedObjectByIndex(i);
    1551             : 
    1552           0 :             if (pObj && pObj->ISA(E3dObject))
    1553             :             {
    1554           0 :                 if(!(static_cast<E3dObject*>(pObj)->IsBreakObjPossible()))
    1555           0 :                     return false;
    1556             :             }
    1557             :             else
    1558             :             {
    1559           0 :                 return false;
    1560             :             }
    1561             :         }
    1562             :     }
    1563             :     else
    1564             :     {
    1565           0 :         return false;
    1566             :     }
    1567             : 
    1568           0 :     return true;
    1569             : }
    1570             : 
    1571           0 : void E3dView::Break3DObj()
    1572             : {
    1573           0 :     if(IsBreak3DObjPossible())
    1574             :     {
    1575             :         // ALL selected objects are changed
    1576           0 :         const size_t nCount = GetMarkedObjectCount();
    1577             : 
    1578           0 :         BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_BREAK_LATHE));
    1579           0 :         for(size_t a=0; a<nCount; ++a)
    1580             :         {
    1581           0 :             E3dObject* pObj = static_cast<E3dObject*>(GetMarkedObjectByIndex(a));
    1582           0 :             BreakSingle3DObj(pObj);
    1583             :         }
    1584           0 :         DeleteMarked();
    1585           0 :         EndUndo();
    1586             :     }
    1587           0 : }
    1588             : 
    1589           0 : void E3dView::BreakSingle3DObj(E3dObject* pObj)
    1590             : {
    1591           0 :     if(pObj->ISA(E3dScene))
    1592             :     {
    1593           0 :         SdrObjList* pSubList = pObj->GetSubList();
    1594           0 :         SdrObjListIter aIter(*pSubList, IM_FLAT);
    1595             : 
    1596           0 :         while(aIter.IsMore())
    1597             :         {
    1598           0 :             E3dObject* pSubObj = static_cast<E3dObject*>(aIter.Next());
    1599           0 :             BreakSingle3DObj(pSubObj);
    1600           0 :         }
    1601             :     }
    1602             :     else
    1603             :     {
    1604           0 :         SdrAttrObj* pNewObj = pObj->GetBreakObj();
    1605           0 :         if(pNewObj)
    1606             :         {
    1607           0 :             InsertObjectAtView(pNewObj, *GetSdrPageView(), SDRINSERT_DONTMARK);
    1608           0 :             pNewObj->SetChanged();
    1609           0 :             pNewObj->BroadcastObjectChange();
    1610             :         }
    1611             :     }
    1612           0 : }
    1613             : 
    1614        3892 : void E3dView::CheckPossibilities()
    1615             : {
    1616             :     // call parent
    1617        3892 :     SdrView::CheckPossibilities();
    1618             : 
    1619             :     // Set other flags
    1620        3892 :     if(bGroupPossible || bUnGroupPossible || bGrpEnterPossible)
    1621             :     {
    1622           0 :         const size_t nMarkCnt = GetMarkedObjectCount();
    1623           0 :         bool bCoumpound = false;
    1624           0 :         bool b3DObject = false;
    1625           0 :         for(size_t nObjs = 0; (nObjs < nMarkCnt) && !bCoumpound; ++nObjs)
    1626             :         {
    1627           0 :             SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
    1628           0 :             if(pObj && pObj->ISA(E3dCompoundObject))
    1629           0 :                 bCoumpound = true;
    1630           0 :             if(pObj && pObj->ISA(E3dObject))
    1631           0 :                 b3DObject = true;
    1632             :         }
    1633             : 
    1634             :         // So far: there are two or more of any objects selected. See if
    1635             :         // compound objects are involved. If yes, ban grouping.
    1636           0 :         if(bGroupPossible && bCoumpound)
    1637           0 :             bGroupPossible = false;
    1638             : 
    1639           0 :         if(bUnGroupPossible && b3DObject)
    1640           0 :             bUnGroupPossible = false;
    1641             : 
    1642           0 :         if(bGrpEnterPossible && bCoumpound)
    1643           0 :             bGrpEnterPossible = false;
    1644             :     }
    1645        4543 : }
    1646             : 
    1647             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10