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