LCOV - code coverage report
Current view: top level - libreoffice/svx/source/engine3d - obj3d.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 2 426 0.5 %
Date: 2012-12-27 Functions: 2 80 2.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      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           0 : TYPEINIT1(E3dObjList, SdrObjList);
      87             : 
      88           0 : E3dObjList::E3dObjList(SdrModel* pNewModel, SdrPage* pNewPage, E3dObjList* pNewUpList)
      89           0 : :   SdrObjList(pNewModel, pNewPage, pNewUpList)
      90             : {
      91           0 : }
      92             : 
      93           0 : E3dObjList::E3dObjList(const E3dObjList& rSrcList)
      94           0 : :   SdrObjList(rSrcList)
      95             : {
      96           0 : }
      97             : 
      98           0 : E3dObjList::~E3dObjList()
      99             : {
     100           0 : }
     101             : 
     102           0 : 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           0 :     if(pObj && pObj->ISA(E3dObject))
     109             :     {
     110             :         // Normal 3D object, insert means
     111             :         // call parent
     112           0 :         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           0 : }
     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           0 : SdrObject* E3dObjList::NbcRemoveObject(sal_uIntPtr nObjNum)
     136             : {
     137             :     DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "Remove 3D object from Parent != 3DObject");
     138             : 
     139             :     // call parent
     140           0 :     SdrObject* pRetval = SdrObjList::NbcRemoveObject(nObjNum);
     141             : 
     142           0 :     E3dScene* pScene = ((E3dObject*)GetOwnerObj())->GetScene();
     143           0 :     if(pScene)
     144             :     {
     145           0 :         pScene->Cleanup3DDepthMapper();
     146             :     }
     147             : 
     148           0 :     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          68 : TYPEINIT1(E3dObject, SdrAttrObj);
     177             : 
     178           0 : E3dObject::E3dObject()
     179             : :   maSubList(),
     180             :     maLocalBoundVol(),
     181             :     maTransformation(),
     182             :     maFullTransform(),
     183             :     mbTfHasChanged(true),
     184           0 :     mbIsSelected(false)
     185             : {
     186           0 :     bIs3DObj = true;
     187           0 :     maSubList.SetOwnerObj(this);
     188           0 :     maSubList.SetListKind(SDROBJLIST_GROUPOBJ);
     189           0 :     bClosedObj = true;
     190           0 : }
     191             : 
     192           0 : E3dObject::~E3dObject()
     193             : {
     194           0 : }
     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 : sal_Bool E3dObject::IsBreakObjPossible()
     217             : {
     218           0 :     return sal_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           0 : void E3dObject::SetRectsDirty(sal_Bool bNotMyself)
     229             : {
     230             :     // call parent
     231           0 :     SdrAttrObj::SetRectsDirty(bNotMyself);
     232             : 
     233           0 :     for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
     234             :     {
     235           0 :         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
     236             : 
     237           0 :         if(pCandidate)
     238             :         {
     239           0 :             pCandidate->SetRectsDirty(bNotMyself);
     240             :         }
     241             :     }
     242           0 : }
     243             : 
     244           0 : sal_uInt32 E3dObject::GetObjInventor() const
     245             : {
     246           0 :     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    = sal_True;
     259           0 :     rInfo.bResizePropAllowed    = sal_True;
     260           0 :     rInfo.bRotateFreeAllowed    = sal_True;
     261           0 :     rInfo.bRotate90Allowed      = sal_True;
     262           0 :     rInfo.bMirrorFreeAllowed    = sal_False;
     263           0 :     rInfo.bMirror45Allowed      = sal_False;
     264           0 :     rInfo.bMirror90Allowed      = sal_False;
     265           0 :     rInfo.bShearAllowed         = sal_False;
     266           0 :     rInfo.bEdgeRadiusAllowed    = sal_False;
     267           0 :     rInfo.bCanConvToPath        = sal_False;
     268             : 
     269             :     // no transparence for 3d objects
     270           0 :     rInfo.bTransparenceAllowed = sal_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 = sal_False;
     283           0 :     rInfo.bCanConvToContour = sal_False;
     284           0 :     rInfo.bCanConvToPathLineToArea = sal_False;
     285           0 :     rInfo.bCanConvToPolyLineToArea = sal_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           0 : void E3dObject::SetObjList(SdrObjList* pNewObjList)
     306             : {
     307           0 :     SdrObject::SetObjList(pNewObjList);
     308           0 :     maSubList.SetUpList(pNewObjList);
     309           0 : }
     310             : 
     311           0 : void E3dObject::SetPage(SdrPage* pNewPage)
     312             : {
     313           0 :     SdrAttrObj::SetPage(pNewPage);
     314           0 :     maSubList.SetPage(pNewPage);
     315           0 : }
     316             : 
     317           0 : void E3dObject::SetModel(SdrModel* pNewModel)
     318             : {
     319           0 :     SdrAttrObj::SetModel(pNewModel);
     320           0 :     maSubList.SetModel(pNewModel);
     321           0 : }
     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           0 : SdrObjList* E3dObject::GetSubList() const
     427             : {
     428           0 :     return &(const_cast< E3dObjList& >(maSubList));
     429             : }
     430             : 
     431           0 : void E3dObject::RecalcSnapRect()
     432             : {
     433           0 :     maSnapRect = Rectangle();
     434             : 
     435           0 :     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           0 : }
     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           0 : void E3dObject::StructureChanged()
     459             : {
     460           0 :     if ( GetParentObj() )
     461             :     {
     462           0 :         GetParentObj()->InvalidateBoundVolume();
     463           0 :         GetParentObj()->StructureChanged();
     464             :     }
     465           0 : }
     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           0 : E3dObject* E3dObject::GetParentObj() const
     494             : {
     495           0 :     E3dObject* pRetval = NULL;
     496             : 
     497           0 :     if(GetObjList()
     498           0 :         && GetObjList()->GetOwnerObj()
     499           0 :         && GetObjList()->GetOwnerObj()->ISA(E3dObject))
     500           0 :         pRetval = ((E3dObject*)GetObjList()->GetOwnerObj());
     501           0 :     return pRetval;
     502             : }
     503             : 
     504             : // Determine the top-level scene object
     505             : 
     506           0 : E3dScene* E3dObject::GetScene() const
     507             : {
     508           0 :     if(GetParentObj())
     509           0 :         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           0 : void E3dObject::InvalidateBoundVolume()
     571             : {
     572           0 :     maLocalBoundVol.reset();
     573           0 : }
     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           0 : void E3dObject::SetTransformChanged()
     595             : {
     596           0 :     InvalidateBoundVolume();
     597           0 :     mbTfHasChanged = true;
     598             : 
     599           0 :     for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
     600             :     {
     601           0 :         E3dObject* pCandidate = dynamic_cast< E3dObject* >(maSubList.GetObj(a));
     602             : 
     603           0 :         if(pCandidate)
     604             :         {
     605           0 :             pCandidate->SetTransformChanged();
     606             :         }
     607             :     }
     608           0 : }
     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           0 : const basegfx::B3DHomMatrix& E3dObject::GetTransform() const
     632             : {
     633           0 :     return maTransformation;
     634             : }
     635             : 
     636           0 : void E3dObject::NbcSetTransform(const basegfx::B3DHomMatrix& rMatrix)
     637             : {
     638           0 :     if(maTransformation != rMatrix)
     639             :     {
     640           0 :         maTransformation = rMatrix;
     641           0 :         SetTransformChanged();
     642           0 :         StructureChanged();
     643             :     }
     644           0 : }
     645             : 
     646             : // Set transformation matrix with repaint broadcast
     647             : 
     648           0 : void E3dObject::SetTransform(const basegfx::B3DHomMatrix& rMatrix)
     649             : {
     650           0 :     if(rMatrix != maTransformation)
     651             :     {
     652           0 :         NbcSetTransform(rMatrix);
     653           0 :         SetChanged();
     654           0 :         BroadcastObjectChange();
     655           0 :         if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle());
     656             :     }
     657           0 : }
     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 : void E3dObject::TakeObjNameSingul(XubString& rName) const
     668             : {
     669           0 :     rName=ImpGetResStr(STR_ObjNameSingulObj3d);
     670             : 
     671           0 :     String aName( GetName() );
     672           0 :     if(aName.Len())
     673             :     {
     674           0 :         rName += sal_Unicode(' ');
     675           0 :         rName += sal_Unicode('\'');
     676           0 :         rName += aName;
     677           0 :         rName += sal_Unicode('\'');
     678           0 :     }
     679           0 : }
     680             : 
     681             : // Get the name of the object (plural)
     682             : 
     683           0 : void E3dObject::TakeObjNamePlural(XubString& rName) const
     684             : {
     685           0 :     rName=ImpGetResStr(STR_ObjNamePluralObj3d);
     686           0 : }
     687             : 
     688           0 : E3dObject* E3dObject::Clone() const
     689             : {
     690           0 :     return CloneHelper< E3dObject >();
     691             : }
     692             : 
     693           0 : E3dObject& E3dObject::operator=(const E3dObject& rObj)
     694             : {
     695           0 :     if( this == &rObj )
     696           0 :         return *this;
     697           0 :     SdrObject::operator=(rObj);
     698             : 
     699           0 :     const E3dObject& r3DObj = (const E3dObject&) rObj;
     700           0 :     if (r3DObj.GetSubList())
     701             :     {
     702           0 :         maSubList.CopyObjects(*r3DObj.GetSubList());
     703             :     }
     704             : 
     705             :     // BoundVol can be copied since also the children are copied
     706           0 :     maLocalBoundVol  = r3DObj.maLocalBoundVol;
     707           0 :     maTransformation = r3DObj.maTransformation;
     708             : 
     709             :     // Because the parent may have changed, definitely redefine the total
     710             :     // transformation next time
     711           0 :     SetTransformChanged();
     712             : 
     713             :     // Copy selection status
     714           0 :     mbIsSelected = r3DObj.mbIsSelected;
     715           0 :     return *this;
     716             : }
     717             : 
     718           0 : SdrObjGeoData *E3dObject::NewGeoData() const
     719             : {
     720           0 :     return new E3DObjGeoData;
     721             : }
     722             : 
     723           0 : void E3dObject::SaveGeoData(SdrObjGeoData& rGeo) const
     724             : {
     725           0 :     SdrAttrObj::SaveGeoData (rGeo);
     726             : 
     727           0 :     ((E3DObjGeoData &) rGeo).maLocalBoundVol  = maLocalBoundVol;
     728           0 :     ((E3DObjGeoData &) rGeo).maTransformation = maTransformation;
     729           0 : }
     730             : 
     731           0 : void E3dObject::RestGeoData(const SdrObjGeoData& rGeo)
     732             : {
     733           0 :     maLocalBoundVol = ((E3DObjGeoData &) rGeo).maLocalBoundVol;
     734           0 :     E3DModifySceneSnapRectUpdater aUpdater(this);
     735           0 :     NbcSetTransform(((E3DObjGeoData &) rGeo).maTransformation);
     736           0 :     SdrAttrObj::RestGeoData (rGeo);
     737           0 : }
     738             : 
     739             : // 2D-rotation of a 3D-body, normally this is done by the scene itself.
     740             : // This is however a correct implementation, because everything that has
     741             : // happened is a rotation around the axis perpendicular to the screen and that
     742             : // is regardless of how the scene has been rotated up until now.
     743             : 
     744           0 : void E3dObject::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
     745             : {
     746             :     // So currently the glue points are defined relative to the scene aOutRect.
     747             :     // Before turning the glue points are defined relative to the page. They
     748             :     // take no part in the rotation of the scene. To ensure this, there is the
     749             :     // SetGlueReallyAbsolute(sal_True);
     750             : 
     751           0 :     double fWinkelInRad = nWink/100 * F_PI180;
     752             : 
     753           0 :     basegfx::B3DHomMatrix aRotateZ;
     754           0 :     aRotateZ.rotate(0.0, 0.0, fWinkelInRad);
     755           0 :     NbcSetTransform(aRotateZ * GetTransform());
     756             : 
     757           0 :     SetRectsDirty();        // This forces a recalculation of all BoundRects
     758           0 :     NbcRotateGluePoints(rRef,nWink,sn,cs);  // Rotate the glue points (who still
     759             :                                             // have coordinates relative to the
     760             :                                             // original page)
     761           0 :     SetGlueReallyAbsolute(sal_False);       // from now they are again relative to BoundRect (that is defined as aOutRect)
     762           0 : }
     763             : 
     764             : /*************************************************************************/
     765             : 
     766             : //////////////////////////////////////////////////////////////////////////////
     767             : 
     768           0 : sdr::properties::BaseProperties* E3dCompoundObject::CreateObjectSpecificProperties()
     769             : {
     770           0 :     return new sdr::properties::E3dCompoundProperties(*this);
     771             : }
     772             : 
     773             : //////////////////////////////////////////////////////////////////////////////
     774             : 
     775        5633 : TYPEINIT1(E3dCompoundObject, E3dObject);
     776             : 
     777           0 : E3dCompoundObject::E3dCompoundObject()
     778             : :   E3dObject(),
     779             :     aMaterialAmbientColor(),
     780             :     bCreateNormals(false),
     781           0 :     bCreateTexture(false)
     782             : {
     783             :     // Set defaults
     784           0 :     E3dDefaultAttributes aDefault;
     785           0 :     SetDefaultAttributes(aDefault);
     786           0 : }
     787             : 
     788           0 : E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault)
     789             : :   E3dObject(),
     790             :     aMaterialAmbientColor(),
     791             :     bCreateNormals(false),
     792           0 :     bCreateTexture(false)
     793             : {
     794             :     // Set defaults
     795           0 :     SetDefaultAttributes(rDefault);
     796           0 : }
     797             : 
     798           0 : void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault)
     799             : {
     800             :     // Set defaults
     801           0 :     aMaterialAmbientColor = rDefault.GetDefaultAmbientColor();
     802             : 
     803           0 :     bCreateNormals = rDefault.GetDefaultCreateNormals();
     804           0 :     bCreateTexture = rDefault.GetDefaultCreateTexture();
     805           0 : }
     806             : 
     807           0 : E3dCompoundObject::~E3dCompoundObject ()
     808             : {
     809           0 : }
     810             : 
     811           0 : basegfx::B2DPolyPolygon E3dCompoundObject::TakeXorPoly() const
     812             : {
     813           0 :     basegfx::B2DPolyPolygon aRetval;
     814           0 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     815           0 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     816           0 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     817             : 
     818           0 :     if(pRootScene)
     819             :     {
     820           0 :         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     821           0 :         const basegfx::B3DPolyPolygon aCubePolyPolygon(CreateWireframe());
     822             :         aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCubePolyPolygon,
     823           0 :             aViewInfo3D.getObjectToView() * GetTransform());
     824           0 :         aRetval.transform(rVCScene.getObjectTransformation());
     825             :     }
     826             : 
     827           0 :     return aRetval;
     828             : }
     829             : 
     830           0 : sal_uInt32 E3dCompoundObject::GetHdlCount() const
     831             : {
     832             :     // 8 corners + 1 E3dVolumeMarker (= Wireframe representation)
     833           0 :     return 9L;
     834             : }
     835             : 
     836           0 : void E3dCompoundObject::AddToHdlList(SdrHdlList& rHdlList) const
     837             : {
     838           0 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     839           0 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     840           0 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     841             : 
     842           0 :     if(pRootScene)
     843             :     {
     844           0 :         const basegfx::B3DRange aBoundVolume(GetBoundVolume());
     845             : 
     846           0 :         if(!aBoundVolume.isEmpty())
     847             :         {
     848           0 :             const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     849             : 
     850           0 :             for(sal_uInt32 a(0); a < 8; a++)
     851             :             {
     852           0 :                 basegfx::B3DPoint aPos3D;
     853             : 
     854           0 :                 switch(a)
     855             :                 {
     856           0 :                     case 0 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     857           0 :                     case 1 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     858           0 :                     case 2 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     859           0 :                     case 3 : aPos3D.setX(aBoundVolume.getMinX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     860           0 :                     case 4 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     861           0 :                     case 5 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMinY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     862           0 :                     case 6 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMinZ()); break;
     863           0 :                     case 7 : aPos3D.setX(aBoundVolume.getMaxX()); aPos3D.setY(aBoundVolume.getMaxY()); aPos3D.setZ(aBoundVolume.getMaxZ()); break;
     864             :                 }
     865             : 
     866             :                 // to 3d view coor
     867           0 :                 aPos3D *= aViewInfo3D.getObjectToView() * GetTransform();
     868             : 
     869             :                 // create 2d relative scene
     870           0 :                 basegfx::B2DPoint aPos2D(aPos3D.getX(), aPos3D.getY());
     871             : 
     872             :                 // to 2d world coor
     873           0 :                 aPos2D *= rVCScene.getObjectTransformation();
     874             : 
     875           0 :                 rHdlList.AddHdl(new SdrHdl(Point(basegfx::fround(aPos2D.getX()), basegfx::fround(aPos2D.getY())), HDL_BWGT));
     876           0 :             }
     877             :         }
     878             :     }
     879             : 
     880           0 :     const basegfx::B2DPolyPolygon aPolyPolygon(TakeXorPoly());
     881             : 
     882           0 :     if(aPolyPolygon.count())
     883             :     {
     884           0 :         E3dVolumeMarker* pVolMarker = new E3dVolumeMarker(aPolyPolygon);
     885           0 :         rHdlList.AddHdl(pVolMarker);
     886           0 :     }
     887           0 : }
     888             : 
     889           0 : sal_uInt16 E3dCompoundObject::GetObjIdentifier() const
     890             : {
     891           0 :     return E3D_COMPOUNDOBJ_ID;
     892             : }
     893             : 
     894           0 : void E3dCompoundObject::RecalcSnapRect()
     895             : {
     896           0 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     897           0 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     898           0 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     899           0 :     maSnapRect = Rectangle();
     900             : 
     901           0 :     if(pRootScene)
     902             :     {
     903             :         // get VC of 3D candidate
     904           0 :         const sdr::contact::ViewContactOfE3d* pVCOfE3D = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&GetViewContact());
     905             : 
     906           0 :         if(pVCOfE3D)
     907             :         {
     908             :             // get 3D primitive sequence
     909           0 :             const drawinglayer::primitive3d::Primitive3DSequence xLocalSequence(pVCOfE3D->getViewIndependentPrimitive3DSequence());
     910             : 
     911           0 :             if(xLocalSequence.hasElements())
     912             :             {
     913             :                 // get BoundVolume
     914             :                 basegfx::B3DRange aBoundVolume(drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
     915           0 :                     xLocalSequence, aViewInfo3D));
     916             : 
     917             :                 // transform bound volume to relative scene coordinates
     918           0 :                 aBoundVolume.transform(aViewInfo3D.getObjectToView());
     919             : 
     920             :                 // build 2d relative scene range
     921             :                 basegfx::B2DRange aSnapRange(
     922             :                     aBoundVolume.getMinX(), aBoundVolume.getMinY(),
     923           0 :                     aBoundVolume.getMaxX(), aBoundVolume.getMaxY());
     924             : 
     925             :                 // transform to 2D world coordiantes
     926           0 :                 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     927           0 :                 aSnapRange.transform(rVCScene.getObjectTransformation());
     928             : 
     929             :                 // snap to integer
     930             :                 maSnapRect = Rectangle(
     931           0 :                     sal_Int32(floor(aSnapRange.getMinX())), sal_Int32(floor(aSnapRange.getMinY())),
     932           0 :                     sal_Int32(ceil(aSnapRange.getMaxX())), sal_Int32(ceil(aSnapRange.getMaxY())));
     933           0 :             }
     934             :         }
     935           0 :     }
     936           0 : }
     937             : 
     938           0 : E3dCompoundObject* E3dCompoundObject::Clone() const
     939             : {
     940           0 :     return CloneHelper< E3dCompoundObject >();
     941             : }
     942             : 
     943             : // convert given basegfx::B3DPolyPolygon to screen coor
     944             : 
     945           0 : basegfx::B2DPolyPolygon E3dCompoundObject::TransformToScreenCoor(const basegfx::B3DPolyPolygon& rCandidate)
     946             : {
     947           0 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     948           0 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     949           0 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, *this);
     950           0 :     basegfx::B2DPolyPolygon aRetval;
     951             : 
     952           0 :     if(pRootScene)
     953             :     {
     954             :         aRetval = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(rCandidate,
     955           0 :             aViewInfo3D.getObjectToView() * GetTransform());
     956           0 :         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     957           0 :         aRetval.transform(rVCScene.getObjectTransformation());
     958             :     }
     959             : 
     960           0 :     return aRetval;
     961             : }
     962             : 
     963           0 : sal_Bool E3dCompoundObject::IsAOrdNumRemapCandidate(E3dScene*& prScene) const
     964             : {
     965           0 :     if(GetObjList()
     966           0 :         && GetObjList()->GetOwnerObj()
     967           0 :         && GetObjList()->GetOwnerObj()->ISA(E3dScene))
     968             :     {
     969           0 :         prScene = (E3dScene*)GetObjList()->GetOwnerObj();
     970           0 :         return sal_True;
     971             :     }
     972             : 
     973           0 :     return sal_False;
     974             : }
     975             : 
     976             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10