LCOV - code coverage report
Current view: top level - svx/source/engine3d - obj3d.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 128 431 29.7 %
Date: 2015-06-13 12:38:46 Functions: 34 82 41.5 %
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             : #include <o3tl/numeric.hxx>
      21             : 
      22             : #include "svx/svdstr.hrc"
      23             : #include "svdglob.hxx"
      24             : #include <svx/svdview.hxx>
      25             : #include <svx/svdattr.hxx>
      26             : #include <svx/svdpage.hxx>
      27             : #include <svx/svdmodel.hxx>
      28             : #include "svx/svditer.hxx"
      29             : #include "svx/globl3d.hxx"
      30             : #include <svx/camera3d.hxx>
      31             : #include <svx/scene3d.hxx>
      32             : #include <svx/polysc3d.hxx>
      33             : #include <svx/cube3d.hxx>
      34             : #include <svx/lathe3d.hxx>
      35             : #include <svx/sphere3d.hxx>
      36             : #include <svx/extrud3d.hxx>
      37             : #include <svx/obj3d.hxx>
      38             : #include <svx/xtable.hxx>
      39             : #include <svx/xflclit.hxx>
      40             : #include <vcl/svapp.hxx>
      41             : #include <vcl/settings.hxx>
      42             : #include <svx/xlnclit.hxx>
      43             : #include <svl/metitem.hxx>
      44             : #include <svx/xfillit.hxx>
      45             : #include <svx/xlnwtit.hxx>
      46             : #include <vcl/virdev.hxx>
      47             : #include <tools/poly.hxx>
      48             : #include <tools/b3dtrans.hxx>
      49             : #include <svx/svxids.hrc>
      50             : #include <editeng/colritem.hxx>
      51             : #include <svx/e3ditem.hxx>
      52             : #include <svx/xlntrit.hxx>
      53             : #include <svx/xfltrit.hxx>
      54             : #include <svx/svdpagv.hxx>
      55             : #include <vcl/gradient.hxx>
      56             : #include <vcl/metaact.hxx>
      57             : #include <svx/svx3ditems.hxx>
      58             : #include <svl/whiter.hxx>
      59             : #include <svtools/colorcfg.hxx>
      60             : #include <editeng/eeitem.hxx>
      61             : #include <svx/xgrscit.hxx>
      62             : #include <sdr/properties/e3dproperties.hxx>
      63             : #include <sdr/properties/e3dcompoundproperties.hxx>
      64             : #include <basegfx/polygon/b3dpolypolygontools.hxx>
      65             : #include <basegfx/point/b3dpoint.hxx>
      66             : #include <basegfx/vector/b3dvector.hxx>
      67             : #include <svx/xlndsit.hxx>
      68             : #include <basegfx/matrix/b3dhommatrix.hxx>
      69             : #include <basegfx/polygon/b3dpolygon.hxx>
      70             : #include <basegfx/matrix/b2dhommatrix.hxx>
      71             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      72             : #include <basegfx/polygon/b3dpolygontools.hxx>
      73             : #include <svx/helperhittest3d.hxx>
      74             : #include <svx/sdr/contact/viewcontactofe3d.hxx>
      75             : #include <drawinglayer/geometry/viewinformation3d.hxx>
      76             : #include <com/sun/star/uno/Sequence.h>
      77             : #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
      78             : #include <svx/e3dsceneupdater.hxx>
      79             : 
      80             : 
      81             : 
      82             : using namespace com::sun::star;
      83             : 
      84             : 
      85             : // List for 3D-Objects
      86             : 
      87       18336 : TYPEINIT1(E3dObjList, SdrObjList);
      88             : 
      89        6167 : E3dObjList::E3dObjList(SdrModel* pNewModel, SdrPage* pNewPage, E3dObjList* pNewUpList)
      90        6167 : :   SdrObjList(pNewModel, pNewPage, pNewUpList)
      91             : {
      92        6167 : }
      93             : 
      94           0 : E3dObjList::E3dObjList(const E3dObjList&)
      95           0 : :   SdrObjList()
      96             : {
      97           0 : }
      98             : 
      99           0 : E3dObjList* E3dObjList::Clone() const
     100             : {
     101           0 :     E3dObjList* const pObjList = new E3dObjList(*this);
     102           0 :     pObjList->lateInit(*this);
     103           0 :     return pObjList;
     104             : }
     105             : 
     106        6167 : E3dObjList::~E3dObjList()
     107             : {
     108        6167 : }
     109             : 
     110        6112 : void E3dObjList::NbcInsertObject(SdrObject* pObj, size_t nPos, const SdrInsertReason* pReason)
     111             : {
     112             :     // Get owner
     113             :     DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "Insert 3D object in parent != 3DObject");
     114             : 
     115             :     // Is it even a 3D object?
     116        6112 :     if(pObj && pObj->ISA(E3dObject))
     117             :     {
     118             :         // Normal 3D object, insert means
     119             :         // call parent
     120        6112 :         SdrObjList::NbcInsertObject(pObj, nPos, pReason);
     121             :     }
     122             :     else
     123             :     {
     124             :         // No 3D object, inserted a page in place in a scene ...
     125           0 :         GetOwnerObj()->GetPage()->InsertObject(pObj, nPos);
     126             :     }
     127        6112 : }
     128             : 
     129           0 : void E3dObjList::InsertObject(SdrObject* pObj, size_t nPos, const SdrInsertReason* pReason)
     130             : {
     131             :     OSL_ENSURE(GetOwnerObj()->ISA(E3dObject), "Insert 3D object in non-3D Parent");
     132             : 
     133             :     // call parent
     134           0 :     SdrObjList::InsertObject(pObj, nPos, pReason);
     135             : 
     136           0 :     E3dScene* pScene = static_cast<E3dObject*>(GetOwnerObj())->GetScene();
     137           0 :     if(pScene)
     138             :     {
     139           0 :         pScene->Cleanup3DDepthMapper();
     140             :     }
     141           0 : }
     142             : 
     143        4131 : SdrObject* E3dObjList::NbcRemoveObject(size_t nObjNum)
     144             : {
     145             :     DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "Remove 3D object from Parent != 3DObject");
     146             : 
     147             :     // call parent
     148        4131 :     SdrObject* pRetval = SdrObjList::NbcRemoveObject(nObjNum);
     149             : 
     150        4131 :     E3dScene* pScene = static_cast<E3dObject*>(GetOwnerObj())->GetScene();
     151        4131 :     if(pScene)
     152             :     {
     153        4131 :         pScene->Cleanup3DDepthMapper();
     154             :     }
     155             : 
     156        4131 :     return pRetval;
     157             : }
     158             : 
     159           0 : SdrObject* E3dObjList::RemoveObject(size_t nObjNum)
     160             : {
     161             :     OSL_ENSURE(GetOwnerObj()->ISA(E3dObject), "3D object is removed from non-3D Parent");
     162             : 
     163             :     // call parent
     164           0 :     SdrObject* pRetval = SdrObjList::RemoveObject(nObjNum);
     165             : 
     166           0 :     E3dScene* pScene = static_cast<E3dObject*>(GetOwnerObj())->GetScene();
     167           0 :     if(pScene)
     168             :     {
     169           0 :         pScene->Cleanup3DDepthMapper();
     170             :     }
     171             : 
     172           0 :     return pRetval;
     173             : }
     174             : 
     175             : 
     176             : 
     177           0 : sdr::properties::BaseProperties* E3dObject::CreateObjectSpecificProperties()
     178             : {
     179           0 :     return new sdr::properties::E3dProperties(*this);
     180             : }
     181             : 
     182             : 
     183             : 
     184    26917777 : TYPEINIT1(E3dObject, SdrAttrObj);
     185             : 
     186        6167 : E3dObject::E3dObject()
     187             : :   maSubList(),
     188             :     maLocalBoundVol(),
     189             :     maTransformation(),
     190             :     maFullTransform(),
     191             :     mbTfHasChanged(true),
     192        6167 :     mbIsSelected(false)
     193             : {
     194        6167 :     bIs3DObj = true;
     195        6167 :     maSubList.SetOwnerObj(this);
     196        6167 :     maSubList.SetListKind(SDROBJLIST_GROUPOBJ);
     197        6167 :     bClosedObj = true;
     198        6167 : }
     199             : 
     200        6167 : E3dObject::~E3dObject()
     201             : {
     202        6167 : }
     203             : 
     204           0 : void E3dObject::SetSelected(bool bNew)
     205             : {
     206           0 :     if((bool)mbIsSelected != bNew)
     207             :     {
     208           0 :         mbIsSelected = bNew;
     209             :     }
     210             : 
     211           0 :     for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
     212             :     {
     213           0 :         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
     214             : 
     215           0 :         if(pCandidate)
     216             :         {
     217           0 :             pCandidate->SetSelected(bNew);
     218             :         }
     219             :     }
     220           0 : }
     221             : 
     222             : // Break, default implementations
     223             : 
     224           0 : bool E3dObject::IsBreakObjPossible()
     225             : {
     226           0 :     return false;
     227             : }
     228             : 
     229           0 : SdrAttrObj* E3dObject::GetBreakObj()
     230             : {
     231           0 :     return 0L;
     232             : }
     233             : 
     234             : // SetRectsDirty must be done through the local SdrSubList
     235             : 
     236     2110192 : void E3dObject::SetRectsDirty(bool bNotMyself)
     237             : {
     238             :     // call parent
     239     2110192 :     SdrAttrObj::SetRectsDirty(bNotMyself);
     240             : 
     241     4077745 :     for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
     242             :     {
     243     1967553 :         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
     244             : 
     245     1967553 :         if(pCandidate)
     246             :         {
     247     1967553 :             pCandidate->SetRectsDirty(bNotMyself);
     248             :         }
     249             :     }
     250     2110192 : }
     251             : 
     252       24623 : sal_uInt32 E3dObject::GetObjInventor() const
     253             : {
     254       24623 :     return E3dInventor;
     255             : }
     256             : 
     257           0 : sal_uInt16 E3dObject::GetObjIdentifier() const
     258             : {
     259           0 :     return E3D_OBJECT_ID;
     260             : }
     261             : 
     262             : // Determine the capabilities of the object
     263             : 
     264           0 : void E3dObject::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
     265             : {
     266           0 :     rInfo.bResizeFreeAllowed    = true;
     267           0 :     rInfo.bResizePropAllowed    = true;
     268           0 :     rInfo.bRotateFreeAllowed    = true;
     269           0 :     rInfo.bRotate90Allowed      = true;
     270           0 :     rInfo.bMirrorFreeAllowed    = false;
     271           0 :     rInfo.bMirror45Allowed      = false;
     272           0 :     rInfo.bMirror90Allowed      = false;
     273           0 :     rInfo.bShearAllowed         = false;
     274           0 :     rInfo.bEdgeRadiusAllowed    = false;
     275           0 :     rInfo.bCanConvToPath        = false;
     276             : 
     277             :     // no transparence for 3d objects
     278           0 :     rInfo.bTransparenceAllowed = false;
     279             : 
     280             :     // gradient depends on fillstyle
     281             :     // BM *** check if SetItem is NULL ***
     282           0 :     drawing::FillStyle eFillStyle = static_cast<const XFillStyleItem&>(GetMergedItem(XATTR_FILLSTYLE)).GetValue();
     283           0 :     rInfo.bGradientAllowed = (eFillStyle == drawing::FillStyle_GRADIENT);
     284             : 
     285             :     // Convert 3D objects in a group of polygons:
     286             :     // At first not only possible, because the creation of a group of
     287             :     // 2D polygons would be required which need to be sorted by depth,
     288             :     // ie at intersections be cut relative to each other. Also the texture
     289             :     // coorinates were an unsolved problem.
     290           0 :     rInfo.bCanConvToPoly = false;
     291           0 :     rInfo.bCanConvToContour = false;
     292           0 :     rInfo.bCanConvToPathLineToArea = false;
     293           0 :     rInfo.bCanConvToPolyLineToArea = false;
     294           0 : }
     295             : 
     296           0 : void E3dObject::NbcSetLayer(SdrLayerID nLayer)
     297             : {
     298           0 :     SdrAttrObj::NbcSetLayer(nLayer);
     299             : 
     300           0 :     for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
     301             :     {
     302           0 :         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
     303             : 
     304           0 :         if(pCandidate)
     305             :         {
     306           0 :             pCandidate->NbcSetLayer(nLayer);
     307             :         }
     308             :     }
     309           0 : }
     310             : 
     311             : // Set ObjList also on SubList
     312             : 
     313       10298 : void E3dObject::SetObjList(SdrObjList* pNewObjList)
     314             : {
     315       10298 :     SdrObject::SetObjList(pNewObjList);
     316       10298 :     maSubList.SetUpList(pNewObjList);
     317       10298 : }
     318             : 
     319       17176 : void E3dObject::SetPage(SdrPage* pNewPage)
     320             : {
     321       17176 :     SdrAttrObj::SetPage(pNewPage);
     322       17176 :     maSubList.SetPage(pNewPage);
     323       17176 : }
     324             : 
     325        6222 : void E3dObject::SetModel(SdrModel* pNewModel)
     326             : {
     327        6222 :     SdrAttrObj::SetModel(pNewModel);
     328        6222 :     maSubList.SetModel(pNewModel);
     329        6222 : }
     330             : 
     331             : // resize object, used from old 2d interfaces, e.g. in Move/Scale dialog (F4)
     332             : 
     333           0 : void E3dObject::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
     334             : {
     335             :     // Movement in X, Y in the eye coordinate system
     336           0 :     E3dScene* pScene = GetScene();
     337             : 
     338           0 :     if(pScene)
     339             :     {
     340             :         // transform pos from 2D world to 3D eye
     341           0 :         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
     342           0 :         const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
     343           0 :         basegfx::B2DPoint aScaleCenter2D((double)rRef.X(), (double)rRef.Y());
     344           0 :         basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());
     345             : 
     346           0 :         aInverseSceneTransform.invert();
     347           0 :         aScaleCenter2D = aInverseSceneTransform * aScaleCenter2D;
     348             : 
     349           0 :         basegfx::B3DPoint aScaleCenter3D(aScaleCenter2D.getX(), aScaleCenter2D.getY(), 0.5);
     350           0 :         basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
     351             : 
     352           0 :         aInverseViewToEye.invert();
     353           0 :         aScaleCenter3D = aInverseViewToEye * aScaleCenter3D;
     354             : 
     355             :         // Get scale factors
     356           0 :         double fScaleX(xFact);
     357           0 :         double fScaleY(yFact);
     358             : 
     359             :         // build transform
     360           0 :         basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
     361           0 :         aInverseOrientation.invert();
     362           0 :         basegfx::B3DHomMatrix mFullTransform(GetFullTransform());
     363           0 :         basegfx::B3DHomMatrix mTrans(mFullTransform);
     364             : 
     365           0 :         mTrans *= aViewInfo3D.getOrientation();
     366           0 :         mTrans.translate(-aScaleCenter3D.getX(), -aScaleCenter3D.getY(), -aScaleCenter3D.getZ());
     367           0 :         mTrans.scale(fScaleX, fScaleY, 1.0);
     368           0 :         mTrans.translate(aScaleCenter3D.getX(), aScaleCenter3D.getY(), aScaleCenter3D.getZ());
     369           0 :         mTrans *= aInverseOrientation;
     370           0 :         mFullTransform.invert();
     371           0 :         mTrans *= mFullTransform;
     372             : 
     373             :         // Apply
     374           0 :         basegfx::B3DHomMatrix mObjTrans(GetTransform());
     375           0 :         mObjTrans *= mTrans;
     376             : 
     377           0 :         E3DModifySceneSnapRectUpdater aUpdater(this);
     378           0 :         SetTransform(mObjTrans);
     379             :     }
     380           0 : }
     381             : 
     382             : 
     383             : // Move object in 2D is needed when using cursor keys
     384             : 
     385           0 : void E3dObject::NbcMove(const Size& rSize)
     386             : {
     387             :     // Movement in X, Y in the eye coordinate system
     388           0 :     E3dScene* pScene = GetScene();
     389             : 
     390           0 :     if(pScene)
     391             :     {
     392             :         //Dimensions of the scene in 3D and 2D for comparison
     393           0 :         Rectangle aRect = pScene->GetSnapRect();
     394             : 
     395           0 :         basegfx::B3DHomMatrix mInvDispTransform;
     396           0 :         if(GetParentObj())
     397             :         {
     398           0 :             mInvDispTransform = GetParentObj()->GetFullTransform();
     399           0 :             mInvDispTransform.invert();
     400             :         }
     401             : 
     402             :         // BoundVolume from 3d world to 3d eye
     403           0 :         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
     404           0 :         const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
     405           0 :         basegfx::B3DRange aEyeVol(pScene->GetBoundVolume());
     406           0 :         aEyeVol.transform(aViewInfo3D.getOrientation());
     407             : 
     408           0 :         if ((aRect.GetWidth() == 0) || (aRect.GetHeight() == 0))
     409           0 :             throw o3tl::divide_by_zero();
     410             : 
     411             :         // build relative movement vector in eye coordinates
     412             :         basegfx::B3DPoint aMove(
     413           0 :             (double)rSize.Width() * aEyeVol.getWidth() / (double)aRect.GetWidth(),
     414           0 :             (double)-rSize.Height() * aEyeVol.getHeight() / (double)aRect.GetHeight(),
     415           0 :             0.0);
     416           0 :         basegfx::B3DPoint aPos(0.0, 0.0, 0.0);
     417             : 
     418             :         // movement vector to local coordinates of objects' parent
     419           0 :         basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
     420           0 :         aInverseOrientation.invert();
     421           0 :         basegfx::B3DHomMatrix aCompleteTrans(mInvDispTransform * aInverseOrientation);
     422             : 
     423           0 :         aMove = aCompleteTrans * aMove;
     424           0 :         aPos = aCompleteTrans * aPos;
     425             : 
     426             :         // build transformation and apply
     427           0 :         basegfx::B3DHomMatrix aTranslate;
     428           0 :         aTranslate.translate(aMove.getX() - aPos.getX(), aMove.getY() - aPos.getY(), aMove.getZ() - aPos.getZ());
     429             : 
     430           0 :         E3DModifySceneSnapRectUpdater aUpdater(pScene);
     431           0 :         SetTransform(aTranslate * GetTransform());
     432             :     }
     433           0 : }
     434             : 
     435             : // Return the sublist, but only if it contains objects!
     436             : 
     437      118146 : SdrObjList* E3dObject::GetSubList() const
     438             : {
     439      118146 :     return &(const_cast< E3dObjList& >(maSubList));
     440             : }
     441             : 
     442        1218 : void E3dObject::RecalcSnapRect()
     443             : {
     444        1218 :     maSnapRect = Rectangle();
     445             : 
     446        1218 :     for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
     447             :     {
     448           0 :         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
     449             : 
     450           0 :         if(pCandidate)
     451             :         {
     452           0 :             maSnapRect.Union(pCandidate->GetSnapRect());
     453             :         }
     454             :     }
     455        1218 : }
     456             : 
     457             : // Inform the parent about insertion of a 3D object, so that the parent is able
     458             : // treat the particualar objects in a special way (eg Light / Label in E3dScene)
     459             : 
     460           0 : void E3dObject::NewObjectInserted(const E3dObject* p3DObj)
     461             : {
     462           0 :     if(GetParentObj())
     463           0 :         GetParentObj()->NewObjectInserted(p3DObj);
     464           0 : }
     465             : 
     466             : // Inform parent of changes in the structure (eg by transformation), in this
     467             : // process the object in which the change has occurred is returned.
     468             : 
     469      133620 : void E3dObject::StructureChanged()
     470             : {
     471      133620 :     if ( GetParentObj() )
     472             :     {
     473       79004 :         GetParentObj()->InvalidateBoundVolume();
     474       79004 :         GetParentObj()->StructureChanged();
     475             :     }
     476      133620 : }
     477             : 
     478           0 : void E3dObject::Insert3DObj(E3dObject* p3DObj)
     479             : {
     480             :     DBG_ASSERT(p3DObj, "Insert3DObj with NULL-pointer!");
     481           0 :     SdrPage* pPg = pPage;
     482           0 :     maSubList.InsertObject(p3DObj);
     483           0 :     pPage = pPg;
     484           0 :     InvalidateBoundVolume();
     485           0 :     NewObjectInserted(p3DObj);
     486           0 :     StructureChanged();
     487           0 : }
     488             : 
     489           0 : void E3dObject::Remove3DObj(E3dObject* p3DObj)
     490             : {
     491             :     DBG_ASSERT(p3DObj, "Remove3DObj with NULL-pointer!");
     492             : 
     493           0 :     if(p3DObj->GetParentObj() == this)
     494             :     {
     495           0 :         SdrPage* pPg = pPage;
     496           0 :         maSubList.RemoveObject(p3DObj->GetOrdNum());
     497           0 :         pPage = pPg;
     498             : 
     499           0 :         InvalidateBoundVolume();
     500           0 :         StructureChanged();
     501             :     }
     502           0 : }
     503             : 
     504     9758235 : E3dObject* E3dObject::GetParentObj() const
     505             : {
     506     9758235 :     E3dObject* pRetval = NULL;
     507             : 
     508    19516470 :     if(GetObjList()
     509     9748723 :         && GetObjList()->GetOwnerObj()
     510    19506958 :         && GetObjList()->GetOwnerObj()->ISA(E3dObject))
     511     8435211 :         pRetval = static_cast<E3dObject*>(GetObjList()->GetOwnerObj());
     512     9758235 :     return pRetval;
     513             : }
     514             : 
     515             : // Determine the top-level scene object
     516             : 
     517       49676 : E3dScene* E3dObject::GetScene() const
     518             : {
     519       49676 :     if(GetParentObj())
     520       49676 :         return GetParentObj()->GetScene();
     521           0 :     return NULL;
     522             : }
     523             : 
     524             : // Calculate enclosed volume, including all child objects
     525             : 
     526           0 : basegfx::B3DRange E3dObject::RecalcBoundVolume() const
     527             : {
     528           0 :     basegfx::B3DRange aRetval;
     529           0 :     const size_t nObjCnt(maSubList.GetObjCount());
     530             : 
     531           0 :     if(nObjCnt)
     532             :     {
     533           0 :         for(size_t a = 0; a < nObjCnt; ++a)
     534             :         {
     535           0 :             const E3dObject* p3DObject = dynamic_cast< const E3dObject* >(maSubList.GetObj(a));
     536             : 
     537           0 :             if(p3DObject)
     538             :             {
     539           0 :                 basegfx::B3DRange aLocalRange(p3DObject->GetBoundVolume());
     540           0 :                 aLocalRange.transform(p3DObject->GetTransform());
     541           0 :                 aRetval.expand(aLocalRange);
     542             :             }
     543             :         }
     544             :     }
     545             :     else
     546             :     {
     547             :         // single 3D object
     548           0 :         const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
     549             : 
     550           0 :         if(pVCOfE3D)
     551             :         {
     552             :             // BoundVolume is without 3D object transformation, use correct sequence
     553           0 :             const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getVIP3DSWithoutObjectTransform());
     554             : 
     555           0 :             if(xLocalSequence.hasElements())
     556             :             {
     557           0 :                 const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     558           0 :                 const drawinglayer::geometry::ViewInformation3D aLocalViewInformation3D(aEmptyParameters);
     559             : 
     560             :                 aRetval = drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
     561           0 :                     xLocalSequence, aLocalViewInformation3D);
     562           0 :             }
     563             :         }
     564             :     }
     565             : 
     566           0 :     return aRetval;
     567             : }
     568             : 
     569             : // Get enclosed volume and possibly recalculate it
     570             : 
     571           0 : const basegfx::B3DRange& E3dObject::GetBoundVolume() const
     572             : {
     573           0 :     if(maLocalBoundVol.isEmpty())
     574             :     {
     575           0 :         const_cast< E3dObject* >(this)->maLocalBoundVol = RecalcBoundVolume();
     576             :     }
     577             : 
     578           0 :     return maLocalBoundVol;
     579             : }
     580             : 
     581       85614 : void E3dObject::InvalidateBoundVolume()
     582             : {
     583       85614 :     maLocalBoundVol.reset();
     584       85614 : }
     585             : 
     586             : // Pass on the changes of the BoundVolumes to all child objects
     587             : 
     588           0 : void E3dObject::SetBoundVolInvalid()
     589             : {
     590           0 :     InvalidateBoundVolume();
     591             : 
     592           0 :     for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
     593             :     {
     594           0 :         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
     595             : 
     596           0 :         if(pCandidate)
     597             :         {
     598           0 :             pCandidate->SetBoundVolInvalid();
     599             :         }
     600             :     }
     601           0 : }
     602             : 
     603             : // Pass on the changes in transformation to all child objects
     604             : 
     605        6346 : void E3dObject::SetTransformChanged()
     606             : {
     607        6346 :     InvalidateBoundVolume();
     608        6346 :     mbTfHasChanged = true;
     609             : 
     610        8064 :     for(size_t a = 0; a < maSubList.GetObjCount(); ++a)
     611             :     {
     612        1718 :         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
     613             : 
     614        1718 :         if(pCandidate)
     615             :         {
     616        1718 :             pCandidate->SetTransformChanged();
     617             :         }
     618             :     }
     619        6346 : }
     620             : 
     621             : // Define the hierarchical transformation over all Parents, store in
     622             : // maFullTransform and return them
     623             : 
     624           0 : const basegfx::B3DHomMatrix& E3dObject::GetFullTransform() const
     625             : {
     626           0 :     if(mbTfHasChanged)
     627             :     {
     628           0 :         basegfx::B3DHomMatrix aNewFullTransformation(maTransformation);
     629             : 
     630           0 :         if ( GetParentObj() )
     631             :         {
     632           0 :             aNewFullTransformation = GetParentObj()->GetFullTransform() * aNewFullTransformation;
     633             :         }
     634             : 
     635           0 :         const_cast< E3dObject* >(this)->maFullTransform = aNewFullTransformation;
     636           0 :         const_cast< E3dObject* >(this)->mbTfHasChanged = false;
     637             :     }
     638             : 
     639           0 :     return maFullTransform;
     640             : }
     641             : 
     642             : 
     643        4628 : void E3dObject::NbcSetTransform(const basegfx::B3DHomMatrix& rMatrix)
     644             : {
     645        4628 :     if(maTransformation != rMatrix)
     646             :     {
     647        4628 :         maTransformation = rMatrix;
     648        4628 :         SetTransformChanged();
     649        4628 :         StructureChanged();
     650             :     }
     651        4628 : }
     652             : 
     653             : // Set transformation matrix with repaint broadcast
     654             : 
     655        4628 : void E3dObject::SetTransform(const basegfx::B3DHomMatrix& rMatrix)
     656             : {
     657        4628 :     if(rMatrix != maTransformation)
     658             :     {
     659        4628 :         NbcSetTransform(rMatrix);
     660        4628 :         SetChanged();
     661        4628 :         BroadcastObjectChange();
     662        4628 :         if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
     663             :     }
     664        4628 : }
     665             : 
     666           0 : basegfx::B3DPolyPolygon E3dObject::CreateWireframe() const
     667             : {
     668           0 :     const basegfx::B3DRange aBoundVolume(GetBoundVolume());
     669           0 :     return basegfx::tools::createCubePolyPolygonFromB3DRange(aBoundVolume);
     670             : }
     671             : 
     672             : // Get the name of the object (singular)
     673             : 
     674           0 : OUString E3dObject::TakeObjNameSingul() const
     675             : {
     676           0 :     OUStringBuffer sName(ImpGetResStr(STR_ObjNameSingulObj3d));
     677             : 
     678           0 :     OUString aName(GetName());
     679           0 :     if (!aName.isEmpty())
     680             :     {
     681           0 :         sName.append(' ');
     682           0 :         sName.append('\'');
     683           0 :         sName.append(aName);
     684           0 :         sName.append('\'');
     685             :     }
     686           0 :     return sName.makeStringAndClear();
     687             : }
     688             : 
     689             : // Get the name of the object (plural)
     690             : 
     691           0 : OUString E3dObject::TakeObjNamePlural() const
     692             : {
     693           0 :     return ImpGetResStr(STR_ObjNamePluralObj3d);
     694             : }
     695             : 
     696           0 : E3dObject* E3dObject::Clone() const
     697             : {
     698           0 :     return CloneHelper< E3dObject >();
     699             : }
     700             : 
     701           0 : E3dObject& E3dObject::operator=(const E3dObject& rObj)
     702             : {
     703           0 :     if( this == &rObj )
     704           0 :         return *this;
     705           0 :     SdrObject::operator=(rObj);
     706             : 
     707           0 :     const E3dObject& r3DObj = (const E3dObject&) rObj;
     708           0 :     if (r3DObj.GetSubList())
     709             :     {
     710           0 :         maSubList.CopyObjects(*r3DObj.GetSubList());
     711             :     }
     712             : 
     713             :     // BoundVol can be copied since also the children are copied
     714           0 :     maLocalBoundVol  = r3DObj.maLocalBoundVol;
     715           0 :     maTransformation = r3DObj.maTransformation;
     716             : 
     717             :     // Because the parent may have changed, definitely redefine the total
     718             :     // transformation next time
     719           0 :     SetTransformChanged();
     720             : 
     721             :     // Copy selection status
     722           0 :     mbIsSelected = r3DObj.mbIsSelected;
     723           0 :     return *this;
     724             : }
     725             : 
     726           0 : SdrObjGeoData *E3dObject::NewGeoData() const
     727             : {
     728           0 :     return new E3DObjGeoData;
     729             : }
     730             : 
     731           0 : void E3dObject::SaveGeoData(SdrObjGeoData& rGeo) const
     732             : {
     733           0 :     SdrAttrObj::SaveGeoData (rGeo);
     734             : 
     735           0 :     static_cast<E3DObjGeoData &>(rGeo).maLocalBoundVol  = maLocalBoundVol;
     736           0 :     static_cast<E3DObjGeoData &>(rGeo).maTransformation = maTransformation;
     737           0 : }
     738             : 
     739           0 : void E3dObject::RestGeoData(const SdrObjGeoData& rGeo)
     740             : {
     741           0 :     maLocalBoundVol = static_cast<const E3DObjGeoData &>(rGeo).maLocalBoundVol;
     742           0 :     E3DModifySceneSnapRectUpdater aUpdater(this);
     743           0 :     NbcSetTransform(static_cast<const E3DObjGeoData &>(rGeo).maTransformation);
     744           0 :     SdrAttrObj::RestGeoData (rGeo);
     745           0 : }
     746             : 
     747             : // 2D-rotation of a 3D-body, normally this is done by the scene itself.
     748             : // This is however a correct implementation, because everything that has
     749             : // happened is a rotation around the axis perpendicular to the screen and that
     750             : // is regardless of how the scene has been rotated up until now.
     751             : 
     752           0 : void E3dObject::NbcRotate(const Point& rRef, long nAngle, double sn, double cs)
     753             : {
     754             :     // So currently the glue points are defined relative to the scene aOutRect.
     755             :     // Before turning the glue points are defined relative to the page. They
     756             :     // take no part in the rotation of the scene. To ensure this, there is the
     757             :     // SetGlueReallyAbsolute(sal_True);
     758             : 
     759           0 :     double fWinkelInRad = nAngle/100.0 * F_PI180;
     760             : 
     761           0 :     basegfx::B3DHomMatrix aRotateZ;
     762           0 :     aRotateZ.rotate(0.0, 0.0, fWinkelInRad);
     763           0 :     NbcSetTransform(aRotateZ * GetTransform());
     764             : 
     765           0 :     SetRectsDirty();        // This forces a recalculation of all BoundRects
     766           0 :     NbcRotateGluePoints(rRef,nAngle,sn,cs);  // Rotate the glue points (who still
     767             :                                             // have coordinates relative to the
     768             :                                             // original page)
     769           0 :     SetGlueReallyAbsolute(false);       // from now they are again relative to BoundRect (that is defined as aOutRect)
     770           0 : }
     771             : 
     772         474 : sdr::properties::BaseProperties* E3dCompoundObject::CreateObjectSpecificProperties()
     773             : {
     774         474 :     return new sdr::properties::E3dCompoundProperties(*this);
     775             : }
     776             : 
     777             : 
     778             : 
     779      371916 : TYPEINIT1(E3dCompoundObject, E3dObject);
     780             : 
     781        4894 : E3dCompoundObject::E3dCompoundObject()
     782             : :   E3dObject(),
     783             :     aMaterialAmbientColor(),
     784             :     bCreateNormals(false),
     785        4894 :     bCreateTexture(false)
     786             : {
     787             :     // Set defaults
     788        4894 :     E3dDefaultAttributes aDefault;
     789        4894 :     SetDefaultAttributes(aDefault);
     790        4894 : }
     791             : 
     792           0 : E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault)
     793             : :   E3dObject(),
     794             :     aMaterialAmbientColor(),
     795             :     bCreateNormals(false),
     796           0 :     bCreateTexture(false)
     797             : {
     798             :     // Set defaults
     799           0 :     SetDefaultAttributes(rDefault);
     800           0 : }
     801             : 
     802        4894 : void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault)
     803             : {
     804             :     // Set defaults
     805        4894 :     aMaterialAmbientColor = rDefault.GetDefaultAmbientColor();
     806             : 
     807        4894 :     bCreateNormals = rDefault.GetDefaultCreateNormals();
     808        4894 :     bCreateTexture = rDefault.GetDefaultCreateTexture();
     809        4894 : }
     810             : 
     811        4894 : E3dCompoundObject::~E3dCompoundObject ()
     812             : {
     813        4894 : }
     814             : 
     815           0 : basegfx::B2DPolyPolygon E3dCompoundObject::TakeXorPoly() const
     816             : {
     817           0 :     basegfx::B2DPolyPolygon aRetval;
     818           0 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     819           0 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     820           0 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     821             : 
     822           0 :     if(pRootScene)
     823             :     {
     824           0 :         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     825           0 :         const basegfx::B3DPolyPolygon aCubePolyPolygon(CreateWireframe());
     826           0 :         aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCubePolyPolygon,
     827           0 :             aViewInfo3D.getObjectToView() * GetTransform());
     828           0 :         aRetval.transform(rVCScene.getObjectTransformation());
     829             :     }
     830             : 
     831           0 :     return aRetval;
     832             : }
     833             : 
     834           0 : sal_uInt32 E3dCompoundObject::GetHdlCount() const
     835             : {
     836             :     // 8 corners + 1 E3dVolumeMarker (= Wireframe representation)
     837           0 :     return 9L;
     838             : }
     839             : 
     840           0 : void E3dCompoundObject::AddToHdlList(SdrHdlList& rHdlList) const
     841             : {
     842           0 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     843           0 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     844           0 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     845             : 
     846           0 :     if(pRootScene)
     847             :     {
     848           0 :         const basegfx::B3DRange aBoundVolume(GetBoundVolume());
     849             : 
     850           0 :         if(!aBoundVolume.isEmpty())
     851             :         {
     852           0 :             const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     853             : 
     854           0 :             for(sal_uInt32 a(0); a < 8; a++)
     855             :             {
     856           0 :                 basegfx::B3DPoint aPos3D;
     857             : 
     858           0 :                 switch(a)
     859             :                 {
     860           0 :                     case 0 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     861           0 :                     case 1 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     862           0 :                     case 2 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     863           0 :                     case 3 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     864           0 :                     case 4 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     865           0 :                     case 5 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     866           0 :                     case 6 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     867           0 :                     case 7 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     868             :                 }
     869             : 
     870             :                 // to 3d view coor
     871           0 :                 aPos3D *= aViewInfo3D.getObjectToView() * GetTransform();
     872             : 
     873             :                 // create 2d relative scene
     874           0 :                 basegfx::B2DPoint aPos2D(aPos3D.getX(), aPos3D.getY());
     875             : 
     876             :                 // to 2d world coor
     877           0 :                 aPos2D *= rVCScene.getObjectTransformation();
     878             : 
     879           0 :                 rHdlList.AddHdl(new SdrHdl(Point(basegfx::fround(aPos2D.getX()), basegfx::fround(aPos2D.getY())), HDL_BWGT));
     880           0 :             }
     881             :         }
     882             :     }
     883             : 
     884           0 :     const basegfx::B2DPolyPolygon aPolyPolygon(TakeXorPoly());
     885             : 
     886           0 :     if(aPolyPolygon.count())
     887             :     {
     888           0 :         E3dVolumeMarker* pVolMarker = new E3dVolumeMarker(aPolyPolygon);
     889           0 :         rHdlList.AddHdl(pVolMarker);
     890           0 :     }
     891           0 : }
     892             : 
     893           0 : sal_uInt16 E3dCompoundObject::GetObjIdentifier() const
     894             : {
     895           0 :     return E3D_COMPOUNDOBJ_ID;
     896             : }
     897             : 
     898        4147 : void E3dCompoundObject::RecalcSnapRect()
     899             : {
     900        4147 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     901        8294 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     902        4147 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     903        4147 :     maSnapRect = Rectangle();
     904             : 
     905        4147 :     if(pRootScene)
     906             :     {
     907             :         // get VC of 3D candidate
     908        4147 :         const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
     909             : 
     910        4147 :         if(pVCOfE3D)
     911             :         {
     912             :             // get 3D primitive sequence
     913        4147 :             const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getViewIndependentPrimitive3DSequence());
     914             : 
     915        4147 :             if(xLocalSequence.hasElements())
     916             :             {
     917             :                 // get BoundVolume
     918             :                 basegfx::B3DRange aBoundVolume(drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
     919        4147 :                     xLocalSequence, aViewInfo3D));
     920             : 
     921             :                 // transform bound volume to relative scene coordinates
     922        4147 :                 aBoundVolume.transform(aViewInfo3D.getObjectToView());
     923             : 
     924             :                 // build 2d relative scene range
     925             :                 basegfx::B2DRange aSnapRange(
     926             :                     aBoundVolume.getMinX(), aBoundVolume.getMinY(),
     927        4147 :                     aBoundVolume.getMaxX(), aBoundVolume.getMaxY());
     928             : 
     929             :                 // transform to 2D world coordiantes
     930        4147 :                 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     931        4147 :                 aSnapRange.transform(rVCScene.getObjectTransformation());
     932             : 
     933             :                 // snap to integer
     934             :                 maSnapRect = Rectangle(
     935        8294 :                     sal_Int32(floor(aSnapRange.getMinX())), sal_Int32(floor(aSnapRange.getMinY())),
     936       12441 :                     sal_Int32(ceil(aSnapRange.getMaxX())), sal_Int32(ceil(aSnapRange.getMaxY())));
     937        4147 :             }
     938             :         }
     939        4147 :     }
     940        4147 : }
     941             : 
     942           0 : E3dCompoundObject* E3dCompoundObject::Clone() const
     943             : {
     944           0 :     return CloneHelper< E3dCompoundObject >();
     945             : }
     946             : 
     947             : // convert given basegfx::B3DPolyPolygon to screen coor
     948             : 
     949           0 : basegfx::B2DPolyPolygon E3dCompoundObject::TransformToScreenCoor(const basegfx::B3DPolyPolygon& rCandidate)
     950             : {
     951           0 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     952           0 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     953           0 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     954           0 :     basegfx::B2DPolyPolygon aRetval;
     955             : 
     956           0 :     if(pRootScene)
     957             :     {
     958           0 :         aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(rCandidate,
     959           0 :             aViewInfo3D.getObjectToView() * GetTransform());
     960           0 :         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     961           0 :         aRetval.transform(rVCScene.getObjectTransformation());
     962             :     }
     963             : 
     964           0 :     return aRetval;
     965             : }
     966             : 
     967           0 : bool E3dCompoundObject::IsAOrdNumRemapCandidate(E3dScene*& prScene) const
     968             : {
     969           0 :     if(GetObjList()
     970           0 :         && GetObjList()->GetOwnerObj()
     971           0 :         && GetObjList()->GetOwnerObj()->ISA(E3dScene))
     972             :     {
     973           0 :         prScene = static_cast<E3dScene*>(GetObjList()->GetOwnerObj());
     974           0 :         return true;
     975             :     }
     976             : 
     977           0 :     return false;
     978         435 : }
     979             : 
     980             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11