23#ifndef __FM_T_CONTOUR2D_IMPL_H__
24#define __FM_T_CONTOUR2D_IMPL_H__
50 bool & bValidRegion );
53 std::vector< Intersection > & vecPoints,
const OdGeTol & gTol );
66template <
class TContourData >
69 protected TContourData
96 return this->_implClass();
105 return this->_closed();
113 if ( this->_closed() != bClosed )
114 this->_setClosed( bClosed );
126 return this->_empty();
132 return this->_numVerts();
139 return this->_numSegments();
168 double & dBulge )
const;
327 virtual bool areEqualParams(
double dParam1,
double dParam2,
const double dTol = 1e-10 )
const;
398 std::vector< Intersection > & vecPoints,
405 std::vector< Intersection > & vecPoints,
415 std::vector< Intersection > & vecPoints,
500 OdUInt32& iNumPeriodsAB,
const double dParamTol = DBL_EPSILON )
const;
521template <
class TContourData >
524 if (
this == &rSrcCont )
530 this->_reset( iNumVerts, bClosed );
534 for (
OdUInt32 iVert = 0; iVert < iNumVerts; iVert++ )
539 eRes = rSrcCont.
getVertexAt( iVert, & rVert.point(), & rVert.bulge(), & rVert.attributes() );
544 this->_setModifiedAll();
548template <
class TContourData >
556template <
class TContourData >
559 OdUInt32 uNumVerts = this->_numVerts();
564 if ( ! this->_vertex( 0 ).point().isEqualTo( this->_vertex( uNumVerts - 1 ).point(), gTol ) )
567 this->_removeVertices( uNumVerts - 1 );
568 this->_setClosed(
true );
574template <
class TContourData >
577 OdUInt32 iNumSeg = this->_numSegments();
580 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
582 this->_getSegment( iSeg, ImplSeg );
583 if ( ImplSeg.type() ==
estArc )
593template <
class TContourData >
597 if (
isError( this->_getSegment( iIndex, Seg ) ) )
604template <
class TContourData >
607 if ( iIndex < this->_numVerts() )
608 return this->_vertex( iIndex ).attributes();
613template <
class TContourData >
616 if ( iIndex < this->_numVerts() )
617 return this->_vertex( iIndex ).attributes();
622template <
class TContourData >
625 if ( iIndex < this->_numVerts() )
627 this->_vertex( iIndex ).attributes() = rAttr;
634template <
class TContourData >
639 if ( iIndex < this->_numVerts() )
644 uData = this->_vertex(iIndex).attributes().metadata();
650template <
class TContourData >
655 if ( iIndex < this->_numVerts() )
656 this->_vertex( iIndex ).attributes().metadata() = uNewData;
687template <
class TContourData >
691 Result eRes = this->_getSegment( iIndex, ImplSeg );
700template <
class TContourData >
704 double & dBulge )
const
707 Result eRes = this->_getSegment( iIndex, ImplSeg );
711 ptStart = ImplSeg._startPt();
712 ptEnd = ImplSeg._endPt();
713 dBulge = ImplSeg._bulge();
721template <
class TContourData >
725 Result eRes = this->_getSegment( iIndex, ImplSeg );
729 return worstResult( eRes, ImplSeg.getLineSeg( geLine ) );
734template <
class TContourData >
738 Result eRes = this->_getSegment( iIndex, ImplSeg );
742 return worstResult( eRes, ImplSeg.getArcSeg( geArc ) );
747template <
class TContourData >
750 Result eRes = this->_normalizeIndex( iIndex );
754 ptPoint = this->_vertex(iIndex).point();
760template <
class TContourData >
763 Result eRes = this->_normalizeIndex( iIndex );
767 dBulge = this->_vertex(iIndex).bulge();
772template <
class TContourData >
775 Result eRes = this->_normalizeIndex( iIndex );
782 *pptPoint = rVert.point();
785 *pdBulge = rVert.bulge();
788 *pAttr = rVert.attributes();
794template <
class TContourData >
797 Result eRes = this->_normalizeIndex( iIndex );
802 if( !this->_closed() && ( iIndex == 0 || iIndex == iSize-1 ) )
812 this->_getSegment( iIndex, rSeg );
813 rSeg.getTangent( 0.0, vA );
816 this->_getSegment( iSize-1, rSeg );
818 this->_getSegment( iIndex-1, rSeg );
820 rSeg.getTangent( 1.0, vB );
831template <
class TContourData >
839template <
class TContourData >
842 this->_reserveVertices( iReservedSize );
847template <
class TContourData >
850 Result eRes = this->_normalizeIndex( iIndex );
854 this->_vertex( iIndex ).point() = ptPoint;
855 this->_setModifiedVerts( iIndex );
862template <
class TContourData >
865 Result eRes = this->_normalizeIndex( iIndex );
869 this->_vertex( iIndex ).bulge() = dBulge;
870 this->_setModifiedSegs( iIndex );
876template <
class TContourData >
879 Result eRes = this->_normalizeIndex( iIndex );
884 rVert.point() = ptPoint;
885 rVert.bulge() = dBulge;
886 this->_setModifiedVerts( iIndex );
893template <
class TContourData >
896 return this->_insertVerticesAt( iIndex, 1, &ptStart, &dBulge, &rAttr );
901template <
class TContourData >
904 return this->_insertVerticesAt( this->_numVerts(), 1, &ptStart, &dBulge, &rAttr );
911template <
class TContourData >
914 if ( vecSource.
empty() )
917 return this->_insertVerticesAt( this->_numVerts(), vecSource.
size(), &(vecSource[0]) );
920template <
class TContourData >
926 return this->_insertVerticesAt( this->_numVerts(),
size, vecSource, bulgeSource );
930template <
class TContourData >
933 if ( this->_empty() )
936 double vBulges[2] = { rSeg.
bulge(), 0.0 };
938 Result eRes = this->_insertVerticesAt( 0, 2, vPoints, vBulges );
940 this->_vertex( 0 ).attributes() = rSeg.
attributes();
946 OdUInt32 iLastVert = this->_numVerts() - 1;
948 TVertexData & rLastVert = this->_vertex( iLastVert );
956 if ( !ptEnd.
isEqualTo( rSegStart, gTol ) )
964 ptSegEnd.
x += ptEnd.
x - rSegStart.
x;
965 ptSegEnd.
y += ptEnd.
y - rSegStart.
y;
968 double dBulge = rSeg.
bulge();
969 if ( dBulge != rLastVert.bulge() )
971 rLastVert.bulge() = dBulge;
972 this->_setModifiedVerts( iLastVert );
976 eRes =
worstResult( eRes, this->_insertVerticesAt( iLastVert+1, 1, &ptSegEnd ) );
983template <
class TContourData >
986 if ( this->_empty() )
990 OdUInt32 iLastVert = this->_numVerts() - 1;
991 TVertexData & rLastVert = this->_vertex( iLastVert );
994 if ( dBulge != rLastVert.bulge() )
996 rLastVert.bulge() = dBulge;
997 this->_setModifiedVerts( iLastVert );
1001 rLastVert.attributes() = rAttr;
1004 return this->_insertVerticesAt( iLastVert+1, 1, &ptNewEnd );
1008template <
class TContourData >
1018 if ( this->_empty() )
1032 OdUInt32 iLastVert = this->_numVerts() - 1;
1034 TVertexData & rLastVert = this->_vertex( iLastVert );
1039 if ( !bCloseGap || dMaxGap < ptEnd.
distanceTo( ptContStart ) )
1046 if ( rLastVert.bulge() != 0.0 )
1048 rLastVert.bulge() = 0.0;
1049 this->_setModifiedVerts( iLastVert );
1058 OdUInt32 iModifiedVert = iLastVert;
1059 this->_resize( iLastVert + iNumContVerts );
1061 for (
OdUInt32 iContVert = 0 ; iContVert < iNumContVerts; ++iContVert, ++iLastVert )
1065 eRes = rCont.
getVertexAt( iContVert, & rVert.point(), & rVert.bulge(), & rVert.attributes() );
1069 this->_setModifiedVerts( iModifiedVert, iNumContVerts );
1078template <
class TContourData >
1081 return this->_removeVertices( iIndex );
1087template <
class TContourData >
1090 if ( this->_empty() )
1093 ptPoint = this->_vertex(0).point();
1100template <
class TContourData >
1103 if ( this->_empty() )
1106 OdUInt32 iIndex = this->_closed() ? 0 : (this->_numVerts()-1);
1108 ptPoint = this->_vertex(iIndex).point();
1116template <
class TContourData >
1119 OdUInt32 iNumSeg = this->_numSegments();
1124 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1126 this->_getSegment( iSeg, ImplSeg );
1127 dL += ImplSeg.length();
1137template <
class TContourData >
1140 long iNumSegs = this->_numSegments();
1141 if ( iNumSegs <= 0 )
1148 const double dParamTol = 4*DBL_EPSILON;
1151 double dNormalizedParam = ::modf( dParam, &dIdx );
1152 long iNormalizedIdx = long( ::floor( dIdx + 0.5 ) );
1153 if ( dNormalizedParam < 0 )
1155 dNormalizedParam += 1;
1156 iNormalizedIdx -= 1;
1161 if ( iNormalizedIdx >=
long(iNumSegs) )
1163 if ( iNormalizedIdx==iNumSegs && dNormalizedParam <= dParamTol )
1166 dNormalizedParam = 1.0;
1168 else if ( this->_closed() )
1170 iNormalizedIdx = ::ldiv( iNormalizedIdx, iNumSegs ).rem;
1176 else if ( iNormalizedIdx < 0 )
1178 if ( iNormalizedIdx== -1 && dNormalizedParam >= (1.0-dParamTol) )
1181 dNormalizedParam = 0.0;
1183 else if ( this->_closed() )
1185 iNormalizedIdx = ::ldiv( iNormalizedIdx, iNumSegs ).rem + iNumSegs;
1192 dSegParam = dNormalizedParam;
1193 iIndex =
OdUInt32( iNormalizedIdx );
1195 FMGE_ASSERT( dSegParam >= -DBL_EPSILON && dSegParam <= (1.0+DBL_EPSILON) );
1203template <
class TContourData >
1209 OdUInt32 iNumSegs = this->_numSegments();
1210 if ( iNumSegs <= 0 )
1215 bool bClosed = this->_closed();
1217 bool bDistNormalized =
false;
1224 double dLength = ((
IContour2D*)
this)->length();
1225 if ( dLength <= dTol )
1229 bDistNormalized =
true;
1230 dDist -= ::floor( dDist/dLength ) * dLength;
1231 if (dDist < 0.0 || dDist >= dLength )
1237 double dCurDist = 0;
1243 this->_getSegment( iSeg, ImplSeg );
1244 double dL = ImplSeg.length();
1245 if ( (dCurDist + dL) > dDist )
1249 dSegParam = (dDist - dCurDist)/dL;
1255 }
while ( ++iSeg < iNumSegs );
1258 if ( bDistNormalized )
1260 FMGE_FAULT(
"It seems that contour::length() returned a wrong value!" );
1265 double dLength = dCurDist;
1267 if ( !this->_closed() || dLength <= dTol )
1269 iIndex = iNumSegs - 1;
1275 bDistNormalized =
true;
1276 dDist -= ::floor( dDist/dLength ) * dLength;
1277 if (dDist < 0.0 || dDist >= dLength )
1285template <
class TContourData >
1299 if ( dSegParam!= 0.0 )
1301 this->_getSegment( iIndex, ImplSeg );
1302 dSumLen += ImplSeg.length()*dSegParam;
1306 for (
OdUInt32 iSeg = 0; iSeg<iIndex; iSeg++ )
1308 this->_getSegment( iSeg, ImplSeg );
1309 dSumLen += ImplSeg.length();
1318template <
class TContourData >
1334 return worstResult( eRes, ImplSeg.getTangent( dSegParam, vTangent ) );
1340template <
class TContourData >
1344 if ( this->_numVerts()<=1 )
1346 if ( !this->_empty() &&
OdZero(dParam) )
1348 ptPoint = this->_vertex(0).point();
1368 return worstResult( eRes, ImplSeg.getPoint( dSegParam, ptPoint ) );
1374template <
class TContourData >
1380 if ( this->_numVerts() <= 1 )
1384 ptPoint = this->_vertex(0).point();
1395 OdUInt32 iNumSegs = this->_numSegments();
1396 if ( dParam < 0.0 || dParam > iNumSegs )
1398 FMGE_FAULT(
"Contour::getParamAtDist returned an invalid parameter value." );
1403 if ( iIndex == iNumSegs )
1407 eRes =
worstResult( eRes, this->_getSegment( iIndex, ImplSeg ) );
1411 return worstResult( eRes, ImplSeg.getPoint( dParam - iIndex, ptPoint ) );
1417template <
class TContourData >
1425template <
class TContourData >
1438 dParam = iIndex + dSegParam;
1447template <
class TContourData >
1450 const double dParamEps = 1e-10;
1452 int iNumSegs = this->_numSegments();
1453 if ( iNumSegs <= 0 )
1455 if ( this->_empty() )
1458 if ( ::fabs( dParam ) > dParamEps )
1468 if ( this->_closed() )
1470 if ( dParam < 0.0 || dParam >= iNumSegs )
1472 dParam -= ::floor(dParam/iNumSegs)*iNumSegs;
1473 if ( dParam < 0.0 || dParam >=iNumSegs )
1482 if ( dParam >= -dParamEps )
1487 else if ( dParam > iNumSegs )
1490 if ( dParam < (iNumSegs+dParamEps) )
1501template <
class TContourData >
1509template <
class TContourData >
1514 double dLength =
length();
1518 if ( this->_closed() )
1520 if ( dDist < 0.0 || dDist >= dLength )
1522 if ( dLength > dTol )
1524 dDist -= ::floor(dDist/dLength)*dLength;
1525 if ( dDist < 0.0 || dDist > dLength )
1537 if ( dDist >= -dTol )
1542 else if ( dDist > dLength )
1545 if ( dDist < (dLength + dTol) )
1556template <
class TContourData >
1559 double dDelta = ::fabs( dParam2 - dParam1 );
1561 if ( this->_closed() )
1563 OdUInt32 iNumSegs = this->_numSegments();
1567 if ( dDelta > iNumSegs )
1568 dDelta -= ::floor(dDelta/iNumSegs)*iNumSegs;
1570 if ( 2.0*dDelta > iNumSegs )
1571 dDelta = iNumSegs - dDelta;
1575 return ( dDelta <= dTol );
1579template <
class TContourData >
1582 double dDelta = ::fabs( dDist2 - dDist1 );
1584 if ( this->_closed() )
1586 if ( dDelta <= dTol )
1589 double dLength =
length();
1591 if ( dLength > dTol )
1593 if ( dDelta > dLength )
1594 dDelta -= ::floor(dDelta/dLength)*dLength;
1596 if ( 2.0*dDelta > dLength )
1597 dDelta = dLength - dDelta;
1601 return ( dDelta <= dTol );
1605template <
class TContourData >
1608 if ( ! this->_closed() )
1611 return dDist2 - dDist1;
1618 if (
OdEqual( dDist1, dDist2, dTol ) )
1621 double dLength =
length();
1623 if ( dLength < dTol )
1626 if ( dDist1 < 0.0 || dDist1 >= dLength )
1627 dDist1 -= ::floor(dDist1/dLength)*dLength;
1629 if ( dDist2 < 0.0 || dDist2 >= dLength )
1630 dDist2 -= ::floor(dDist2/dLength)*dLength;
1632 bool bSwap = ( dDist1 > dDist2 );
1634 std::swap( dDist1, dDist2 );
1636 double dDelta = dDist2 - dDist1;
1638 if ( dDelta > dLength/2 )
1639 dDelta = dLength - dDelta;
1641 return bSwap ? -dDelta : dDelta;
1645template <
class TContourData >
1648 if ( dParam1 == dParam2 )
1651 double dDist1, dDist2;
1672template <
class TContourData >
1675 if ( this->_empty() )
1680 OdUInt32 iNumSeg = this->_numSegments();
1686 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1688 this->_getSegment( iSeg, ImplSeg );
1689 ImplSeg.addExtents( myExts );
1694 myExts.
addPoint( this->_vertex(0).point() );
1699 geExtents.
addExt( myExts );
1707template <
class TContourData >
1713 OdUInt32 iNumSeg = this->_numSegments();
1719 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1721 this->_getSegment( iSeg, ImplSeg );
1722 dSum += ImplSeg.integrate();
1725 if ( !this->_closed() )
1728 dSum +=
BulgeSeg2D( this->_vertex(iNumSeg).point(), this->_vertex(0).point() ).
integrate();
1738template <
class TContourData >
1741 bool bResult =
false;
1744 if( iSize > 1 && this->_closed() )
1747 this->_getSegment( iSize-1, rSeg );
1751 rSeg.getTangent( 1.0, vB );
1753 double dCrossProduct;
1757 for(
OdUInt32 i = 0; i < iSize; i++ )
1760 this->_getSegment( i, rSeg );
1761 rSeg.getTangent( 0.0, vA );
1793template <
class TContourData >
1801template <
class TContourData >
1807 OdUInt32 iNumSeg = this->_numSegments();
1813 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1815 this->_getSegment( iSeg, ImplSeg );
1818 bOn = ImplSeg.isOn( ptTest, &dSegParam, gTol );
1821 dParam = iSeg + dSegParam;
1826 else if ( !this->_empty() )
1829 bOn =
BulgeSeg2D( this->_vertex(0).point(), this->_vertex(0).point() ).
isOn( ptTest, &dParam, gTol);
1840template <
class TContourData >
1843 if ( this->_empty() )
1846 *pptNearest = ptTest;
1851 double dNearestParam = 0;
1855 double dMinDist = ptNearest.
distanceTo( ptTest );
1857 const double dZeroDist = 1e-15;
1859 OdUInt32 iNumSeg = this->_numSegments();
1860 if ( ( iNumSeg > 0 ) && (dMinDist > dZeroDist) )
1867 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1869 this->_getSegment( iSeg, ImplSeg );
1871 double dSegParam = ImplSeg.nearestParam( ptTest, &ptTmp );
1875 if ( dDist < dMinDist )
1879 dNearestParam = iSeg + dSegParam;
1882 if ( dMinDist <= dZeroDist )
1889 *pptNearest = ptNearest;
1891 return dNearestParam;
1896template <
class TContourData >
1900 *pbOnBorder =
false;
1902 if ( this->_empty() )
1905 if ( !this->_closed() )
1908 bool bInside =
false;
1911 OdUInt32 iNumSeg = this->_numSegments();
1917 for (
OdUInt32 iSeg = 0; iSeg<iNumSeg; iSeg++ )
1919 this->_getSegment( iSeg, ImplSeg );
1921 bool bOnSegment =
false;
1922 OdUInt32 iCount = ImplSeg.intersectXRay( rPoint, &bOnSegment, gTol );
1934 else if ( !this->_empty() )
1937 bInside =
BulgeSeg2D( this->_vertex(0).point(), this->_vertex(0).point() ).
isOn( rPoint, 0, gTol);
1939 *pbOnBorder = bInside;
1949template <
class TContourData >
1952 OdUInt32 iNumSegs = this->_numSegments();
1954 if ( iNumSegs <= 1 )
1959 if ( iNumSegs > 16 && !bExcludeTouch )
1961 bool bIntersects =
false;
1975 for (
OdUInt32 iSegA = 0; iSegA < iNumSegs; iSegA++ )
1977 this->_getSegment( iSegA, ImplSegA );
1979 for (
OdUInt32 iSegB = 0; iSegB < iSegA; iSegB++ )
1981 this->_getSegment( iSegB, ImplSegB );
1983 OdUInt32 iCrosses = ImplSegA.intersect( ImplSegB, &(XPt[0]), &(XPt[1]), gTol );
1989 if(bExcludeTouch && (iSegA != iNumSegs-1 || iSegB != 0) && iCrosses == 1 &&
Intersection::eitTouch == XPt[0].eType && !this->
areEqualParams( iSegB + XPt[0].dParamB, iSegA + XPt[0].dParamA, 1e-14 ))
1991 const bool bAisTouchEnd =
OdEqual(XPt[0].dParamA, 1., 1e-10);
1992 const bool bAisTouchBeg =
OdEqual(XPt[0].dParamA, 0., 1e-10);
1994 const bool bBisTouchEnd =
OdEqual(XPt[0].dParamB, 1., 1e-10);
1995 const bool bBisTouchBeg =
OdEqual(XPt[0].dParamB, 0., 1e-10);
1997 const bool bAisTouch = bAisTouchEnd || bAisTouchBeg;
1998 const bool bBisTouch = bBisTouchEnd || bBisTouchBeg;
1999 if(bAisTouch && bBisTouch)
2001 const OdGeVector2d vA1 = bAisTouchEnd ? ImplSegA.startPt() - ImplSegA.endPt() : ImplSegA.endPt() - ImplSegA.startPt();
2002 int iNext = ((iSegA + (bAisTouchEnd ? 1 : -1)) + iNumSegs) % iNumSegs;
2004 this->_getSegment( iNext, ImplNext );
2005 const OdGeVector2d vA2 = bAisTouchEnd ? ImplNext.endPt() - ImplSegA.endPt() : ImplNext.startPt() - ImplSegA.startPt();
2007 const OdGeVector2d vB1 = bBisTouchEnd ? ImplSegB.startPt() - ImplSegB.endPt() : ImplSegB.endPt() - ImplSegB.startPt();
2008 iNext = ((iSegB + (bBisTouchEnd ? 1 : -1)) + iNumSegs) % iNumSegs;
2009 this->_getSegment( iNext, ImplNext );
2010 const OdGeVector2d vB2 = bBisTouchEnd ? ImplNext.endPt() - ImplSegB.endPt() : ImplNext.startPt() - ImplSegB.startPt();
2027 if((angB1 < angA && angB2 < angA) || (angB1 > angA && angB2 > angA))
2034 int iNext = ((iSegA + (bAisTouchEnd ? 1 : -1)) + iNumSegs) % iNumSegs;
2036 this->_getSegment( iNext, ImplNext );
2037 const OdGePoint2d pt1 = bAisTouchEnd ? ImplNext.endPt() : ImplNext.startPt();
2038 const OdGePoint2d pt2 = bAisTouchEnd ? ImplSegA.startPt() : ImplSegA.endPt();
2040 OdGeVector2d vLine = ImplSegB.endPt() - ImplSegB.startPt();
2041 const double sign1 = vLine.
crossProduct(pt1 - ImplSegB.startPt());
2042 const double sign2 = vLine.
crossProduct(pt2 - ImplSegB.startPt());
2043 if(sign1*sign2 > -1e-14)
2050 int iNext = ((iSegB + (bBisTouchEnd ? 1 : -1)) + iNumSegs) % iNumSegs;
2052 this->_getSegment( iNext, ImplNext );
2053 const OdGePoint2d pt1 = bBisTouchEnd ? ImplNext.endPt() : ImplNext.startPt();
2054 const OdGePoint2d pt2 = bBisTouchEnd ? ImplSegB.startPt() : ImplSegB.endPt();
2056 OdGeVector2d vLine = ImplSegA.endPt() - ImplSegA.startPt();
2057 const double sign1 = vLine.
crossProduct(pt1 - ImplSegA.startPt());
2058 const double sign2 = vLine.
crossProduct(pt2 - ImplSegA.startPt());
2059 if(sign1*sign2 > -1e-14)
2068 for (
OdUInt32 iC = 0; iC < iCrosses; iC++ )
2070 if ( !XPt[iC].eType )
2079 if ( this->
areEqualParams( iSegB + XPt[iC].dParamB, iSegA + XPt[iC].dParamA, 1e-14 ) )
2095template <
class TContourData >
2098 bool bValidRegion =
false;
2102 return bValidRegion;
2105template <
class TContourData >
2114 for(
OdUInt32 uVertexIdx = 0; uVertexIdx < numVertices; uVertexIdx++)
2118 bool fOnBorder =
false;
2119 if(!c2dOuter.
contains(ptVertex, &fOnBorder))
2122 if(!fAllowBordersTouch && fOnBorder)
2130template <
class TContourData >
2132 std::vector< Intersection > & vecPoints,
2135 if ( this->_empty() )
2142 OdUInt32 iNumSegs = this->_numSegments();
2151 for (
OdUInt32 iSeg = 0; iSeg < iNumSegs; iSeg++ )
2153 this->_getSegment( iSeg, ImplSeg );
2155 OdUInt32 iCrosses = ImplSeg.intersect( rSegB, &(XPt[0]), &(XPt[1]), gTol );
2159 for (
OdUInt32 iC = 0; iC < iCrosses; iC++ )
2166 vecPoints.push_back( XPt[iC] );
2170 else if ( this->_numVerts() > 0 )
2172 const OdGePoint2d & ptVert = this->_vertex(0).point();
2175 if ( rSegB.
isOn( ptVert, &dBParam, gTol ) )
2182 vecPoints.push_back( XPt[0] );
2186 return (
OdUInt32)vecPoints.size() - iOrigCrossCount;
2192template <
class TContourData >
2194 std::vector< Intersection > & vecPoints,
2197 if ( this->_empty() || rContB.
isEmpty() )
2200 OdUInt32 iNumSegs = this->_numSegments();
2204 OdUInt32 iCrossCount = iOrigCrossCount;
2213 return (
OdUInt32)vecPoints.size() - iOrigCrossCount;
2223 for (
OdUInt32 iSeg = 0; iSeg < iNumSegs; iSeg++ )
2225 this->_getSegment( iSeg, ImplSeg );
2228 rContB.
intersect( ImplSeg, vecPoints, gTol );
2232 while ( iCrossCount < vecPoints.size() )
2236 double dBParam = rCross.
dParamA;
2248 else if ( this->_numVerts() > 0 )
2251 BulgeSeg2D ASeg( this->_vertex(0).point(), this->_vertex(0).point() );
2254 rContB.
intersect( ASeg, vecPoints, gTol );
2256 while ( iCrossCount < vecPoints.size() )
2266 return iCrossCount - iOrigCrossCount;
2270template <
class TContourData >
2274 std::vector< Intersection > & vecPoints,
2280 OdUInt32 iNumSegs = this->_numSegments();
2301 for (
OdUInt32 iSeg = 0; iSeg < iNumSegs; iSeg++ )
2303 this->_getSegment( iSeg, ImplSeg );
2305 OdUInt32 iCrosses = ImplSeg.intersectLine( ptLineOrigin, vLineDir, &(XPt[0]), &(XPt[1]), gTol );
2311 for (
OdUInt32 iC = 0; iC < iCrosses; iC++ )
2318 vecPoints.push_back( XPt[iC] );
2323 else if ( this->_numVerts() > 0 )
2325 BulgeSeg2D ASeg( this->_vertex(0).point(), this->_vertex(0).point() );
2333 vecPoints.push_back( XPt[0] );
2337 return (
OdUInt32)vecPoints.size() - iOrigCrossCount;
2341template <
class TContourData >
2352 bool bExplodeRequired =
false;
2360 bExplodeRequired =
true;
2364 if ( bExplodeRequired )
2371 OdUInt32 iNumVerts = this->_numVerts();
2372 if ( this->_numVerts() <= 0 )
2375 bool bInverse = ( geMatrix.
det() < 0 );
2377 for (
OdUInt32 iVert = 0; iVert<iNumVerts; iVert++ )
2380 rVert.point().transformBy( geMatrix );
2382 rVert.bulge() = -rVert.bulge();
2385 this->_setModifiedAll();
2392template <
class TContourData >
2395 OdUInt32 iNumVerts = this->_numVerts();
2396 if ( this->_numVerts() <= 0 )
2399 if ( ! this->_closed() )
2404 for (
OdUInt32 iS = 0; iS < iSwapNum; iS++ )
2407 OdGePoint2d& rPtB = this->_vertex(iNumVerts - 1 - iS).point();
2409 std::swap( rVertA.point(), rPtB );
2411 TVertexData & rVertB = this->_vertex(iNumVerts - 2 - iS);
2413 std::swap( rVertA.bulge(), rVertB.bulge() );
2414 std::swap( rVertA.attributes(), rVertB.attributes() );
2423 OdUInt32 iPSwapNum = (iNumVerts-1)/2;
2424 for (
OdUInt32 iS = 0; iS < iPSwapNum; iS++ )
2427 OdGePoint2d& rPtB = this->_vertex(iNumVerts - iS - 1).point();
2428 std::swap( rPtA, rPtB );
2435 for (
OdUInt32 iS = 0; iS < iBSwapNum; iS++ )
2438 TVertexData & rVertB = this->_vertex(iNumVerts - iS - 1);
2440 std::swap( rVertA.bulge(), rVertB.bulge() );
2441 std::swap( rVertA.attributes(), rVertB.attributes() );
2451 rVert.bulge() = -rVert.bulge();
2452 rVert.attributes().reverse();
2456 this->_setModifiedAll();
2463template <
class TContourData >
2466 OdUInt32 iNumVerts = this->_numVerts();
2467 if ( this->_numVerts() <= 1 )
2475 for (
OdUInt32 iVert = 1; iVert<iNumVerts; iVert++)
2478 if ( rThisVert.point().isEqualTo( pPrevVert->point(), gTol ) )
2481 pPrevVert->bulge() = rThisVert.bulge();
2482 pPrevVert->attributes() = rThisVert.attributes();
2486 pPrevVert = & this->_vertex(iNumHandled);
2487 if ( iNumHandled < iVert )
2488 *pPrevVert = rThisVert;
2494 if ( this->_closed() )
2496 if ( this->_vertex(0).point().isEqualTo( pPrevVert->point(), gTol ) )
2504 if ( iNumHandled < (iNumVerts-1) )
2505 this->_vertex(iNumHandled) = this->_vertex( iNumVerts-1 );
2508 if ( iNumHandled < iNumVerts )
2511 this->_resize( iNumHandled );
2512 this->_setModifiedAll();
2517template <
class TContourData >
2524template <
class TContourData >
2530 bool bThisDest = ( ((
const IContour2D*)
this) == &rDestCont );
2532 bool bClosed = this->_closed();
2534 OdUInt32 iNumVerts = this->_numVerts();
2535 OdUInt32 iNumSegs = this->_numSegments();
2542 rDestCont.
set( *
this );
2553 typedef std::pair< OdUInt32, Attributes2D > SegDataPair;
2554 std::vector< SegDataPair > vecAttributes;
2556 vecAttributes.reserve( iNumVerts + 1);
2557 vecPoints.
reserve( iNumVerts );
2562 bool bHasArcs =
false;
2564 for (
OdUInt32 iSeg = 0; iSeg < iNumSegs; iSeg++ )
2566 this->_getSegment( iSeg, ImplSeg );
2569 vecAttributes.push_back( SegDataPair( vecPoints.
size(), Attr ) );
2571 vecPoints.
push_back( ImplSeg.startPt() );
2573 if ( ImplSeg.type() ==
estArc )
2576 vecAttributes.back().second.setExplodedArc(
true).metadata() |= uArcMetadata;
2578 eRes = arcSeg.
set( ImplSeg );
2590 for (
OdUInt32 iPt = 1; iPt<iSegmentCount; iPt++ )
2592 eRes = arcSeg.
getPoint(
double(iPt)/iSegmentCount, ptVertex );
2604 const TVertexData & rLast = this->_vertex( iNumVerts-1 );
2605 FMGE_ASSERT( ImplSeg.endPt().isEqualTo( rLast.point() ) );
2607 vecAttributes.push_back( SegDataPair( vecPoints.
size(), rLast.attributes() ) );
2619 rDestCont.
set( *
this );
2632 for (
OdUInt32 uI = 1; uI < vecAttributes.size(); ++uI )
2634 const Attributes2D& rAttr = vecAttributes[ uI-1 ].second;
2637 OdUInt32 uVert = vecAttributes[ uI-1 ].first;
2638 OdUInt32 uLastVert = vecAttributes[ uI ].first;
2640 for ( ; uVert < uLastVert; ++uVert )
2652template <
class TContourData >
2662 eRes = this->_getSegment( iIndex, ImplSeg );
2668 double dLen = ImplSeg.length();
2674 if ( dSegParam*dLen <= dTol )
2679 else if ( (1.0 - dSegParam)*dLen <= dTol )
2682 return (iIndex+1) % this->_numVerts();
2690 eRes = ImplSeg.getPoint( dSegParam, ptSplit);
2697 if ( ImplSeg.type()==
estArc )
2700 double dAngle = ImplSeg.arcAngle();
2701 double dBulge1 = ::tan( 0.25 * dAngle * dSegParam );
2702 double dBulge2 = ::tan( 0.25 * dAngle * (1.0 - dSegParam) );
2706 this->_vertex( iIndex ).bulge() = dBulge1;
2707 this->_setModifiedSegs( iIndex );
2708 eRes = this->_insertVerticesAt(iNewIndex, 1, &ptSplit, &dBulge2, &Attr );
2713 if ( ImplSeg._bulge() != 0.0 )
2715 this->_vertex( iIndex ).bulge() = 0.0;
2716 this->_setModifiedSegs( iIndex );
2719 eRes = this->_insertVerticesAt(iNewIndex, 1, &ptSplit, 0, &Attr );
2730template <
class TContourData >
2734 if ( uCount<1 || !pdParams )
2737 typedef std::pair< OdUInt32, double > SegOffsPair;
2738 std::vector< SegOffsPair > vecParams;
2739 vecParams.reserve( uCount );
2747 for (
OdUInt32 uP = 0; uP < uCount; ++uP )
2752 vecParams.push_back( currSO );
2755 std::sort( vecParams.begin(), vecParams.end() );
2759 if ( !vecParams.empty() )
2765 std::vector< double > vecSegParams;
2766 std::vector< OdGePoint2d > vecSegPoints;
2767 std::vector< double > vecSegBulges;
2768 std::vector< Attributes2D > vecSegAttributes;
2778 OdUInt32 uSeg = vecParams[uSBegin].first;
2779 while ( uSBegin > 0 && ( uSeg == vecParams[uSBegin-1].first ) )
2783 eRes = this->_getSegment( uSeg, ImplSeg );
2785 currSeg.
set( ImplSeg );
2788 double dLen = currSeg.
length();
2792 vecSegParams.resize( 0 );
2794 for (
OdUInt32 uP = uSBegin; uP < uSEnd; ++uP )
2796 double dSegParam = vecParams[uP].second;
2797 if ( dSegParam*dLen > dTol && (1.0 - dSegParam)*dLen > dTol )
2800 if ( vecSegParams.empty()
2801 || !
OdEqual( vecSegParams.back(), dSegParam, dTol ) )
2804 vecSegParams.push_back( dSegParam );
2810 if ( !vecSegParams.empty() )
2815 vecSegPoints.resize( uNewNum );
2817 for (
OdUInt32 uP = 0 ; uP < uNewNum; ++uP )
2819 eRes = currSeg.
getPoint( vecSegParams[uP], vecSegPoints[uP] );
2826 vecSegAttributes.resize( 0 );
2829 vecSegAttributes.resize( uNewNum, currSeg.
attributes() );
2830 pAttributes = &( vecSegAttributes.front() );
2837 vecSegBulges.resize( uNewNum+1 );
2838 vecSegParams.push_back( 1.0 );
2840 double dAngle4 = currSeg.
arcAngle()/4.0;
2842 double dPrevParam = 0;
2843 for (
OdUInt32 uP = 0; uP <= uNewNum; ++uP )
2845 vecSegBulges[ uP ] = ::tan( dAngle4 * ( vecSegParams[uP] - dPrevParam ) );
2846 dPrevParam = vecSegParams[uP];
2850 this->_vertex( uSeg ).bulge() = vecSegBulges[0];
2851 this->_setModifiedSegs( uSeg );
2854 eRes = this->_insertVerticesAt( uSeg + 1, uNewNum,
2855 & ( vecSegPoints[0] ),
2856 & ( vecSegBulges[1] ),
2866 if ( ImplSeg._bulge() != 0.0 )
2868 this->_vertex( uSeg ).bulge() = 0.0;
2869 this->_setModifiedSegs( uSeg );
2873 eRes = this->_insertVerticesAt( uSeg + 1, uNewNum, &( vecSegPoints.front() ), 0, pAttributes );
2888template <
class TContourData >
2894template <
class TContourData>
2901template <
class TContourData >
2903 const double dParamA,
const double dParamB,
2905 OdUInt32& iNumPeriodsAB,
const double dParamTol )
const
2909 OdUInt32 iNumSegs = this->_numSegments();
2910 if ( iNumSegs <= 0 )
2913 dSegParamA = dSegParamB = 0;
2914 if ( this->_numVerts() > 0 &&
OdZero(dParamA, dParamTol) &&
OdZero(dParamB, dParamTol) )
2920 bool bReverse = (dParamA > dParamB);
2924 double adSegParams[2];
2926 for (
int i = 0; i<2; ++i )
2929 adSegParams[i] = ::modf( i==
int(bReverse) ? dParamA : dParamB, &dIdx );
2930 aiIdx[i] = long( ::floor( dIdx + 0.5 ) );
2931 if ( adSegParams[i] < 0 )
2933 adSegParams[i] += 1;
2941 if ( adSegParams[0] >= 1.0-dParamTol )
2943 adSegParams[0] = 0.0;
2946 else if ( adSegParams[0] <= dParamTol )
2948 adSegParams[0] = 0.0;
2951 if ( adSegParams[1] <= dParamTol )
2953 adSegParams[1] = 1.0;
2956 else if ( adSegParams[1] >= 1.0-dParamTol )
2958 adSegParams[1] = 1.0;
2964 if ( aiIdx[0] > aiIdx[1] || ( aiIdx[0] == aiIdx[1] && adSegParams[0] >= adSegParams[1] ) )
2967 "Critical floating-point inaccuracy!" );
2969 aiIdx[1] = aiIdx[0];
2970 adSegParams[1] = adSegParams[0];
2976 if ( this->_closed() )
2980 ldiv_t aPeriodsIdxs[2];
2981 for (
int i=0; i<2; ++i )
2983 ldiv_t& rDest = aPeriodsIdxs[i];
2984 rDest = ::ldiv( aiIdx[i],
long(iNumSegs) );
2985 if ( rDest.rem < 0 )
2987 rDest.rem += long(iNumSegs);
2992 iNumPeriodsAB = aPeriodsIdxs[ !bReverse ].quot - aPeriodsIdxs[ bReverse ].quot;
2993 uIdxA =
OdUInt32( aPeriodsIdxs[ bReverse ].rem );
2994 uIdxB =
OdUInt32( aPeriodsIdxs[!bReverse ].rem );
2995 dSegParamA = adSegParams[ bReverse ];
2996 dSegParamB = adSegParams[!bReverse ];
3003 for (
int i=0; i<2; ++i )
3007 if ( aiIdx[i] == -1 && adSegParams[i] >= (1.0-dParamTol) )
3010 adSegParams[i] = 0.0;
3015 else if ( aiIdx[i] >=
long(iNumSegs) )
3017 if ( aiIdx[i] ==
long(iNumSegs) && adSegParams[i] <= dParamTol )
3019 aiIdx[i] = long(iNumSegs)-1;
3020 adSegParams[i] = 1.0;
3028 uIdxA =
OdUInt32( aiIdx[ bReverse ] );
3029 uIdxB =
OdUInt32( aiIdx[!bReverse ] );
3030 dSegParamA = adSegParams[ bReverse ];
3031 dSegParamB = adSegParams[!bReverse ];
3039template <
class TContourData >
3043 Result eRes = this->_getSegment( iIndex, srcSeg );
3047 return worstResult( eRes, srcSeg.getSubSegment( dStartOffs, dEndOffs, rDestSeg ) );
3051template <
class TContourData >
3055 OdUInt32 iNumSegs = this->_numSegments();
3061 double adSegParams[2];
3064 bool bReverse = ( dStartParam > dEndParam );
3067 bReverse ? dEndParam : dStartParam,
3068 bReverse ? dStartParam : dEndParam,
3069 auSegIdxs[0], adSegParams[0], auSegIdxs[1], adSegParams[1], iNumPeriods, 1e-14 );
3076 double dOldLen = ( bReverse ? -1 : 1)*(dEndParam - dStartParam);
3077 double dNewLen = (auSegIdxs[1]+adSegParams[1]) - (auSegIdxs[0]+adSegParams[0]) + iNumPeriods*double(iNumSegs);
3085 if ( iNumPeriods < 0 || ( iNumPeriods==0 && auSegIdxs[0] > auSegIdxs[1] ) )
3087 FMGE_FAULT(
"Illegal values caused by buggy code or FP-inaccuracy!");
3095 Result tmpRes = this->_getSegment( auSegIdxs[bReverse], srcSeg );
3100 tmpRes = srcSeg.getPoint( adSegParams[bReverse], ptPoint );
3105 BulgeSeg2D( ptPoint, ptPoint, 0.0, srcSeg.attributes() ),
3112 if ( auSegIdxs[0]==auSegIdxs[1] && 0==iNumPeriods )
3116 auSegIdxs[0], adSegParams[ bReverse ], adSegParams[ !bReverse ], gSingleSeg ) );
3126 if ( iNumSegs <= 0 )
3141 aiUnbrokenSegs[0] = auSegIdxs[0] + 1;
3142 aiUnbrokenSegs[1] = auSegIdxs[1] - 1 + iNumPeriods*
OdUInt32(iNumSegs);
3144 OdUInt32 iNumUnbroken = ( aiUnbrokenSegs[1] - aiUnbrokenSegs[0] + 1 );
3168 for (
OdUInt32 iSeg = aiUnbrokenSegs[0]; iSeg <= aiUnbrokenSegs[1]; ++iSeg )
3171 Result tmpRes = this->_getSegment( iIndex, srcSeg );
3177 tmpRes = rSubContour.
appendSegment( srcSeg._bulge(), srcSeg._endPt(), srcSeg._attr() );
3186 for (
OdUInt32 iSeg = aiUnbrokenSegs[1]; iSeg >= aiUnbrokenSegs[0]; --iSeg )
3189 const TVertexData & rVert = this->_vertex( iIndex );
3192 Result tmpRes = rSubContour.
appendSegment( -rVert.bulge(), rVert.point(), rVert.attributes().getReversed() );
3209template <
class TContourData >
3211 double dStartParam,
double dEndParam,
IContour2D & rSubContour,
const OdGeTol & gTol )
const
3217 rSubContour.
reset();
3221template <
class TContourData >
3223 double dStartParam,
double dEndParam,
IContour2D & rSubContour,
const OdGeTol & gTol )
const
3234template <
class TContourData >
3255 if ( !
isOn( aSubEnds[0], &(adParams[0]), gTol )
3256 ||!
isOn( aSubEnds[1], &(adParams[1]), gTol ) )
3262 bool bEqualEnds = aSubEnds[0].
isEqualTo( aSubEnds[1], gTol );
3263 double dParamLength = double( this->_numSegments() );
3265 if ( this->_closed() )
3269 double dLoopStart = adParams[1];
3270 double dLoopEnd = adParams[0];
3273 dLoopEnd = dLoopStart + dParamLength;
3274 else if ( dLoopEnd < dLoopStart )
3275 dLoopEnd += dParamLength;
3293 adParams[1] = adParams[0];
3294 else if ( adParams[0] > adParams[1] )
3299 if ( adParams[0] > 0 )
3305 if (
isOk(eRes) && ( adParams[1] < dParamLength ) )
#define FMGE_ASSERTMSG(x, c)
#define FMGE_MUSTNOTEXECUTE
OdArray< OdGePoint2d, OdMemoryAllocator< OdGePoint2d > > OdGePoint2dArray
bool OdEqual(double x, double y, double tol=1.e-10)
bool OdZero(double x, double tol=1.e-10)
bool OdGreaterOrEqual(double x, double y, double tol=1.e-10)
static FMGEOMETRY_API_STATIC const Attributes2D kNull
Result set(const CachedSeg2D &rSeg)
virtual const Attributes2D & attributes() const
virtual double arcAngle() const
virtual double arcRadius() const
virtual SegmentType type() const
virtual double length() const
virtual Result getPoint(double dParam, OdGePoint2d &ptPoint) const
virtual OdUInt32 intersectLine(const OdGePoint2d &ptLineOrigin, const OdGeVector2d &vLineDir, Intersection *pInt1=0, Intersection *pInt2=0, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual double integrate(const OdGePoint2d &ptOrigin=OdGePoint2d::kOrigin) const
virtual bool isOn(const OdGePoint2d &ptTest, double *pdParam=0, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual const Attributes2D & attributes() const =0
virtual Result set(const OdGePoint2d &ptA, const OdGePoint2d &ptB, double dBulge, const Attributes2D &rAttr)=0
virtual const OdGePoint2d & endPt() const =0
virtual const OdGePoint2d & startPt() const =0
virtual double bulge() const =0
virtual bool isOn(const OdGePoint2d &ptTest, double *pdParam=0, const OdGeTol &gTol=FMGeGbl::gTol) const =0
virtual OdUInt32 intersect(const IBulgeSeg2D &rSegB, std::vector< Intersection > &vecPoints, const OdGeTol &gTol=FMGeGbl::gTol) const =0
virtual Result appendSegment(const IBulgeSeg2D &rSeg, bool bShiftToHit=false, const OdGeTol &gTol=FMGeGbl::gTol)=0
virtual Result getVertexAt(OdUInt32 iIndex, OdGePoint2d *pptPoint, double *pdBulge=0, Attributes2D *pAttr=0) const =0
virtual bool isClosed() const =0
virtual void set(const IContour2D &rSrcCont)=0
virtual Result setAttributesAt(OdUInt32 iIndex, const Attributes2D &rAttr)=0
virtual Result getStartPoint(OdGePoint2d &ptPoint) const =0
virtual void reserveVertices(OdUInt32 iReservedSize)=0
virtual bool setClosedIfEndsAreEqual(const OdGeTol &gTol=FMGeGbl::gTol)=0
virtual bool hasArcs() const =0
virtual bool isEmpty() const =0
virtual void setClosed(bool bClosed=true)=0
virtual bool contains(const OdGePoint2d &rPoint, bool *pbOnBorder=0, const OdGeTol &gTol=FMGeGbl::gTol) const =0
virtual OdUInt32 numVerts() const =0
virtual Result appendContour(const IContour2D &rCont, bool bCloseGap=false, double dMaxGap=1e99)=0
virtual Result getEndPoint(OdGePoint2d &ptPoint) const =0
virtual Result appendVertices(const OdGePoint2dArray &vecSource)=0
virtual OdUInt32 numSegments() const =0
virtual Result getPointAt(OdUInt32 iIndex, OdGePoint2d &ptPoint) const
virtual Result replaceSubContourTo(IContour2D &rDest, const IContour2D &rSubContour, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual OdUInt32 intersect(const IContour2D &rContB, std::vector< Intersection > &vecPoints, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual bool isSelfIntersecting(const OdGeTol &gTol=FMGeGbl::gTol, bool bExcludeTouch=false) const
Result _getSubSegment(OdUInt32 iIndex, double dStartOffs, double dEndOffs, IBulgeSeg2D &rDestSeg) const
Result _param2dist(double dParam, double &dDist) const
virtual Result appendSegment(double dBulge, const OdGePoint2d &ptNewEnd, const Attributes2D &rAttr=Attributes2D::kNull)
virtual OdUInt32 intersect(const IBulgeSeg2D &rSegB, std::vector< Intersection > &vecPoints, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result appendContour(const IContour2D &rCont, bool bCloseGap=false, double dMaxGap=1e99)
virtual Result getInternalPoint(OdGePoint2d &rPoint, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual double signedMinDistByParams(double dParam1, double dParam2) const
virtual Result setVertexAt(OdUInt32 iIndex, const OdGePoint2d &ptPoint, double dBulge)
virtual bool isClosed() const
virtual Result removeVertexAt(OdUInt32 iIndex)
virtual double signedMinDist(double dDist1, double dDist2) const
virtual Result getSubContour(double dStartParam, double dEndParam, IContour2D &rSubContour, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result getNormalizedDist(double &dDist) const
virtual double nearestParam(const OdGePoint2d &ptTest, OdGePoint2d *ptNearest=0) const
virtual OdUInt32 createVertexAt(double dParam, const OdGeTol &gTol=FMGeGbl::gTol)
Result _dist2IdxParam(double dDist, OdUInt32 &iIndex, double &dSegParam) const
virtual void deleteCoincident(const OdGeTol &gTol=FMGeGbl::gTol)
Result _param2IdxParam(double dParam, OdUInt32 &iIndex, double &dSegParam) const
virtual Result appendVertex(const OdGePoint2d &ptStart, double dBulge=0.0, const Attributes2D &rAttr=Attributes2D::kNull)
virtual IContour2D * clone() const
virtual OdUInt32 numSegments() const
Result _normalizeParam(double &dParam) const
Result _createVerticesAt(OdUInt32 uCount, const double *pdParams, const OdGeTol &gTol)
virtual Result setBulgeAt(OdUInt32 iIndex, double dBulge)
virtual Result getSegmentAt(OdUInt32 iIndex, IBulgeSeg2D &rSegment) const
virtual void reserveVertices(OdUInt32 iReservedSize)
virtual bool isConvex() const
Result _appendSubContourTo(double dStartParam, double dEndParam, IContour2D &rSubContour, const OdGeTol &gTol) const
virtual OdUInt32 intersectLine(const OdGePoint2d &ptLineOrigin, const OdGeVector2d &vLineDir, std::vector< Intersection > &vecPoints, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result getInternalAngleAt(OdUInt32 iIndex, double &dAngle) const
virtual Result appendSubContourTo(double dStartParam, double dEndParam, IContour2D &rSubContour, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result createVerticesAt(OdUInt32 size, const double *vecParams, const OdGeTol &gTol=FMGeGbl::gTol)
virtual Result getSegmentAt(OdUInt32 iIndex, OdGePoint2d &ptStart, OdGePoint2d &ptEnd, double &dBulge) const
virtual double signedArea() const
virtual Result explodeTo(IContour2D &rDestCont, const DeviationParams &devDeviation=FMGeGbl::gDefDev, OdIntPtr uArcMetadata=0) const
virtual Result setAttributesAt(OdUInt32 iIndex, const Attributes2D &rAttr)
virtual bool isEmpty() const
virtual Result transformBy(const OdGeMatrix2d &geMatrix, const DeviationParams &devDeviation=FMGeGbl::gDefDev)
virtual Result appendSegment(const IBulgeSeg2D &rSeg, bool bShiftToHit=false, const OdGeTol &gTol=FMGeGbl::gTol)
virtual Result getParamAtDist(double dDist, double &dParam) const
virtual Result getStartPoint(OdGePoint2d &ptPoint) const
virtual OdUInt32 numVerts() const
virtual Result getPoint(double dParam, OdGePoint2d &ptPoint) const
virtual Result getDistAtParam(double dParam, double &dDist) const
virtual Result getNormalizedParam(double &dParam) const
virtual Attributes2D & attributes4UAt(OdUInt32 iIndex)
virtual SegmentType segmentType(OdUInt32 iIndex) const
virtual void setClosed(bool bClosed=true)
virtual bool setClosedIfEndsAreEqual(const OdGeTol &gTol=FMGeGbl::gTol)
virtual bool areEqualDists(double dDist1, double dDist2, const double dTol=FMGeGbl::gTol.equalPoint()) const
virtual Result getBulgeAt(OdUInt32 iIndex, double &dBulge) const
Result _paramRange2IdxParams(const double dParamA, const double dParamB, OdUInt32 &uIdxA, double &dSegParamA, OdUInt32 &uIdxB, double &dSegParamB, OdUInt32 &iNumPeriodsAB, const double dParamTol=DBL_EPSILON) const
virtual Result getPointAtDist(double dDist, OdGePoint2d &ptPoint) const
virtual bool contains(const OdGePoint2d &rPoint, bool *pbOnBorder=0, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual void set(const IContour2D &rSrcCont)
virtual ContourImplClass implClass() const
virtual bool hasArcs() const
TContourData::VertexData TVertexData
virtual Result getEndPoint(OdGePoint2d &ptPoint) const
virtual Result createVerticesAt(const std::vector< double > &vecParams, const OdGeTol &gTol=FMGeGbl::gTol)
virtual Result addVertexAt(OdUInt32 iIndex, const OdGePoint2d &ptStart, double dBulge=0.0, const Attributes2D &rAttr=Attributes2D::kNull)
virtual Result appendVertices(const OdGePoint2dArray &vecSource)
TContour2DImpl(const TContour2DImpl &rSrcCont)
virtual const Attributes2D & attributesAt(OdUInt32 iIndex) const
virtual bool isInsideContour(const IContour2D &c2dOuter, bool fAllowBordersTouch=false, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result getArcSegAt(OdUInt32 iIndex, OdGeCircArc2d &geArc) const
TContourData::ImplSeg2D TImplSeg2D
virtual Result getLineSegAt(OdUInt32 iIndex, OdGeLineSeg2d &geLine) const
virtual OdIntPtr metadataAt(OdUInt32 iIndex) const
virtual Result getTangent(double dParam, OdGeVector2d &vTangent) const
bool _isEqualToThis(const IContour2D &rC) const
virtual double length() const
virtual bool areEqualParams(double dParam1, double dParam2, const double dTol=1e-10) const
virtual void mergeSegments(int iMergeFlags=0, const OdGeTol &gTol=FMGeGbl::gTol)
virtual bool isOn(const OdGePoint2d &ptTest, double *pdParam=0, const OdGeTol &gTol=FMGeGbl::gTol) const
virtual Result addExtents(OdGeExtents2d &geExtents) const
virtual Result appendVertices(OdUInt32 size, const OdGePoint2d *vecSource, const double *bulgeSource)
virtual Result getVertexAt(OdUInt32 iIndex, OdGePoint2d *pptPoint, double *pdBulge=0, Attributes2D *pAttr=0) const
virtual Result setMetadataAt(OdUInt32 iIndex, OdIntPtr uNewData)
virtual Result setPointAt(OdUInt32 iIndex, const OdGePoint2d &ptPoint)
virtual bool isValidRegion(const OdGeTol &gTol=FMGeGbl::gTol) const
void push_back(const T &value)
void reserve(size_type reserveLength)
OdGeExtents2d & addPoint(const OdGePoint2d &point)
OdGeExtents2d & addExt(const OdGeExtents2d &extents)
void getCoordSystem(OdGePoint2d &origin, OdGeVector2d &xAxis, OdGeVector2d &yAxis) const
bool isEqualTo(const OdGePoint2d &point, const OdGeTol &tol=OdGeContext::gTol) const
static GE_STATIC_EXPORT const OdGePoint2d kOrigin
double distanceTo(const OdGePoint2d &point) const
double equalVector() const
double equalPoint() const
double crossProduct(const OdGeVector2d &vect) const
bool isZeroLength(const OdGeTol &tol=OdGeContext::gTol) const
static GE_STATIC_EXPORT const OdGeVector2d kIdentity
double angleToCCW(const OdGeVector2d &vect) const
GLuint GLsizei GLsizei * length
Result fast_isValidRegion(const IContour2D &rContour, const OdGeTol &gTol, bool &bValidRegion)
Attributes2D & nullAttributesForUpdate()
Result fast_isSelfIntersecting(const IContour2D &rContour, const OdGeTol &gTol, bool &bIntersects)
Result fast_getInternalPoint(const IContour2D &rContour, OdGePoint2d &rPoint, const OdGeTol &gTol)
bool isError(Result eRes)
Result fast_intersect(const IContour2D &rContA, const IContour2D &rContB, std::vector< Intersection > &vecPoints, const OdGeTol &gTol)
void contour2d_mergeSegments(IContour2D &rContour, int iMergeFlags=0, const OdGeTol &gTol=FMGeGbl::gTol)
Result worstResult(Result eRes1, Result eRes2)
static FMGEOMETRY_API_STATIC OdUInt16 GetSegmentCount(double dAngle, double dRadius, const DeviationParams &devDeviation)
static FMGEOMETRY_API_STATIC DeviationParams gDefDev
static FMGEOMETRY_API_STATIC OdGeTol gTol