LibreOffice Module svx (master)  1
view3d.cxx
Go to the documentation of this file.
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/svdopath.hxx>
22 #include <svx/svditer.hxx>
23 #include <svx/svdmodel.hxx>
24 #include <svx/svdpagv.hxx>
25 #include <editeng/colritem.hxx>
26 #include <editeng/eeitem.hxx>
27 #include <svx/svdview.hxx>
28 #include <svx/strings.hrc>
29 #include <svx/dialmgr.hxx>
30 #include <svx/obj3d.hxx>
31 #include <svx/lathe3d.hxx>
32 #include <extrud3d.hxx>
33 #include <dragmt3d.hxx>
34 #include <svx/scene3d.hxx>
35 #include <svx/view3d.hxx>
36 #include <svx/svdundo.hxx>
37 #include <svx/xflclit.hxx>
38 #include <svx/xlnclit.hxx>
39 #include <svx/xfillit0.hxx>
40 #include <svx/xlineit0.hxx>
43 #include <svx/xlnwtit.hxx>
46 #include <svx/sdrpaintwindow.hxx>
53 #include <svx/e3dsceneupdater.hxx>
54 
55 using namespace com::sun::star;
56 
57 
58 // Migrate Marking
59 
61 {
62  // The OverlayObjects
64 
65  // the view
66  const E3dView& mrView;
67 
68  // the object count
69  size_t mnCount;
70 
71  // the unmirrored polygons
73 
74  // the overlay geometry from selected objects
76 
77  // Copy assignment is forbidden and not implemented.
79  Impl3DMirrorConstructOverlay & operator= (const Impl3DMirrorConstructOverlay &) = delete;
80 
81 public:
82  explicit Impl3DMirrorConstructOverlay(const E3dView& rView);
84 
85  void SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB);
86 };
87 
89 : maObjects(),
90  mrView(rView),
91  mnCount(rView.GetMarkedObjectCount()),
92  mpPolygons(nullptr),
93  maFullOverlay()
94 {
95  if(!mnCount)
96  return;
97 
99  {
100  SdrPageView* pPV = rView.GetSdrPageView();
101 
102  if(pPV && pPV->PageWindowCount())
103  {
104  for(size_t a = 0; a < mnCount; ++a)
105  {
107 
108  if(pObject)
109  {
110  // use the view-independent primitive representation (without
111  // evtl. GridOffset, that may be applied to the DragEntry individually)
114  maFullOverlay.append(aNewSequence);
115  }
116  }
117  }
118  }
119  else
120  {
122 
123  for(size_t a = 0; a < mnCount; ++a)
124  {
126  mpPolygons[mnCount - (a + 1)] = pObject->TakeXorPoly();
127  }
128  }
129 }
130 
132 {
133  // The OverlayObjects are cleared using the destructor of OverlayObjectList.
134  // That destructor calls clear() at the list which removes all objects from the
135  // OverlayManager and deletes them.
136  if(!mrView.IsSolidDragging())
137  {
138  delete[] mpPolygons;
139  }
140 }
141 
142 void Impl3DMirrorConstructOverlay::SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB)
143 {
144  // get rid of old overlay objects
145  maObjects.clear();
146 
147  // create new ones
148  for(sal_uInt32 a(0); a < mrView.PaintWindowCount(); a++)
149  {
150  SdrPaintWindow* pCandidate = mrView.GetPaintWindow(a);
151  const rtl::Reference< sdr::overlay::OverlayManager >& xTargetOverlay = pCandidate->GetOverlayManager();
152 
153  if(xTargetOverlay.is())
154  {
155  // build transformation: translate and rotate so that given edge is
156  // on x axis, them mirror in y and translate back
157  const basegfx::B2DVector aEdge(aMirrorAxisB.X() - aMirrorAxisA.X(), aMirrorAxisB.Y() - aMirrorAxisA.Y());
159  -aMirrorAxisA.X(), -aMirrorAxisA.Y()));
160  aMatrixTransform.rotate(-atan2(aEdge.getY(), aEdge.getX()));
161  aMatrixTransform.scale(1.0, -1.0);
162  aMatrixTransform.rotate(atan2(aEdge.getY(), aEdge.getX()));
163  aMatrixTransform.translate(aMirrorAxisA.X(), aMirrorAxisA.Y());
164 
165  if(mrView.IsSolidDragging())
166  {
167  if(!maFullOverlay.empty())
168  {
170 
171  if(!aMatrixTransform.isIdentity())
172  {
173  // embed in transformation group
174  drawinglayer::primitive2d::Primitive2DReference aTransformPrimitive2D(new drawinglayer::primitive2d::TransformPrimitive2D(aMatrixTransform, aContent));
175  aContent = drawinglayer::primitive2d::Primitive2DContainer { aTransformPrimitive2D };
176  }
177 
178  // if we have full overlay from selected objects, embed with 50% transparence, the
179  // transformation is added to the OverlayPrimitive2DSequenceObject
181  aContent = drawinglayer::primitive2d::Primitive2DContainer { aUnifiedTransparencePrimitive2D };
182 
183  std::unique_ptr<sdr::overlay::OverlayPrimitive2DSequenceObject> pNew(new sdr::overlay::OverlayPrimitive2DSequenceObject(aContent));
184 
185  xTargetOverlay->add(*pNew);
186  maObjects.append(std::move(pNew));
187  }
188  }
189  else
190  {
191  for(size_t b = 0; b < mnCount; ++b)
192  {
193  // apply to polygon
194  basegfx::B2DPolyPolygon aPolyPolygon(mpPolygons[b]);
195  aPolyPolygon.transform(aMatrixTransform);
196 
197  std::unique_ptr<sdr::overlay::OverlayPolyPolygonStripedAndFilled> pNew(new sdr::overlay::OverlayPolyPolygonStripedAndFilled(
198  aPolyPolygon));
199  xTargetOverlay->add(*pNew);
200  maObjects.append(std::move(pNew));
201  }
202  }
203  }
204  }
205 }
206 
208  SdrModel& rSdrModel,
209  OutputDevice* pOut)
210 : SdrView(rSdrModel, pOut)
211 {
212  InitView();
213 }
214 
215 // DrawMarkedObj override, since possibly only a single 3D object is to be
216 // drawn
217 
219 {
220  // Does 3D objects exist which scenes are not selected?
221  bool bSpecialHandling = false;
222  E3dScene *pScene = nullptr;
223 
224  const size_t nCnt = GetMarkedObjectCount();
225  for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
226  {
227  SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
228  if(auto pCompoundObject = dynamic_cast<E3dCompoundObject*>(pObj))
229  {
230  // related scene
231  pScene = pCompoundObject->getRootE3dSceneFromE3dObject();
232 
233  if(nullptr != pScene && !IsObjMarked(pScene))
234  {
235  bSpecialHandling = true;
236  }
237  }
238  // Reset all selection flags
239  if(auto p3dObject = dynamic_cast< const E3dObject*>(pObj))
240  {
241  pScene = p3dObject->getRootE3dSceneFromE3dObject();
242 
243  if(nullptr != pScene)
244  {
245  pScene->SetSelected(false);
246  }
247  }
248  }
249 
250  if(bSpecialHandling)
251  {
252  // Set selection flag to "not selected" for scenes related to all 3D
253  // objects
254  for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
255  {
256  SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
257  if(auto pCompoundObject = dynamic_cast<E3dCompoundObject*>(pObj))
258  {
259  // related scene
260  pScene = pCompoundObject->getRootE3dSceneFromE3dObject();
261 
262  if(nullptr != pScene)
263  {
264  pScene->SetSelected(false);
265  }
266  }
267  }
268 
269  for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
270  {
271  SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
272  if(auto p3DObj = dynamic_cast<E3dObject*>(pObj))
273  {
274  // Select object
275  p3DObj->SetSelected(true);
276  pScene = p3DObj->getRootE3dSceneFromE3dObject();
277  }
278  }
279 
280  if(nullptr != pScene)
281  {
282  // code from parent
284 
285  pScene->SetDrawOnlySelected(true);
286  pScene->SingleObjectPainter(rOut);
287  pScene->SetDrawOnlySelected(false);
288  }
289 
290  // Reset selection flag
291  for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
292  {
293  SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
294  if(auto pCompoundObject = dynamic_cast<E3dCompoundObject*>(pObj))
295  {
296  // related scene
297  pScene = pCompoundObject->getRootE3dSceneFromE3dObject();
298 
299  if(nullptr != pScene)
300  {
301  pScene->SetSelected(false);
302  }
303  }
304  }
305  }
306  else
307  {
308  // call parent
310  }
311 }
312 
313 // override get model, since in some 3D objects an additional scene
314 // must be pushed in
315 
316 std::unique_ptr<SdrModel> E3dView::CreateMarkedObjModel() const
317 {
318  // Does 3D objects exist which scenes are not selected?
319  bool bSpecialHandling(false);
320  const size_t nCount(GetMarkedObjectCount());
321  E3dScene *pScene = nullptr;
322 
323  for(size_t nObjs = 0; nObjs < nCount; ++nObjs)
324  {
325  const SdrObject* pObj = GetMarkedObjectByIndex(nObjs);
326 
327  if(!bSpecialHandling && dynamic_cast< const E3dCompoundObject*>(pObj))
328  {
329  // if the object is selected, but it's scene not,
330  // we need special handling
331  pScene = static_cast<const E3dCompoundObject*>(pObj)->getRootE3dSceneFromE3dObject();
332 
333  if(nullptr != pScene && !IsObjMarked(pScene))
334  {
335  bSpecialHandling = true;
336  }
337  }
338 
339  if(auto p3dObject = dynamic_cast< const E3dObject*>(pObj))
340  {
341  // reset all selection flags at 3D objects
342  pScene = p3dObject->getRootE3dSceneFromE3dObject();
343 
344  if(nullptr != pScene)
345  {
346  pScene->SetSelected(false);
347  }
348  }
349  }
350 
351  if(!bSpecialHandling)
352  {
353  // call parent
355  }
356 
357  std::unique_ptr<SdrModel> pNewModel;
358  tools::Rectangle aSelectedSnapRect;
359 
360  // set 3d selection flags at all directly selected objects
361  // and collect SnapRect of selected objects
362  for(size_t nObjs = 0; nObjs < nCount; ++nObjs)
363  {
364  SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
365 
366  if(auto p3DObj = dynamic_cast<E3dCompoundObject*>(pObj))
367  {
368  // mark object, but not scenes
369  p3DObj->SetSelected(true);
370  aSelectedSnapRect.Union(p3DObj->GetSnapRect());
371  }
372  }
373 
374  // create new mark list which contains all indirectly selected3d
375  // scenes as selected objects
377  SdrMarkList aNewML;
378  SdrMarkList& rCurrentMarkList = const_cast<E3dView*>(this)->GetMarkedObjectListWriteAccess();
379  rCurrentMarkList = aNewML;
380 
381  for(size_t nObjs = 0; nObjs < nCount; ++nObjs)
382  {
383  SdrObject *pObj = aOldML.GetMark(nObjs)->GetMarkedSdrObj();
384 
385  if(auto p3dObject = dynamic_cast< E3dObject* >(pObj))
386  {
387  pScene = p3dObject->getRootE3dSceneFromE3dObject();
388 
389  if(nullptr != pScene && !IsObjMarked(pScene) && GetSdrPageView())
390  {
391  const_cast<E3dView*>(this)->MarkObj(pScene, GetSdrPageView(), false, true);
392  }
393  }
394  }
395 
396  // call parent. This will copy all scenes and the selection flags at the 3D objects. So
397  // it will be possible to delete all non-selected 3d objects from the cloned 3d scenes
398  pNewModel = SdrView::CreateMarkedObjModel();
399 
400  if(pNewModel)
401  {
402  for(sal_uInt16 nPg(0); nPg < pNewModel->GetPageCount(); nPg++)
403  {
404  const SdrPage* pSrcPg=pNewModel->GetPage(nPg);
405  const size_t nObjCount(pSrcPg->GetObjCount());
406 
407  for(size_t nOb = 0; nOb < nObjCount; ++nOb)
408  {
409  const SdrObject* pSrcOb=pSrcPg->GetObj(nOb);
410 
411  if(auto p3dscene = dynamic_cast< const E3dScene* >( pSrcOb))
412  {
413  pScene = const_cast<E3dScene*>(p3dscene);
414 
415  // delete all not intentionally cloned 3d objects
416  pScene->removeAllNonSelectedObjects();
417 
418  // reset select flags and set SnapRect of all selected objects
419  pScene->SetSelected(false);
420  pScene->SetSnapRect(aSelectedSnapRect);
421  }
422  }
423  }
424  }
425 
426  // restore old selection
427  rCurrentMarkList = aOldML;
428 
429  return pNewModel;
430 }
431 
432 // When pasting objects have to integrated if a scene is inserted, but
433 // not the scene itself
434 
436  const SdrModel& rMod, const Point& rPos, SdrObjList* pLst, SdrInsertFlags nOptions)
437 {
438  bool bRetval = false;
439 
440  // Get list
441  Point aPos(rPos);
442  SdrObjList* pDstList = pLst;
443  ImpGetPasteObjList(aPos, pDstList);
444 
445  if(!pDstList)
446  return false;
447 
448  // Get owner of the list
449  E3dScene* pDstScene(dynamic_cast< E3dScene* >(pDstList->getSdrObjectFromSdrObjList()));
450 
451  if(nullptr != pDstScene)
452  {
453  BegUndo(SvxResId(RID_SVX_3D_UNDO_EXCHANGE_PASTE));
454 
455  // Copy all objects from E3dScenes and insert them directly
456  for(sal_uInt16 nPg(0); nPg < rMod.GetPageCount(); nPg++)
457  {
458  const SdrPage* pSrcPg=rMod.GetPage(nPg);
459  const size_t nObjCount(pSrcPg->GetObjCount());
460 
461  // calculate offset for paste
462  tools::Rectangle aR = pSrcPg->GetAllObjBoundRect();
463  Point aDist(aPos - aR.Center());
464 
465  // Insert sub-objects for scenes
466  for(size_t nOb = 0; nOb < nObjCount; ++nOb)
467  {
468  const SdrObject* pSrcOb = pSrcPg->GetObj(nOb);
469  if(auto p3dscene = dynamic_cast< const E3dScene* >(pSrcOb))
470  {
471  E3dScene* pSrcScene = const_cast<E3dScene*>(p3dscene);
472  ImpCloneAll3DObjectsToDestScene(pSrcScene, pDstScene, aDist);
473  }
474  }
475  }
476  EndUndo();
477  }
478  else
479  {
480  // call parent
481  bRetval = SdrView::Paste(rMod, rPos, pLst, nOptions);
482  }
483 
484  return bRetval;
485 }
486 
487 // Service routine used from local Clone() and from SdrCreateView::EndCreateObj(...)
488 bool E3dView::ImpCloneAll3DObjectsToDestScene(E3dScene const * pSrcScene, E3dScene* pDstScene, Point /*aOffset*/)
489 {
490  bool bRetval(false);
491 
492  if(pSrcScene && pDstScene)
493  {
494  for(size_t i = 0; i < pSrcScene->GetSubList()->GetObjCount(); ++i)
495  {
496  E3dCompoundObject* pCompoundObj = dynamic_cast< E3dCompoundObject* >(pSrcScene->GetSubList()->GetObj(i));
497 
498  if(pCompoundObj)
499  {
500  E3dCompoundObject* pNewCompoundObj(pCompoundObj->CloneSdrObject(pDstScene->getSdrModelFromSdrObject()));
501 
502  if(pNewCompoundObj)
503  {
504  // get dest scene's current range in 3D world coordinates
505  const basegfx::B3DHomMatrix aSceneToWorldTrans(pDstScene->GetFullTransform());
506  basegfx::B3DRange aSceneRange(pDstScene->GetBoundVolume());
507  aSceneRange.transform(aSceneToWorldTrans);
508 
509  // get new object's implied object transformation
510  const basegfx::B3DHomMatrix aNewObjectTrans(pNewCompoundObj->GetTransform());
511 
512  // get new object's range in 3D world coordinates in dest scene
513  // as if it were already added
514  const basegfx::B3DHomMatrix aObjectToWorldTrans(aSceneToWorldTrans * aNewObjectTrans);
515  basegfx::B3DRange aObjectRange(pNewCompoundObj->GetBoundVolume());
516  aObjectRange.transform(aObjectToWorldTrans);
517 
518  // get scale adaptation
519  const basegfx::B3DVector aSceneScale(aSceneRange.getRange());
520  const basegfx::B3DVector aObjectScale(aObjectRange.getRange());
521  double fScale(1.0);
522 
523  // if new object's size in X,Y or Z is bigger that 80% of dest scene, adapt scale
524  // to not change the scene by the inserted object
525  const double fSizeFactor(0.5);
526 
527  if(aObjectScale.getX() * fScale > aSceneScale.getX() * fSizeFactor)
528  {
529  const double fObjSize(aObjectScale.getX() * fScale);
530  const double fFactor((aSceneScale.getX() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
531  fScale *= fFactor;
532  }
533 
534  if(aObjectScale.getY() * fScale > aSceneScale.getY() * fSizeFactor)
535  {
536  const double fObjSize(aObjectScale.getY() * fScale);
537  const double fFactor((aSceneScale.getY() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
538  fScale *= fFactor;
539  }
540 
541  if(aObjectScale.getZ() * fScale > aSceneScale.getZ() * fSizeFactor)
542  {
543  const double fObjSize(aObjectScale.getZ() * fScale);
544  const double fFactor((aSceneScale.getZ() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
545  fScale *= fFactor;
546  }
547 
548  // get translation adaptation
549  const basegfx::B3DPoint aSceneCenter(aSceneRange.getCenter());
550  const basegfx::B3DPoint aObjectCenter(aObjectRange.getCenter());
551 
552  // build full modification transform. The object's transformation
553  // shall be modified, so start at object coordinates; transform to 3d world coor
554  basegfx::B3DHomMatrix aModifyingTransform(aObjectToWorldTrans);
555 
556  // translate to absolute center in 3d world coor
557  aModifyingTransform.translate(-aObjectCenter.getX(), -aObjectCenter.getY(), -aObjectCenter.getZ());
558 
559  // scale to dest size in 3d world coor
560  aModifyingTransform.scale(fScale, fScale, fScale);
561 
562  // translate to dest scene center in 3d world coor
563  aModifyingTransform.translate(aSceneCenter.getX(), aSceneCenter.getY(), aSceneCenter.getZ());
564 
565  // transform from 3d world to dest object coordinates
566  basegfx::B3DHomMatrix aWorldToObject(aObjectToWorldTrans);
567  aWorldToObject.invert();
568  aModifyingTransform = aWorldToObject * aModifyingTransform;
569 
570  // correct implied object transform by applying changing one in object coor
571  pNewCompoundObj->SetTransform(aModifyingTransform * aNewObjectTrans);
572 
573  // fill and insert new object
574  pNewCompoundObj->NbcSetLayer(pCompoundObj->GetLayer());
575  pNewCompoundObj->NbcSetStyleSheet(pCompoundObj->GetStyleSheet(), true);
576  pDstScene->InsertObject(pNewCompoundObj);
577  bRetval = true;
578 
579  // Create undo
580  if( GetModel()->IsUndoEnabled() )
581  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNewCompoundObj));
582  }
583  }
584  }
585  }
586 
587  return bRetval;
588 }
589 
591 {
592  bool bAny3D(false);
593  bool bGroupSelected(false);
594  bool bRetval(true);
595 
596  for(size_t a=0; !bAny3D && a<GetMarkedObjectCount(); ++a)
597  {
599  if(pObj)
600  {
601  ImpIsConvertTo3DPossible(pObj, bAny3D, bGroupSelected);
602  }
603  }
604 
605  bRetval = !bAny3D
606  && (
609  || IsImportMtfPossible());
610  return bRetval;
611 }
612 
613 void E3dView::ImpIsConvertTo3DPossible(SdrObject const * pObj, bool& rAny3D,
614  bool& rGroupSelected) const
615 {
616  if(!pObj)
617  return;
618 
619  if(dynamic_cast< const E3dObject* >(pObj) != nullptr)
620  {
621  rAny3D = true;
622  }
623  else
624  {
625  if(pObj->IsGroupObject())
626  {
628  while(aIter.IsMore())
629  {
630  SdrObject* pNewObj = aIter.Next();
631  ImpIsConvertTo3DPossible(pNewObj, rAny3D, rGroupSelected);
632  }
633  rGroupSelected = true;
634  }
635  }
636 }
637 
639 {
640  if(dynamic_cast<const SdrTextObj*>( pObj) == nullptr)
641  return;
642 
643  const SfxItemSet& rSet = pObj->GetMergedItemSet();
644  const SvxColorItem& rTextColorItem = rSet.Get(EE_CHAR_COLOR);
645  if(rTextColorItem.GetValue() != COL_BLACK)
646  return;
647 
648  //For black text objects, the color set to gray
649  if(pObj->getSdrPageFromSdrObject())
650  {
651  // if black is only default attribute from
652  // pattern set it hard so that it is used in undo.
654 
655  // add undo now
656  if( GetModel()->IsUndoEnabled() )
657  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
658  }
659 
661 }
662 
664 {
665  if(dynamic_cast<const SdrPathObj*>( pObj) == nullptr)
666  return;
667 
668  const SfxItemSet& rSet = pObj->GetMergedItemSet();
669  sal_Int32 nLineWidth = rSet.Get(XATTR_LINEWIDTH).GetValue();
670  drawing::LineStyle eLineStyle = rSet.Get(XATTR_LINESTYLE).GetValue();
671  drawing::FillStyle eFillStyle = rSet.Get(XATTR_FILLSTYLE).GetValue();
672 
673  if(static_cast<SdrPathObj*>(pObj)->IsClosed()
674  && eLineStyle == drawing::LineStyle_SOLID
675  && !nLineWidth
676  && eFillStyle != drawing::FillStyle_NONE)
677  {
678  if(pObj->getSdrPageFromSdrObject() && GetModel()->IsUndoEnabled() )
679  {
680  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
681  }
682 
683  pObj->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
684  pObj->SetMergedItem(XLineWidthItem(0));
685  }
686 }
687 
688 void E3dView::ImpCreateSingle3DObjectFlat(E3dScene* pScene, SdrObject* pObj, bool bExtrude, double fDepth, basegfx::B2DHomMatrix const & rLatheMat)
689 {
690  // Single PathObject, transform this
691  SdrPathObj* pPath = dynamic_cast<SdrPathObj*>( pObj );
692 
693  if(!pPath)
694  return;
695 
696  E3dDefaultAttributes aDefault = Get3DDefaultAttributes();
697 
698  if(bExtrude)
699  {
700  aDefault.SetDefaultExtrudeCharacterMode(true);
701  }
702  else
703  {
704  aDefault.SetDefaultLatheCharacterMode(true);
705  }
706 
707  // Get Itemset of the original object
708  SfxItemSet aSet(pObj->GetMergedItemSet());
709 
710  drawing::FillStyle eFillStyle = aSet.Get(XATTR_FILLSTYLE).GetValue();
711 
712  // line style turned off
713  aSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
714 
715  //Determining if FILL_Attribute is set.
716  if(!pPath->IsClosed() || eFillStyle == drawing::FillStyle_NONE)
717  {
718  // This SdrPathObj is not filled, leave the front and rear face out.
719  // Moreover, a two-sided representation necessary.
720  aDefault.SetDefaultExtrudeCloseFront(false);
721  aDefault.SetDefaultExtrudeCloseBack(false);
722 
723  aSet.Put(makeSvx3DDoubleSidedItem(true));
724 
725  // Set fill attribute
726  aSet.Put(XFillStyleItem(drawing::FillStyle_SOLID));
727 
728  // Fill color must be the color line, because the object was
729  // previously just a line
730  Color aColorLine = aSet.Get(XATTR_LINECOLOR).GetColorValue();
731  aSet.Put(XFillColorItem(OUString(), aColorLine));
732  }
733 
734  // Create a new extrude object
735  E3dObject* p3DObj = nullptr;
736  if(bExtrude)
737  {
738  p3DObj = new E3dExtrudeObj(pObj->getSdrModelFromSdrObject(), aDefault, pPath->GetPathPoly(), fDepth);
739  }
740  else
741  {
742  // rLatheMat expects coordinates with y-axis up, pPath uses y-axis down
743  basegfx::B2DHomMatrix aFlipVerticalMat(1.0, 0.0, 0.0, 0.0, -1.0, 0.0);
744  basegfx::B2DPolyPolygon aPolyPoly2D(pPath->GetPathPoly());
745  aPolyPoly2D.transform(aFlipVerticalMat);
746  aPolyPoly2D.transform(rLatheMat);
747  // ctor E3dLatheObj expects coordinates with y-axis down
748  aPolyPoly2D.transform(aFlipVerticalMat);
749  p3DObj = new E3dLatheObj(pObj->getSdrModelFromSdrObject(), aDefault, aPolyPoly2D);
750  }
751 
752  // Set attribute
753  p3DObj->NbcSetLayer(pObj->GetLayer());
754 
755  p3DObj->SetMergedItemSet(aSet);
756 
757  p3DObj->NbcSetStyleSheet(pObj->GetStyleSheet(), true);
758 
759  // Insert a new extrude object
760  pScene->InsertObject(p3DObj);
761 }
762 
763 void E3dView::ImpCreate3DObject(E3dScene* pScene, SdrObject* pObj, bool bExtrude, double fDepth, basegfx::B2DHomMatrix const & rLatheMat)
764 {
765  if(!pObj)
766  return;
767 
768  // change text color attribute for not so dark colors
769  if(pObj->IsGroupObject())
770  {
772  while(aIter.IsMore())
773  {
774  SdrObject* pGroupMember = aIter.Next();
776  }
777  }
778  else
780 
781  // convert completely to path objects
782  SdrObject* pNewObj1 = pObj->ConvertToPolyObj(false, false).release();
783 
784  if(!pNewObj1)
785  return;
786 
787  // change text color attribute for not so dark colors
788  if(pNewObj1->IsGroupObject())
789  {
791  while(aIter.IsMore())
792  {
793  SdrObject* pGroupMember = aIter.Next();
795  }
796  }
797  else
799 
800  // convert completely to path objects
801  SdrObject* pNewObj2 = pObj->ConvertToContourObj(pNewObj1, true);
802 
803  if(pNewObj2)
804  {
805  // add all to flat scene
806  if(pNewObj2->IsGroupObject())
807  {
809  while(aIter.IsMore())
810  {
811  SdrObject* pGroupMember = aIter.Next();
812  ImpCreateSingle3DObjectFlat(pScene, pGroupMember, bExtrude, fDepth, rLatheMat);
813  }
814  }
815  else
816  ImpCreateSingle3DObjectFlat(pScene, pNewObj2, bExtrude, fDepth, rLatheMat);
817 
818  // delete object in between
819  if (pNewObj2 != pObj && pNewObj2 != pNewObj1)
820  SdrObject::Free( pNewObj2 );
821  }
822 
823  // delete object in between
824  if (pNewObj1 != pObj)
825  SdrObject::Free( pNewObj1 );
826 }
827 
828 void E3dView::ConvertMarkedObjTo3D(bool bExtrude, const basegfx::B2DPoint& rPnt1, const basegfx::B2DPoint& rPnt2)
829 {
830  if(!AreObjectsMarked())
831  return;
832 
833  // Create undo
834  if(bExtrude)
835  BegUndo(SvxResId(RID_SVX_3D_UNDO_EXTRUDE));
836  else
837  BegUndo(SvxResId(RID_SVX_3D_UNDO_LATHE));
838 
839  SdrModel& rSdrModel(GetSdrMarkByIndex(0)->GetMarkedSdrObj()->getSdrModelFromSdrObject());
840 
841  // Create a new scene for the created 3D object
842  E3dScene* pScene = new E3dScene(rSdrModel);
843 
844  // Determine rectangle and possibly correct it
846  if(aRect.GetWidth() <= 1)
847  aRect.SetSize(Size(500, aRect.GetHeight()));
848  if(aRect.GetHeight() <= 1)
849  aRect.SetSize(Size(aRect.GetWidth(), 500));
850 
851  // Determine the depth relative to the size of the selection
852  double fDepth = 0.0;
853  double fRot3D = 0.0;
854  basegfx::B2DHomMatrix aLatheMat;
855 
856  if(bExtrude)
857  {
858  double fW = static_cast<double>(aRect.GetWidth());
859  double fH = static_cast<double>(aRect.GetHeight());
860  fDepth = sqrt(fW*fW + fH*fH) / 6.0;
861  }
862  if(!bExtrude)
863  {
864  // Create transformation for the polygons rotating body
865  if (rPnt1 != rPnt2)
866  {
867  // Rotation around control point #1 with set angle
868  // for 3D coordinates
869  basegfx::B2DPoint aDiff(rPnt1 - rPnt2);
870  fRot3D = atan2(aDiff.getY(), aDiff.getX()) - F_PI2;
871 
872  if(basegfx::fTools::equalZero(fabs(fRot3D)))
873  fRot3D = 0.0;
874 
875  if(fRot3D != 0.0)
876  {
877  aLatheMat = basegfx::utils::createRotateAroundPoint(rPnt2, -fRot3D)
878  * aLatheMat;
879  }
880  }
881 
882  if (rPnt2.getX() != 0.0)
883  {
884  // Translation to Y=0 - axis
885  aLatheMat.translate(-rPnt2.getX(), 0.0);
886  }
887  else
888  {
889  aLatheMat.translate(static_cast<double>(-aRect.Left()), 0.0);
890  }
891 
892  // Form the inverse matrix to determine the target expansion
893  basegfx::B2DHomMatrix aInvLatheMat(aLatheMat);
894  aInvLatheMat.invert();
895 
896  // SnapRect extension enables mirroring in the axis of rotation
897  for(size_t a=0; a<GetMarkedObjectCount(); ++a)
898  {
899  SdrMark* pMark = GetSdrMarkByIndex(a);
900  SdrObject* pObj = pMark->GetMarkedSdrObj();
901  tools::Rectangle aTurnRect = pObj->GetSnapRect();
902  basegfx::B2DPoint aRot;
903  Point aRotPnt;
904 
905  aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Top());
906  aRot *= aLatheMat;
907  aRot.setX(-aRot.getX());
908  aRot *= aInvLatheMat;
909  aRotPnt = Point(static_cast<long>(aRot.getX() + 0.5), static_cast<long>(-aRot.getY() - 0.5));
910  aRect.Union(tools::Rectangle(aRotPnt, aRotPnt));
911 
912  aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Bottom());
913  aRot *= aLatheMat;
914  aRot.setX(-aRot.getX());
915  aRot *= aInvLatheMat;
916  aRotPnt = Point(static_cast<long>(aRot.getX() + 0.5), static_cast<long>(-aRot.getY() - 0.5));
917  aRect.Union(tools::Rectangle(aRotPnt, aRotPnt));
918 
919  aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Top());
920  aRot *= aLatheMat;
921  aRot.setX(-aRot.getX());
922  aRot *= aInvLatheMat;
923  aRotPnt = Point(static_cast<long>(aRot.getX() + 0.5), static_cast<long>(-aRot.getY() - 0.5));
924  aRect.Union(tools::Rectangle(aRotPnt, aRotPnt));
925 
926  aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Bottom());
927  aRot *= aLatheMat;
928  aRot.setX(-aRot.getX());
929  aRot *= aInvLatheMat;
930  aRotPnt = Point(static_cast<long>(aRot.getX() + 0.5), static_cast<long>(-aRot.getY() - 0.5));
931  aRect.Union(tools::Rectangle(aRotPnt, aRotPnt));
932  }
933  }
934 
935  // Walk through the selection and convert it into 3D, complete with
936  // Conversion to SdrPathObject, also fonts
937  for(size_t a=0; a<GetMarkedObjectCount(); ++a)
938  {
939  SdrMark* pMark = GetSdrMarkByIndex(a);
940  SdrObject* pObj = pMark->GetMarkedSdrObj();
941 
942  ImpCreate3DObject(pScene, pObj, bExtrude, fDepth, aLatheMat);
943  }
944 
945  if(pScene->GetSubList() && pScene->GetSubList()->GetObjCount() != 0)
946  {
947  // Arrange all created objects by depth
948  if(bExtrude)
949  DoDepthArrange(pScene, fDepth);
950 
951  // Center 3D objects in the middle of the overall rectangle
952  basegfx::B3DPoint aCenter(pScene->GetBoundVolume().getCenter());
953  basegfx::B3DHomMatrix aMatrix;
954 
955  aMatrix.translate(-aCenter.getX(), -aCenter.getY(), -aCenter.getZ());
956  pScene->SetTransform(aMatrix * pScene->GetTransform());
957 
958  // Initialize scene
959  pScene->NbcSetSnapRect(aRect);
960  basegfx::B3DRange aBoundVol = pScene->GetBoundVolume();
961  InitScene(pScene, static_cast<double>(aRect.GetWidth()), static_cast<double>(aRect.GetHeight()), aBoundVol.getDepth());
962 
963  // Insert scene instead of the first selected object and throw away
964  // all the old objects
965  SdrObject* pRepObj = GetMarkedObjectByIndex(0);
967  MarkObj(pRepObj, pPV, true);
968  ReplaceObjectAtView(pRepObj, *pPV, pScene, false);
969  DeleteMarked();
970  MarkObj(pScene, pPV);
971 
972  // Rotate Rotation body around the axis of rotation
973  if(!bExtrude && fRot3D != 0.0)
974  {
975  basegfx::B3DHomMatrix aRotate;
976  aRotate.rotate(0.0, 0.0, fRot3D);
977  pScene->SetTransform(aRotate * pScene->GetTransform());
978  }
979 
980  // Set default rotation
981  {
982  basegfx::B3DHomMatrix aRotate;
983  aRotate.rotate(DEG2RAD(20.0), 0.0, 0.0);
984  // E3DModifySceneSnapRectUpdater updates the 2D representation of the scene.
985  // It prepares things in ctor and acts in dtor.
987  pScene->SetTransform(aRotate * pScene->GetTransform());
988  }
989  }
990  else
991  {
992  // No 3D object was created, throw away everything
993  // always use SdrObject::Free(...) for SdrObjects (!)
994  SdrObject* pTemp(pScene);
995  SdrObject::Free(pTemp);
996  }
997 
998  EndUndo();
999 }
1000 
1001 //Arrange all created extrude objects by depth
1002 
1003 namespace {
1004 
1005 struct E3dDepthNeighbour
1006 {
1007  E3dExtrudeObj* mpObj;
1008  basegfx::B2DPolyPolygon maPreparedPolyPolygon;
1009 
1010  E3dDepthNeighbour(E3dExtrudeObj* pObj, basegfx::B2DPolyPolygon const & rPreparedPolyPolygon)
1011  : mpObj(pObj),
1012  maPreparedPolyPolygon(rPreparedPolyPolygon)
1013  {
1014  }
1015 };
1016 
1017 struct E3dDepthLayer
1018 {
1019  E3dDepthLayer* mpDown;
1020  std::vector<E3dDepthNeighbour> mvNeighbours;
1021 
1022  E3dDepthLayer()
1023  : mpDown(nullptr)
1024  {
1025  }
1026 };
1027 
1028 }
1029 
1030 void E3dView::DoDepthArrange(E3dScene const * pScene, double fDepth)
1031 {
1032  if(!(pScene && pScene->GetSubList() && pScene->GetSubList()->GetObjCount() > 1))
1033  return;
1034 
1035  SdrObjList* pSubList = pScene->GetSubList();
1036  SdrObjListIter aIter(pSubList, SdrIterMode::Flat);
1037  E3dDepthLayer* pBaseLayer = nullptr;
1038  E3dDepthLayer* pLayer = nullptr;
1039  sal_Int32 nNumLayers = 0;
1040 
1041  while(aIter.IsMore())
1042  {
1043  E3dExtrudeObj* pExtrudeObj = dynamic_cast< E3dExtrudeObj* >(aIter.Next());
1044 
1045  if(pExtrudeObj)
1046  {
1047  const basegfx::B2DPolyPolygon aExtrudePoly(
1048  basegfx::utils::prepareForPolygonOperation(pExtrudeObj->GetExtrudePolygon()));
1049  const SfxItemSet& rLocalSet = pExtrudeObj->GetMergedItemSet();
1050  const drawing::FillStyle eLocalFillStyle = rLocalSet.Get(XATTR_FILLSTYLE).GetValue();
1051  const Color aLocalColor = rLocalSet.Get(XATTR_FILLCOLOR).GetColorValue();
1052 
1053  // sort in ExtrudeObj
1054  if(pLayer)
1055  {
1056  // do we have overlap with an object of this layer?
1057  bool bOverlap(false);
1058 
1059  for(const auto& rAct : pLayer->mvNeighbours)
1060  {
1061  // do rAct.mpObj and pExtrudeObj overlap? Check by
1062  // using logical AND clipping
1063  const basegfx::B2DPolyPolygon aAndPolyPolygon(
1065  aExtrudePoly,
1066  rAct.maPreparedPolyPolygon));
1067 
1068  if(aAndPolyPolygon.count() != 0)
1069  {
1070  // second criteria: is another fillstyle or color used?
1071  const SfxItemSet& rCompareSet = rAct.mpObj->GetMergedItemSet();
1072 
1073  drawing::FillStyle eCompareFillStyle = rCompareSet.Get(XATTR_FILLSTYLE).GetValue();
1074 
1075  if(eLocalFillStyle == eCompareFillStyle)
1076  {
1077  if(eLocalFillStyle == drawing::FillStyle_SOLID)
1078  {
1079  Color aCompareColor = rCompareSet.Get(XATTR_FILLCOLOR).GetColorValue();
1080 
1081  if(aCompareColor == aLocalColor)
1082  {
1083  continue;
1084  }
1085  }
1086  else if(eLocalFillStyle == drawing::FillStyle_NONE)
1087  {
1088  continue;
1089  }
1090  }
1091 
1092  bOverlap = true;
1093  break;
1094  }
1095  }
1096 
1097  if(bOverlap)
1098  {
1099  // yes, start a new layer
1100  pLayer->mpDown = new E3dDepthLayer;
1101  pLayer = pLayer->mpDown;
1102  nNumLayers++;
1103  pLayer->mvNeighbours.emplace_back(pExtrudeObj, aExtrudePoly);
1104  }
1105  else
1106  {
1107  // no, add to current layer
1108  pLayer->mvNeighbours.emplace(pLayer->mvNeighbours.begin(), pExtrudeObj, aExtrudePoly);
1109  }
1110  }
1111  else
1112  {
1113  // first layer ever
1114  pBaseLayer = new E3dDepthLayer;
1115  pLayer = pBaseLayer;
1116  nNumLayers++;
1117  pLayer->mvNeighbours.emplace_back(pExtrudeObj, aExtrudePoly);
1118  }
1119  }
1120  }
1121 
1122  // number of layers is done
1123  if(nNumLayers > 1)
1124  {
1125  // need to be arranged
1126  double fMinDepth = fDepth * 0.8;
1127  double fStep = (fDepth - fMinDepth) / static_cast<double>(nNumLayers);
1128  pLayer = pBaseLayer;
1129 
1130  while(pLayer)
1131  {
1132  // move along layer
1133  for(auto& rAct : pLayer->mvNeighbours)
1134  {
1135  // adapt extrude value
1136  rAct.mpObj->SetMergedItem(SfxUInt32Item(SDRATTR_3DOBJ_DEPTH, sal_uInt32(fMinDepth + 0.5)));
1137  }
1138 
1139  // next layer
1140  pLayer = pLayer->mpDown;
1141  fMinDepth += fStep;
1142  }
1143  }
1144 
1145  // cleanup
1146  while(pBaseLayer)
1147  {
1148  pLayer = pBaseLayer->mpDown;
1149  delete pBaseLayer;
1150  pBaseLayer = pLayer;
1151  }
1152 }
1153 
1154 // Start drag, create for 3D objects before possibly drag method
1155 
1156 bool E3dView::BegDragObj(const Point& rPnt, OutputDevice* pOut,
1157  SdrHdl* pHdl, short nMinMov,
1158  SdrDragMethod* pForcedMeth)
1159 {
1161  {
1162  // Determine all selected polygons and return the mirrored helper overlay
1163  mpMirrorOverlay->SetMirrorAxis(maRef1, maRef2);
1164  }
1165  else
1166  {
1167  bool bOwnActionNecessary;
1168  if (pHdl == nullptr)
1169  {
1170  bOwnActionNecessary = true;
1171  }
1172  else if (pHdl->IsVertexHdl() || pHdl->IsCornerHdl())
1173  {
1174  bOwnActionNecessary = true;
1175  }
1176  else
1177  {
1178  bOwnActionNecessary = false;
1179  }
1180 
1181  if(bOwnActionNecessary && GetMarkedObjectCount() > 0)
1182  {
1184  bool bThereAreRootScenes = false;
1185  bool bThereAre3DObjects = false;
1186  const size_t nCnt = GetMarkedObjectCount();
1187  for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
1188  {
1189  SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
1190  if(pObj)
1191  {
1192  if(nullptr != dynamic_cast< const E3dScene* >(pObj) && static_cast< E3dScene* >(pObj)->getRootE3dSceneFromE3dObject() == pObj)
1193  {
1194  bThereAreRootScenes = true;
1195  }
1196 
1197  if(dynamic_cast< const E3dObject* >(pObj) != nullptr)
1198  {
1199  bThereAre3DObjects = true;
1200  }
1201  }
1202  }
1203  if( bThereAre3DObjects )
1204  {
1205  meDragHdl = ( pHdl == nullptr ? SdrHdlKind::Move : pHdl->GetKind() );
1206  switch ( meDragMode )
1207  {
1208  case SdrDragMode::Rotate:
1209  case SdrDragMode::Shear:
1210  {
1211  switch ( meDragHdl )
1212  {
1213  case SdrHdlKind::Left:
1214  case SdrHdlKind::Right:
1215  {
1216  eConstraint = E3dDragConstraint::X;
1217  }
1218  break;
1219 
1220  case SdrHdlKind::Upper:
1221  case SdrHdlKind::Lower:
1222  {
1223  eConstraint = E3dDragConstraint::Y;
1224  }
1225  break;
1226 
1227  case SdrHdlKind::UpperLeft:
1229  case SdrHdlKind::LowerLeft:
1231  {
1232  eConstraint = E3dDragConstraint::Z;
1233  }
1234  break;
1235  default: break;
1236  }
1237 
1238  // do not mask the allowed rotations
1239  eConstraint &= E3dDragConstraint::XYZ;
1240  pForcedMeth = new E3dDragRotate(*this, GetMarkedObjectList(), eConstraint, IsSolidDragging());
1241  }
1242  break;
1243 
1244  case SdrDragMode::Move:
1245  {
1246  if(!bThereAreRootScenes)
1247  {
1248  pForcedMeth = new E3dDragMove(*this, GetMarkedObjectList(), meDragHdl, eConstraint, IsSolidDragging());
1249  }
1250  }
1251  break;
1252 
1253  // later on
1254  case SdrDragMode::Mirror:
1255  case SdrDragMode::Crook:
1257  case SdrDragMode::Gradient:
1258  default:
1259  {
1260  }
1261  break;
1262  }
1263  }
1264  }
1265  }
1266  return SdrView::BegDragObj(rPnt, pOut, pHdl, nMinMov, pForcedMeth);
1267 }
1268 
1269 // Set current 3D drawing object, create the scene for this
1271 {
1272  DBG_ASSERT(p3DObj != nullptr, "Who puts in a NULL-pointer here");
1273 
1274  // get transformed BoundVolume of the object
1275  basegfx::B3DRange aVolume(p3DObj->GetBoundVolume());
1276  aVolume.transform(p3DObj->GetTransform());
1277  double fW(aVolume.getWidth());
1278  double fH(aVolume.getHeight());
1279 
1280  tools::Rectangle aRect(0,0, static_cast<long>(fW), static_cast<long>(fH));
1281 
1282  E3dScene* pScene = new E3dScene(p3DObj->getSdrModelFromSdrObject());
1283 
1284  InitScene(pScene, fW, fH, aVolume.getMaxZ() + ((fW + fH) / 4.0));
1285 
1286  pScene->InsertObject(p3DObj);
1287  pScene->NbcSetSnapRect(aRect);
1288 
1289  return pScene;
1290 }
1291 
1292 void E3dView::InitScene(E3dScene* pScene, double fW, double fH, double fCamZ)
1293 {
1294  Camera3D aCam(pScene->GetCamera());
1295 
1296  aCam.SetAutoAdjustProjection(false);
1297  aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
1298  basegfx::B3DPoint aLookAt;
1299 
1300  double fDefaultCamPosZ = GetDefaultCamPosZ();
1301  basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
1302 
1303  aCam.SetPosAndLookAt(aCamPos, aLookAt);
1304  aCam.SetFocalLength(GetDefaultCamFocal());
1305  pScene->SetCamera(aCam);
1306 }
1307 
1309 {
1310  if (!GetMarkedObjectCount())
1311  return;
1312 
1313  //positioned
1314  long nOutMin = 0;
1315  long nOutMax = 0;
1316  long nMinLen = 0;
1317  long nObjDst = 0;
1318  long nOutHgt = 0;
1320 
1321  // first determine representation boundaries
1322  if (pOut != nullptr)
1323  {
1324  nMinLen = pOut->PixelToLogic(Size(0,50)).Height();
1325  nObjDst = pOut->PixelToLogic(Size(0,20)).Height();
1326 
1327  long nDst = pOut->PixelToLogic(Size(0,10)).Height();
1328 
1329  nOutMin = -pOut->GetMapMode().GetOrigin().Y();
1330  nOutMax = pOut->GetOutputSize().Height() - 1 + nOutMin;
1331  nOutMin += nDst;
1332  nOutMax -= nDst;
1333 
1334  if (nOutMax - nOutMin < nDst)
1335  {
1336  nOutMin += nOutMax + 1;
1337  nOutMin /= 2;
1338  nOutMin -= (nDst + 1) / 2;
1339  nOutMax = nOutMin + nDst;
1340  }
1341 
1342  nOutHgt = nOutMax - nOutMin;
1343 
1344  long nTemp = nOutHgt / 4;
1345  if (nTemp > nMinLen) nMinLen = nTemp;
1346  }
1347 
1348  // and then attach the marks at the top and bottom of the object
1349  basegfx::B2DRange aR;
1350  for(size_t nMark = 0; nMark < GetMarkedObjectCount(); ++nMark)
1351  {
1352  SdrObject* pMark = GetMarkedObjectByIndex(nMark);
1353  basegfx::B2DPolyPolygon aXPP(pMark->TakeXorPoly());
1354  aR.expand(basegfx::utils::getRange(aXPP));
1355  }
1356 
1357  basegfx::B2DPoint aCenter(aR.getCenter());
1358  long nMarkHgt = basegfx::fround(aR.getHeight()) - 1;
1359  long nHgt = nMarkHgt + nObjDst * 2;
1360 
1361  if (nHgt < nMinLen) nHgt = nMinLen;
1362 
1363  long nY1 = basegfx::fround(aCenter.getY()) - (nHgt + 1) / 2;
1364  long nY2 = nY1 + nHgt;
1365 
1366  if (pOut && (nMinLen > nOutHgt)) nMinLen = nOutHgt;
1367  if (pOut)
1368  {
1369  if (nY1 < nOutMin)
1370  {
1371  nY1 = nOutMin;
1372  if (nY2 < nY1 + nMinLen) nY2 = nY1 + nMinLen;
1373  }
1374  if (nY2 > nOutMax)
1375  {
1376  nY2 = nOutMax;
1377  if (nY1 > nY2 - nMinLen) nY1 = nY2 - nMinLen;
1378  }
1379  }
1380 
1381  maRef1.setX( basegfx::fround(aR.getMinX()) ); // Initial move axis 2/100mm to the left
1382  maRef1.setY( nY1 );
1383  maRef2.setX( maRef1.X() );
1384  maRef2.setY( nY2 );
1385 
1386  // Turn on marks
1387  SetMarkHandles(nullptr);
1388 
1389  //HMHif (bVis) ShowMarkHdl();
1391 
1392  // Show mirror polygon IMMEDIATELY
1393  const SdrHdlList &aHdlList = GetHdlList();
1395  mpMirrorOverlay->SetMirrorAxis(aHdlList.GetHdl(SdrHdlKind::Ref1)->GetPos(), aHdlList.GetHdl(SdrHdlKind::Ref2)->GetPos());
1396 }
1397 
1398 // what happens with a mouse movement when the object is created?
1399 
1400 void E3dView::MovAction(const Point& rPnt)
1401 {
1403  {
1404  SdrHdl* pHdl = GetDragHdl();
1405 
1406  if (pHdl)
1407  {
1408  SdrHdlKind eHdlKind = pHdl->GetKind();
1409 
1410  // reacts only due to a mirror axis
1411  if ((eHdlKind == SdrHdlKind::Ref1) ||
1412  (eHdlKind == SdrHdlKind::Ref2) ||
1413  (eHdlKind == SdrHdlKind::MirrorAxis))
1414  {
1415  const SdrHdlList &aHdlList = GetHdlList ();
1416 
1417  // delete the mirrored polygon, mirrors the original and draws
1418  // it anew
1419  SdrView::MovAction (rPnt);
1420  mpMirrorOverlay->SetMirrorAxis(
1421  aHdlList.GetHdl (SdrHdlKind::Ref1)->GetPos(),
1422  aHdlList.GetHdl (SdrHdlKind::Ref2)->GetPos());
1423  }
1424  }
1425  else
1426  {
1427  SdrView::MovAction (rPnt);
1428  }
1429  }
1430  else
1431  {
1432  SdrView::MovAction (rPnt);
1433  }
1434 }
1435 
1436 // The End. Create object and any child objects through ImpCreate3DLathe.
1437 // With the parameter value sal_True (SDefault: sal_False) is simply a
1438 // rotation body created, without letting the user set the position of the
1439 // axis. It is sufficient with this call, if an object is selected.
1440 // (No initialization necessary)
1441 
1442 void E3dView::End3DCreation(bool bUseDefaultValuesForMirrorAxes)
1443 {
1445 
1446  if(!AreObjectsMarked())
1447  return;
1448 
1449  if(bUseDefaultValuesForMirrorAxes)
1450  {
1452  if(aRect.GetWidth() <= 1)
1453  aRect.SetSize(Size(500, aRect.GetHeight()));
1454  if(aRect.GetHeight() <= 1)
1455  aRect.SetSize(Size(aRect.GetWidth(), 500));
1456 
1457  basegfx::B2DPoint aPnt1(aRect.Left(), -aRect.Top());
1458  basegfx::B2DPoint aPnt2(aRect.Left(), -aRect.Bottom());
1459 
1460  ConvertMarkedObjTo3D(false, aPnt1, aPnt2);
1461  }
1462  else
1463  {
1464  // Turn off helper overlay
1465  // Determine from the handle positions and the displacement of
1466  // the points
1467  const SdrHdlList &aHdlList = GetHdlList();
1468  Point aMirrorRef1 = aHdlList.GetHdl(SdrHdlKind::Ref1)->GetPos();
1469  Point aMirrorRef2 = aHdlList.GetHdl(SdrHdlKind::Ref2)->GetPos();
1470 
1471  basegfx::B2DPoint aPnt1(aMirrorRef1.X(), -aMirrorRef1.Y());
1472  basegfx::B2DPoint aPnt2(aMirrorRef2.X(), -aMirrorRef2.Y());
1473 
1474  ConvertMarkedObjTo3D(false, aPnt1, aPnt2);
1475  }
1476 }
1477 
1479 {
1480 }
1481 
1483 {
1484  mpMirrorOverlay.reset();
1485 }
1486 
1488 {
1489  mpMirrorOverlay = nullptr;
1490 }
1491 
1493 {
1494  const size_t nCount = GetMarkedObjectCount();
1495 
1496  if (nCount > 0)
1497  {
1498  for (size_t i = 0; i < nCount; ++i)
1499  {
1501 
1502  if (auto p3dObject = dynamic_cast< E3dObject* >(pObj))
1503  {
1504  if(!p3dObject->IsBreakObjPossible())
1505  return false;
1506  }
1507  else
1508  {
1509  return false;
1510  }
1511  }
1512  }
1513  else
1514  {
1515  return false;
1516  }
1517 
1518  return true;
1519 }
1520 
1522 {
1523  if(!IsBreak3DObjPossible())
1524  return;
1525 
1526  // ALL selected objects are changed
1527  const size_t nCount = GetMarkedObjectCount();
1528 
1529  BegUndo(SvxResId(RID_SVX_3D_UNDO_BREAK_LATHE));
1530  for(size_t a=0; a<nCount; ++a)
1531  {
1532  E3dObject* pObj = static_cast<E3dObject*>(GetMarkedObjectByIndex(a));
1533  BreakSingle3DObj(pObj);
1534  }
1535  DeleteMarked();
1536  EndUndo();
1537 }
1538 
1540 {
1541  if(dynamic_cast< const E3dScene* >(pObj) != nullptr)
1542  {
1543  SdrObjList* pSubList = pObj->GetSubList();
1544  SdrObjListIter aIter(pSubList, SdrIterMode::Flat);
1545 
1546  while(aIter.IsMore())
1547  {
1548  E3dObject* pSubObj = static_cast<E3dObject*>(aIter.Next());
1549  BreakSingle3DObj(pSubObj);
1550  }
1551  }
1552  else
1553  {
1554  SdrAttrObj* pNewObj = pObj->GetBreakObj().release();
1555  if (pNewObj)
1556  {
1558  {
1559  pNewObj->SetChanged();
1560  pNewObj->BroadcastObjectChange();
1561  }
1562  }
1563  }
1564 }
1565 
1567 {
1568  // call parent
1570 
1571  // Set other flags
1573  return;
1574 
1575  const size_t nMarkCnt = GetMarkedObjectCount();
1576  bool bCompound = false;
1577  bool b3DObject = false;
1578  for(size_t nObjs = 0; (nObjs < nMarkCnt) && !bCompound; ++nObjs)
1579  {
1580  SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
1581  if(dynamic_cast< const E3dCompoundObject* >(pObj))
1582  bCompound = true;
1583  if(dynamic_cast< const E3dObject* >(pObj))
1584  b3DObject = true;
1585  }
1586 
1587  // So far: there are two or more of any objects selected. See if
1588  // compound objects are involved. If yes, ban grouping.
1589  if(m_bGroupPossible && bCompound)
1590  m_bGroupPossible = false;
1591 
1592  if(m_bUnGroupPossible && b3DObject)
1593  m_bUnGroupPossible = false;
1594 
1595  if(m_bGrpEnterPossible && bCompound)
1596  m_bGrpEnterPossible = false;
1597 }
1598 
1599 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetAutoAdjustProjection(bool bAdjust)
Definition: camera3d.hxx:62
virtual basegfx::B2DPolyPolygon TakeXorPoly() const
The Xor-Polygon is required by the View to drag the object.
Definition: svdobj.cxx:1067
long GetWidth() const
void setX(double fX)
basegfx::B2DPolyPolygon * mpPolygons
Definition: view3d.cxx:72
B2DPoint getCenter() const
virtual bool BegDragObj(const Point &rPnt, OutputDevice *pOut, SdrHdl *pHdl, short nMinMov=-3, SdrDragMethod *pForcedMeth=nullptr)
Definition: svddrgv.cxx:193
void expand(const B2DTuple &rTuple)
SfxBoolItem makeSvx3DDoubleSidedItem(bool bVal)
Definition: svx3ditems.hxx:58
long GetHeight() const
void ImpGetPasteObjList(Point &rPos, SdrObjList *&rpLst)
Definition: svdxcgv.cxx:94
void SortMarkedObjects() const
Definition: svdmrkv.hxx:259
double getHeight() const
void ImpChangeSomeAttributesFor3DConversion2(SdrObject *pObj)
Definition: view3d.cxx:663
rtl::Reference< sdr::overlay::OverlayManager > const & GetOverlayManager() const
void ReplaceObjectAtView(SdrObject *pOldObj, SdrPageView &rPV, SdrObject *pNewObj, bool bMark=true)
Definition: svdedtv.cxx:986
const tools::Rectangle & GetAllObjBoundRect() const
Definition: svdpage.cxx:688
long Height() const
virtual bool Paste(const SdrModel &rMod, const Point &rPos, SdrObjList *pLst, SdrInsertFlags nOptions)
Definition: svdxcgv.cxx:228
SdrHdlKind
Definition: svdhdl.hxx:52
bool AreObjectsMarked() const
Definition: svdmrkv.hxx:260
bool IsUndoEnabled() const
Definition: svdedtv.cxx:1027
void BreakSingle3DObj(E3dObject *pObj)
Definition: view3d.cxx:1539
constexpr TypedWhichId< XFillStyleItem > XATTR_FILLSTYLE(XATTR_FILL_FIRST)
constexpr TypedWhichId< XLineWidthItem > XATTR_LINEWIDTH(XATTR_LINE_FIRST+2)
double getX() const
SdrObject * GetObj(size_t nNum) const
Definition: svdpage.cxx:758
#define F_PI2
size_t GetObjCount() const
Definition: svdpage.cxx:752
void SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB)
Definition: view3d.cxx:142
void BegUndo()
Definition: svdedtv.hxx:179
const MapMode & GetMapMode() const
double getY() const
bool IsConvertTo3DObjPossible() const
Definition: view3d.cxx:590
void Break3DObj()
Definition: view3d.cxx:1521
SdrPageView * GetSdrPageViewOfMarkedByIndex(size_t nNum) const
Definition: svdmrkv.hxx:255
constexpr TypedWhichId< XLineStyleItem > XATTR_LINESTYLE(XATTR_LINE_FIRST)
SdrMark * GetMark(size_t nNum) const
Definition: svdmark.cxx:229
constexpr TypedWhichId< SfxUInt32Item > SDRATTR_3DOBJ_DEPTH(SDRATTR_3DOBJ_FIRST+2)
void append(std::unique_ptr< OverlayObject > pOverlayObject)
const Point & GetPos() const
Definition: svdhdl.hxx:197
#define DEG2RAD(fAngle)
Definition: def3d.hxx:27
const basegfx::B3DHomMatrix & GetTransform() const
Definition: obj3d.hxx:111
static void Free(SdrObject *&_rpObject)
Definition: svdobj.cxx:396
virtual SdrObjList * GetSubList() const override
Definition: scene3d.cxx:868
EmbeddedObjectRef * pObject
virtual void SetMarkHandles(SfxViewShell *pOtherShell) override
Definition: svddrgv.cxx:902
E3dScene * SetCurrent3DObj(E3dObject *p3DObj)
Definition: view3d.cxx:1270
virtual SdrObjList * GetSubList() const
Definition: svdobj.cxx:647
virtual void MarkListHasChanged() override
Definition: svdedxv.cxx:2471
bool InsertObjectAtView(SdrObject *pObj, SdrPageView &rPV, SdrInsertFlags nOptions=SdrInsertFlags::NONE)
Definition: svdedtv.cxx:955
sdr::contact::ViewContact & GetViewContact() const
Definition: svdobj.cxx:245
SdrHdlKind meDragHdl
Definition: svddrgv.hxx:46
bool m_bUnGroupPossible
Definition: svdedtv.hxx:83
virtual const tools::Rectangle & GetSnapRect() const
Definition: svdobj.cxx:1598
void End3DCreation(bool bUseDefaultValuesForMirrorAxes=false)
Definition: view3d.cxx:1442
virtual void MovAction(const Point &rPnt) override
Definition: view3d.cxx:1400
long Right() const
virtual SdrObject * getSdrObjectFromSdrObjList() const override
Definition: scene3d.cxx:216
virtual std::unique_ptr< SdrModel > CreateMarkedObjModel() const override
Definition: view3d.cxx:316
void InitScene(E3dScene *pScene, double fW, double fH, double fCamZ)
Definition: view3d.cxx:1292
double GetDefaultCamPosZ()
Definition: view3d1.cxx:167
void ImpCreate3DObject(E3dScene *pScene, SdrObject *pObj, bool bExtrude, double fDepth, basegfx::B2DHomMatrix const &rLatheMat)
Definition: view3d.cxx:763
B3DPoint getCenter() const
bool IsMore() const
Definition: svditer.hxx:62
SdrPage * getSdrPageFromSdrObject() const
Definition: svdobj.cxx:263
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
void SetCamera(const Camera3D &rNewCamera)
Definition: scene3d.cxx:313
std::unique_ptr< Impl3DMirrorConstructOverlay > mpMirrorOverlay
Definition: view3d.hxx:47
bool IsBreak3DObjPossible() const
Definition: view3d.cxx:1492
int nCount
bool IsClosed() const
Definition: svdopath.hxx:144
E3dDefaultAttributes & Get3DDefaultAttributes()
Definition: view3d.hxx:72
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2141
oslFileHandle & pOut
void removeAllNonSelectedObjects()
Definition: scene3d.cxx:369
void SetMergedItemSet(const SfxItemSet &rSet, bool bClearAllItems=false)
Definition: svdobj.cxx:1915
static void DoDepthArrange(E3dScene const *pScene, double fDepth)
Definition: view3d.cxx:1030
long Top() const
virtual void SetSelected(bool bNew) override
Definition: scene3d.cxx:737
OutputDevice * GetFirstOutputDevice() const
Definition: svdpntv.cxx:87
B2DPolyPolygon solvePolygonOperationAnd(const B2DPolyPolygon &rCandidateA, const B2DPolyPolygon &rCandidateB)
Point maRef1
Definition: svdmrkv.hxx:106
void SetDrawOnlySelected(bool bNew)
Definition: scene3d.hxx:115
B2IRange fround(const B2DRange &rRange)
void ImpCreateSingle3DObjectFlat(E3dScene *pScene, SdrObject *pObj, bool bExtrude, double fDepth, basegfx::B2DHomMatrix const &rLatheMat)
Definition: view3d.cxx:688
Point maRef2
Definition: svdmrkv.hxx:107
void EndUndo()
Definition: svdedtv.cxx:275
sal_uInt32 PaintWindowCount() const
Definition: svdpntv.hxx:222
bool IsConvertToPolyObjPossible() const
Definition: svdedtv.hxx:347
void ResetCreationActive()
Definition: view3d.cxx:1482
SdrObject * GetMarkedSdrObj() const
Definition: svdmark.hxx:68
Everything a View needs to know about a selected object.
Definition: svdmark.hxx:44
sdr::overlay::OverlayObjectList maObjects
Definition: view3d.cxx:63
SdrDragMode meDragMode
Definition: svdmrkv.hxx:119
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: svdedtv.hxx:183
virtual std::unique_ptr< SdrModel > CreateMarkedObjModel() const
Definition: svdxcgv.cxx:699
#define DBG_ASSERT(sCon, aError)
int i
uno_Any a
void ImpChangeSomeAttributesFor3DConversion(SdrObject *pObj)
Definition: view3d.cxx:638
bool m_bGroupPossible
Definition: svdedtv.hxx:82
bool IsUndoEnabled() const
returns true if undo is currently enabled This returns false if undo was disabled using EnableUndo( f...
Definition: svdmodel.cxx:577
void SingleObjectPainter(OutputDevice &rOut) const
Definition: svdobj.cxx:951
size_t GetMarkedObjectCount() const
Definition: svdmrkv.hxx:258
void SetSize(const Size &rSize)
void BroadcastObjectChange() const
Definition: svdobj.cxx:905
const SdrMarkList & GetMarkedObjectList() const
Definition: svdmrkv.hxx:252
Size GetOutputSize() const
const SdrPage * GetPage(sal_uInt16 nPgNum) const
Definition: svdmodel.cxx:1904
static bool equalZero(const double &rfVal)
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_GRAY
void InitView()
Definition: view3d.cxx:1487
long Bottom() const
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:273
void transform(const basegfx::B2DHomMatrix &rMatrix)
double GetDefaultCamFocal()
Definition: view3d1.cxx:172
virtual void DrawMarkedObj(OutputDevice &rOut) const override
Definition: view3d.cxx:218
virtual void append(const Primitive2DReference &) override
bool IsGroupObject() const
Definition: svdobj.cxx:642
const basegfx::B3DRange & GetBoundVolume() const
Definition: obj3d.cxx:290
void SetMergedItem(const SfxPoolItem &rItem)
Definition: svdobj.cxx:1900
const basegfx::B3DHomMatrix & GetFullTransform() const
Definition: obj3d.cxx:314
std::size_t mnCount
Abstract DrawObject.
Definition: svdobj.hxx:312
void ConvertMarkedObjTo3D(bool bExtrude=true, const basegfx::B2DPoint &rPnt1=basegfx::B2DPoint(0.0, 0.0), const basegfx::B2DPoint &rPnt2=basegfx::B2DPoint(0.0, 1.0))
Definition: view3d.cxx:828
sal_Int32 nLineWidth
const tools::Rectangle & GetAllMarkedRect() const
Definition: svdmrkv.hxx:420
SdrInsertFlags
Definition: svdedtv.hxx:58
virtual bool Paste(const SdrModel &rMod, const Point &rPos, SdrObjList *pLst, SdrInsertFlags nOptions) override
Definition: view3d.cxx:435
B2DRange getRange(const B2DPolygon &rCandidate)
BASEGFX_DLLPUBLIC void transform(const B3DHomMatrix &rMatrix)
virtual SdrLayerID GetLayer() const
Definition: svdobj.cxx:577
SdrHdl * GetDragHdl() const
Definition: svddrgv.hxx:107
void translate(double fX, double fY, double fZ)
Point PixelToLogic(const Point &rDevicePt) const
virtual void CheckPossibilities()
Definition: svdedtv.cxx:455
drawinglayer::primitive2d::Primitive2DContainer maFullOverlay
Definition: view3d.cxx:75
virtual void SetTransform(const basegfx::B3DHomMatrix &rMatrix)
Definition: obj3d.cxx:344
SdrObject * Next()
Definition: svditer.hxx:63
virtual void SetTransform(const basegfx::B3DHomMatrix &rMatrix) override
Definition: scene3d.cxx:609
constexpr TypedWhichId< XFillColorItem > XATTR_FILLCOLOR(XATTR_FILL_FIRST+1)
SdrHdl * GetHdl(size_t nNum) const
Definition: svdhdl.hxx:462
css::uno::Reference< css::graphic::XPrimitive2D > Primitive2DReference
SdrObjectUniquePtr ConvertToPolyObj(bool bBezier, bool bLineToArea) const
Definition: svdobj.cxx:2511
Derived class of SdrView to edit 3D objects.
Definition: view3d.hxx:41
drawinglayer::primitive2d::Primitive2DContainer const & getViewIndependentPrimitive2DContainer() const
sal_uInt32 count() const
E3dView(SdrModel &rSdrModel, OutputDevice *pOut)
Definition: view3d.cxx:207
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE) override
Definition: scene3d.cxx:772
tools::Rectangle & Union(const tools::Rectangle &rRect)
Impl3DMirrorConstructOverlay(const Impl3DMirrorConstructOverlay &)=delete
SdrObject * ConvertToContourObj(SdrObject *pRet, bool bForceLineDash=false) const
Definition: svdobj.cxx:2473
SlideSorterView & mrView
B2DHomMatrix createRotateAroundPoint(double fPointX, double fPointY, double fRadiant)
bool IsSolidDragging() const
Definition: svddrgv.cxx:918
void ImpIsConvertTo3DPossible(SdrObject const *pObj, bool &rAny3D, bool &rGroupSelected) const
Definition: view3d.cxx:613
virtual void DrawMarkedObj(OutputDevice &rOut) const
Definition: svdxcgv.cxx:685
const SfxItemSet & GetMergedItemSet() const
Definition: svdobj.cxx:1890
constexpr TypedWhichId< SvxColorItem > EE_CHAR_COLOR(EE_CHAR_START+0)
E3dDragConstraint
Definition: def3d.hxx:31
virtual void DeleteMarked()
Definition: svdview.cxx:1369
bool IsVertexHdl() const
Definition: svdhdl.hxx:213
void Start3DCreation()
Definition: view3d.cxx:1308
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
SdrObject * GetMarkedObjectByIndex(size_t nNum) const
Definition: svdmrkv.hxx:257
const Point & GetOrigin() const
long Left() const
void translate(double fX, double fY)
const basegfx::B2DPolyPolygon & GetPathPoly() const
Definition: svdopath.hxx:139
SdrPageView * GetSdrPageView() const
Definition: svdpntv.hxx:304
virtual void CheckPossibilities() override
Definition: view3d.cxx:1566
Helper for 3d object changes affecting 2d geometry.
virtual void SetSnapRect(const tools::Rectangle &rRect)
Definition: svdobj.cxx:1623
void rotate(double fAngleX, double fAngleY, double fAngleZ)
virtual void MovAction(const Point &rPnt) override
Definition: svdcrtv.cxx:217
double getMinX() const
bool MarkObj(const Point &rPnt, short nTol=-2, bool bToggle=false, bool bDeep=false)
Definition: svdmrkv.cxx:1714
virtual bool BegDragObj(const Point &rPnt, OutputDevice *pOut, SdrHdl *pHdl, short nMinMov=-3, SdrDragMethod *pForcedMeth=nullptr) override
Definition: view3d.cxx:1156
const SdrHdlList & GetHdlList() const
Definition: svdmrkv.hxx:354
SdrMark * GetSdrMarkByIndex(size_t nNum) const
Definition: svdmrkv.hxx:256
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:365
bool IsCornerHdl() const
Definition: svdhdl.hxx:212
bool Is3DRotationCreationActive() const
Definition: view3d.hxx:101
bool IsConvertToPathObjPossible() const
Definition: svdedtv.hxx:346
double getDepth() const
bool IsImportMtfPossible() const
Definition: svdedtv.hxx:405
virtual void NbcSetStyleSheet(SfxStyleSheet *pNewStyleSheet, bool bDontRemoveHardAttr)
Definition: svdobj.cxx:2159
virtual ~E3dView() override
Definition: view3d.cxx:1478
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
virtual std::unique_ptr< SdrAttrObj, SdrObjectFreeOp > GetBreakObj()
Definition: obj3d.cxx:81
virtual void SetChanged()
Definition: svdobj.cxx:929
B2DPolyPolygon prepareForPolygonOperation(const B2DPolygon &rCandidate)
constexpr TypedWhichId< XLineColorItem > XATTR_LINECOLOR(XATTR_LINE_FIRST+3)
SdrMarkList & GetMarkedObjectListWriteAccess()
Definition: svdmrkv.hxx:248
SdrModel * GetModel() const
Definition: svdpntv.hxx:265
const Camera3D & GetCamera() const
Definition: scene3d.hxx:127
virtual SdrObject * getSdrObjectFromSdrObjList() const
Definition: svdpage.cxx:137
virtual E3dCompoundObject * CloneSdrObject(SdrModel &rTargetModel) const override
Definition: obj3d.cxx:593
virtual E3dScene * getRootE3dSceneFromE3dObject() const override
Definition: scene3d.cxx:357
SdrPaintWindow * GetPaintWindow(sal_uInt32 nIndex) const
Definition: svdpntv.cxx:71
bool ImpCloneAll3DObjectsToDestScene(E3dScene const *pSrcScene, E3dScene *pDstScene, Point aOffset)
Definition: view3d.cxx:488
const E3dView & mrView
Definition: view3d.cxx:66
sal_uInt16 GetPageCount() const
Definition: svdmodel.cxx:1916
const Color & GetValue() const
SdrHdlKind GetKind() const
Definition: svdhdl.hxx:194
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
Definition: scene3d.cxx:285
bool m_bGrpEnterPossible
Definition: svdedtv.hxx:84
virtual void NbcSetLayer(SdrLayerID nLayer)
Definition: svdobj.cxx:594
sal_uInt32 PageWindowCount() const
Definition: svdpagv.hxx:94
bool IsObjMarked(SdrObject const *pObj) const
Definition: svdmrkv.cxx:1981