Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vcl/wrkwin.hxx>
31 : : #include <svx/svdogrp.hxx>
32 : : #include <svx/svdopath.hxx>
33 : : #include <tools/shl.hxx>
34 : : #include "svx/svditer.hxx"
35 : : #include <svx/svdpool.hxx>
36 : : #include <svx/svdorect.hxx>
37 : : #include <svx/svdmodel.hxx>
38 : : #include <svx/svdpagv.hxx>
39 : : #include <svx/svxids.hrc>
40 : : #include <editeng/colritem.hxx>
41 : : #include <svx/xtable.hxx>
42 : : #include <svx/svdview.hxx>
43 : : #include <svx/dialogs.hrc>
44 : : #include <svx/dialmgr.hxx>
45 : : #include "svx/globl3d.hxx"
46 : : #include <svx/obj3d.hxx>
47 : : #include <svx/lathe3d.hxx>
48 : : #include <svx/sphere3d.hxx>
49 : : #include <svx/extrud3d.hxx>
50 : : #include <svx/cube3d.hxx>
51 : : #include <svx/polysc3d.hxx>
52 : : #include "dragmt3d.hxx"
53 : : #include <svx/view3d.hxx>
54 : : #include <svx/svdundo.hxx>
55 : : #include <svx/xflclit.hxx>
56 : : #include <svx/xlnclit.hxx>
57 : : #include <svx/svdograf.hxx>
58 : : #include <svx/xbtmpit.hxx>
59 : : #include <svx/xflbmtit.hxx>
60 : : #include <basegfx/range/b2drange.hxx>
61 : : #include <basegfx/polygon/b2dpolygontools.hxx>
62 : : #include <basegfx/polygon/b2dpolypolygontools.hxx>
63 : : #include <svx/xlnwtit.hxx>
64 : : #include <svx/sdr/overlay/overlaypolypolygon.hxx>
65 : : #include <svx/sdr/overlay/overlaymanager.hxx>
66 : : #include <svx/sdrpaintwindow.hxx>
67 : : #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
68 : : #include <drawinglayer/geometry/viewinformation3d.hxx>
69 : : #include <svx/sdrpagewindow.hxx>
70 : : #include <svx/sdr/contact/displayinfo.hxx>
71 : : #include <svx/sdr/contact/objectcontact.hxx>
72 : : #include <svx/sdr/contact/viewobjectcontact.hxx>
73 : : #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
74 : : #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
75 : : #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
76 : : #include <basegfx/matrix/b2dhommatrixtools.hxx>
77 : : #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
78 : :
79 : : #define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
80 : :
81 [ - + ][ + - ]: 51616 : TYPEINIT1(E3dView, SdrView);
82 : :
83 : : //////////////////////////////////////////////////////////////////////////////
84 : : // Migrate Marking
85 : :
86 : : class Impl3DMirrorConstructOverlay
87 : : {
88 : : // The OverlayObjects
89 : : ::sdr::overlay::OverlayObjectList maObjects;
90 : :
91 : : // the view
92 : : const E3dView& mrView;
93 : :
94 : : // the object count
95 : : sal_uInt32 mnCount;
96 : :
97 : : // the unmirrored polygons
98 : : basegfx::B2DPolyPolygon* mpPolygons;
99 : :
100 : : // the overlay geometry from selected objects
101 : : drawinglayer::primitive2d::Primitive2DSequence maFullOverlay;
102 : :
103 : : public:
104 : : Impl3DMirrorConstructOverlay(const E3dView& rView);
105 : : ~Impl3DMirrorConstructOverlay();
106 : :
107 : : void SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB);
108 : : };
109 : :
110 : 0 : Impl3DMirrorConstructOverlay::Impl3DMirrorConstructOverlay(const E3dView& rView)
111 : : : maObjects(),
112 : : mrView(rView),
113 : 0 : mnCount(rView.GetMarkedObjectCount()),
114 : : mpPolygons(0),
115 [ # # ]: 0 : maFullOverlay()
116 : : {
117 [ # # ]: 0 : if(mnCount)
118 : : {
119 [ # # ][ # # ]: 0 : if(mrView.IsSolidDragging())
120 : : {
121 : 0 : SdrPageView* pPV = rView.GetSdrPageView();
122 : :
123 [ # # ][ # # ]: 0 : if(pPV && pPV->PageWindowCount())
[ # # ]
124 : : {
125 [ # # ][ # # ]: 0 : sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
126 [ # # ]: 0 : sdr::contact::DisplayInfo aDisplayInfo;
127 : :
128 : : // Do not use the last ViewPort set at the OC at the last ProcessDisplay()
129 [ # # ]: 0 : rOC.resetViewPort();
130 : :
131 [ # # ]: 0 : for(sal_uInt32 a(0);a < mnCount;a++)
132 : : {
133 [ # # ]: 0 : SdrObject* pObject = mrView.GetMarkedObjectByIndex(a);
134 : :
135 [ # # ]: 0 : if(pObject)
136 : : {
137 [ # # ]: 0 : sdr::contact::ViewContact& rVC = pObject->GetViewContact();
138 [ # # ]: 0 : sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rOC);
139 : :
140 [ # # ]: 0 : const drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo));
141 [ # # ][ # # ]: 0 : drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(maFullOverlay, aNewSequence);
142 : : }
143 [ # # ]: 0 : }
144 : : }
145 : : }
146 : : else
147 : : {
148 [ # # ][ # # ]: 0 : mpPolygons = new basegfx::B2DPolyPolygon[mnCount];
[ # # # #
# # ]
149 : :
150 [ # # ]: 0 : for(sal_uInt32 a(0); a < mnCount; a++)
151 : : {
152 [ # # ]: 0 : SdrObject* pObject = mrView.GetMarkedObjectByIndex(a);
153 [ # # ][ # # ]: 0 : mpPolygons[mnCount - (a + 1)] = pObject->TakeXorPoly();
[ # # ]
154 : : }
155 : : }
156 : : }
157 : 0 : }
158 : :
159 [ # # ]: 0 : Impl3DMirrorConstructOverlay::~Impl3DMirrorConstructOverlay()
160 : : {
161 : : // The OverlayObjects are cleared using the destructor of OverlayObjectList.
162 : : // That destructor calls clear() at the list which removes all objects from the
163 : : // OverlayManager and deletes them.
164 [ # # ][ # # ]: 0 : if(!mrView.IsSolidDragging())
165 : : {
166 [ # # ][ # # ]: 0 : delete[] mpPolygons;
[ # # ]
167 : : }
168 : 0 : }
169 : :
170 : 0 : void Impl3DMirrorConstructOverlay::SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB)
171 : : {
172 : : // get rid of old overlay objects
173 : 0 : maObjects.clear();
174 : :
175 : : // create new ones
176 [ # # ]: 0 : for(sal_uInt32 a(0); a < mrView.PaintWindowCount(); a++)
177 : : {
178 [ # # ]: 0 : SdrPaintWindow* pCandidate = mrView.GetPaintWindow(a);
179 [ # # ]: 0 : rtl::Reference< ::sdr::overlay::OverlayManager > xTargetOverlay = pCandidate->GetOverlayManager();
180 : :
181 [ # # ]: 0 : if(xTargetOverlay.is())
182 : : {
183 : : // buld transfoprmation: translate and rotate so that given edge is
184 : : // on x axis, them mirror in y and translate back
185 : 0 : const basegfx::B2DVector aEdge(aMirrorAxisB.X() - aMirrorAxisA.X(), aMirrorAxisB.Y() - aMirrorAxisA.Y());
186 : : basegfx::B2DHomMatrix aMatrixTransform(basegfx::tools::createTranslateB2DHomMatrix(
187 [ # # ]: 0 : -aMirrorAxisA.X(), -aMirrorAxisA.Y()));
188 [ # # ]: 0 : aMatrixTransform.rotate(-atan2(aEdge.getY(), aEdge.getX()));
189 [ # # ]: 0 : aMatrixTransform.scale(1.0, -1.0);
190 [ # # ]: 0 : aMatrixTransform.rotate(atan2(aEdge.getY(), aEdge.getX()));
191 [ # # ]: 0 : aMatrixTransform.translate(aMirrorAxisA.X(), aMirrorAxisA.Y());
192 : :
193 [ # # ][ # # ]: 0 : if(mrView.IsSolidDragging())
194 : : {
195 [ # # ]: 0 : if(maFullOverlay.hasElements())
196 : : {
197 [ # # ]: 0 : drawinglayer::primitive2d::Primitive2DSequence aContent(maFullOverlay);
198 : :
199 [ # # ][ # # ]: 0 : if(!aMatrixTransform.isIdentity())
200 : : {
201 : : // embed in transformation group
202 [ # # ][ # # ]: 0 : drawinglayer::primitive2d::Primitive2DReference aTransformPrimitive2D(new drawinglayer::primitive2d::TransformPrimitive2D(aMatrixTransform, aContent));
[ # # ]
203 [ # # ][ # # ]: 0 : aContent = drawinglayer::primitive2d::Primitive2DSequence(&aTransformPrimitive2D, 1);
[ # # ]
204 : : }
205 : :
206 : : // if we have full overlay from selected objects, embed with 50% transparence, the
207 : : // transformation is added to the OverlayPrimitive2DSequenceObject
208 [ # # ][ # # ]: 0 : drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aContent, 0.5));
[ # # ]
209 [ # # ][ # # ]: 0 : aContent = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparencePrimitive2D, 1);
[ # # ]
210 : :
211 [ # # ][ # # ]: 0 : sdr::overlay::OverlayPrimitive2DSequenceObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aContent);
212 : :
213 [ # # ]: 0 : xTargetOverlay->add(*pNew);
214 [ # # ][ # # ]: 0 : maObjects.append(*pNew);
215 : : }
216 : : }
217 : : else
218 : : {
219 [ # # ]: 0 : for(sal_uInt32 b(0); b < mnCount; b++)
220 : : {
221 : : // apply to polygon
222 [ # # ]: 0 : basegfx::B2DPolyPolygon aPolyPolygon(mpPolygons[b]);
223 [ # # ]: 0 : aPolyPolygon.transform(aMatrixTransform);
224 : :
225 [ # # ][ # # ]: 0 : ::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(aPolyPolygon);
226 [ # # ]: 0 : xTargetOverlay->add(*pNew);
227 [ # # ]: 0 : maObjects.append(*pNew);
228 [ # # ]: 0 : }
229 [ # # ]: 0 : }
230 : : }
231 [ # # ]: 0 : }
232 : 0 : }
233 : :
234 : 2031 : E3dView::E3dView(SdrModel* pModel, OutputDevice* pOut) :
235 [ + - ][ + - ]: 2031 : SdrView(pModel, pOut)
236 : : {
237 [ + - ]: 2031 : InitView ();
238 : 2031 : }
239 : :
240 : : // DrawMarkedObj overloaded, since possibly only a single 3D object is to be
241 : : // drawn
242 : :
243 : 21 : void E3dView::DrawMarkedObj(OutputDevice& rOut) const
244 : : {
245 : : // Does 3D objects exist which scenes are not selected?
246 : 21 : sal_Bool bSpecialHandling = sal_False;
247 : 21 : E3dScene *pScene = NULL;
248 : :
249 : 21 : long nCnt = GetMarkedObjectCount();
250 [ + + ]: 42 : for(long nObjs = 0;nObjs < nCnt;nObjs++)
251 : : {
252 : 21 : SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
253 [ - + ][ - + ]: 21 : if(pObj && pObj->ISA(E3dCompoundObject))
[ + - ]
254 : : {
255 : : // related scene
256 : 0 : pScene = ((E3dCompoundObject*)pObj)->GetScene();
257 [ # # ][ # # ]: 0 : if(pScene && !IsObjMarked(pScene))
[ # # ]
258 : 0 : bSpecialHandling = sal_True;
259 : : }
260 : : // Reset all selection flags
261 [ + - ][ - + ]: 21 : if(pObj && pObj->ISA(E3dObject))
[ - + ]
262 : : {
263 : 0 : pScene = ((E3dObject*)pObj)->GetScene();
264 [ # # ]: 0 : if(pScene)
265 : 0 : pScene->SetSelected(sal_False);
266 : : }
267 : : }
268 : :
269 [ - + ]: 21 : if(bSpecialHandling)
270 : : {
271 : : // Set selection flag to "not selected" for scenes related to all 3D
272 : : // objects
273 : : long nObjs;
274 [ # # ]: 0 : for(nObjs = 0;nObjs < nCnt;nObjs++)
275 : : {
276 : 0 : SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
277 [ # # ][ # # ]: 0 : if(pObj && pObj->ISA(E3dCompoundObject))
[ # # ]
278 : : {
279 : : // relatated scene
280 : 0 : pScene = ((E3dCompoundObject*)pObj)->GetScene();
281 [ # # ]: 0 : if(pScene)
282 : 0 : pScene->SetSelected(sal_False);
283 : : }
284 : : }
285 : :
286 [ # # ]: 0 : for(nObjs = 0;nObjs < nCnt;nObjs++)
287 : : {
288 : 0 : SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
289 [ # # ][ # # ]: 0 : if(pObj && pObj->ISA(E3dObject))
[ # # ]
290 : : {
291 : : // Select object
292 : 0 : E3dObject* p3DObj = (E3dObject*)pObj;
293 : 0 : p3DObj->SetSelected(sal_True);
294 : 0 : pScene = p3DObj->GetScene();
295 : : }
296 : : }
297 : :
298 [ # # ]: 0 : if(pScene)
299 : : {
300 : : // code from parent
301 : 0 : SortMarkedObjects();
302 : :
303 : 0 : pScene->SetDrawOnlySelected(sal_True);
304 : 0 : pScene->SingleObjectPainter(rOut);
305 : 0 : pScene->SetDrawOnlySelected(sal_False);
306 : : }
307 : :
308 : : // Reset selection flag
309 [ # # ]: 0 : for(nObjs = 0;nObjs < nCnt;nObjs++)
310 : : {
311 : 0 : SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
312 [ # # ][ # # ]: 0 : if(pObj && pObj->ISA(E3dCompoundObject))
[ # # ]
313 : : {
314 : : // releated scene
315 : 0 : pScene = ((E3dCompoundObject*)pObj)->GetScene();
316 [ # # ]: 0 : if(pScene)
317 : 0 : pScene->SetSelected(sal_False);
318 : : }
319 : : }
320 : : }
321 : : else
322 : : {
323 : : // call parent
324 : 21 : SdrExchangeView::DrawMarkedObj(rOut);
325 : : }
326 : 21 : }
327 : :
328 : : // Get overloaded model, since in some 3D objects an additional scene
329 : : // must be pushed in
330 : :
331 : 0 : SdrModel* E3dView::GetMarkedObjModel() const
332 : : {
333 : : // Does 3D objects exist which scenes are not selected?
334 : 0 : bool bSpecialHandling(false);
335 : 0 : const sal_uInt32 nCount(GetMarkedObjectCount());
336 : 0 : sal_uInt32 nObjs(0);
337 : 0 : E3dScene *pScene = 0;
338 : :
339 [ # # ]: 0 : for(nObjs = 0; nObjs < nCount; nObjs++)
340 : : {
341 [ # # ]: 0 : const SdrObject* pObj = GetMarkedObjectByIndex(nObjs);
342 : :
343 [ # # ][ # # ]: 0 : if(!bSpecialHandling && pObj && pObj->ISA(E3dCompoundObject))
[ # # ][ # # ]
[ # # ][ # # ]
344 : : {
345 : : // if the object is selected, but it's scene not,
346 : : // we need special handling
347 [ # # ]: 0 : pScene = ((E3dCompoundObject*)pObj)->GetScene();
348 : :
349 [ # # ][ # # ]: 0 : if(pScene && !IsObjMarked(pScene))
[ # # ][ # # ]
350 : : {
351 : 0 : bSpecialHandling = true;
352 : : }
353 : : }
354 : :
355 [ # # ][ # # ]: 0 : if(pObj && pObj->ISA(E3dObject))
[ # # ][ # # ]
[ # # ]
356 : : {
357 : : // reset all selection flags at 3D objects
358 [ # # ]: 0 : pScene = ((E3dObject*)pObj)->GetScene();
359 : :
360 [ # # ]: 0 : if(pScene)
361 : : {
362 [ # # ]: 0 : pScene->SetSelected(false);
363 : : }
364 : : }
365 : : }
366 : :
367 [ # # ]: 0 : if(!bSpecialHandling)
368 : : {
369 : : // call parent
370 [ # # ]: 0 : return SdrView::GetMarkedObjModel();
371 : : }
372 : :
373 : 0 : SdrModel* pNewModel = 0;
374 [ # # ]: 0 : Rectangle aSelectedSnapRect;
375 : :
376 : : // set 3d selection flags at all directly selected objects
377 : : // and collect SnapRect of selected objects
378 [ # # ]: 0 : for(nObjs = 0; nObjs < nCount; nObjs++)
379 : : {
380 [ # # ]: 0 : SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
381 : :
382 [ # # ][ # # ]: 0 : if(pObj && pObj->ISA(E3dCompoundObject))
[ # # ][ # # ]
[ # # ]
383 : : {
384 : : // mark object, but not scenes
385 : 0 : E3dCompoundObject* p3DObj = (E3dCompoundObject*)pObj;
386 [ # # ]: 0 : p3DObj->SetSelected(true);
387 [ # # ][ # # ]: 0 : aSelectedSnapRect.Union(p3DObj->GetSnapRect());
388 : : }
389 : : }
390 : :
391 : : // create new mark list which contains all indirectly selected3d
392 : : // scenes as selected objects
393 [ # # ]: 0 : SdrMarkList aOldML(GetMarkedObjectList());
394 [ # # ]: 0 : SdrMarkList aNewML;
395 : 0 : SdrMarkList& rCurrentMarkList = ((E3dView*)this)->GetMarkedObjectListWriteAccess();
396 [ # # ]: 0 : rCurrentMarkList = aNewML;
397 : :
398 [ # # ]: 0 : for(nObjs = 0; nObjs < nCount; nObjs++)
399 : : {
400 [ # # ][ # # ]: 0 : SdrObject *pObj = aOldML.GetMark(nObjs)->GetMarkedSdrObj();
401 : :
402 [ # # ][ # # ]: 0 : if(pObj && pObj->ISA(E3dObject))
[ # # ][ # # ]
[ # # ]
403 : : {
404 [ # # ]: 0 : pScene = ((E3dObject*)pObj)->GetScene();
405 : :
406 [ # # ][ # # ]: 0 : if(pScene && !IsObjMarked(pScene) && GetSdrPageView())
[ # # ][ # # ]
[ # # ]
407 : : {
408 [ # # ]: 0 : ((E3dView*)this)->MarkObj(pScene, GetSdrPageView(), sal_False, sal_True);
409 : : }
410 : : }
411 : : }
412 : :
413 : : // call parent. This will copy all scenes and the selection flags at the 3d objectss. So
414 : : // it will be possible to delete all non-selected 3d objects from the cloned 3d scenes
415 [ # # ]: 0 : pNewModel = SdrView::GetMarkedObjModel();
416 : :
417 [ # # ]: 0 : if(pNewModel)
418 : : {
419 [ # # ][ # # ]: 0 : for(sal_uInt16 nPg(0); nPg < pNewModel->GetPageCount(); nPg++)
420 : : {
421 [ # # ]: 0 : const SdrPage* pSrcPg=pNewModel->GetPage(nPg);
422 [ # # ]: 0 : const sal_uInt32 nObAnz(pSrcPg->GetObjCount());
423 : :
424 [ # # ]: 0 : for(sal_uInt32 nOb(0); nOb < nObAnz; nOb++)
425 : : {
426 [ # # ]: 0 : const SdrObject* pSrcOb=pSrcPg->GetObj(nOb);
427 : :
428 [ # # ][ # # ]: 0 : if(pSrcOb->ISA(E3dScene))
[ # # ]
429 : : {
430 : 0 : pScene = (E3dScene*)pSrcOb;
431 : :
432 : : // delete all not intentionally cloned 3d objects
433 [ # # ]: 0 : pScene->removeAllNonSelectedObjects();
434 : :
435 : : // reset select flags and set SnapRect of all selected objects
436 [ # # ]: 0 : pScene->SetSelected(false);
437 [ # # ]: 0 : pScene->SetSnapRect(aSelectedSnapRect);
438 : : }
439 : : }
440 : : }
441 : : }
442 : :
443 : : // restore old selection
444 [ # # ]: 0 : rCurrentMarkList = aOldML;
445 : :
446 [ # # ][ # # ]: 0 : return pNewModel;
447 : : }
448 : :
449 : : // When pasting objects have to integrated if a scene is inserted, but
450 : : // not the scene itself
451 : :
452 : 0 : sal_Bool E3dView::Paste(const SdrModel& rMod, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
453 : : {
454 : 0 : sal_Bool bRetval = sal_False;
455 : :
456 : : // Get list
457 : 0 : Point aPos(rPos);
458 : 0 : SdrObjList* pDstList = pLst;
459 [ # # ]: 0 : ImpGetPasteObjList(aPos, pDstList);
460 : :
461 [ # # ]: 0 : if(!pDstList)
462 : 0 : return sal_False;
463 : :
464 : : // Get owner of the list
465 : 0 : SdrObject* pOwner = pDstList->GetOwnerObj();
466 [ # # ][ # # ]: 0 : if(pOwner && pOwner->ISA(E3dScene))
[ # # ][ # # ]
[ # # ]
467 : : {
468 : 0 : E3dScene* pDstScene = (E3dScene*)pOwner;
469 [ # # ][ # # ]: 0 : BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_EXCHANGE_PASTE));
[ # # ][ # # ]
[ # # ]
470 : :
471 : : // Copy all objects from E3dScenes and insert them directly
472 [ # # ][ # # ]: 0 : for(sal_uInt16 nPg(0); nPg < rMod.GetPageCount(); nPg++)
473 : : {
474 [ # # ]: 0 : const SdrPage* pSrcPg=rMod.GetPage(nPg);
475 [ # # ]: 0 : sal_uInt32 nObAnz(pSrcPg->GetObjCount());
476 : :
477 : : // calculate offset for paste
478 [ # # ]: 0 : Rectangle aR = pSrcPg->GetAllObjBoundRect();
479 [ # # ]: 0 : Point aDist(aPos - aR.Center());
480 : :
481 : : // Insert sub-objects for scenes
482 [ # # ]: 0 : for(sal_uInt32 nOb(0); nOb < nObAnz; nOb++)
483 : : {
484 [ # # ]: 0 : const SdrObject* pSrcOb = pSrcPg->GetObj(nOb);
485 [ # # ][ # # ]: 0 : if(pSrcOb->ISA(E3dScene))
[ # # ]
486 : : {
487 : 0 : E3dScene* pSrcScene = (E3dScene*)pSrcOb;
488 [ # # ]: 0 : ImpCloneAll3DObjectsToDestScene(pSrcScene, pDstScene, aDist);
489 : : }
490 : : }
491 : : }
492 [ # # ]: 0 : EndUndo();
493 : : }
494 : : else
495 : : {
496 : : // call parent
497 [ # # ]: 0 : bRetval = SdrView::Paste(rMod, rPos, pLst, nOptions);
498 : : }
499 : :
500 : 0 : return bRetval;
501 : : }
502 : :
503 : : // Service routine used from local Clone() and from SdrCreateView::EndCreateObj(...)
504 : 0 : sal_Bool E3dView::ImpCloneAll3DObjectsToDestScene(E3dScene* pSrcScene, E3dScene* pDstScene, Point /*aOffset*/)
505 : : {
506 : 0 : sal_Bool bRetval(sal_False);
507 : :
508 [ # # ][ # # ]: 0 : if(pSrcScene && pDstScene)
509 : : {
510 [ # # ]: 0 : const sdr::contact::ViewContactOfE3dScene& rVCSceneDst = static_cast< sdr::contact::ViewContactOfE3dScene& >(pDstScene->GetViewContact());
511 [ # # ][ # # ]: 0 : const drawinglayer::geometry::ViewInformation3D aViewInfo3DDst(rVCSceneDst.getViewInformation3D());
512 [ # # ]: 0 : const sdr::contact::ViewContactOfE3dScene& rVCSceneSrc = static_cast< sdr::contact::ViewContactOfE3dScene& >(pSrcScene->GetViewContact());
513 [ # # ][ # # ]: 0 : const drawinglayer::geometry::ViewInformation3D aViewInfo3DSrc(rVCSceneSrc.getViewInformation3D());
514 : :
515 [ # # ][ # # ]: 0 : for(sal_uInt32 i(0); i < pSrcScene->GetSubList()->GetObjCount(); i++)
[ # # ]
516 : : {
517 [ # # ][ # # ]: 0 : E3dCompoundObject* pCompoundObj = dynamic_cast< E3dCompoundObject* >(pSrcScene->GetSubList()->GetObj(i));
[ # # ]
518 : :
519 [ # # ]: 0 : if(pCompoundObj)
520 : : {
521 [ # # ]: 0 : E3dCompoundObject* pNewCompoundObj = dynamic_cast< E3dCompoundObject* >(pCompoundObj->Clone());
522 : :
523 [ # # ]: 0 : if(pNewCompoundObj)
524 : : {
525 : : // get dest scene's current range in 3D world coordinates
526 [ # # ][ # # ]: 0 : const basegfx::B3DHomMatrix aSceneToWorldTrans(pDstScene->GetFullTransform());
527 [ # # ]: 0 : basegfx::B3DRange aSceneRange(pDstScene->GetBoundVolume());
528 [ # # ]: 0 : aSceneRange.transform(aSceneToWorldTrans);
529 : :
530 : : // get new object's implied object transformation
531 [ # # ][ # # ]: 0 : const basegfx::B3DHomMatrix aNewObjectTrans(pNewCompoundObj->GetTransform());
532 : :
533 : : // get new object's range in 3D world coordinates in dest scene
534 : : // as if it were already added
535 [ # # ]: 0 : const basegfx::B3DHomMatrix aObjectToWorldTrans(aSceneToWorldTrans * aNewObjectTrans);
536 [ # # ]: 0 : basegfx::B3DRange aObjectRange(pNewCompoundObj->GetBoundVolume());
537 [ # # ]: 0 : aObjectRange.transform(aObjectToWorldTrans);
538 : :
539 : : // get scale adaption
540 [ # # ]: 0 : const basegfx::B3DVector aSceneScale(aSceneRange.getRange());
541 [ # # ]: 0 : const basegfx::B3DVector aObjectScale(aObjectRange.getRange());
542 : 0 : double fScale(1.0);
543 : :
544 : : // if new object's size in X,Y or Z is bigger that 80% of dest scene, adapt scale
545 : : // to not change the scene by the inserted object
546 : 0 : const double fSizeFactor(0.5);
547 : :
548 [ # # ]: 0 : if(aObjectScale.getX() * fScale > aSceneScale.getX() * fSizeFactor)
549 : : {
550 : 0 : const double fObjSize(aObjectScale.getX() * fScale);
551 [ # # ]: 0 : const double fFactor((aSceneScale.getX() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
552 : 0 : fScale *= fFactor;
553 : : }
554 : :
555 [ # # ]: 0 : if(aObjectScale.getY() * fScale > aSceneScale.getY() * fSizeFactor)
556 : : {
557 : 0 : const double fObjSize(aObjectScale.getY() * fScale);
558 [ # # ]: 0 : const double fFactor((aSceneScale.getY() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
559 : 0 : fScale *= fFactor;
560 : : }
561 : :
562 [ # # ]: 0 : if(aObjectScale.getZ() * fScale > aSceneScale.getZ() * fSizeFactor)
563 : : {
564 : 0 : const double fObjSize(aObjectScale.getZ() * fScale);
565 [ # # ]: 0 : const double fFactor((aSceneScale.getZ() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
566 : 0 : fScale *= fFactor;
567 : : }
568 : :
569 : : // get translation adaption
570 [ # # ]: 0 : const basegfx::B3DPoint aSceneCenter(aSceneRange.getCenter());
571 [ # # ]: 0 : const basegfx::B3DPoint aObjectCenter(aObjectRange.getCenter());
572 : :
573 : : // build full modification transform. The object's transformation
574 : : // shall be modified, so start at object coordinates; transform to 3d world coor
575 [ # # ]: 0 : basegfx::B3DHomMatrix aModifyingTransform(aObjectToWorldTrans);
576 : :
577 : : // translate to absolute center in 3d world coor
578 [ # # ]: 0 : aModifyingTransform.translate(-aObjectCenter.getX(), -aObjectCenter.getY(), -aObjectCenter.getZ());
579 : :
580 : : // scale to dest size in 3d world coor
581 [ # # ]: 0 : aModifyingTransform.scale(fScale, fScale, fScale);
582 : :
583 : : // translate to dest scene center in 3d world coor
584 [ # # ]: 0 : aModifyingTransform.translate(aSceneCenter.getX(), aSceneCenter.getY(), aSceneCenter.getZ());
585 : :
586 : : // transform from 3d world to dest object coordinates
587 [ # # ]: 0 : basegfx::B3DHomMatrix aWorldToObject(aObjectToWorldTrans);
588 [ # # ]: 0 : aWorldToObject.invert();
589 [ # # ][ # # ]: 0 : aModifyingTransform = aWorldToObject * aModifyingTransform;
[ # # ]
590 : :
591 : : // correct implied object transform by applying changing one in object coor
592 [ # # ][ # # ]: 0 : pNewCompoundObj->SetTransform(aModifyingTransform * aNewObjectTrans);
[ # # ]
593 : :
594 : : // fill and insert new object
595 [ # # ][ # # ]: 0 : pNewCompoundObj->SetModel(pDstScene->GetModel());
596 [ # # ][ # # ]: 0 : pNewCompoundObj->SetPage(pDstScene->GetPage());
597 [ # # ][ # # ]: 0 : pNewCompoundObj->NbcSetLayer(pCompoundObj->GetLayer());
598 [ # # ][ # # ]: 0 : pNewCompoundObj->NbcSetStyleSheet(pCompoundObj->GetStyleSheet(), sal_True);
599 [ # # ]: 0 : pDstScene->Insert3DObj(pNewCompoundObj);
600 : 0 : bRetval = sal_True;
601 : :
602 : : // Create undo
603 [ # # ][ # # ]: 0 : if( GetModel()->IsUndoEnabled() )
604 [ # # ][ # # ]: 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNewCompoundObj));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
605 : : }
606 : : }
607 [ # # ][ # # ]: 0 : }
608 : : }
609 : :
610 : 0 : return bRetval;
611 : : }
612 : :
613 : 6385 : sal_Bool E3dView::IsConvertTo3DObjPossible() const
614 : : {
615 : 6385 : sal_Bool bAny3D(sal_False);
616 : 6385 : sal_Bool bGroupSelected(sal_False);
617 : 6385 : sal_Bool bRetval(sal_True);
618 : :
619 [ + - ][ + + ]: 6388 : for(sal_uInt32 a=0;!bAny3D && a<GetMarkedObjectCount();a++)
[ + + ]
620 : : {
621 [ + - ]: 3 : SdrObject *pObj = GetMarkedObjectByIndex(a);
622 [ + - ]: 3 : if(pObj)
623 : : {
624 [ + - ]: 3 : ImpIsConvertTo3DPossible(pObj, bAny3D, bGroupSelected);
625 : : }
626 : : }
627 : :
628 : 6385 : bRetval = !bAny3D
629 : : && (
630 [ + - ]: 6385 : IsConvertToPolyObjPossible(sal_False)
631 [ + - ]: 6382 : || IsConvertToPathObjPossible(sal_False)
632 [ + - ][ + + ]: 19152 : || IsImportMtfPossible());
[ + - ][ + - ]
[ - + ]
633 : 6385 : return bRetval;
634 : : }
635 : :
636 : 3 : void E3dView::ImpIsConvertTo3DPossible(SdrObject* pObj, sal_Bool& rAny3D,
637 : : sal_Bool& rGroupSelected) const
638 : : {
639 [ + - ]: 3 : if(pObj)
640 : : {
641 [ - + ]: 3 : if(pObj->ISA(E3dObject))
642 : : {
643 : 0 : rAny3D = sal_True;
644 : : }
645 : : else
646 : : {
647 [ - + ]: 3 : if(pObj->IsGroupObject())
648 : : {
649 [ # # ]: 0 : SdrObjListIter aIter(*pObj, IM_DEEPNOGROUPS);
650 [ # # ]: 0 : while(aIter.IsMore())
651 : : {
652 [ # # ]: 0 : SdrObject* pNewObj = aIter.Next();
653 [ # # ]: 0 : ImpIsConvertTo3DPossible(pNewObj, rAny3D, rGroupSelected);
654 : : }
655 : 0 : rGroupSelected = sal_True;
656 : : }
657 : : }
658 : : }
659 : 3 : }
660 : :
661 : : #include <editeng/eeitem.hxx>
662 : :
663 : 0 : void E3dView::ImpChangeSomeAttributesFor3DConversion(SdrObject* pObj)
664 : : {
665 [ # # ]: 0 : if(pObj->ISA(SdrTextObj))
666 : : {
667 : 0 : const SfxItemSet& rSet = pObj->GetMergedItemSet();
668 : 0 : const SvxColorItem& rTextColorItem = (const SvxColorItem&)rSet.Get(EE_CHAR_COLOR);
669 [ # # ]: 0 : if(rTextColorItem.GetValue() == RGB_Color(COL_BLACK))
670 : : {
671 : : //For black text objects, the color set to gray
672 [ # # ]: 0 : if(pObj->GetPage())
673 : : {
674 : : // if black is only default attribute from
675 : : // pattern set it hard so that it is used in undo.
676 [ # # ][ # # ]: 0 : pObj->SetMergedItem(SvxColorItem(RGB_Color(COL_BLACK), EE_CHAR_COLOR));
[ # # ]
677 : :
678 : : // add undo now
679 [ # # ]: 0 : if( GetModel()->IsUndoEnabled() )
680 : 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj, false, false));
681 : : }
682 : :
683 [ # # ][ # # ]: 0 : pObj->SetMergedItem(SvxColorItem(RGB_Color(COL_GRAY), EE_CHAR_COLOR));
[ # # ]
684 : : }
685 : : }
686 : 0 : }
687 : :
688 : 0 : void E3dView::ImpChangeSomeAttributesFor3DConversion2(SdrObject* pObj)
689 : : {
690 [ # # ]: 0 : if(pObj->ISA(SdrPathObj))
691 : : {
692 : 0 : const SfxItemSet& rSet = pObj->GetMergedItemSet();
693 : 0 : sal_Int32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue();
694 : 0 : XLineStyle eLineStyle = (XLineStyle)((const XLineStyleItem&)rSet.Get(XATTR_LINESTYLE)).GetValue();
695 : 0 : XFillStyle eFillStyle = ITEMVALUE(rSet, XATTR_FILLSTYLE, XFillStyleItem);
696 : :
697 [ # # ][ # # ]: 0 : if(((SdrPathObj*)pObj)->IsClosed()
[ # # ][ # # ]
[ # # ]
698 : : && eLineStyle == XLINE_SOLID
699 : : && !nLineWidth
700 : : && eFillStyle != XFILL_NONE)
701 : : {
702 [ # # ][ # # ]: 0 : if(pObj->GetPage() && GetModel()->IsUndoEnabled() )
[ # # ]
703 : 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj, false, false));
704 [ # # ]: 0 : pObj->SetMergedItem(XLineStyleItem(XLINE_NONE));
705 [ # # ]: 0 : pObj->SetMergedItem(XLineWidthItem(0L));
706 : : }
707 : : }
708 : 0 : }
709 : :
710 : 0 : void E3dView::ImpCreateSingle3DObjectFlat(E3dScene* pScene, SdrObject* pObj, sal_Bool bExtrude, double fDepth, basegfx::B2DHomMatrix& rLatheMat)
711 : : {
712 : : // Single PathObject, transform this
713 [ # # ][ # # ]: 0 : SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj);
714 : :
715 [ # # ]: 0 : if(pPath)
716 : : {
717 [ # # ]: 0 : E3dDefaultAttributes aDefault = Get3DDefaultAttributes();
718 [ # # ]: 0 : if(bExtrude)
719 : 0 : aDefault.SetDefaultExtrudeCharacterMode(sal_True);
720 : : else
721 : 0 : aDefault.SetDefaultLatheCharacterMode(sal_True);
722 : :
723 : : // Get Itemset of the original object
724 [ # # ][ # # ]: 0 : SfxItemSet aSet(pObj->GetMergedItemSet());
725 : :
726 [ # # ]: 0 : XFillStyle eFillStyle = ITEMVALUE(aSet, XATTR_FILLSTYLE, XFillStyleItem);
727 : :
728 : : // line style turned off
729 [ # # ][ # # ]: 0 : aSet.Put(XLineStyleItem(XLINE_NONE));
[ # # ]
730 : :
731 : : //Determining if FILL_Attribut is set.
732 [ # # ][ # # ]: 0 : if(!pPath->IsClosed() || eFillStyle == XFILL_NONE)
[ # # ]
733 : : {
734 : : // This SdrPathObj is not filled, leave the front and rear face out.
735 : : // Moreover, a two-sided representation necessary.
736 : 0 : aDefault.SetDefaultExtrudeCloseFront(sal_False);
737 : 0 : aDefault.SetDefaultExtrudeCloseBack(sal_False);
738 : :
739 [ # # ][ # # ]: 0 : aSet.Put(Svx3DDoubleSidedItem(sal_True));
[ # # ]
740 : :
741 : : // Set fill attribute
742 [ # # ][ # # ]: 0 : aSet.Put(XFillStyleItem(XFILL_SOLID));
[ # # ]
743 : :
744 : : // Fill color must be the color line, because the object was
745 : : // previously just a line
746 [ # # ][ # # ]: 0 : Color aColorLine = ((const XLineColorItem&)(aSet.Get(XATTR_LINECOLOR))).GetColorValue();
747 [ # # ][ # # ]: 0 : aSet.Put(XFillColorItem(String(), aColorLine));
[ # # ][ # # ]
[ # # ]
748 : : }
749 : :
750 : : // Create a new extrude object
751 : 0 : E3dObject* p3DObj = NULL;
752 [ # # ]: 0 : if(bExtrude)
753 : : {
754 [ # # ][ # # ]: 0 : p3DObj = new E3dExtrudeObj(aDefault, pPath->GetPathPoly(), fDepth);
755 : : }
756 : : else
757 : : {
758 [ # # ]: 0 : basegfx::B2DPolyPolygon aPolyPoly2D(pPath->GetPathPoly());
759 [ # # ]: 0 : aPolyPoly2D.transform(rLatheMat);
760 [ # # ][ # # ]: 0 : p3DObj = new E3dLatheObj(aDefault, aPolyPoly2D);
[ # # ][ # # ]
[ # # ]
761 : : }
762 : :
763 : : // Set attribute
764 [ # # ]: 0 : if(p3DObj)
765 : : {
766 [ # # ][ # # ]: 0 : p3DObj->NbcSetLayer(pObj->GetLayer());
767 : :
768 [ # # ]: 0 : p3DObj->SetMergedItemSet(aSet);
769 : :
770 [ # # ][ # # ]: 0 : p3DObj->NbcSetStyleSheet(pObj->GetStyleSheet(), sal_True);
771 : :
772 : : // Insert a new extrude object
773 [ # # ]: 0 : pScene->Insert3DObj(p3DObj);
774 [ # # ][ # # ]: 0 : }
775 : : }
776 : 0 : }
777 : :
778 : 0 : void E3dView::ImpCreate3DObject(E3dScene* pScene, SdrObject* pObj, sal_Bool bExtrude, double fDepth, basegfx::B2DHomMatrix& rLatheMat)
779 : : {
780 [ # # ]: 0 : if(pObj)
781 : : {
782 : : // change text color attribute for not so dark colors
783 [ # # ][ # # ]: 0 : if(pObj->IsGroupObject())
784 : : {
785 [ # # ]: 0 : SdrObjListIter aIter(*pObj, IM_DEEPWITHGROUPS);
786 [ # # ]: 0 : while(aIter.IsMore())
787 : : {
788 [ # # ]: 0 : SdrObject* pGroupMember = aIter.Next();
789 [ # # ]: 0 : ImpChangeSomeAttributesFor3DConversion(pGroupMember);
790 : 0 : }
791 : : }
792 : : else
793 [ # # ]: 0 : ImpChangeSomeAttributesFor3DConversion(pObj);
794 : :
795 : : // convert completely to path objects
796 [ # # ]: 0 : SdrObject* pNewObj1 = pObj->ConvertToPolyObj(sal_False, sal_False);
797 : :
798 [ # # ]: 0 : if(pNewObj1)
799 : : {
800 : : // change text color attribute for not so dark colors
801 [ # # ][ # # ]: 0 : if(pNewObj1->IsGroupObject())
802 : : {
803 [ # # ]: 0 : SdrObjListIter aIter(*pNewObj1, IM_DEEPWITHGROUPS);
804 [ # # ]: 0 : while(aIter.IsMore())
805 : : {
806 [ # # ]: 0 : SdrObject* pGroupMember = aIter.Next();
807 [ # # ]: 0 : ImpChangeSomeAttributesFor3DConversion2(pGroupMember);
808 : 0 : }
809 : : }
810 : : else
811 [ # # ]: 0 : ImpChangeSomeAttributesFor3DConversion2(pNewObj1);
812 : :
813 : : // convert completely to path objects
814 [ # # ]: 0 : SdrObject* pNewObj2 = pObj->ConvertToContourObj(pNewObj1, sal_True);
815 : :
816 [ # # ]: 0 : if(pNewObj2)
817 : : {
818 : : // add all to flat scene
819 [ # # ][ # # ]: 0 : if(pNewObj2->IsGroupObject())
820 : : {
821 [ # # ]: 0 : SdrObjListIter aIter(*pNewObj2, IM_DEEPWITHGROUPS);
822 [ # # ]: 0 : while(aIter.IsMore())
823 : : {
824 [ # # ]: 0 : SdrObject* pGroupMember = aIter.Next();
825 [ # # ]: 0 : ImpCreateSingle3DObjectFlat(pScene, pGroupMember, bExtrude, fDepth, rLatheMat);
826 : 0 : }
827 : : }
828 : : else
829 [ # # ]: 0 : ImpCreateSingle3DObjectFlat(pScene, pNewObj2, bExtrude, fDepth, rLatheMat);
830 : :
831 : : // delete object in between
832 [ # # ][ # # ]: 0 : if(pNewObj2 != pObj && pNewObj2 != pNewObj1 && pNewObj2)
[ # # ]
833 [ # # ]: 0 : SdrObject::Free( pNewObj2 );
834 : : }
835 : :
836 : : // delete object in between
837 [ # # ][ # # ]: 0 : if(pNewObj1 != pObj && pNewObj1)
838 [ # # ]: 0 : SdrObject::Free( pNewObj1 );
839 : : }
840 : : }
841 : 0 : }
842 : :
843 : 0 : void E3dView::ConvertMarkedObjTo3D(sal_Bool bExtrude, basegfx::B2DPoint aPnt1, basegfx::B2DPoint aPnt2)
844 : : {
845 [ # # ]: 0 : if(AreObjectsMarked())
846 : : {
847 : : // Create undo
848 [ # # ]: 0 : if(bExtrude)
849 [ # # ][ # # ]: 0 : BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_EXTRUDE));
[ # # ][ # # ]
[ # # ]
850 : : else
851 [ # # ][ # # ]: 0 : BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_LATHE));
[ # # ][ # # ]
[ # # ]
852 : :
853 : : // Create a new scene for the created 3D object
854 [ # # ][ # # ]: 0 : E3dScene* pScene = new E3dPolyScene(Get3DDefaultAttributes());
855 : :
856 : : // Determine rectangle and possibly correct it
857 [ # # ]: 0 : Rectangle aRect = GetAllMarkedRect();
858 [ # # ][ # # ]: 0 : if(aRect.GetWidth() <= 1)
859 [ # # ][ # # ]: 0 : aRect.SetSize(Size(500, aRect.GetHeight()));
860 [ # # ][ # # ]: 0 : if(aRect.GetHeight() <= 1)
861 [ # # ][ # # ]: 0 : aRect.SetSize(Size(aRect.GetWidth(), 500));
862 : :
863 : : // Determine the depth relative to the size of the selection
864 : 0 : double fDepth = 0.0;
865 : 0 : double fRot3D = 0.0;
866 [ # # ]: 0 : basegfx::B2DHomMatrix aLatheMat;
867 : :
868 [ # # ]: 0 : if(bExtrude)
869 : : {
870 [ # # ]: 0 : double fW = (double)aRect.GetWidth();
871 [ # # ]: 0 : double fH = (double)aRect.GetHeight();
872 : 0 : fDepth = sqrt(fW*fW + fH*fH) / 6.0;
873 : : }
874 [ # # ]: 0 : if(!bExtrude)
875 : : {
876 : : // Create transformation for the polygons rotating body
877 [ # # ]: 0 : if(aPnt1 != aPnt2)
878 : : {
879 : : // Rotation around control point #1 with set angle
880 : : // for 3D coordinates
881 : 0 : basegfx::B2DPoint aDiff(aPnt1 - aPnt2);
882 : 0 : fRot3D = atan2(aDiff.getY(), aDiff.getX()) - F_PI2;
883 : :
884 [ # # ]: 0 : if(basegfx::fTools::equalZero(fabs(fRot3D)))
885 : 0 : fRot3D = 0.0;
886 : :
887 [ # # ]: 0 : if(fRot3D != 0.0)
888 : : {
889 : : aLatheMat = basegfx::tools::createRotateAroundPoint(aPnt2, -fRot3D)
890 [ # # ][ # # ]: 0 : * aLatheMat;
[ # # ][ # # ]
[ # # ]
891 : 0 : }
892 : : }
893 : :
894 [ # # ]: 0 : if(aPnt2.getX() != 0.0)
895 : : {
896 : : // Translation to Y=0 - axis
897 [ # # ]: 0 : aLatheMat.translate(-aPnt2.getX(), 0.0);
898 : : }
899 : : else
900 : : {
901 [ # # ]: 0 : aLatheMat.translate((double)-aRect.Left(), 0.0);
902 : : }
903 : :
904 : : // Form the inverse matrix to determine the target expansion
905 [ # # ]: 0 : basegfx::B2DHomMatrix aInvLatheMat(aLatheMat);
906 [ # # ]: 0 : aInvLatheMat.invert();
907 : :
908 : : // SnapRect extension enables mirroring in the axis of rotation
909 [ # # ]: 0 : for(sal_uInt32 a=0;a<GetMarkedObjectCount();a++)
910 : : {
911 [ # # ]: 0 : SdrMark* pMark = GetSdrMarkByIndex(a);
912 [ # # ]: 0 : SdrObject* pObj = pMark->GetMarkedSdrObj();
913 [ # # ]: 0 : Rectangle aTurnRect = pObj->GetSnapRect();
914 : 0 : basegfx::B2DPoint aRot;
915 : 0 : Point aRotPnt;
916 : :
917 : 0 : aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Top());
918 [ # # ]: 0 : aRot *= aLatheMat;
919 : 0 : aRot.setX(-aRot.getX());
920 [ # # ]: 0 : aRot *= aInvLatheMat;
921 : 0 : aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
922 [ # # ][ # # ]: 0 : aRect.Union(Rectangle(aRotPnt, aRotPnt));
923 : :
924 : 0 : aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Bottom());
925 [ # # ]: 0 : aRot *= aLatheMat;
926 : 0 : aRot.setX(-aRot.getX());
927 [ # # ]: 0 : aRot *= aInvLatheMat;
928 : 0 : aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
929 [ # # ][ # # ]: 0 : aRect.Union(Rectangle(aRotPnt, aRotPnt));
930 : :
931 : 0 : aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Top());
932 [ # # ]: 0 : aRot *= aLatheMat;
933 : 0 : aRot.setX(-aRot.getX());
934 [ # # ]: 0 : aRot *= aInvLatheMat;
935 : 0 : aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
936 [ # # ][ # # ]: 0 : aRect.Union(Rectangle(aRotPnt, aRotPnt));
937 : :
938 : 0 : aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Bottom());
939 [ # # ]: 0 : aRot *= aLatheMat;
940 : 0 : aRot.setX(-aRot.getX());
941 [ # # ]: 0 : aRot *= aInvLatheMat;
942 : 0 : aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
943 [ # # ][ # # ]: 0 : aRect.Union(Rectangle(aRotPnt, aRotPnt));
944 [ # # ]: 0 : }
945 : : }
946 : :
947 : : // Walk throguh the selection and convert it into 3D, complete with
948 : : // Convertion to SdrPathObject, also fonts
949 [ # # ]: 0 : for(sal_uInt32 a=0;a<GetMarkedObjectCount();a++)
950 : : {
951 [ # # ]: 0 : SdrMark* pMark = GetSdrMarkByIndex(a);
952 [ # # ]: 0 : SdrObject* pObj = pMark->GetMarkedSdrObj();
953 : :
954 [ # # ]: 0 : ImpCreate3DObject(pScene, pObj, bExtrude, fDepth, aLatheMat);
955 : : }
956 : :
957 [ # # ][ # # ]: 0 : if(pScene->GetSubList() && pScene->GetSubList()->GetObjCount() != 0)
[ # # ][ # # ]
[ # # ][ # # ]
958 : : {
959 : : // Arrange all created objects by depth
960 [ # # ]: 0 : if(bExtrude)
961 [ # # ]: 0 : DoDepthArrange(pScene, fDepth);
962 : :
963 : : // Center 3D objects in the middle of the overall rectangle
964 [ # # ][ # # ]: 0 : basegfx::B3DPoint aCenter(pScene->GetBoundVolume().getCenter());
965 [ # # ]: 0 : basegfx::B3DHomMatrix aMatrix;
966 : :
967 [ # # ]: 0 : aMatrix.translate(-aCenter.getX(), -aCenter.getY(), -aCenter.getZ());
968 [ # # ][ # # ]: 0 : pScene->SetTransform(aMatrix * pScene->GetTransform());
[ # # ][ # # ]
969 : :
970 : : // Initialize scene
971 [ # # ]: 0 : pScene->NbcSetSnapRect(aRect);
972 [ # # ]: 0 : basegfx::B3DRange aBoundVol = pScene->GetBoundVolume();
973 [ # # ][ # # ]: 0 : InitScene(pScene, (double)aRect.GetWidth(), (double)aRect.GetHeight(), aBoundVol.getDepth());
[ # # ][ # # ]
974 : :
975 : : // Insert scene instead of the first selected object and throw away
976 : : // all the old objects
977 [ # # ]: 0 : SdrObject* pRepObj = GetMarkedObjectByIndex(0);
978 [ # # ]: 0 : SdrPageView* pPV = GetSdrPageViewOfMarkedByIndex(0);
979 [ # # ]: 0 : MarkObj(pRepObj, pPV, sal_True);
980 [ # # ]: 0 : ReplaceObjectAtView(pRepObj, *pPV, pScene, sal_False);
981 [ # # ]: 0 : DeleteMarked();
982 [ # # ]: 0 : MarkObj(pScene, pPV);
983 : :
984 : : // Rotate Rotation body around the axis of rotation
985 [ # # ]: 0 : basegfx::B3DHomMatrix aRotate;
986 : :
987 [ # # ][ # # ]: 0 : if(!bExtrude && fRot3D != 0.0)
988 : : {
989 [ # # ]: 0 : aRotate.rotate(0.0, 0.0, fRot3D);
990 : : }
991 : :
992 : : // Set default rotation
993 : : {
994 : 0 : double XRotateDefault = 20;
995 [ # # ]: 0 : aRotate.rotate(DEG2RAD(XRotateDefault), 0.0, 0.0);
996 : : }
997 : :
998 [ # # ][ # # ]: 0 : if(!aRotate.isIdentity())
999 : : {
1000 [ # # ][ # # ]: 0 : pScene->SetTransform(aRotate * pScene->GetTransform());
[ # # ][ # # ]
1001 : : }
1002 : :
1003 : : // Invalid SnapRects of objects
1004 [ # # ][ # # ]: 0 : pScene->SetSnapRect(aRect);
[ # # ]
1005 : : }
1006 : : else
1007 : : {
1008 : : // No 3D object was created, throw away everything
1009 [ # # ][ # # ]: 0 : delete pScene;
1010 : : }
1011 : :
1012 [ # # ][ # # ]: 0 : EndUndo();
1013 : : }
1014 : 0 : }
1015 : :
1016 : : //Arrange all created extrude objects by depth
1017 : :
1018 : 0 : struct E3dDepthNeighbour
1019 : : {
1020 : : E3dDepthNeighbour* mpNext;
1021 : : E3dExtrudeObj* mpObj;
1022 : : basegfx::B2DPolyPolygon maPreparedPolyPolygon;
1023 : :
1024 : 0 : E3dDepthNeighbour()
1025 : : : mpNext(0),
1026 : : mpObj(0),
1027 : 0 : maPreparedPolyPolygon()
1028 : : {
1029 : 0 : }
1030 : : };
1031 : :
1032 : : struct E3dDepthLayer
1033 : : {
1034 : : E3dDepthLayer* mpDown;
1035 : : E3dDepthNeighbour* mpNext;
1036 : :
1037 : 0 : E3dDepthLayer()
1038 : : : mpDown(0),
1039 : 0 : mpNext(0)
1040 : : {
1041 : 0 : }
1042 : :
1043 : 0 : ~E3dDepthLayer()
1044 : : {
1045 [ # # ]: 0 : while(mpNext)
1046 : : {
1047 : 0 : E3dDepthNeighbour* pSucc = mpNext->mpNext;
1048 [ # # ]: 0 : delete mpNext;
1049 : 0 : mpNext = pSucc;
1050 : : }
1051 : 0 : }
1052 : : };
1053 : :
1054 : 0 : void E3dView::DoDepthArrange(E3dScene* pScene, double fDepth)
1055 : : {
1056 [ # # ][ # # ]: 0 : if(pScene && pScene->GetSubList() && pScene->GetSubList()->GetObjCount() > 1)
[ # # ][ # # ]
1057 : : {
1058 [ # # ]: 0 : SdrObjList* pSubList = pScene->GetSubList();
1059 [ # # ]: 0 : SdrObjListIter aIter(*pSubList, IM_FLAT);
1060 : 0 : E3dDepthLayer* pBaseLayer = NULL;
1061 : 0 : E3dDepthLayer* pLayer = NULL;
1062 : 0 : sal_Int32 nNumLayers = 0;
1063 : :
1064 [ # # ]: 0 : while(aIter.IsMore())
1065 : : {
1066 [ # # ][ # # ]: 0 : E3dExtrudeObj* pExtrudeObj = dynamic_cast< E3dExtrudeObj* >(aIter.Next());
1067 : :
1068 [ # # ]: 0 : if(pExtrudeObj)
1069 : : {
1070 : : const basegfx::B2DPolyPolygon aExtrudePoly(
1071 [ # # ]: 0 : basegfx::tools::prepareForPolygonOperation(pExtrudeObj->GetExtrudePolygon()));
1072 [ # # ]: 0 : const SfxItemSet& rLocalSet = pExtrudeObj->GetMergedItemSet();
1073 [ # # ]: 0 : const XFillStyle eLocalFillStyle = ITEMVALUE(rLocalSet, XATTR_FILLSTYLE, XFillStyleItem);
1074 [ # # ][ # # ]: 0 : const Color aLocalColor = ((const XFillColorItem&)(rLocalSet.Get(XATTR_FILLCOLOR))).GetColorValue();
1075 : :
1076 : : // sort in ExtrudeObj
1077 [ # # ]: 0 : if(pLayer)
1078 : : {
1079 : : // do we have overlap with an object of this layer?
1080 : 0 : bool bOverlap(false);
1081 : 0 : E3dDepthNeighbour* pAct = pLayer->mpNext;
1082 : :
1083 [ # # ][ # # ]: 0 : while(!bOverlap && pAct)
[ # # ]
1084 : : {
1085 : : // do pAct->mpObj and pExtrudeObj overlap? Check by
1086 : : // using logical AND clipping
1087 : : const basegfx::B2DPolyPolygon aAndPolyPolygon(
1088 : : basegfx::tools::solvePolygonOperationAnd(
1089 : : aExtrudePoly,
1090 [ # # ]: 0 : pAct->maPreparedPolyPolygon));
1091 : :
1092 [ # # ]: 0 : bOverlap = (0 != aAndPolyPolygon.count());
1093 : :
1094 [ # # ]: 0 : if(bOverlap)
1095 : : {
1096 : : // second ciriteria: is another fillstyle or color used?
1097 [ # # ]: 0 : const SfxItemSet& rCompareSet = pAct->mpObj->GetMergedItemSet();
1098 : :
1099 [ # # ]: 0 : XFillStyle eCompareFillStyle = ITEMVALUE(rCompareSet, XATTR_FILLSTYLE, XFillStyleItem);
1100 : :
1101 [ # # ]: 0 : if(eLocalFillStyle == eCompareFillStyle)
1102 : : {
1103 [ # # ]: 0 : if(eLocalFillStyle == XFILL_SOLID)
1104 : : {
1105 [ # # ][ # # ]: 0 : Color aCompareColor = ((const XFillColorItem&)(rCompareSet.Get(XATTR_FILLCOLOR))).GetColorValue();
1106 : :
1107 [ # # ]: 0 : if(aCompareColor == aLocalColor)
1108 : : {
1109 : 0 : bOverlap = sal_False;
1110 : : }
1111 : : }
1112 [ # # ]: 0 : else if(eLocalFillStyle == XFILL_NONE)
1113 : : {
1114 : 0 : bOverlap = sal_False;
1115 : : }
1116 : : }
1117 : : }
1118 : :
1119 : 0 : pAct = pAct->mpNext;
1120 [ # # ]: 0 : }
1121 : :
1122 [ # # ]: 0 : if(bOverlap)
1123 : : {
1124 : : // yes, start a new layer
1125 [ # # ]: 0 : pLayer->mpDown = new E3dDepthLayer;
1126 : 0 : pLayer = pLayer->mpDown;
1127 : 0 : nNumLayers++;
1128 [ # # ][ # # ]: 0 : pLayer->mpNext = new E3dDepthNeighbour;
1129 : 0 : pLayer->mpNext->mpObj = pExtrudeObj;
1130 [ # # ]: 0 : pLayer->mpNext->maPreparedPolyPolygon = aExtrudePoly;
1131 : : }
1132 : : else
1133 : : {
1134 : : // no, add to current layer
1135 [ # # ][ # # ]: 0 : E3dDepthNeighbour* pNewNext = new E3dDepthNeighbour;
1136 : 0 : pNewNext->mpObj = pExtrudeObj;
1137 [ # # ]: 0 : pNewNext->maPreparedPolyPolygon = aExtrudePoly;
1138 : 0 : pNewNext->mpNext = pLayer->mpNext;
1139 : 0 : pLayer->mpNext = pNewNext;
1140 : : }
1141 : : }
1142 : : else
1143 : : {
1144 : : // first layer ever
1145 [ # # ]: 0 : pBaseLayer = new E3dDepthLayer;
1146 : 0 : pLayer = pBaseLayer;
1147 : 0 : nNumLayers++;
1148 [ # # ][ # # ]: 0 : pLayer->mpNext = new E3dDepthNeighbour;
1149 : 0 : pLayer->mpNext->mpObj = pExtrudeObj;
1150 [ # # ]: 0 : pLayer->mpNext->maPreparedPolyPolygon = aExtrudePoly;
1151 [ # # ]: 0 : }
1152 : : }
1153 : : }
1154 : :
1155 : : // number of layers is done
1156 [ # # ]: 0 : if(nNumLayers > 1)
1157 : : {
1158 : : // need to be arranged
1159 : 0 : double fMinDepth = fDepth * 0.8;
1160 : 0 : double fStep = (fDepth - fMinDepth) / (double)nNumLayers;
1161 : 0 : pLayer = pBaseLayer;
1162 : :
1163 [ # # ]: 0 : while(pLayer)
1164 : : {
1165 : : // move along layer
1166 : 0 : E3dDepthNeighbour* pAct = pLayer->mpNext;
1167 : :
1168 [ # # ]: 0 : while(pAct)
1169 : : {
1170 : : // adapt extrude value
1171 [ # # ][ # # ]: 0 : pAct->mpObj->SetMergedItem(SfxUInt32Item(SDRATTR_3DOBJ_DEPTH, sal_uInt32(fMinDepth + 0.5)));
[ # # ]
1172 : :
1173 : : // next
1174 : 0 : pAct = pAct->mpNext;
1175 : : }
1176 : :
1177 : : // next layer
1178 : 0 : pLayer = pLayer->mpDown;
1179 : 0 : fMinDepth += fStep;
1180 : : }
1181 : : }
1182 : :
1183 : : // cleanup
1184 [ # # ]: 0 : while(pBaseLayer)
1185 : : {
1186 : 0 : pLayer = pBaseLayer->mpDown;
1187 [ # # ][ # # ]: 0 : delete pBaseLayer;
1188 : 0 : pBaseLayer = pLayer;
1189 : 0 : }
1190 : : }
1191 : 0 : }
1192 : :
1193 : : // Start drag, create for 3D objects before possibly drag method
1194 : :
1195 : 0 : sal_Bool E3dView::BegDragObj(const Point& rPnt, OutputDevice* pOut,
1196 : : SdrHdl* pHdl, short nMinMov,
1197 : : SdrDragMethod* pForcedMeth)
1198 : : {
1199 [ # # ][ # # ]: 0 : if(Is3DRotationCreationActive() && GetMarkedObjectCount())
[ # # ]
1200 : : {
1201 : : // Determine all selected polygons and return rhe mirrored helper overlay
1202 : 0 : mpMirrorOverlay->SetMirrorAxis(aRef1, aRef2);
1203 : : }
1204 : : else
1205 : : {
1206 : : sal_Bool bOwnActionNecessary;
1207 [ # # ]: 0 : if (pHdl == NULL)
1208 : : {
1209 : 0 : bOwnActionNecessary = sal_True;
1210 : : }
1211 [ # # ][ # # ]: 0 : else if (pHdl->IsVertexHdl() || pHdl->IsCornerHdl())
[ # # ]
1212 : : {
1213 : 0 : bOwnActionNecessary = sal_True;
1214 : : }
1215 : : else
1216 : : {
1217 : 0 : bOwnActionNecessary = sal_False;
1218 : : }
1219 : :
1220 [ # # ][ # # ]: 0 : if(bOwnActionNecessary && GetMarkedObjectCount() >= 1)
[ # # ]
1221 : : {
1222 : 0 : E3dDragConstraint eConstraint = E3DDRAG_CONSTR_XYZ;
1223 : 0 : sal_Bool bThereAreRootScenes = sal_False;
1224 : 0 : sal_Bool bThereAre3DObjects = sal_False;
1225 : 0 : long nCnt = GetMarkedObjectCount();
1226 [ # # ]: 0 : for(long nObjs = 0;nObjs < nCnt;nObjs++)
1227 : : {
1228 : 0 : SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
1229 [ # # ]: 0 : if(pObj)
1230 : : {
1231 [ # # ][ # # ]: 0 : if(pObj->ISA(E3dScene) && ((E3dScene*)pObj)->GetScene() == pObj)
[ # # ]
1232 : 0 : bThereAreRootScenes = sal_True;
1233 [ # # ]: 0 : if(pObj->ISA(E3dObject))
1234 : 0 : bThereAre3DObjects = sal_True;
1235 : : }
1236 : : }
1237 [ # # ]: 0 : if( bThereAre3DObjects )
1238 : : {
1239 [ # # ]: 0 : eDragHdl = ( pHdl == NULL ? HDL_MOVE : pHdl->GetKind() );
1240 [ # # # ]: 0 : switch ( eDragMode )
1241 : : {
1242 : : case SDRDRAG_ROTATE:
1243 : : case SDRDRAG_SHEAR:
1244 : : {
1245 [ # # # # ]: 0 : switch ( eDragHdl )
1246 : : {
1247 : : case HDL_LEFT:
1248 : : case HDL_RIGHT:
1249 : : {
1250 : 0 : eConstraint = E3DDRAG_CONSTR_X;
1251 : : }
1252 : 0 : break;
1253 : :
1254 : : case HDL_UPPER:
1255 : : case HDL_LOWER:
1256 : : {
1257 : 0 : eConstraint = E3DDRAG_CONSTR_Y;
1258 : : }
1259 : 0 : break;
1260 : :
1261 : : case HDL_UPLFT:
1262 : : case HDL_UPRGT:
1263 : : case HDL_LWLFT:
1264 : : case HDL_LWRGT:
1265 : : {
1266 : 0 : eConstraint = E3DDRAG_CONSTR_Z;
1267 : : }
1268 : 0 : break;
1269 : 0 : default: break;
1270 : : }
1271 : :
1272 : : // do not mask the allowed rotations
1273 : 0 : eConstraint = E3dDragConstraint(eConstraint& eDragConstraint);
1274 [ # # ]: 0 : pForcedMeth = new E3dDragRotate(*this, GetMarkedObjectList(), eConstraint, IsSolidDragging());
1275 : : }
1276 : 0 : break;
1277 : :
1278 : : case SDRDRAG_MOVE:
1279 : : {
1280 [ # # ]: 0 : if(!bThereAreRootScenes)
1281 : : {
1282 [ # # ]: 0 : pForcedMeth = new E3dDragMove(*this, GetMarkedObjectList(), eDragHdl, eConstraint, IsSolidDragging());
1283 : : }
1284 : : }
1285 : 0 : break;
1286 : :
1287 : : // later on
1288 : : case SDRDRAG_MIRROR:
1289 : : case SDRDRAG_CROOK:
1290 : : case SDRDRAG_DISTORT:
1291 : : case SDRDRAG_TRANSPARENCE:
1292 : : case SDRDRAG_GRADIENT:
1293 : : default:
1294 : : {
1295 : : }
1296 : 0 : break;
1297 : : }
1298 : : }
1299 : : }
1300 : : }
1301 : 0 : return SdrView::BegDragObj(rPnt, pOut, pHdl, nMinMov, pForcedMeth);
1302 : : }
1303 : :
1304 : : // Set current 3D drawing object, create the scene for this
1305 : :
1306 : 0 : E3dScene* E3dView::SetCurrent3DObj(E3dObject* p3DObj)
1307 : : {
1308 : : DBG_ASSERT(p3DObj != NULL, "Who puts in a NULL-pointer here");
1309 : 0 : E3dScene* pScene = NULL;
1310 : :
1311 : : // get transformed BoundVolume of the object
1312 [ # # ]: 0 : basegfx::B3DRange aVolume(p3DObj->GetBoundVolume());
1313 [ # # ][ # # ]: 0 : aVolume.transform(p3DObj->GetTransform());
1314 [ # # ]: 0 : double fW(aVolume.getWidth());
1315 [ # # ]: 0 : double fH(aVolume.getHeight());
1316 : :
1317 [ # # ]: 0 : Rectangle aRect(0,0, (long) fW, (long) fH);
1318 : :
1319 [ # # ][ # # ]: 0 : pScene = new E3dPolyScene(Get3DDefaultAttributes());
1320 : :
1321 [ # # ][ # # ]: 0 : InitScene(pScene, fW, fH, aVolume.getMaxZ() + ((fW + fH) / 4.0));
1322 : :
1323 [ # # ]: 0 : pScene->Insert3DObj(p3DObj);
1324 [ # # ]: 0 : pScene->NbcSetSnapRect(aRect);
1325 : :
1326 : 0 : return pScene;
1327 : : }
1328 : :
1329 : 0 : void E3dView::InitScene(E3dScene* pScene, double fW, double fH, double fCamZ)
1330 : : {
1331 [ # # ]: 0 : Camera3D aCam(pScene->GetCamera());
1332 : :
1333 : 0 : aCam.SetAutoAdjustProjection(sal_False);
1334 [ # # ]: 0 : aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
1335 : 0 : basegfx::B3DPoint aLookAt;
1336 : :
1337 [ # # ]: 0 : double fDefaultCamPosZ = GetDefaultCamPosZ();
1338 [ # # ]: 0 : basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
1339 : :
1340 [ # # ]: 0 : aCam.SetPosAndLookAt(aCamPos, aLookAt);
1341 [ # # ][ # # ]: 0 : aCam.SetFocalLength(GetDefaultCamFocal());
1342 [ # # ][ # # ]: 0 : aCam.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, GetDefaultCamFocal());
1343 [ # # ][ # # ]: 0 : pScene->SetCamera(aCam);
1344 : 0 : }
1345 : :
1346 : 0 : void E3dView::Start3DCreation()
1347 : : {
1348 [ # # ]: 0 : if (GetMarkedObjectCount())
1349 : : {
1350 : : //positioned
1351 : 0 : long nOutMin = 0;
1352 : 0 : long nOutMax = 0;
1353 : 0 : long nMinLen = 0;
1354 : 0 : long nObjDst = 0;
1355 : 0 : long nOutHgt = 0;
1356 [ # # ]: 0 : OutputDevice* pOut = GetFirstOutputDevice();
1357 : :
1358 : : // first determine representation boundaries
1359 [ # # ]: 0 : if (pOut != NULL)
1360 : : {
1361 [ # # ]: 0 : nMinLen = pOut->PixelToLogic(Size(0,50)).Height();
1362 [ # # ]: 0 : nObjDst = pOut->PixelToLogic(Size(0,20)).Height();
1363 : :
1364 [ # # ]: 0 : long nDst = pOut->PixelToLogic(Size(0,10)).Height();
1365 : :
1366 : 0 : nOutMin = -pOut->GetMapMode().GetOrigin().Y();
1367 [ # # ]: 0 : nOutMax = pOut->GetOutputSize().Height() - 1 + nOutMin;
1368 : 0 : nOutMin += nDst;
1369 : 0 : nOutMax -= nDst;
1370 : :
1371 [ # # ]: 0 : if (nOutMax - nOutMin < nDst)
1372 : : {
1373 : 0 : nOutMin += nOutMax + 1;
1374 : 0 : nOutMin /= 2;
1375 : 0 : nOutMin -= (nDst + 1) / 2;
1376 : 0 : nOutMax = nOutMin + nDst;
1377 : : }
1378 : :
1379 : 0 : nOutHgt = nOutMax - nOutMin;
1380 : :
1381 : 0 : long nTemp = nOutHgt / 4;
1382 [ # # ]: 0 : if (nTemp > nMinLen) nMinLen = nTemp;
1383 : : }
1384 : :
1385 : : // and then attach the marks at the top and bottom of the object
1386 [ # # ]: 0 : basegfx::B2DRange aR;
1387 [ # # ]: 0 : for(sal_uInt32 nMark(0L); nMark < GetMarkedObjectCount(); nMark++)
1388 : : {
1389 [ # # ]: 0 : SdrObject* pMark = GetMarkedObjectByIndex(nMark);
1390 [ # # ]: 0 : basegfx::B2DPolyPolygon aXPP(pMark->TakeXorPoly());
1391 [ # # ][ # # ]: 0 : aR.expand(basegfx::tools::getRange(aXPP));
1392 [ # # ]: 0 : }
1393 : :
1394 [ # # ]: 0 : basegfx::B2DPoint aCenter(aR.getCenter());
1395 [ # # ]: 0 : long nMarkHgt = basegfx::fround(aR.getHeight()) - 1;
1396 : 0 : long nHgt = nMarkHgt + nObjDst * 2;
1397 : :
1398 [ # # ]: 0 : if (nHgt < nMinLen) nHgt = nMinLen;
1399 : :
1400 : 0 : long nY1 = basegfx::fround(aCenter.getY()) - (nHgt + 1) / 2;
1401 : 0 : long nY2 = nY1 + nHgt;
1402 : :
1403 [ # # ][ # # ]: 0 : if (pOut && (nMinLen > nOutHgt)) nMinLen = nOutHgt;
1404 [ # # ]: 0 : if (pOut)
1405 : : {
1406 [ # # ]: 0 : if (nY1 < nOutMin)
1407 : : {
1408 : 0 : nY1 = nOutMin;
1409 [ # # ]: 0 : if (nY2 < nY1 + nMinLen) nY2 = nY1 + nMinLen;
1410 : : }
1411 [ # # ]: 0 : if (nY2 > nOutMax)
1412 : : {
1413 : 0 : nY2 = nOutMax;
1414 [ # # ]: 0 : if (nY1 > nY2 - nMinLen) nY1 = nY2 - nMinLen;
1415 : : }
1416 : : }
1417 : :
1418 [ # # ]: 0 : aRef1.X() = basegfx::fround(aR.getMinX()); // Initial move axis 2/100mm to the left
1419 : 0 : aRef1.Y() = nY1;
1420 : 0 : aRef2.X() = aRef1.X();
1421 : 0 : aRef2.Y() = nY2;
1422 : :
1423 : : // Turn on marks
1424 [ # # ]: 0 : SetMarkHandles();
1425 : :
1426 : : //HMHif (bVis) ShowMarkHdl();
1427 [ # # ][ # # ]: 0 : if (AreObjectsMarked()) MarkListHasChanged();
1428 : :
1429 : : // Show mirror polygon IMMEDIATELY
1430 : 0 : const SdrHdlList &aHdlList = GetHdlList();
1431 [ # # ][ # # ]: 0 : mpMirrorOverlay = new Impl3DMirrorConstructOverlay(*this);
1432 [ # # ][ # # ]: 0 : mpMirrorOverlay->SetMirrorAxis(aHdlList.GetHdl(HDL_REF1)->GetPos(), aHdlList.GetHdl(HDL_REF2)->GetPos());
[ # # ]
1433 : : }
1434 : 0 : }
1435 : :
1436 : : // what happens with a mouse movement when the object is created?
1437 : :
1438 : 0 : void E3dView::MovAction(const Point& rPnt)
1439 : : {
1440 [ # # ]: 0 : if(Is3DRotationCreationActive())
1441 : : {
1442 : 0 : SdrHdl* pHdl = GetDragHdl();
1443 : :
1444 [ # # ]: 0 : if (pHdl)
1445 : : {
1446 : 0 : SdrHdlKind eHdlKind = pHdl->GetKind();
1447 : :
1448 : : // reacts only due to a mirror axis
1449 [ # # ][ # # ]: 0 : if ((eHdlKind == HDL_REF1) ||
[ # # ]
1450 : : (eHdlKind == HDL_REF2) ||
1451 : : (eHdlKind == HDL_MIRX))
1452 : : {
1453 : 0 : const SdrHdlList &aHdlList = GetHdlList ();
1454 : :
1455 : : // delete the mirroed polygon, mirrors the original and draws
1456 : : // it anew
1457 : 0 : SdrView::MovAction (rPnt);
1458 : : mpMirrorOverlay->SetMirrorAxis(
1459 : 0 : aHdlList.GetHdl (HDL_REF1)->GetPos(),
1460 : 0 : aHdlList.GetHdl (HDL_REF2)->GetPos());
1461 : : }
1462 : : }
1463 : : else
1464 : : {
1465 : 0 : SdrView::MovAction (rPnt);
1466 : : }
1467 : : }
1468 : : else
1469 : : {
1470 : 0 : SdrView::MovAction (rPnt);
1471 : : }
1472 : 0 : }
1473 : :
1474 : : // The End. Create object and any child objects through ImpCreate3DLathe.
1475 : : // With the parameter value sal_True (SDefault: sal_False) is simply a
1476 : : // rotation body created, without letting the user set the position of the
1477 : : // axis. It is sufficient with this call, if an object is selected.
1478 : : // (No initialization necessary)
1479 : :
1480 : 0 : void E3dView::End3DCreation(sal_Bool bUseDefaultValuesForMirrorAxes)
1481 : : {
1482 : 0 : ResetCreationActive();
1483 : :
1484 [ # # ]: 0 : if(AreObjectsMarked())
1485 : : {
1486 [ # # ]: 0 : if(bUseDefaultValuesForMirrorAxes)
1487 : : {
1488 [ # # ]: 0 : Rectangle aRect = GetAllMarkedRect();
1489 [ # # ][ # # ]: 0 : if(aRect.GetWidth() <= 1)
1490 [ # # ][ # # ]: 0 : aRect.SetSize(Size(500, aRect.GetHeight()));
1491 [ # # ][ # # ]: 0 : if(aRect.GetHeight() <= 1)
1492 [ # # ][ # # ]: 0 : aRect.SetSize(Size(aRect.GetWidth(), 500));
1493 : :
1494 : 0 : basegfx::B2DPoint aPnt1(aRect.Left(), -aRect.Top());
1495 : 0 : basegfx::B2DPoint aPnt2(aRect.Left(), -aRect.Bottom());
1496 : :
1497 [ # # ]: 0 : ConvertMarkedObjTo3D(sal_False, aPnt1, aPnt2);
1498 : : }
1499 : : else
1500 : : {
1501 : : // Turn off helper overlay
1502 : : // Determine from the handle positions and the displacement of
1503 : : // the points
1504 : 0 : const SdrHdlList &aHdlList = GetHdlList();
1505 [ # # ]: 0 : Point aMirrorRef1 = aHdlList.GetHdl(HDL_REF1)->GetPos();
1506 [ # # ]: 0 : Point aMirrorRef2 = aHdlList.GetHdl(HDL_REF2)->GetPos();
1507 : :
1508 : 0 : basegfx::B2DPoint aPnt1(aMirrorRef1.X(), -aMirrorRef1.Y());
1509 : 0 : basegfx::B2DPoint aPnt2(aMirrorRef2.X(), -aMirrorRef2.Y());
1510 : :
1511 [ # # ]: 0 : ConvertMarkedObjTo3D(sal_False, aPnt1, aPnt2);
1512 : : }
1513 : : }
1514 : 0 : }
1515 : :
1516 [ + - ]: 1940 : E3dView::~E3dView ()
1517 : : {
1518 [ - + ]: 1961 : }
1519 : :
1520 : 535 : void E3dView::ResetCreationActive ()
1521 : : {
1522 [ - + ]: 535 : if(mpMirrorOverlay)
1523 : : {
1524 [ # # ]: 0 : delete mpMirrorOverlay;
1525 : 0 : mpMirrorOverlay = 0L;
1526 : : }
1527 : 535 : }
1528 : :
1529 : 2031 : void E3dView::InitView ()
1530 : : {
1531 : 2031 : eDragConstraint = E3DDRAG_CONSTR_XYZ;
1532 : : fDefaultScaleX =
1533 : : fDefaultScaleY =
1534 : 2031 : fDefaultScaleZ = 1.0;
1535 : : fDefaultRotateX =
1536 : : fDefaultRotateY =
1537 : 2031 : fDefaultRotateZ = 0.0;
1538 : 2031 : fDefaultExtrusionDeepth = 1000; // old: 2000;
1539 : 2031 : fDefaultLightIntensity = 0.8; // old: 0.6;
1540 : 2031 : fDefaultAmbientIntensity = 0.4;
1541 : 2031 : nHDefaultSegments = 12;
1542 : 2031 : nVDefaultSegments = 12;
1543 : 2031 : aDefaultLightColor = RGB_Color(COL_WHITE);
1544 : 2031 : aDefaultAmbientColor = RGB_Color(COL_BLACK);
1545 : 2031 : bDoubleSided = sal_False;
1546 : 2031 : mpMirrorOverlay = 0L;
1547 : 2031 : }
1548 : :
1549 : 0 : sal_Bool E3dView::IsBreak3DObjPossible() const
1550 : : {
1551 : 0 : sal_uIntPtr nCount = GetMarkedObjectCount();
1552 : :
1553 [ # # ]: 0 : if (nCount > 0)
1554 : : {
1555 : 0 : sal_uIntPtr i = 0;
1556 : :
1557 [ # # ]: 0 : while (i < nCount)
1558 : : {
1559 : 0 : SdrObject* pObj = GetMarkedObjectByIndex(i);
1560 : :
1561 [ # # ][ # # ]: 0 : if (pObj && pObj->ISA(E3dObject))
[ # # ]
1562 : : {
1563 [ # # ]: 0 : if(!(((E3dObject*)pObj)->IsBreakObjPossible()))
1564 : 0 : return sal_False;
1565 : : }
1566 : : else
1567 : : {
1568 : 0 : return sal_False;
1569 : : }
1570 : :
1571 : 0 : i++;
1572 : : }
1573 : : }
1574 : : else
1575 : : {
1576 : 0 : return sal_False;
1577 : : }
1578 : :
1579 : 0 : return sal_True;
1580 : : }
1581 : :
1582 : 0 : void E3dView::Break3DObj()
1583 : : {
1584 [ # # ]: 0 : if(IsBreak3DObjPossible())
1585 : : {
1586 : : // ALL selected objects are changed
1587 : 0 : sal_uInt32 nCount = GetMarkedObjectCount();
1588 : :
1589 [ # # ][ # # ]: 0 : BegUndo(String(SVX_RESSTR(RID_SVX_3D_UNDO_BREAK_LATHE)));
[ # # ][ # # ]
1590 [ # # ]: 0 : for(sal_uInt32 a=0;a<nCount;a++)
1591 : : {
1592 : 0 : E3dObject* pObj = (E3dObject*)GetMarkedObjectByIndex(a);
1593 : 0 : BreakSingle3DObj(pObj);
1594 : : }
1595 : 0 : DeleteMarked();
1596 : 0 : EndUndo();
1597 : : }
1598 : 0 : }
1599 : :
1600 : 0 : void E3dView::BreakSingle3DObj(E3dObject* pObj)
1601 : : {
1602 [ # # ]: 0 : if(pObj->ISA(E3dScene))
1603 : : {
1604 [ # # ]: 0 : SdrObjList* pSubList = pObj->GetSubList();
1605 [ # # ]: 0 : SdrObjListIter aIter(*pSubList, IM_FLAT);
1606 : :
1607 [ # # ]: 0 : while(aIter.IsMore())
1608 : : {
1609 [ # # ]: 0 : E3dObject* pSubObj = (E3dObject*)aIter.Next();
1610 [ # # ]: 0 : BreakSingle3DObj(pSubObj);
1611 : 0 : }
1612 : : }
1613 : : else
1614 : : {
1615 : 0 : SdrAttrObj* pNewObj = pObj->GetBreakObj();
1616 [ # # ]: 0 : if(pNewObj)
1617 : : {
1618 : 0 : InsertObjectAtView(pNewObj, *GetSdrPageView(), SDRINSERT_DONTMARK);
1619 : 0 : pNewObj->SetChanged();
1620 : 0 : pNewObj->BroadcastObjectChange();
1621 : : }
1622 : : }
1623 : 0 : }
1624 : :
1625 : 9573 : void E3dView::CheckPossibilities()
1626 : : {
1627 : : // call parent
1628 : 9573 : SdrView::CheckPossibilities();
1629 : :
1630 : : // Set other flags
1631 [ + - ][ - + ]: 9573 : if(bGroupPossible || bUnGroupPossible || bGrpEnterPossible)
[ + - ]
1632 : : {
1633 : 0 : sal_Int32 nMarkCnt = GetMarkedObjectCount();
1634 : 0 : sal_Bool bCoumpound = sal_False;
1635 : 0 : sal_Bool b3DObject = sal_False;
1636 [ # # ][ # # ]: 0 : for(sal_Int32 nObjs = 0L; (nObjs < nMarkCnt) && !bCoumpound; nObjs++)
[ # # ]
1637 : : {
1638 : 0 : SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
1639 [ # # ][ # # ]: 0 : if(pObj && pObj->ISA(E3dCompoundObject))
[ # # ]
1640 : 0 : bCoumpound = sal_True;
1641 [ # # ][ # # ]: 0 : if(pObj && pObj->ISA(E3dObject))
[ # # ]
1642 : 0 : b3DObject = sal_True;
1643 : : }
1644 : :
1645 : : // So far: there are two or more of any objects selected. See if
1646 : : // compound objects are involved. If yes, ban grouping.
1647 [ # # ][ # # ]: 0 : if(bGroupPossible && bCoumpound)
1648 : 0 : bGroupPossible = sal_False;
1649 : :
1650 [ # # ][ # # ]: 0 : if(bUnGroupPossible && b3DObject)
1651 : 0 : bUnGroupPossible = sal_False;
1652 : :
1653 [ # # ][ # # ]: 0 : if(bGrpEnterPossible && bCoumpound)
1654 : 0 : bGrpEnterPossible = sal_False;
1655 : : }
1656 : 9573 : }
1657 : :
1658 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|