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  {
98  {
99  SdrPageView* pPV = rView.GetSdrPageView();
100 
101  if(pPV && pPV->PageWindowCount())
102  {
103  for(size_t a = 0; a < mnCount; ++a)
104  {
106 
107  if(pObject)
108  {
109  // use the view-independent primitive representation (without
110  // evtl. GridOffset, that may be applied to the DragEntry individually)
113  maFullOverlay.append(aNewSequence);
114  }
115  }
116  }
117  }
118  else
119  {
121 
122  for(size_t a = 0; a < mnCount; ++a)
123  {
125  mpPolygons[mnCount - (a + 1)] = pObject->TakeXorPoly();
126  }
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  {
618  if(dynamic_cast< const E3dObject* >(pObj) != nullptr)
619  {
620  rAny3D = true;
621  }
622  else
623  {
624  if(pObj->IsGroupObject())
625  {
627  while(aIter.IsMore())
628  {
629  SdrObject* pNewObj = aIter.Next();
630  ImpIsConvertTo3DPossible(pNewObj, rAny3D, rGroupSelected);
631  }
632  rGroupSelected = true;
633  }
634  }
635  }
636 }
637 
639 {
640  if(dynamic_cast<const SdrTextObj*>( pObj) != nullptr)
641  {
642  const SfxItemSet& rSet = pObj->GetMergedItemSet();
643  const SvxColorItem& rTextColorItem = rSet.Get(EE_CHAR_COLOR);
644  if(rTextColorItem.GetValue() == COL_BLACK)
645  {
646  //For black text objects, the color set to gray
647  if(pObj->getSdrPageFromSdrObject())
648  {
649  // if black is only default attribute from
650  // pattern set it hard so that it is used in undo.
652 
653  // add undo now
654  if( GetModel()->IsUndoEnabled() )
655  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
656  }
657 
659  }
660  }
661 }
662 
664 {
665  if(dynamic_cast<const SdrPathObj*>( pObj) != nullptr)
666  {
667  const SfxItemSet& rSet = pObj->GetMergedItemSet();
668  sal_Int32 nLineWidth = rSet.Get(XATTR_LINEWIDTH).GetValue();
669  drawing::LineStyle eLineStyle = rSet.Get(XATTR_LINESTYLE).GetValue();
670  drawing::FillStyle eFillStyle = rSet.Get(XATTR_FILLSTYLE).GetValue();
671 
672  if(static_cast<SdrPathObj*>(pObj)->IsClosed()
673  && eLineStyle == drawing::LineStyle_SOLID
674  && !nLineWidth
675  && eFillStyle != drawing::FillStyle_NONE)
676  {
677  if(pObj->getSdrPageFromSdrObject() && GetModel()->IsUndoEnabled() )
678  {
679  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
680  }
681 
682  pObj->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
683  pObj->SetMergedItem(XLineWidthItem(0));
684  }
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  {
695  E3dDefaultAttributes aDefault = Get3DDefaultAttributes();
696 
697  if(bExtrude)
698  {
699  aDefault.SetDefaultExtrudeCharacterMode(true);
700  }
701  else
702  {
703  aDefault.SetDefaultLatheCharacterMode(true);
704  }
705 
706  // Get Itemset of the original object
707  SfxItemSet aSet(pObj->GetMergedItemSet());
708 
709  drawing::FillStyle eFillStyle = aSet.Get(XATTR_FILLSTYLE).GetValue();
710 
711  // line style turned off
712  aSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
713 
714  //Determining if FILL_Attribut is set.
715  if(!pPath->IsClosed() || eFillStyle == drawing::FillStyle_NONE)
716  {
717  // This SdrPathObj is not filled, leave the front and rear face out.
718  // Moreover, a two-sided representation necessary.
719  aDefault.SetDefaultExtrudeCloseFront(false);
720  aDefault.SetDefaultExtrudeCloseBack(false);
721 
722  aSet.Put(makeSvx3DDoubleSidedItem(true));
723 
724  // Set fill attribute
725  aSet.Put(XFillStyleItem(drawing::FillStyle_SOLID));
726 
727  // Fill color must be the color line, because the object was
728  // previously just a line
729  Color aColorLine = aSet.Get(XATTR_LINECOLOR).GetColorValue();
730  aSet.Put(XFillColorItem(OUString(), aColorLine));
731  }
732 
733  // Create a new extrude object
734  E3dObject* p3DObj = nullptr;
735  if(bExtrude)
736  {
737  p3DObj = new E3dExtrudeObj(pObj->getSdrModelFromSdrObject(), aDefault, pPath->GetPathPoly(), fDepth);
738  }
739  else
740  {
741  // rLatheMat expects coordinates with y-axis up, pPath uses y-axis down
742  basegfx::B2DHomMatrix aFlipVerticalMat(1.0, 0.0, 0.0, 0.0, -1.0, 0.0);
743  basegfx::B2DPolyPolygon aPolyPoly2D(pPath->GetPathPoly());
744  aPolyPoly2D.transform(aFlipVerticalMat);
745  aPolyPoly2D.transform(rLatheMat);
746  // ctor E3dLatheObj expects coordinates with y-axis down
747  aPolyPoly2D.transform(aFlipVerticalMat);
748  p3DObj = new E3dLatheObj(pObj->getSdrModelFromSdrObject(), aDefault, aPolyPoly2D);
749  }
750 
751  // Set attribute
752  p3DObj->NbcSetLayer(pObj->GetLayer());
753 
754  p3DObj->SetMergedItemSet(aSet);
755 
756  p3DObj->NbcSetStyleSheet(pObj->GetStyleSheet(), true);
757 
758  // Insert a new extrude object
759  pScene->InsertObject(p3DObj);
760  }
761 }
762 
763 void E3dView::ImpCreate3DObject(E3dScene* pScene, SdrObject* pObj, bool bExtrude, double fDepth, basegfx::B2DHomMatrix const & rLatheMat)
764 {
765  if(pObj)
766  {
767  // change text color attribute for not so dark colors
768  if(pObj->IsGroupObject())
769  {
771  while(aIter.IsMore())
772  {
773  SdrObject* pGroupMember = aIter.Next();
775  }
776  }
777  else
779 
780  // convert completely to path objects
781  SdrObject* pNewObj1 = pObj->ConvertToPolyObj(false, false).release();
782 
783  if(pNewObj1)
784  {
785  // change text color attribute for not so dark colors
786  if(pNewObj1->IsGroupObject())
787  {
789  while(aIter.IsMore())
790  {
791  SdrObject* pGroupMember = aIter.Next();
793  }
794  }
795  else
797 
798  // convert completely to path objects
799  SdrObject* pNewObj2 = pObj->ConvertToContourObj(pNewObj1, true);
800 
801  if(pNewObj2)
802  {
803  // add all to flat scene
804  if(pNewObj2->IsGroupObject())
805  {
807  while(aIter.IsMore())
808  {
809  SdrObject* pGroupMember = aIter.Next();
810  ImpCreateSingle3DObjectFlat(pScene, pGroupMember, bExtrude, fDepth, rLatheMat);
811  }
812  }
813  else
814  ImpCreateSingle3DObjectFlat(pScene, pNewObj2, bExtrude, fDepth, rLatheMat);
815 
816  // delete object in between
817  if (pNewObj2 != pObj && pNewObj2 != pNewObj1)
818  SdrObject::Free( pNewObj2 );
819  }
820 
821  // delete object in between
822  if (pNewObj1 != pObj)
823  SdrObject::Free( pNewObj1 );
824  }
825  }
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  {
1034  SdrObjList* pSubList = pScene->GetSubList();
1035  SdrObjListIter aIter(pSubList, SdrIterMode::Flat);
1036  E3dDepthLayer* pBaseLayer = nullptr;
1037  E3dDepthLayer* pLayer = nullptr;
1038  sal_Int32 nNumLayers = 0;
1039 
1040  while(aIter.IsMore())
1041  {
1042  E3dExtrudeObj* pExtrudeObj = dynamic_cast< E3dExtrudeObj* >(aIter.Next());
1043 
1044  if(pExtrudeObj)
1045  {
1046  const basegfx::B2DPolyPolygon aExtrudePoly(
1047  basegfx::utils::prepareForPolygonOperation(pExtrudeObj->GetExtrudePolygon()));
1048  const SfxItemSet& rLocalSet = pExtrudeObj->GetMergedItemSet();
1049  const drawing::FillStyle eLocalFillStyle = rLocalSet.Get(XATTR_FILLSTYLE).GetValue();
1050  const Color aLocalColor = rLocalSet.Get(XATTR_FILLCOLOR).GetColorValue();
1051 
1052  // sort in ExtrudeObj
1053  if(pLayer)
1054  {
1055  // do we have overlap with an object of this layer?
1056  bool bOverlap(false);
1057 
1058  for(const auto& rAct : pLayer->mvNeighbours)
1059  {
1060  // do rAct.mpObj and pExtrudeObj overlap? Check by
1061  // using logical AND clipping
1062  const basegfx::B2DPolyPolygon aAndPolyPolygon(
1064  aExtrudePoly,
1065  rAct.maPreparedPolyPolygon));
1066 
1067  if(aAndPolyPolygon.count() != 0)
1068  {
1069  // second criteria: is another fillstyle or color used?
1070  const SfxItemSet& rCompareSet = rAct.mpObj->GetMergedItemSet();
1071 
1072  drawing::FillStyle eCompareFillStyle = rCompareSet.Get(XATTR_FILLSTYLE).GetValue();
1073 
1074  if(eLocalFillStyle == eCompareFillStyle)
1075  {
1076  if(eLocalFillStyle == drawing::FillStyle_SOLID)
1077  {
1078  Color aCompareColor = rCompareSet.Get(XATTR_FILLCOLOR).GetColorValue();
1079 
1080  if(aCompareColor == aLocalColor)
1081  {
1082  continue;
1083  }
1084  }
1085  else if(eLocalFillStyle == drawing::FillStyle_NONE)
1086  {
1087  continue;
1088  }
1089  }
1090 
1091  bOverlap = true;
1092  break;
1093  }
1094  }
1095 
1096  if(bOverlap)
1097  {
1098  // yes, start a new layer
1099  pLayer->mpDown = new E3dDepthLayer;
1100  pLayer = pLayer->mpDown;
1101  nNumLayers++;
1102  pLayer->mvNeighbours.emplace_back(pExtrudeObj, aExtrudePoly);
1103  }
1104  else
1105  {
1106  // no, add to current layer
1107  pLayer->mvNeighbours.emplace(pLayer->mvNeighbours.begin(), pExtrudeObj, aExtrudePoly);
1108  }
1109  }
1110  else
1111  {
1112  // first layer ever
1113  pBaseLayer = new E3dDepthLayer;
1114  pLayer = pBaseLayer;
1115  nNumLayers++;
1116  pLayer->mvNeighbours.emplace_back(pExtrudeObj, aExtrudePoly);
1117  }
1118  }
1119  }
1120 
1121  // number of layers is done
1122  if(nNumLayers > 1)
1123  {
1124  // need to be arranged
1125  double fMinDepth = fDepth * 0.8;
1126  double fStep = (fDepth - fMinDepth) / static_cast<double>(nNumLayers);
1127  pLayer = pBaseLayer;
1128 
1129  while(pLayer)
1130  {
1131  // move along layer
1132  for(auto& rAct : pLayer->mvNeighbours)
1133  {
1134  // adapt extrude value
1135  rAct.mpObj->SetMergedItem(SfxUInt32Item(SDRATTR_3DOBJ_DEPTH, sal_uInt32(fMinDepth + 0.5)));
1136  }
1137 
1138  // next layer
1139  pLayer = pLayer->mpDown;
1140  fMinDepth += fStep;
1141  }
1142  }
1143 
1144  // cleanup
1145  while(pBaseLayer)
1146  {
1147  pLayer = pBaseLayer->mpDown;
1148  delete pBaseLayer;
1149  pBaseLayer = pLayer;
1150  }
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  {
1448  if(bUseDefaultValuesForMirrorAxes)
1449  {
1451  if(aRect.GetWidth() <= 1)
1452  aRect.SetSize(Size(500, aRect.GetHeight()));
1453  if(aRect.GetHeight() <= 1)
1454  aRect.SetSize(Size(aRect.GetWidth(), 500));
1455 
1456  basegfx::B2DPoint aPnt1(aRect.Left(), -aRect.Top());
1457  basegfx::B2DPoint aPnt2(aRect.Left(), -aRect.Bottom());
1458 
1459  ConvertMarkedObjTo3D(false, aPnt1, aPnt2);
1460  }
1461  else
1462  {
1463  // Turn off helper overlay
1464  // Determine from the handle positions and the displacement of
1465  // the points
1466  const SdrHdlList &aHdlList = GetHdlList();
1467  Point aMirrorRef1 = aHdlList.GetHdl(SdrHdlKind::Ref1)->GetPos();
1468  Point aMirrorRef2 = aHdlList.GetHdl(SdrHdlKind::Ref2)->GetPos();
1469 
1470  basegfx::B2DPoint aPnt1(aMirrorRef1.X(), -aMirrorRef1.Y());
1471  basegfx::B2DPoint aPnt2(aMirrorRef2.X(), -aMirrorRef2.Y());
1472 
1473  ConvertMarkedObjTo3D(false, aPnt1, aPnt2);
1474  }
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  {
1525  // ALL selected objects are changed
1526  const size_t nCount = GetMarkedObjectCount();
1527 
1528  BegUndo(SvxResId(RID_SVX_3D_UNDO_BREAK_LATHE));
1529  for(size_t a=0; a<nCount; ++a)
1530  {
1531  E3dObject* pObj = static_cast<E3dObject*>(GetMarkedObjectByIndex(a));
1532  BreakSingle3DObj(pObj);
1533  }
1534  DeleteMarked();
1535  EndUndo();
1536  }
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  {
1574  const size_t nMarkCnt = GetMarkedObjectCount();
1575  bool bCoumpound = false;
1576  bool b3DObject = false;
1577  for(size_t nObjs = 0; (nObjs < nMarkCnt) && !bCoumpound; ++nObjs)
1578  {
1579  SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
1580  if(dynamic_cast< const E3dCompoundObject* >(pObj))
1581  bCoumpound = true;
1582  if(dynamic_cast< const E3dObject* >(pObj))
1583  b3DObject = true;
1584  }
1585 
1586  // So far: there are two or more of any objects selected. See if
1587  // compound objects are involved. If yes, ban grouping.
1588  if(m_bGroupPossible && bCoumpound)
1589  m_bGroupPossible = false;
1590 
1591  if(m_bUnGroupPossible && b3DObject)
1592  m_bUnGroupPossible = false;
1593 
1594  if(m_bGrpEnterPossible && bCoumpound)
1595  m_bGrpEnterPossible = false;
1596  }
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:1066
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
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
void ImpGetPasteObjList(Point &rPos, SdrObjList *&rpLst)
Definition: svdxcgv.cxx:94
void SortMarkedObjects() const
Definition: svdmrkv.hxx:250
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:696
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:251
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:766
#define F_PI2
size_t GetObjCount() const
Definition: svdpage.cxx:760
void SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB)
Definition: view3d.cxx:142
void BegUndo()
Definition: svdedtv.hxx:179
const MapMode & GetMapMode() const
constexpr::Color COL_GRAY(0x80, 0x80, 0x80)
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:246
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:28
const basegfx::B3DHomMatrix & GetTransform() const
Definition: obj3d.hxx:111
static void Free(SdrObject *&_rpObject)
Definition: svdobj.cxx:395
virtual SdrObjList * GetSubList() const override
Definition: scene3d.cxx:867
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:646
virtual void MarkListHasChanged() override
Definition: svdedxv.cxx:2468
bool InsertObjectAtView(SdrObject *pObj, SdrPageView &rPV, SdrInsertFlags nOptions=SdrInsertFlags::NONE)
Definition: svdedtv.cxx:955
sdr::contact::ViewContact & GetViewContact() const
Definition: svdobj.cxx:244
SdrHdlKind meDragHdl
Definition: svddrgv.hxx:46
bool m_bUnGroupPossible
Definition: svdedtv.hxx:83
virtual const tools::Rectangle & GetSnapRect() const
Definition: svdobj.cxx:1596
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:215
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:262
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
void SetCamera(const Camera3D &rNewCamera)
Definition: scene3d.cxx:312
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:2134
oslFileHandle & pOut
void removeAllNonSelectedObjects()
Definition: scene3d.cxx:368
void SetMergedItemSet(const SfxItemSet &rSet, bool bClearAllItems=false)
Definition: svdobj.cxx:1908
static void DoDepthArrange(E3dScene const *pScene, double fDepth)
Definition: view3d.cxx:1030
long Top() const
virtual void SetSelected(bool bNew) override
Definition: scene3d.cxx:736
OutputDevice * GetFirstOutputDevice() const
Definition: svdpntv.cxx:87
B2DPolyPolygon solvePolygonOperationAnd(const B2DPolyPolygon &rCandidateA, const B2DPolyPolygon &rCandidateB)
Point maRef1
Definition: svdmrkv.hxx:101
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:102
void EndUndo()
Definition: svdedtv.cxx:275
sal_uInt32 PaintWindowCount() const
Definition: svdpntv.hxx:228
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:112
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:576
void SingleObjectPainter(OutputDevice &rOut) const
Definition: svdobj.cxx:950
size_t GetMarkedObjectCount() const
Definition: svdmrkv.hxx:249
void SetSize(const Size &rSize)
void BroadcastObjectChange() const
Definition: svdobj.cxx:904
const SdrMarkList & GetMarkedObjectList() const
Definition: svdmrkv.hxx:243
Size GetOutputSize() const
const SdrPage * GetPage(sal_uInt16 nPgNum) const
Definition: svdmodel.cxx:1903
static bool equalZero(const double &rfVal)
void InitView()
Definition: view3d.cxx:1487
long Bottom() const
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:272
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:641
const basegfx::B3DRange & GetBoundVolume() const
Definition: obj3d.cxx:289
void SetMergedItem(const SfxPoolItem &rItem)
Definition: svdobj.cxx:1893
const basegfx::B3DHomMatrix & GetFullTransform() const
Definition: obj3d.cxx:313
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:410
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:576
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:343
SdrObject * Next()
Definition: svditer.hxx:63
virtual void SetTransform(const basegfx::B3DHomMatrix &rMatrix) override
Definition: scene3d.cxx:608
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:2504
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:771
tools::Rectangle & Union(const tools::Rectangle &rRect)
Impl3DMirrorConstructOverlay(const Impl3DMirrorConstructOverlay &)=delete
SdrObject * ConvertToContourObj(SdrObject *pRet, bool bForceLineDash=false) const
Definition: svdobj.cxx:2466
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:1883
constexpr TypedWhichId< SvxColorItem > EE_CHAR_COLOR(EE_CHAR_START+0)
E3dDragConstraint
Definition: def3d.hxx:32
virtual void DeleteMarked()
Definition: svdview.cxx:1370
bool IsVertexHdl() const
Definition: svdhdl.hxx:213
void Start3DCreation()
Definition: view3d.cxx:1308
SdrObject * GetMarkedObjectByIndex(size_t nNum) const
Definition: svdmrkv.hxx:248
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:310
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:1621
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:1671
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:344
SdrMark * GetSdrMarkByIndex(size_t nNum) const
Definition: svdmrkv.hxx:247
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:366
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:2152
virtual ~E3dView() override
Definition: view3d.cxx:1478
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
virtual std::unique_ptr< SdrAttrObj, SdrObjectFreeOp > GetBreakObj()
Definition: obj3d.cxx:80
virtual void SetChanged()
Definition: svdobj.cxx:928
B2DPolyPolygon prepareForPolygonOperation(const B2DPolygon &rCandidate)
constexpr TypedWhichId< XLineColorItem > XATTR_LINECOLOR(XATTR_LINE_FIRST+3)
SdrMarkList & GetMarkedObjectListWriteAccess()
Definition: svdmrkv.hxx:239
SdrModel * GetModel() const
Definition: svdpntv.hxx:271
const Camera3D & GetCamera() const
Definition: scene3d.hxx:127
virtual SdrObject * getSdrObjectFromSdrObjList() const
Definition: svdpage.cxx:145
virtual E3dCompoundObject * CloneSdrObject(SdrModel &rTargetModel) const override
Definition: obj3d.cxx:592
virtual E3dScene * getRootE3dSceneFromE3dObject() const override
Definition: scene3d.cxx:356
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:1915
const Color & GetValue() const
SdrHdlKind GetKind() const
Definition: svdhdl.hxx:194
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
Definition: scene3d.cxx:284
bool m_bGrpEnterPossible
Definition: svdedtv.hxx:84
virtual void NbcSetLayer(SdrLayerID nLayer)
Definition: svdobj.cxx:593
sal_uInt32 PageWindowCount() const
Definition: svdpagv.hxx:94
bool IsObjMarked(SdrObject const *pObj) const
Definition: svdmrkv.cxx:1933