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