LCOV - code coverage report
Current view: top level - svx/source/engine3d - obj3d.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 129 426 30.3 %
Date: 2014-04-11 Functions: 33 80 41.2 %
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 "svx/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 <svx/sdr/properties/e3dproperties.hxx>
      62             : #include <svx/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        4401 : TYPEINIT1(E3dObjList, SdrObjList);
      87             : 
      88        1479 : E3dObjList::E3dObjList(SdrModel* pNewModel, SdrPage* pNewPage, E3dObjList* pNewUpList)
      89        1479 : :   SdrObjList(pNewModel, pNewPage, pNewUpList)
      90             : {
      91        1479 : }
      92             : 
      93           0 : E3dObjList::E3dObjList(const E3dObjList& rSrcList)
      94           0 : :   SdrObjList(rSrcList)
      95             : {
      96           0 : }
      97             : 
      98        1250 : E3dObjList::~E3dObjList()
      99             : {
     100        1250 : }
     101             : 
     102        1467 : void E3dObjList::NbcInsertObject(SdrObject* pObj, sal_uIntPtr 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        1467 :     if(pObj && pObj->ISA(E3dObject))
     109             :     {
     110             :         // Normal 3D object, insert means
     111             :         // call parent
     112        1467 :         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        1467 : }
     120             : 
     121           0 : void E3dObjList::InsertObject(SdrObject* pObj, sal_uIntPtr 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 = ((E3dObject*)GetOwnerObj())->GetScene();
     129           0 :     if(pScene)
     130             :     {
     131           0 :         pScene->Cleanup3DDepthMapper();
     132             :     }
     133           0 : }
     134             : 
     135        1013 : SdrObject* E3dObjList::NbcRemoveObject(sal_uIntPtr nObjNum)
     136             : {
     137             :     DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "Remove 3D object from Parent != 3DObject");
     138             : 
     139             :     // call parent
     140        1013 :     SdrObject* pRetval = SdrObjList::NbcRemoveObject(nObjNum);
     141             : 
     142        1013 :     E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene();
     143        1013 :     if(pScene)
     144             :     {
     145        1013 :         pScene->Cleanup3DDepthMapper();
     146             :     }
     147             : 
     148        1013 :     return pRetval;
     149             : }
     150             : 
     151           0 : SdrObject* E3dObjList::RemoveObject(sal_uIntPtr 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 = ((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      626642 : TYPEINIT1(E3dObject, SdrAttrObj);
     177             : 
     178        1479 : E3dObject::E3dObject()
     179             : :   maSubList(),
     180             :     maLocalBoundVol(),
     181             :     maTransformation(),
     182             :     maFullTransform(),
     183             :     mbTfHasChanged(true),
     184        1479 :     mbIsSelected(false)
     185             : {
     186        1479 :     bIs3DObj = true;
     187        1479 :     maSubList.SetOwnerObj(this);
     188        1479 :     maSubList.SetListKind(SDROBJLIST_GROUPOBJ);
     189        1479 :     bClosedObj = true;
     190        1479 : }
     191             : 
     192        1250 : E3dObject::~E3dObject()
     193             : {
     194        1250 : }
     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(sal_uInt32 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       17406 : void E3dObject::SetRectsDirty(bool bNotMyself)
     229             : {
     230             :     // call parent
     231       17406 :     SdrAttrObj::SetRectsDirty(bNotMyself);
     232             : 
     233       27364 :     for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
     234             :     {
     235        9958 :         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
     236             : 
     237        9958 :         if(pCandidate)
     238             :         {
     239        9958 :             pCandidate->SetRectsDirty(bNotMyself);
     240             :         }
     241             :     }
     242       17406 : }
     243             : 
     244        5896 : sal_uInt32 E3dObject::GetObjInventor() const
     245             : {
     246        5896 :     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 :     XFillStyle eFillStyle = ((XFillStyleItem&)(GetMergedItem(XATTR_FILLSTYLE))).GetValue();
     275           0 :     rInfo.bGradientAllowed = (eFillStyle == XFILL_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(sal_uInt32 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        2492 : void E3dObject::SetObjList(SdrObjList* pNewObjList)
     306             : {
     307        2492 :     SdrObject::SetObjList(pNewObjList);
     308        2492 :     maSubList.SetUpList(pNewObjList);
     309        2492 : }
     310             : 
     311        4195 : void E3dObject::SetPage(SdrPage* pNewPage)
     312             : {
     313        4195 :     SdrAttrObj::SetPage(pNewPage);
     314        4195 :     maSubList.SetPage(pNewPage);
     315        4195 : }
     316             : 
     317        1491 : void E3dObject::SetModel(SdrModel* pNewModel)
     318             : {
     319        1491 :     SdrAttrObj::SetModel(pNewModel);
     320        1491 :     maSubList.SetModel(pNewModel);
     321        1491 : }
     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       20680 : SdrObjList* E3dObject::GetSubList() const
     427             : {
     428       20680 :     return &(const_cast< E3dObjList& >(maSubList));
     429             : }
     430             : 
     431         332 : void E3dObject::RecalcSnapRect()
     432             : {
     433         332 :     maSnapRect = Rectangle();
     434             : 
     435         332 :     for(sal_uInt32 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         332 : }
     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       30400 : void E3dObject::StructureChanged()
     459             : {
     460       30400 :     if ( GetParentObj() )
     461             :     {
     462       17903 :         GetParentObj()->InvalidateBoundVolume();
     463       17903 :         GetParentObj()->StructureChanged();
     464             :     }
     465       30400 : }
     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      205039 : E3dObject* E3dObject::GetParentObj() const
     494             : {
     495      205039 :     E3dObject* pRetval = NULL;
     496             : 
     497      410078 :     if(GetObjList()
     498      202682 :         && GetObjList()->GetOwnerObj()
     499      407721 :         && GetObjList()->GetOwnerObj()->ISA(E3dObject))
     500      175172 :         pRetval = ((E3dObject*)GetObjList()->GetOwnerObj());
     501      205039 :     return pRetval;
     502             : }
     503             : 
     504             : // Determine the top-level scene object
     505             : 
     506       11387 : E3dScene* E3dObject::GetScene() const
     507             : {
     508       11387 :     if(GetParentObj())
     509       11387 :         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 sal_uInt32 nObjCnt(maSubList.GetObjCount());
     519             : 
     520           0 :     if(nObjCnt)
     521             :     {
     522           0 :         for(sal_uInt32 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       19408 : void E3dObject::InvalidateBoundVolume()
     571             : {
     572       19408 :     maLocalBoundVol.reset();
     573       19408 : }
     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(sal_uInt32 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        1447 : void E3dObject::SetTransformChanged()
     595             : {
     596        1447 :     InvalidateBoundVolume();
     597        1447 :     mbTfHasChanged = true;
     598             : 
     599        1852 :     for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
     600             :     {
     601         405 :         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
     602             : 
     603         405 :         if(pCandidate)
     604             :         {
     605         405 :             pCandidate->SetTransformChanged();
     606             :         }
     607             :     }
     608        1447 : }
     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        6295 : const basegfx::B3DHomMatrix& E3dObject::GetTransform() const
     632             : {
     633        6295 :     return maTransformation;
     634             : }
     635             : 
     636        1042 : void E3dObject::NbcSetTransform(const basegfx::B3DHomMatrix& rMatrix)
     637             : {
     638        1042 :     if(maTransformation != rMatrix)
     639             :     {
     640        1042 :         maTransformation = rMatrix;
     641        1042 :         SetTransformChanged();
     642        1042 :         StructureChanged();
     643             :     }
     644        1042 : }
     645             : 
     646             : // Set transformation matrix with repaint broadcast
     647             : 
     648        1042 : void E3dObject::SetTransform(const basegfx::B3DHomMatrix& rMatrix)
     649             : {
     650        1042 :     if(rMatrix != maTransformation)
     651             :     {
     652        1042 :         NbcSetTransform(rMatrix);
     653        1042 :         SetChanged();
     654        1042 :         BroadcastObjectChange();
     655        1042 :         if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
     656             :     }
     657        1042 : }
     658             : 
     659           0 : basegfx::B3DPolyPolygon E3dObject::CreateWireframe() const
     660             : {
     661           0 :     const basegfx::B3DRange aBoundVolume(GetBoundVolume());
     662           0 :     return basegfx::tools::createCubePolyPolygonFromB3DRange(aBoundVolume);
     663             : }
     664             : 
     665             : // Get the name of the object (singular)
     666             : 
     667           0 : OUString E3dObject::TakeObjNameSingul() const
     668             : {
     669           0 :     OUStringBuffer sName(ImpGetResStr(STR_ObjNameSingulObj3d));
     670             : 
     671           0 :     OUString aName(GetName());
     672           0 :     if (!aName.isEmpty())
     673             :     {
     674           0 :         sName.append(' ');
     675           0 :         sName.append('\'');
     676           0 :         sName.append(aName);
     677           0 :         sName.append('\'');
     678             :     }
     679           0 :     return sName.makeStringAndClear();
     680             : }
     681             : 
     682             : // Get the name of the object (plural)
     683             : 
     684           0 : OUString E3dObject::TakeObjNamePlural() const
     685             : {
     686           0 :     return ImpGetResStr(STR_ObjNamePluralObj3d);
     687             : }
     688             : 
     689           0 : E3dObject* E3dObject::Clone() const
     690             : {
     691           0 :     return CloneHelper< E3dObject >();
     692             : }
     693             : 
     694           0 : E3dObject& E3dObject::operator=(const E3dObject& rObj)
     695             : {
     696           0 :     if( this == &rObj )
     697           0 :         return *this;
     698           0 :     SdrObject::operator=(rObj);
     699             : 
     700           0 :     const E3dObject& r3DObj = (const E3dObject&) rObj;
     701           0 :     if (r3DObj.GetSubList())
     702             :     {
     703           0 :         maSubList.CopyObjects(*r3DObj.GetSubList());
     704             :     }
     705             : 
     706             :     // BoundVol can be copied since also the children are copied
     707           0 :     maLocalBoundVol  = r3DObj.maLocalBoundVol;
     708           0 :     maTransformation = r3DObj.maTransformation;
     709             : 
     710             :     // Because the parent may have changed, definitely redefine the total
     711             :     // transformation next time
     712           0 :     SetTransformChanged();
     713             : 
     714             :     // Copy selection status
     715           0 :     mbIsSelected = r3DObj.mbIsSelected;
     716           0 :     return *this;
     717             : }
     718             : 
     719           0 : SdrObjGeoData *E3dObject::NewGeoData() const
     720             : {
     721           0 :     return new E3DObjGeoData;
     722             : }
     723             : 
     724           0 : void E3dObject::SaveGeoData(SdrObjGeoData& rGeo) const
     725             : {
     726           0 :     SdrAttrObj::SaveGeoData (rGeo);
     727             : 
     728           0 :     ((E3DObjGeoData &) rGeo).maLocalBoundVol  = maLocalBoundVol;
     729           0 :     ((E3DObjGeoData &) rGeo).maTransformation = maTransformation;
     730           0 : }
     731             : 
     732           0 : void E3dObject::RestGeoData(const SdrObjGeoData& rGeo)
     733             : {
     734           0 :     maLocalBoundVol = ((E3DObjGeoData &) rGeo).maLocalBoundVol;
     735           0 :     E3DModifySceneSnapRectUpdater aUpdater(this);
     736           0 :     NbcSetTransform(((E3DObjGeoData &) rGeo).maTransformation);
     737           0 :     SdrAttrObj::RestGeoData (rGeo);
     738           0 : }
     739             : 
     740             : // 2D-rotation of a 3D-body, normally this is done by the scene itself.
     741             : // This is however a correct implementation, because everything that has
     742             : // happened is a rotation around the axis perpendicular to the screen and that
     743             : // is regardless of how the scene has been rotated up until now.
     744             : 
     745           0 : void E3dObject::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
     746             : {
     747             :     // So currently the glue points are defined relative to the scene aOutRect.
     748             :     // Before turning the glue points are defined relative to the page. They
     749             :     // take no part in the rotation of the scene. To ensure this, there is the
     750             :     // SetGlueReallyAbsolute(sal_True);
     751             : 
     752           0 :     double fWinkelInRad = nWink/100 * F_PI180;
     753             : 
     754           0 :     basegfx::B3DHomMatrix aRotateZ;
     755           0 :     aRotateZ.rotate(0.0, 0.0, fWinkelInRad);
     756           0 :     NbcSetTransform(aRotateZ * GetTransform());
     757             : 
     758           0 :     SetRectsDirty();        // This forces a recalculation of all BoundRects
     759           0 :     NbcRotateGluePoints(rRef,nWink,sn,cs);  // Rotate the glue points (who still
     760             :                                             // have coordinates relative to the
     761             :                                             // original page)
     762           0 :     SetGlueReallyAbsolute(false);       // from now they are again relative to BoundRect (that is defined as aOutRect)
     763           0 : }
     764             : 
     765             : /*************************************************************************/
     766             : 
     767             : 
     768             : 
     769         154 : sdr::properties::BaseProperties* E3dCompoundObject::CreateObjectSpecificProperties()
     770             : {
     771         154 :     return new sdr::properties::E3dCompoundProperties(*this);
     772             : }
     773             : 
     774             : 
     775             : 
     776      139040 : TYPEINIT1(E3dCompoundObject, E3dObject);
     777             : 
     778        1135 : E3dCompoundObject::E3dCompoundObject()
     779             : :   E3dObject(),
     780             :     aMaterialAmbientColor(),
     781             :     bCreateNormals(false),
     782        1135 :     bCreateTexture(false)
     783             : {
     784             :     // Set defaults
     785        1135 :     E3dDefaultAttributes aDefault;
     786        1135 :     SetDefaultAttributes(aDefault);
     787        1135 : }
     788             : 
     789           0 : E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault)
     790             : :   E3dObject(),
     791             :     aMaterialAmbientColor(),
     792             :     bCreateNormals(false),
     793           0 :     bCreateTexture(false)
     794             : {
     795             :     // Set defaults
     796           0 :     SetDefaultAttributes(rDefault);
     797           0 : }
     798             : 
     799        1135 : void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault)
     800             : {
     801             :     // Set defaults
     802        1135 :     aMaterialAmbientColor = rDefault.GetDefaultAmbientColor();
     803             : 
     804        1135 :     bCreateNormals = rDefault.GetDefaultCreateNormals();
     805        1135 :     bCreateTexture = rDefault.GetDefaultCreateTexture();
     806        1135 : }
     807             : 
     808        1035 : E3dCompoundObject::~E3dCompoundObject ()
     809             : {
     810        1035 : }
     811             : 
     812           0 : basegfx::B2DPolyPolygon E3dCompoundObject::TakeXorPoly() const
     813             : {
     814           0 :     basegfx::B2DPolyPolygon aRetval;
     815           0 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     816           0 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     817           0 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     818             : 
     819           0 :     if(pRootScene)
     820             :     {
     821           0 :         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     822           0 :         const basegfx::B3DPolyPolygon aCubePolyPolygon(CreateWireframe());
     823           0 :         aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCubePolyPolygon,
     824           0 :             aViewInfo3D.getObjectToView() * GetTransform());
     825           0 :         aRetval.transform(rVCScene.getObjectTransformation());
     826             :     }
     827             : 
     828           0 :     return aRetval;
     829             : }
     830             : 
     831           0 : sal_uInt32 E3dCompoundObject::GetHdlCount() const
     832             : {
     833             :     // 8 corners + 1 E3dVolumeMarker (= Wireframe representation)
     834           0 :     return 9L;
     835             : }
     836             : 
     837           0 : void E3dCompoundObject::AddToHdlList(SdrHdlList& rHdlList) const
     838             : {
     839           0 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     840           0 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     841           0 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     842             : 
     843           0 :     if(pRootScene)
     844             :     {
     845           0 :         const basegfx::B3DRange aBoundVolume(GetBoundVolume());
     846             : 
     847           0 :         if(!aBoundVolume.isEmpty())
     848             :         {
     849           0 :             const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     850             : 
     851           0 :             for(sal_uInt32 a(0); a < 8; a++)
     852             :             {
     853           0 :                 basegfx::B3DPoint aPos3D;
     854             : 
     855           0 :                 switch(a)
     856             :                 {
     857           0 :                     case 0 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     858           0 :                     case 1 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     859           0 :                     case 2 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     860           0 :                     case 3 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     861           0 :                     case 4 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     862           0 :                     case 5 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     863           0 :                     case 6 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     864           0 :                     case 7 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     865             :                 }
     866             : 
     867             :                 // to 3d view coor
     868           0 :                 aPos3D *= aViewInfo3D.getObjectToView() * GetTransform();
     869             : 
     870             :                 // create 2d relative scene
     871           0 :                 basegfx::B2DPoint aPos2D(aPos3D.getX(), aPos3D.getY());
     872             : 
     873             :                 // to 2d world coor
     874           0 :                 aPos2D *= rVCScene.getObjectTransformation();
     875             : 
     876           0 :                 rHdlList.AddHdl(new SdrHdl(Point(basegfx::fround(aPos2D.getX()), basegfx::fround(aPos2D.getY())), HDL_BWGT));
     877           0 :             }
     878             :         }
     879             :     }
     880             : 
     881           0 :     const basegfx::B2DPolyPolygon aPolyPolygon(TakeXorPoly());
     882             : 
     883           0 :     if(aPolyPolygon.count())
     884             :     {
     885           0 :         E3dVolumeMarker* pVolMarker = new E3dVolumeMarker(aPolyPolygon);
     886           0 :         rHdlList.AddHdl(pVolMarker);
     887           0 :     }
     888           0 : }
     889             : 
     890           0 : sal_uInt16 E3dCompoundObject::GetObjIdentifier() const
     891             : {
     892           0 :     return E3D_COMPOUNDOBJ_ID;
     893             : }
     894             : 
     895         946 : void E3dCompoundObject::RecalcSnapRect()
     896             : {
     897         946 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     898        1892 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     899         946 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     900         946 :     maSnapRect = Rectangle();
     901             : 
     902         946 :     if(pRootScene)
     903             :     {
     904             :         // get VC of 3D candidate
     905         946 :         const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
     906             : 
     907         946 :         if(pVCOfE3D)
     908             :         {
     909             :             // get 3D primitive sequence
     910         946 :             const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getViewIndependentPrimitive3DSequence());
     911             : 
     912         946 :             if(xLocalSequence.hasElements())
     913             :             {
     914             :                 // get BoundVolume
     915             :                 basegfx::B3DRange aBoundVolume(drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
     916         946 :                     xLocalSequence, aViewInfo3D));
     917             : 
     918             :                 // transform bound volume to relative scene coordinates
     919         946 :                 aBoundVolume.transform(aViewInfo3D.getObjectToView());
     920             : 
     921             :                 // build 2d relative scene range
     922             :                 basegfx::B2DRange aSnapRange(
     923             :                     aBoundVolume.getMinX(), aBoundVolume.getMinY(),
     924         946 :                     aBoundVolume.getMaxX(), aBoundVolume.getMaxY());
     925             : 
     926             :                 // transform to 2D world coordiantes
     927         946 :                 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     928         946 :                 aSnapRange.transform(rVCScene.getObjectTransformation());
     929             : 
     930             :                 // snap to integer
     931             :                 maSnapRect = Rectangle(
     932        1892 :                     sal_Int32(floor(aSnapRange.getMinX())), sal_Int32(floor(aSnapRange.getMinY())),
     933        2838 :                     sal_Int32(ceil(aSnapRange.getMaxX())), sal_Int32(ceil(aSnapRange.getMaxY())));
     934         946 :             }
     935             :         }
     936         946 :     }
     937         946 : }
     938             : 
     939           0 : E3dCompoundObject* E3dCompoundObject::Clone() const
     940             : {
     941           0 :     return CloneHelper< E3dCompoundObject >();
     942             : }
     943             : 
     944             : // convert given basegfx::B3DPolyPolygon to screen coor
     945             : 
     946           0 : basegfx::B2DPolyPolygon E3dCompoundObject::TransformToScreenCoor(const basegfx::B3DPolyPolygon& rCandidate)
     947             : {
     948           0 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     949           0 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     950           0 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     951           0 :     basegfx::B2DPolyPolygon aRetval;
     952             : 
     953           0 :     if(pRootScene)
     954             :     {
     955           0 :         aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(rCandidate,
     956           0 :             aViewInfo3D.getObjectToView() * GetTransform());
     957           0 :         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     958           0 :         aRetval.transform(rVCScene.getObjectTransformation());
     959             :     }
     960             : 
     961           0 :     return aRetval;
     962             : }
     963             : 
     964           0 : bool E3dCompoundObject::IsAOrdNumRemapCandidate(E3dScene*& prScene) const
     965             : {
     966           0 :     if(GetObjList()
     967           0 :         && GetObjList()->GetOwnerObj()
     968           0 :         && GetObjList()->GetOwnerObj()->ISA(E3dScene))
     969             :     {
     970           0 :         prScene = (E3dScene*)GetObjList()->GetOwnerObj();
     971           0 :         return true;
     972             :     }
     973             : 
     974           0 :     return false;
     975             : }
     976             : 
     977             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10