16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cvaux.h"
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 0
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <malloc.h>
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//#include "decomppoly.h"
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ZERO_CLOSE 0.00001f
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ONE_CLOSE  0.99999f
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CHECK_COLLINEARITY(vec1_x,vec1_y,vec2_x,vec2_y) \
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( vec1_x == 0 ) {                                 \
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( vec1_y * vec2_y > 0 ) {                     \
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return 0;                                   \
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                               \
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                   \
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else {                                              \
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( vec1_x * vec2_x > 0 ) {                     \
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return 0;                                   \
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                               \
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// determines if edge number one lies in counterclockwise
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  earlier than edge number two
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline int  icvIsFirstEdgeClosier( int x0,
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   int y0,
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   int x0_end,
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   int y0_end,
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   int x1_end,
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   int y1_end,
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   int x2_end,
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   int y2_end )
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int mult, mult1, mult2;
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int vec0_x, vec0_y;
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int vec1_x, vec1_y;
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int vec2_x, vec2_y;
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vec0_x = x0_end - x0;
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vec0_y = y0_end - y0;
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vec1_x = x1_end - x0;
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vec1_y = y1_end - y0;
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vec2_x = x2_end - x0;
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vec2_y = y2_end - y0;
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    mult1 = vec1_x * vec0_y - vec0_x * vec1_y;
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    mult2 = vec2_x * vec0_y - vec0_x * vec2_y;
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( mult1 == 0 ) {
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CHECK_COLLINEARITY( vec0_x, vec0_y, vec1_x, vec1_y );
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( mult2 == 0 ) {
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CHECK_COLLINEARITY( vec0_x, vec0_y, vec2_x, vec2_y );
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( mult1 > 0 && mult2 < 0 ) {
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return 1;
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( mult1 < 0 && mult2 > 0 ) {
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return -1;
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    mult = vec1_x * vec2_y - vec2_x * vec1_y;
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( mult == 0 ) {
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CHECK_COLLINEARITY( vec1_x, vec1_y, vec2_x, vec2_y );
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( mult1 > 0 )
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( mult > 0 ) {
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return -1;
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else {
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return 1;
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // if( mult1 > 0 )
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( mult1 != 0 ) {
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( mult > 0 ) {
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return 1;
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else {
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return -1;
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } // if( mult1 != 0 )
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else {
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( mult2 > 0 ) {
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return -1;
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else {
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return 1;
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } // if( mult1 != 0 ) else
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // if( mult1 > 0 ) else
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // icvIsFirstEdgeClosier
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool icvEarCutTriangulation( CvPoint* contour,
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               int num,
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               int* outEdges,
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               int* numEdges )
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int notFoundFlag = 0;
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int begIndex = -1;
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int isInternal;
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int currentNum = num;
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int index1, index2, index3;
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ix0, iy0, ix1, iy1, ix2, iy2;
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x1, y1, x2, y2, x3, y3;
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dx1, dy1, dx2, dy2;
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* pointExist = ( int* )0;
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int det, det1, det2;
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float t1, t2;
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (*numEdges) = 0;
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( num <= 2 ) {
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return false;
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pointExist = ( int* )malloc( num * sizeof( int ) );
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < num; i ++ ) {
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pointExist[i] = 1;
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < num; i ++ ) {
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        outEdges[ (*numEdges) * 2 ] = i;
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( i != num - 1 ) {
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            outEdges[ (*numEdges) * 2 + 1 ] = i + 1;
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else {
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            outEdges[ (*numEdges) * 2 + 1 ] = 0;
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (*numEdges) ++;
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // for( i = 0; i < num; i ++ )
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // initializing data before while cycle
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    index1 = 0;
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    index2 = 1;
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    index3 = 2;
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    x1 = contour[ index1 ].x;
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    y1 = contour[ index1 ].y;
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    x2 = contour[ index2 ].x;
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    y2 = contour[ index2 ].y;
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    x3 = contour[ index3 ].x;
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    y3 = contour[ index3 ].y;
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( currentNum > 3 )
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dx1 = x2 - x1;
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dy1 = y2 - y1;
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dx2 = x3 - x2;
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dy2 = y3 - y2;
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( dx1 * dy2 - dx2 * dy1 < 0 ) // convex condition
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // checking for noncrossing edge
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ix1 = x3 - x1;
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            iy1 = y3 - y1;
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            isInternal = 1;
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < num; i ++ )
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( i != num - 1 ) {
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ix2 = contour[ i + 1 ].x - contour[ i ].x;
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    iy2 = contour[ i + 1 ].y - contour[ i ].y;
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else {
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ix2 = contour[ 0 ].x - contour[ i ].x;
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    iy2 = contour[ 0 ].y - contour[ i ].y;
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ix0 = contour[ i ].x - x1;
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                iy0 = contour[ i ].y - y1;
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                det  = ix2 * iy1 - ix1 * iy2;
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                det1 = ix2 * iy0 - ix0 * iy2;
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( det != 0.0f )
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    t1 = ( ( float )( det1 ) ) / det;
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( t1 > ZERO_CLOSE && t1 < ONE_CLOSE )
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        det2 = ix1 * iy0 - ix0 * iy1;
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        t2 = ( ( float )( det2 ) ) / det;
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( t2 > ZERO_CLOSE && t2 < ONE_CLOSE ) {
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            isInternal = 0;
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    } // if( t1 > ZERO_CLOSE && t1 < ONE_CLOSE )
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } // if( det != 0.0f )
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } // for( i = 0; i < (*numEdges); i ++ )
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( isInternal )
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                // this edge is internal
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                notFoundFlag = 0;
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                outEdges[ (*numEdges) * 2     ] = index1;
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                outEdges[ (*numEdges) * 2 + 1 ] = index3;
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (*numEdges) ++;
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pointExist[ index2 ] = 0;
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                index2 = index3;
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x2 = x3;
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y2 = y3;
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                currentNum --;
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( currentNum >= 3 ) {
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    do {
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        index3 ++;
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( index3 == num ) {
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            index3 = 0;
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    } while( !pointExist[ index3 ] );
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x3 = contour[ index3 ].x;
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    y3 = contour[ index3 ].y;
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } // if( currentNum >= 3 )
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } // if( isInternal )
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else {
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                // this edge intersects some other initial edges
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !notFoundFlag ) {
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    notFoundFlag = 1;
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    begIndex = index1;
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                index1 = index2;
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x1 = x2;
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y1 = y2;
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                index2 = index3;
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x2 = x3;
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y2 = y3;
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                do {
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    index3 ++;
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( index3 == num ) {
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        index3 = 0;
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( index3 == begIndex ) {
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( pointExist ) {
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            free( pointExist );
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        return false;
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } while( !pointExist[ index3 ] );
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x3 = contour[ index3 ].x;
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y3 = contour[ index3 ].y;
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } // if( isInternal ) else
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } // if( dx1 * dy2 - dx2 * dy1 < 0 )
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !notFoundFlag ) {
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                notFoundFlag = 1;
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                begIndex = index1;
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            index1 = index2;
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x1 = x2;
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            y1 = y2;
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            index2 = index3;
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x2 = x3;
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            y2 = y3;
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            do {
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                index3 ++;
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( index3 == num ) {
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    index3 = 0;
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( index3 == begIndex ) {
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( pointExist ) {
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        free( pointExist );
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    return false;
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } while( !pointExist[ index3 ] );
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x3 = contour[ index3 ].x;
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            y3 = contour[ index3 ].y;
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } // if( dx1 * dy2 - dx2 * dy1 < 0 ) else
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // while( currentNum > 3 )
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( pointExist ) {
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        free( pointExist );
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return true;
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // icvEarCutTriangulation
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline bool icvFindTwoNeighbourEdges( CvPoint* contour,
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      int* edges,
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      int numEdges,
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      int vtxIdx,
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      int mainEdgeIdx,
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      int* leftEdgeIdx,
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      int* rightEdgeIdx )
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int compRes;
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int vec0_x, vec0_y;
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x0, y0, x0_end, y0_end;
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x1_left = 0, y1_left = 0, x1_right = 0, y1_right = 0, x2, y2;
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (*leftEdgeIdx)  = -1;
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (*rightEdgeIdx) = -1;
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( edges[ mainEdgeIdx * 2 ] == vtxIdx ) {
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x0 = contour[ vtxIdx ].x;
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        y0 = contour[ vtxIdx ].y;
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x0_end = contour[ edges[ mainEdgeIdx * 2 + 1 ] ].x;
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        y0_end = contour[ edges[ mainEdgeIdx * 2 + 1 ] ].y;
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        vec0_x = x0_end - x0;
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        vec0_y = y0_end - y0;
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else {
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //x0 = contour[ edges[ mainEdgeIdx * 2 ] ].x;
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //y0 = contour[ edges[ mainEdgeIdx * 2 ] ].y;
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //x0_end = contour[ vtxIdx ].x;
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //y0_end = contour[ vtxIdx ].y;
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x0 = contour[ vtxIdx ].x;
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        y0 = contour[ vtxIdx ].y;
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x0_end = contour[ edges[ mainEdgeIdx * 2 ] ].x;
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        y0_end = contour[ edges[ mainEdgeIdx * 2 ] ].y;
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        vec0_x = x0_end - x0;
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        vec0_y = y0_end - y0;
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < numEdges; i ++ )
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ( i != mainEdgeIdx ) &&
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( edges[ i * 2 ] == vtxIdx || edges[ i * 2 + 1 ] == vtxIdx ) )
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( (*leftEdgeIdx) == -1 )
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (*leftEdgeIdx) = (*rightEdgeIdx) = i;
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( edges[ i * 2 ] == vtxIdx ) {
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x1_left = x1_right = contour[ edges[ i * 2 + 1 ] ].x;
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    y1_left = y1_right = contour[ edges[ i * 2 + 1 ] ].y;
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else {
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x1_left = x1_right = contour[ edges[ i * 2 ] ].x;
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    y1_left = y1_right = contour[ edges[ i * 2 ] ].y;
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } // if( (*leftEdgeIdx) == -1 )
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( edges[ i * 2 ] == vtxIdx ) {
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x2 = contour[ edges[ i * 2 + 1 ] ].x;
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    y2 = contour[ edges[ i * 2 + 1 ] ].y;
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else {
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x2 = contour[ edges[ i * 2 ] ].x;
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    y2 = contour[ edges[ i * 2 ] ].y;
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                compRes = icvIsFirstEdgeClosier( x0,
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    y0, x0_end, y0_end, x1_left, y1_left, x2, y2 );
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( compRes == 0 ) {
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    return false;
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( compRes == -1 ) {
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    (*leftEdgeIdx) = i;
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x1_left = x2;
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    y1_left = y2;
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } // if( compRes == -1 )
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else {
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    compRes = icvIsFirstEdgeClosier( x0,
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        y0, x0_end, y0_end, x1_right, y1_right, x2, y2 );
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( compRes == 0 ) {
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        return false;
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( compRes == 1 ) {
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        (*rightEdgeIdx) = i;
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        x1_right = x2;
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        y1_right = y2;
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } // if( compRes == -1 ) else
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } // if( (*leftEdgeIdx) == -1 ) else
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } // if( ( i != mainEdgesIdx ) && ...
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // for( i = 0; i < numEdges; i ++ )
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return true;
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // icvFindTwoNeighbourEdges
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool icvFindReferences( CvPoint* contour,
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int num,
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int* outEdges,
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int* refer,
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int* numEdges )
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int currPntIdx;
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int leftEdgeIdx, rightEdgeIdx;
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( icvEarCutTriangulation( contour, num, outEdges, numEdges ) )
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < (*numEdges); i ++ )
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            refer[ i * 4     ] = -1;
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            refer[ i * 4 + 1 ] = -1;
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            refer[ i * 4 + 2 ] = -1;
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            refer[ i * 4 + 3 ] = -1;
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } // for( i = 0; i < (*numEdges); i ++ )
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < (*numEdges); i ++ )
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            currPntIdx = outEdges[ i * 2 ];
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !icvFindTwoNeighbourEdges( contour,
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                outEdges, (*numEdges), currPntIdx,
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i, &leftEdgeIdx, &rightEdgeIdx ) )
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return false;
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } // if( !icvFindTwoNeighbourEdges( contour, ...
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( outEdges[ leftEdgeIdx * 2 ] == currPntIdx ) {
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( refer[ i * 4     ] == -1 ) {
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        refer[ i * 4     ] = ( leftEdgeIdx << 2 );
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else {
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( refer[ i * 4     ] == -1 ) {
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        refer[ i * 4     ] = ( leftEdgeIdx << 2 ) | 2;
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( outEdges[ rightEdgeIdx * 2 ] == currPntIdx ) {
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( refer[ i * 4 + 1 ] == -1 ) {
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        refer[ i * 4 + 1 ] = ( rightEdgeIdx << 2 ) | 3;
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else {
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( refer[ i * 4 + 1 ] == -1 ) {
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        refer[ i * 4 + 1 ] = ( rightEdgeIdx << 2 ) | 1;
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } // if( !icvFindTwoNeighbourEdges( contour, ... ) else
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            currPntIdx = outEdges[ i * 2 + 1 ];
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i == 18 ) {
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i = i;
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !icvFindTwoNeighbourEdges( contour,
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                outEdges, (*numEdges), currPntIdx,
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i, &leftEdgeIdx, &rightEdgeIdx ) )
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return false;
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } // if( !icvFindTwoNeighbourEdges( contour, ...
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( outEdges[ leftEdgeIdx * 2 ] == currPntIdx ) {
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( refer[ i * 4 + 3 ] == -1 ) {
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        refer[ i * 4 + 3 ] = ( leftEdgeIdx << 2 );
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else {
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( refer[ i * 4 + 3 ] == -1 ) {
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        refer[ i * 4 + 3 ] = ( leftEdgeIdx << 2 ) | 2;
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( outEdges[ rightEdgeIdx * 2 ] == currPntIdx ) {
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( refer[ i * 4 + 2 ] == -1 ) {
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        refer[ i * 4 + 2 ] = ( rightEdgeIdx << 2 ) | 3;
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else {
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( refer[ i * 4 + 2 ] == -1 ) {
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        refer[ i * 4 + 2 ] = ( rightEdgeIdx << 2 ) | 1;
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } // if( !icvFindTwoNeighbourEdges( contour, ... ) else
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } // for( i = 0; i < (*numEdges); i ++ )
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // if( icvEarCutTriangulation( contour, num, outEdges, numEdges ) )
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else {
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return false;
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // if( icvEarCutTriangulation( contour, num, outEdges, ... ) else
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return true;
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // icvFindReferences
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid cvDecompPoly( CvContour* cont,
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      CvSubdiv2D** subdiv,
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      CvMemStorage* storage )
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int*    memory;
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint*    contour;
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int*        outEdges;
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int*        refer;
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSubdiv2DPoint**   pntsPtrs;
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvQuadEdge2D**      edgesPtrs;
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int numVtx;
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int numEdges;
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqReader reader;
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint2D32f pnt;
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvQuadEdge2D* quadEdge;
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    numVtx = cont -> total;
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( numVtx < 3 ) {
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return;
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *subdiv = ( CvSubdiv2D* )0;
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memory = ( int* )malloc( sizeof( int ) * ( numVtx * 2
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        + numVtx * numVtx * 2 * 5 )
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        + sizeof( CvQuadEdge2D* ) * ( numVtx * numVtx )
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        + sizeof( CvSubdiv2DPoint* ) * ( numVtx * 2 ) );
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    contour     = ( CvPoint* )memory;
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    outEdges    = ( int* )( contour + numVtx );
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    refer       = outEdges + numVtx * numVtx * 2;
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    edgesPtrs   = ( CvQuadEdge2D** )( refer + numVtx * numVtx * 4 );
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pntsPtrs    = ( CvSubdiv2DPoint** )( edgesPtrs + numVtx * numVtx );
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartReadSeq( ( CvSeq* )cont, &reader, 0 );
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < numVtx; i ++ )
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_READ_SEQ_ELEM( (contour[ i ]), reader );
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // for( i = 0; i < numVtx; i ++ )
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !icvFindReferences( contour, numVtx, outEdges, refer, &numEdges ) )
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        free( memory );
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return;
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // if( !icvFindReferences( contour, numVtx, outEdges, refer, ...
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *subdiv = cvCreateSubdiv2D( CV_SEQ_KIND_SUBDIV2D,
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                sizeof( CvSubdiv2D ),
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                sizeof( CvSubdiv2DPoint ),
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                sizeof( CvQuadEdge2D ),
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                storage );
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < numVtx; i ++ )
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pnt.x = ( float )contour[ i ].x;
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pnt.y = ( float )contour[ i ].y;
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pntsPtrs[ i ] = cvSubdiv2DAddPoint( *subdiv, pnt, 0 );
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // for( i = 0; i < numVtx; i ++ )
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < numEdges; i ++ )
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        edgesPtrs[ i ] = ( CvQuadEdge2D* )
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( cvSubdiv2DMakeEdge( *subdiv ) & 0xfffffffc );
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // for( i = 0; i < numEdges; i ++ )
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < numEdges; i ++ )
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        quadEdge = edgesPtrs[ i ];
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        quadEdge -> next[ 0 ] =
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4     ] >> 2 ] )
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            | ( refer[ i * 4     ] & 3 );
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        quadEdge -> next[ 1 ] =
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4 + 1 ] >> 2 ] )
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            | ( refer[ i * 4 + 1 ] & 3 );
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        quadEdge -> next[ 2 ] =
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4 + 2 ] >> 2 ] )
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            | ( refer[ i * 4 + 2 ] & 3 );
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        quadEdge -> next[ 3 ] =
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4 + 3 ] >> 2 ] )
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            | ( refer[ i * 4 + 3 ] & 3 );
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        quadEdge -> pt[ 0 ] = pntsPtrs[ outEdges[ i * 2     ] ];
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        quadEdge -> pt[ 1 ] = ( CvSubdiv2DPoint* )0;
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        quadEdge -> pt[ 2 ] = pntsPtrs[ outEdges[ i * 2 + 1 ] ];
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        quadEdge -> pt[ 3 ] = ( CvSubdiv2DPoint* )0;
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // for( i = 0; i < numEdges; i ++ )
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (*subdiv) -> topleft.x = ( float )cont -> rect.x;
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (*subdiv) -> topleft.y = ( float )cont -> rect.y;
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (*subdiv) -> bottomright.x =
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ( float )( cont -> rect.x + cont -> rect.width );
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (*subdiv) -> bottomright.y =
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ( float )( cont -> rect.y + cont -> rect.height );
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    free( memory );
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return;
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // cvDecompPoly
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// End of file decomppoly.cpp
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
630