48 TubeBuffer(
const TubeBuffer&) =
delete;
49 const TubeBuffer& operator=(
const TubeBuffer&) =
delete;
51 Primitive3DContainer getLineTubeSegments(
53 const attribute::MaterialAttribute3D& rMaterial)
81 aNewPolygon.
append(aNextLeft);
84 aNewPolygon.
append(aLastLeft);
87 aNewPolygon.
append(aLastRight);
90 aNewPolygon.
append(aNextRight);
98 aLastLeft = aNextLeft;
99 aLastRight = aNextRight;
106 Primitive3DContainer getLineTubeSegments(
107 sal_uInt32 nSegments,
108 const attribute::MaterialAttribute3D& rMaterial)
111 static TubeBuffer theTubeBuffer;
112 return theTubeBuffer.getLineTubeSegments(nSegments, rMaterial);
128 CapBuffer(
const CapBuffer&) =
delete;
129 const CapBuffer& operator=(
const CapBuffer&) =
delete;
131 Primitive3DContainer getLineCapSegments(
132 sal_uInt32 nSegments,
133 const attribute::MaterialAttribute3D& rMaterial)
158 aNewPolygon.
append(aLast);
161 aNewPolygon.
append(aNext);
164 aNewPolygon.
append(aNull);
180 Primitive3DContainer getLineCapSegments(
181 sal_uInt32 nSegments,
182 const attribute::MaterialAttribute3D& rMaterial)
185 static CapBuffer theCapBuffer;
186 return theCapBuffer.getLineCapSegments(nSegments, rMaterial);
202 CapRoundBuffer(
const CapRoundBuffer&) =
delete;
203 const CapRoundBuffer& operator=(
const CapRoundBuffer&) =
delete;
205 Primitive3DContainer getLineCapRoundSegments(
206 sal_uInt32 nSegments,
207 const attribute::MaterialAttribute3D& rMaterial)
222 sal_uInt32 nVerSeg(nSegments / 2);
237 const sal_uInt32
nCount(aSphere.count());
245 aSphereTrans.
rotate(0.0, 0.0, M_PI_2);
246 aSphere.transform(aSphereTrans);
247 aSphere.transformNormals(aSphereTrans);
252 for (sal_uInt32 a = 0;
a <
nCount; ++
a)
260 std::move(aPartPolyPolygon),
272 Primitive3DContainer getLineCapRoundSegments(
273 sal_uInt32 nSegments,
274 const attribute::MaterialAttribute3D& rMaterial)
277 static CapRoundBuffer theCapRoundBuffer;
278 return theCapRoundBuffer.getLineCapRoundSegments(nSegments, rMaterial);
281 Primitive3DContainer getLineJoinSegments(
282 sal_uInt32 nSegments,
283 const attribute::MaterialAttribute3D& rMaterial,
285 double fMiterMinimumAngle,
289 const sal_uInt32 nVerSeg(nSegments >> 1);
290 std::vector< BasePrimitive3D* > aResultVector;
297 const sal_uInt32 nHorSeg(
basegfx::fround((fAngle / (2 * M_PI)) *
static_cast<double>(nSegments)));
304 for(sal_uInt32
a(0);
a < aSphere.count();
a++)
308 aResultVector.push_back(
new PolyPolygonMaterialPrimitive3D(std::move(aPartPolyPolygon), rMaterial,
false));
323 const double fMiterAngle(fAngle/2.0);
325 if(fMiterAngle < fMiterMinimumAngle)
332 const double fInc(M_PI /
static_cast<double>(nVerSeg));
333 const double fSin(sin(-fAngle));
334 const double fCos(cos(-fAngle));
336 const double fMiterSin(bMiter ? sin(-(fAngle/2.0)) : 0.0);
337 const double fMiterCos(bMiter ? cos(-(fAngle/2.0)) : 0.0);
338 double fPos(-M_PI_2);
347 for(sal_uInt32
a(0);
a < nVerSeg;
a++)
349 const bool bFirst(0 == a);
350 const bool bLast(a + 1 == nVerSeg);
362 aNextPointOnXY.
getX() * fCos,
363 aNextPointOnXY.
getY(),
364 aNextPointOnXY.
getX() * fSin);
369 aNextPointOnXY.
getX(),
370 aNextPointOnXY.
getY(),
371 fMiterSin * (aNextPointOnXY.
getX() / fMiterCos));
382 aNewPolygon.
append(aNextPointOnXY);
383 aNewPolygon.
append(aNextMiter);
385 aMiterPolygon.
clear();
387 aMiterPolygon.
append(aNextMiter);
388 aMiterPolygon.
append(aNextPointRotY);
393 aNewPolygon.
append(aNextPointOnXY);
394 aNewPolygon.
append(aNextPointRotY);
404 aNewPolygon.
append(aCurrMiter);
405 aNewPolygon.
append(aPointOnXY);
407 aMiterPolygon.
clear();
409 aMiterPolygon.
append(aPointRotY);
410 aMiterPolygon.
append(aCurrMiter);
415 aNewPolygon.
append(aPointRotY);
416 aNewPolygon.
append(aPointOnXY);
425 aNewPolygon.
append(aPointOnXY);
426 aNewPolygon.
append(aNextPointOnXY);
427 aNewPolygon.
append(aNextMiter);
428 aNewPolygon.
append(aCurrMiter);
430 aMiterPolygon.
clear();
431 aMiterPolygon.
append(aCurrMiter);
432 aMiterPolygon.
append(aNextMiter);
433 aMiterPolygon.
append(aNextPointRotY);
434 aMiterPolygon.
append(aPointRotY);
438 aNewPolygon.
append(aPointRotY);
439 aNewPolygon.
append(aPointOnXY);
440 aNewPolygon.
append(aNextPointOnXY);
441 aNewPolygon.
append(aNextPointRotY);
446 for(sal_uInt32 b(0); b < aNewPolygon.
count(); b++)
452 if(aNewPolygon.
count())
455 aResultVector.push_back(
new PolyPolygonMaterialPrimitive3D(std::move(aNewPolyPolygon), rMaterial,
false));
458 if(bMiter && aMiterPolygon.
count())
461 for(sal_uInt32 c(0); c < aMiterPolygon.
count(); c++)
468 aResultVector.push_back(
new PolyPolygonMaterialPrimitive3D(std::move(aMiterPolyPolygon), rMaterial,
false));
474 aPointOnXY = aNextPointOnXY;
475 aPointRotY = aNextPointRotY;
479 aCurrMiter = aNextMiter;
486 Primitive3DContainer aRetval(aResultVector.size());
488 std::transform(aResultVector.cbegin(), aResultVector.cend(), aRetval.begin(), [](
auto &rResult){return Primitive3DReference(rResult);});
500 const double fRotInXZ(atan2(-rVector.
getZ(), rVector.
getX()));
503 aRetval.
rotate(0.0, 0.0, fRotInXY);
504 aRetval.
rotate(0.0, fRotInXZ, 0.0);
516 std::vector< BasePrimitive3D* > aResultVector;
523 static const sal_uInt32 nSegments(8);
526 const sal_uInt32 nLoopCount(bClosed ? nPointCount : nPointCount - 1);
530 for(sal_uInt32
a(0);
a < nLoopCount;
a++)
535 const double fForwLen(aForw.
getLength());
540 const bool bFirst(!
a);
541 const bool bLast(
a + 1 == nLoopCount);
542 const bool bLineCapPossible(!bClosed && (bFirst || bLast));
543 const bool bLineCapRound(bLineCapPossible && css::drawing::LineCap_ROUND ==
getLineCap());
544 const bool bLineCapSquare(bLineCapPossible && css::drawing::LineCap_SQUARE ==
getLineCap());
578 aTubeTrans *= aRotVector;
580 aCapTrans *= aRotVector;
583 if(bNoLineJoin || (!bClosed && bFirst))
588 if(bLineCapRound && bFirst)
591 aSequence = getLineCapRoundSegments(nSegments, aMaterial);
596 aSequence = getLineCapSegments(nSegments, aMaterial);
609 const double fAngle(acos(aBack.
scalar(aForw) / (fForwLen * aBack.
getLength())));
622 const double fRotInYZ(atan2(aTransBack.
getY(), aTransBack.
getZ()));
627 aSphereTrans.
rotate(0.0, M_PI_2, 0.0);
628 aSphereTrans.
rotate(M_PI - fRotInYZ, 0.0, 0.0);
629 aSphereTrans *= aRotVector;
634 aResultVector.push_back(
636 std::move(aSphereTrans),
642 aResultVector.push_back(
644 std::move(aTubeTrans),
645 getLineTubeSegments(nSegments, aMaterial)));
647 if(bNoLineJoin || (!bClosed && bLast))
653 aBackCapTrans.
rotate(0.0, M_PI, 0.0);
656 if(bLineCapSquare && bLast)
664 aBackCapTrans.
translate(fForwLen, 0.0, 0.0);
668 aBackCapTrans *= aRotVector;
674 if(bLineCapRound && bLast)
677 aSequence = getLineCapRoundSegments(nSegments, aMaterial);
682 aSequence = getLineCapSegments(nSegments, aMaterial);
685 aResultVector.push_back(
687 std::move(aBackCapTrans),
707 std::transform(aResultVector.cbegin(), aResultVector.cend(), aRetval.begin(), [](
auto &rResult){return Primitive3DReference(rResult);});
716 css::drawing::LineCap aLineCap,
717 double fDegreeStepWidth,
718 double fMiterMinimumAngle)
721 mfDegreeStepWidth(fDegreeStepWidth),
722 mfMiterMinimumAngle(fMiterMinimumAngle),
723 maLineJoin(aLineJoin),
730 if(PolygonHairlinePrimitive3D::operator==(rPrimitive))
746 std::unique_lock aGuard(
m_aMutex );
void rotate(double fAngleX, double fAngleY, double fAngleZ)
void translate(double fX, double fY, double fZ)
void scale(double fX, double fY, double fZ)
void append(const B3DPoint &rPoint, sal_uInt32 nCount=1)
B3DPoint const & getB3DPoint(sal_uInt32 nIndex) const
void setNormal(sal_uInt32 nIndex, const B3DVector &rValue)
void setClosed(bool bNew)
double getXZLength() const
double scalar(const B3DVector &rVec) const
PolygonHairlinePrimitive3D class.
PolygonHairlinePrimitive3D(basegfx::B3DPolygon aPolygon, const basegfx::BColor &rBColor)
constructor
const basegfx::BColor & getBColor() const
const basegfx::B3DPolygon & getB3DPolygon() const
data read access
PolygonStrokePrimitive3D class.
PolygonTubePrimitive3D(const basegfx::B3DPolygon &rPolygon, const basegfx::BColor &rBColor, double fRadius, basegfx::B2DLineJoin aLineJoin, css::drawing::LineCap aLineCap, double fDegreeStepWidth=basegfx::deg2rad(10.0), double fMiterMinimumAngle=basegfx::deg2rad(15.0))
constructor
Primitive3DContainer maLast3DDecomposition
hold the last decomposition since it's expensive
virtual Primitive3DContainer get3DDecomposition(const geometry::ViewInformation3D &rViewInformation) const override
local decomposition.
double getRadius() const
data read access
css::drawing::LineCap getLineCap() const
virtual bool operator==(const BasePrimitive3D &rPrimitive) const override
compare operator
const Primitive3DContainer & getLast3DDecomposition() const
access methods to maLast3DDecomposition.
basegfx::B2DLineJoin getLineJoin() const
double getMiterMinimumAngle() const
double getDegreeStepWidth() const
Primitive3DContainer impCreate3DDecomposition(const geometry::ViewInformation3D &rViewInformation) const
local decomposition.
#define PRIMITIVE3D_ID_POLYGONTUBEPRIMITIVE3D
double getLength(const B2DPolygon &rCandidate)
B3DPolyPolygon createUnitSphereFillPolyPolygon(sal_uInt32 nHorSeg, sal_uInt32 nVerSeg, bool bNormals=false, double fVerStart=M_PI_2, double fVerStop=-M_PI_2, double fHorStart=0.0, double fHorStop=2 *M_PI)
B3DVector cross(const B3DVector &rVecA, const B3DVector &rVecB)
B2IRange fround(const B2DRange &rRange)
ImplPrimitive3DIDBlock(PolygonHairlinePrimitive3D, PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D) Primitive3DContainer PolygonStrokePrimitive3D
attribute::MaterialAttribute3D m_aLineMaterial
Primitive3DContainer m_aLineCapList
sal_uInt32 m_nLineTubeSegments
sal_uInt32 m_nLineCapSegments
Primitive3DContainer m_aLineTubeList
Primitive3DContainer m_aLineCapRoundList
sal_uInt32 m_nLineCapRoundSegments