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

Generated by: LCOV version 1.10