22#include <osl/diagnose.h>
57 aTrans.
translate(-aCenter.getX(), -aCenter.getY());
58 aTrans.
scale(fScale, fScale);
59 aTrans.
translate(aCenter.getX(), aCenter.getY());
60 aRetval.transform(aTrans);
66 void impGetOuterPolyPolygon(
72 rOuterPolyPolygon = rPolygon;
89 aScaleTrans.
translate(-aGrownRange.getMinX(), -aGrownRange.getMinY());
90 aScaleTrans.
scale(fScaleX, fScaleY);
91 aScaleTrans.
translate(aRange.getMinX(), aRange.getMinY());
104 void impAddInBetweenFill(
111 bool bCreateTextureCoordinates)
113 OSL_ENSURE(rPolA.
count() == rPolB.
count(),
"impAddInBetweenFill: unequally sized polygons (!)");
114 const sal_uInt32 nPolygonCount(std::min(rPolA.
count(), rPolB.
count()));
116 for(sal_uInt32
a(0);
a < nPolygonCount;
a++)
120 OSL_ENSURE(aSubA.count() == aSubB.count(),
"impAddInBetweenFill: unequally sized polygons (!)");
121 const sal_uInt32 nPointCount(std::min(aSubA.count(), aSubB.count()));
125 const sal_uInt32 nEdgeCount(aSubA.isClosed() ? nPointCount : nPointCount - 1);
126 double fTexHorMultiplicatorA(0.0), fTexHorMultiplicatorB(0.0);
127 double fPolygonPosA(0.0), fPolygonPosB(0.0);
129 if(bCreateTextureCoordinates)
138 for(sal_uInt32 b(0); b < nEdgeCount; b++)
140 const sal_uInt32 nIndexA(b);
141 const sal_uInt32 nIndexB((b + 1) % nPointCount);
158 aNew.
setNormal(0, aSubA.getNormal(nIndexA));
159 aNew.
setNormal(1, aSubB.getNormal(nIndexA));
160 aNew.
setNormal(2, aSubB.getNormal(nIndexB));
161 aNew.
setNormal(3, aSubA.getNormal(nIndexB));
164 if(bCreateTextureCoordinates)
166 const double fRelTexAL(fPolygonPosA * fTexHorMultiplicatorA);
168 fPolygonPosA += fEdgeLengthA;
169 const double fRelTexAR(fPolygonPosA * fTexHorMultiplicatorA);
171 const double fRelTexBL(fPolygonPosB * fTexHorMultiplicatorB);
173 fPolygonPosB += fEdgeLengthB;
174 const double fRelTexBR(fPolygonPosB * fTexHorMultiplicatorB);
192 for(sal_uInt32
a(0);
a < rCandidate.
count();
a++)
196 for(sal_uInt32 b(0); b < aSub.count(); b++)
198 aSub.setNormal(b, rNormal);
205 void impCreateInBetweenNormals(
209 OSL_ENSURE(rPolA.
count() == rPolB.
count(),
"sdrExtrudePrimitive3D: unequally sized polygons (!)");
210 const sal_uInt32 nPolygonCount(std::min(rPolA.
count(), rPolB.
count()));
212 for(sal_uInt32
a(0);
a < nPolygonCount;
a++)
216 OSL_ENSURE(aSubA.count() == aSubB.count(),
"sdrExtrudePrimitive3D: unequally sized polygons (!)");
217 const sal_uInt32 nPointCount(std::min(aSubA.count(), aSubB.count()));
223 const bool bClosed(aSubA.isClosed());
225 for(sal_uInt32 b(0); b < nPointCount; b++)
227 const sal_uInt32 nIndNext((b + 1) % nPointCount);
235 if(aDepth.equalZero())
239 aDepth = aNextB - aNextA;
244 const bool bFirstAndNotClosed(!bClosed && 0 == b);
254 const bool bLastAndNotClosed(!bClosed && b + 1 == nPointCount);
263 aNewNormal.normalize();
266 aSubA.setNormal(b, aNewNormal);
267 aSubB.setNormal(b, aNewNormal);
286 const double fWeightB(1.0 - fWeightA);
287 OSL_ENSURE(rPolA.
count() == rPolB.
count(),
"sdrExtrudePrimitive3D: unequally sized polygons (!)");
288 const sal_uInt32 nPolygonCount(std::min(rPolA.
count(), rPolB.
count()));
290 for(sal_uInt32
a(0);
a < nPolygonCount;
a++)
294 OSL_ENSURE(aSubA.count() == aSubB.count(),
"sdrExtrudePrimitive3D: unequally sized polygons (!)");
295 const sal_uInt32 nPointCount(std::min(aSubA.count(), aSubB.count()));
297 for(sal_uInt32 b(0); b < nPointCount; b++)
303 aSubA.setNormal(b, aVNew);
313 const sal_uInt32 nPointCount(rPoly.
count());
321 for(sal_uInt32
a(0);
a < nPointCount;
a++)
323 const sal_uInt32 nNextIndex((a + 1) % nPointCount);
329 aCurrent, aEdgeVector) != CutFlagValue::NONE)
371 bCloseFront = bCloseBack =
false;
379 fBackScale = 0.000001;
383 aBack = impScalePolyPolygonOnCenter(aBack, fBackScale);
386 if(bCloseFront || bCloseBack)
389 const double fOuterLength(aBaseRange.
getMaxX() * fRotation);
390 const double fInnerLength(aBaseRange.
getMinX() * fRotation);
391 const double fAverageLength((fOuterLength + fInnerLength) * 0.5);
395 const double fOffsetLen((fAverageLength / 12.0) * fDiagonal);
397 impGetOuterPolyPolygon(aFront, aOuterFront, fOffsetLen, bCharacterMode);
399 aTransform.
translate(0.0, 0.0, fOffsetLen);
405 const double fOffsetLen((fAverageLength / 12.0) * fDiagonal);
406 impGetOuterPolyPolygon(aBack, aOuterBack, fOffsetLen, bCharacterMode);
407 aTransformBack.
translate(0.0, 0.0, -fOffsetLen);
408 aTransformBack.
rotate(0.0, fRotation, 0.0);
419 const double fStepSize(1.0 /
static_cast<double>(nSteps));
421 for(sal_uInt32
a(0);
a < nSteps;
a++)
423 const double fStep(
static_cast<double>(
a + 1) * fStepSize);
426 aNewMat.
rotate(0.0, fRotation * fStep, 0.0);
427 rSliceVector.emplace_back(aNewPoly, aNewMat);
458 double fZFront(fDepth);
467 fBackScale = 0.000001;
471 aFront = impScalePolyPolygonOnCenter(aFront, fBackScale);
476 const double fOffset(fDepth * fDiagonal * 0.5);
477 fZFront = fDepth - fOffset;
479 impGetOuterPolyPolygon(aFront, aOuterFront, fOffset, bCharacterMode);
481 aTransformFront.
translate(0.0, 0.0, fDepth);
487 const double fOffset(fDepth * fDiagonal * 0.5);
489 impGetOuterPolyPolygon(aBack, aOuterBack, fOffset, bCharacterMode);
496 aTransformA.
translate(0.0, 0.0, fZFront);
497 rSliceVector.emplace_back(aFront, aTransformA);
500 rSliceVector.emplace_back(aBack, aTransformB);
513 const sal_uInt32 nNumSlices(rSliceVector.size());
517 const sal_uInt32 nSlideSubPolygonCount(rSliceVector[0].getB3DPolyPolygon().
count());
519 for(sal_uInt32 b(0); b < nSlideSubPolygonCount; b++)
521 const sal_uInt32 nSubPolygonPointCount(rSliceVector[0].getB3DPolyPolygon().getB3DPolygon(b).
count());
523 for(sal_uInt32 c(0); c < nSubPolygonPointCount; c++)
527 for(sal_uInt32
d(0);
d < nNumSlices;
d++)
529 const bool bSamePolygonCount(nSlideSubPolygonCount == rSliceVector[
d].getB3DPolyPolygon().
count());
530 const bool bSamePointCount(nSubPolygonPointCount == rSliceVector[
d].getB3DPolyPolygon().getB3DPolygon(b).
count());
532 if(bSamePolygonCount && bSamePointCount)
534 aNew.
append(rSliceVector[
d].getB3DPolyPolygon().getB3DPolygon(b).getB3DPoint(c));
538 OSL_ENSURE(bSamePolygonCount,
"Slice tools::PolyPolygon with different Polygon count (!)");
539 OSL_ENSURE(bSamePointCount,
"Slice Polygon with different point count (!)");
555 const sal_uInt32 nNumSlices(rSliceVector.size());
557 for(sal_uInt32
a(0);
a < nNumSlices;
a++)
559 aRetval.
append(rSliceVector[
a].getB3DPolyPolygon());
566 std::vector< basegfx::B3DPolyPolygon >& rFill,
572 double fSmoothNormalsMix,
573 double fSmoothLidsMix,
574 bool bCreateTextureCoordinates,
577 const sal_uInt32 nNumSlices(rSliceVector.size());
583 const sal_uInt32 nLoopCount(bClosed ? nNumSlices : nNumSlices - 1);
588 double fInvTexHeight(1.0);
589 std::vector<double> aTexHeightArray;
593 if(bCreateTextureCoordinates)
610 for(
a = 0;
a < nLoopCount;
a++)
614 aTexHeightArray.push_back(fLength);
615 aCenter = aNextCenter;
618 const double fTexHeight(std::accumulate(aTexHeightArray.begin(), aTexHeightArray.end(), 0.0));
622 fInvTexHeight = 1.0 / fTexHeight;
628 double fTexHeightPos(0.0);
629 for(
a = 0;
a < nLoopCount;
a++)
631 const Slice3D& rSliceA(rSliceVector[
a]);
632 const Slice3D& rSliceB(rSliceVector[(
a + 1) % nNumSlices]);
641 impCreateInBetweenNormals(aPolB, aPolA);
645 const sal_uInt32 nIndPrev((
a + nNumSlices - 1) % nNumSlices);
646 const Slice3D& rSlicePrev(rSliceVector[nIndPrev]);
653 const bool bHasSlant(aPolAA != aPrev);
655 if(bCreateTextureCoordinates)
669 impSetNormal(aFront, aNormal);
673 impCreateInBetweenNormals(aPolAA, aPrev);
678 impMixNormals(aPolA, aPolAA, fSmoothNormalsMix);
690 impMixNormals(aFront, aPrev, fSmoothLidsMix);
704 impMixNormals(aPolA, aFront, fSmoothNormalsMix);
710 impMixNormals(aFront, aPolA, fSmoothLidsMix);
720 if(bCreateTextureCoordinates)
722 fTexStart = fTexHeightPos * fInvTexHeight;
723 fTexStop = (fTexHeightPos - aTexHeightArray[(
a + nLoopCount - 1) % nLoopCount]) * fInvTexHeight;
726 impAddInBetweenFill(aEdgeRounding, aPolAA, aPrev, fTexStart, fTexStop, bCreateNormals, bCreateTextureCoordinates);
730 rFill.push_back(aFront);
734 if(bCreateNormals && bSmoothNormals && (nIndPrev !=
a + 1))
736 impCreateInBetweenNormals(aPolAA, aPrev);
737 impMixNormals(aPolA, aPolAA, 0.5);
743 const sal_uInt32 nIndNext((
a + 2) % nNumSlices);
744 const Slice3D& rSliceNext(rSliceVector[nIndNext]);
751 const bool bHasSlant(aPolBB != aNext);
753 if(bCreateTextureCoordinates)
761 impSetNormal(aBack, aNormal);
765 impCreateInBetweenNormals(aNext, aPolBB);
770 impMixNormals(aPolB, aPolBB, fSmoothNormalsMix);
782 impMixNormals(aBack, aNext, fSmoothLidsMix);
796 impMixNormals(aPolB, aBack, fSmoothNormalsMix);
802 impMixNormals(aBack, aPolB, fSmoothLidsMix);
812 if(bCreateTextureCoordinates)
814 fTexStart = (fTexHeightPos + aTexHeightArray[
a] + aTexHeightArray[(
a + 1) % nLoopCount]) * fInvTexHeight;
815 fTexStop = (fTexHeightPos + aTexHeightArray[
a]) * fInvTexHeight;
818 impAddInBetweenFill(aEdgeRounding, aNext, aPolBB, fTexStart, fTexStop, bCreateNormals, bCreateTextureCoordinates);
821 rFill.push_back(aBack);
825 if(bCreateNormals && bSmoothNormals && (nIndNext !=
a))
827 impCreateInBetweenNormals(aNext, aPolBB);
828 impMixNormals(aPolB, aPolBB, 0.5);
835 if(bCreateTextureCoordinates)
837 fTexStart = (fTexHeightPos + aTexHeightArray[
a]) * fInvTexHeight;
838 fTexStop = fTexHeightPos * fInvTexHeight;
841 impAddInBetweenFill(aEdgeRounding, aPolB, aPolA, fTexStart, fTexStop, bCreateNormals, bCreateTextureCoordinates);
844 if(bCreateTextureCoordinates)
846 fTexHeightPos += aTexHeightArray[
a];
854 const Slice3D& rSlice(rSliceVector[0]);
857 if(bCreateTextureCoordinates)
871 impSetNormal(aFront, aNormal);
875 rFill.push_back(aFront);
878 if(bCreateTextureCoordinates)
883 for(
a = 0;
a < aEdgeRounding.
count();
a++)
896 const sal_uInt32 nPointCount(rLoopA.
count());
902 if(!(nPointCount && nPointCount == rLoopB.
count()))
912 if(a2DCenterA.
equal(a2DCenterB))
918 double fMaxLeft(0.0);
919 double fMaxRight(0.0);
920 sal_uInt32 nIndexLeft(0);
921 sal_uInt32 nIndexRight(0);
923 for(sal_uInt32
a(0);
a < nPointCount;
a++)
933 if(!impHasCutWith(a2DLoopA, aStart, aEnd))
935 if(!impHasCutWith(a2DLoopB, aStart, aEnd))
938 const double fCross(aCandidateVector.
cross(aAxisVector));
939 const double fDistance(aCandidateVector.
getLength());
943 if(fDistance > fMaxLeft)
945 fMaxLeft = fDistance;
949 else if(fCross < 0.0)
951 if(fDistance > fMaxRight)
953 fMaxRight = fDistance;
void translate(double fX, double fY)
void scale(double fX, double fY)
void transform(const basegfx::B2DHomMatrix &rMatrix)
basegfx::B2DPoint const & getB2DPoint(sal_uInt32 nIndex) const
B2DRange const & getB2DRange() const
B2DPoint getCenter() const
double cross(const B2DVector &rVec) const
void rotate(double fAngleX, double fAngleY, double fAngleZ)
void translate(double fX, double fY, double fZ)
void transformTextureCoordinates(const B2DHomMatrix &rMatrix)
void setB3DPolygon(sal_uInt32 nIndex, const B3DPolygon &rPolygon)
void append(const B3DPolygon &rPolygon, sal_uInt32 nCount=1)
B3DPolygon const & getB3DPolygon(sal_uInt32 nIndex) const
void append(const B3DPoint &rPoint, sal_uInt32 nCount=1)
void setTextureCoordinate(sal_uInt32 nIndex, const B2DPoint &rValue)
B3DPoint const & getB3DPoint(sal_uInt32 nIndex) const
void setNormal(sal_uInt32 nIndex, const B3DVector &rValue)
B3DVector const & getNormal() const
void setClosed(bool bNew)
bool equal(const Tuple2D< TYPE > &rTup) const
class to hold one Slice3D
SliceType3D getSliceType() const
const basegfx::B3DPolyPolygon & getB3DPolyPolygon() const
CutFlagValue findCut(const B2DPoint &rEdge1Start, const B2DVector &rEdge1Delta, const B2DPoint &rEdge2Start, const B2DVector &rEdge2Delta, CutFlagValue aCutFlags, double *pCut1, double *pCut2)
double getLength(const B2DPolygon &rCandidate)
B2DPolygon interpolate(const B2DPolygon &rOld1, const B2DPolygon &rOld2, double t)
B2DPolygon growInNormalDirection(const B2DPolygon &rCandidate, double fValue)
bool isInside(const B2DPolygon &rCandidate, const B2DPoint &rPoint, bool bWithBorder)
B2DPolygon createB2DPolygonFromB3DPolygon(const B3DPolygon &rCandidate, const B3DHomMatrix &rMat)
B3DPolygon applyDefaultTextureCoordinatesParallel(const B3DPolygon &rCandidate, const B3DRange &rRange, bool bChangeX, bool bChangeY)
B2DRange getRange(const B2DPolygon &rCandidate)
B2DTuple average(const B2DTuple &rOld1, const B2DTuple &rOld2)
void createLatheSlices(Slice3DVector &rSliceVector, const basegfx::B2DPolyPolygon &rSource, double fBackScale, double fDiagonal, double fRotation, sal_uInt32 nSteps, bool bCharacterMode, bool bCloseFront, bool bCloseBack)
helpers for creation
basegfx::B3DPolyPolygon extractHorizontalLinesFromSlice(const Slice3DVector &rSliceVector, bool bCloseHorLines)
helpers for geometry extraction
void extractPlanesFromSlice(std::vector< basegfx::B3DPolyPolygon > &rFill, const Slice3DVector &rSliceVector, bool bCreateNormals, bool bSmoothNormals, bool bSmoothLids, bool bClosed, double fSmoothNormalsMix, double fSmoothLidsMix, bool bCreateTextureCoordinates, const basegfx::B2DHomMatrix &rTexTransform)
void createExtrudeSlices(Slice3DVector &rSliceVector, const basegfx::B2DPolyPolygon &rSource, double fBackScale, double fDiagonal, double fDepth, bool bCharacterMode, bool bCloseFront, bool bCloseBack)
::std::vector< Slice3D > Slice3DVector
typedef for a group of Slice3Ds
void createReducedOutlines(const geometry::ViewInformation3D &rViewInformation, const basegfx::B3DHomMatrix &rObjectTransform, const basegfx::B3DPolygon &rLoopA, const basegfx::B3DPolygon &rLoopB, basegfx::B3DPolyPolygon &rTarget)
basegfx::B3DPolyPolygon extractVerticalLinesFromSlice(const Slice3DVector &rSliceVector)