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

Generated by: LCOV version 1.10