Пример #1
0
        private static EdgeTable build_lmt( LmtTable lmt_table, 
			ScanBeamTreeEntries sbte,
			IPoly p, 
			int type, //poly type SUBJ/CLIP
			OperationType op)
        {
            /* Create the entire input polygon edge table in one go */
            EdgeTable edge_table = new EdgeTable();

            for ( int c= 0; c < p.InnerPolygonCount; c++)
            {
                IPoly ip = p.GetInnerPoly(c);
                if( !ip.IsContributing(0) )
                {
                    /* Ignore the non-contributing contour */
                    ip.SetContributing(0, true);
                }
                else
                {
                    /* Perform contour optimisation */
                    int num_vertices= 0;
                    int e_index = 0 ;
                    edge_table = new EdgeTable();
                    for ( int i= 0; i < ip.PointCount; i++)
                    {
                        if( OPTIMAL(ip, i) )
                        {
                            double x = ip.GetX(i);
                            double y = ip.GetY(i);
                            edge_table.addNode( x, y );

                            /* Record vertex in the scanbeam table */
                            add_to_sbtree( sbte, ip.GetY(i) );

                            num_vertices++;
                        }
                    }

                    /* Do the contour forward pass */
                    for ( int min= 0; min < num_vertices; min++)
                    {
                        /* If a forward local minimum... */
                        if( edge_table.FWD_MIN( min ) )
                        {
                            /* Search for the next local maximum... */
                            int num_edges = 1;
                            int max = NEXT_INDEX( min, num_vertices );
                            while( edge_table.NOT_FMAX( max ) )
                            {
                                num_edges++;
                                max = NEXT_INDEX( max, num_vertices );
                            }

                            /* Build the next edge list */
                            int v = min;
                            EdgeNode e = edge_table.getNode( e_index );
                            e.bstate[BELOW] = BundleState.UNBUNDLED;
                            e.bundle[BELOW, CLIP] = 0;
                            e.bundle[BELOW, SUBJ] = 0;

                            for ( int i= 0; i < num_edges; i++)
                            {
                                EdgeNode ei = edge_table.getNode( e_index+i );
                                EdgeNode ev = edge_table.getNode( v );

                                ei.xb    = ev.vertex.X;
                                ei.bot.X = ev.vertex.X;
                                ei.bot.Y = ev.vertex.Y;

                                v = NEXT_INDEX(v, num_vertices);
                                ev = edge_table.getNode( v );

                                ei.top.X= ev.vertex.X;
                                ei.top.Y= ev.vertex.Y;
                                ei.dx= (ev.vertex.X - ei.bot.X) / (ei.top.Y - ei.bot.Y);
                                ei.type = type;
                                ei.outp[ABOVE] = null ;
                                ei.outp[BELOW] = null;
                                ei.next = null;
                                ei.prev = null;
                                ei.succ = ((num_edges > 1) && (i < (num_edges - 1))) ? edge_table.getNode(e_index+i+1) : null;
                                ei.pred = ((num_edges > 1) && (i > 0)) ? edge_table.getNode(e_index+i-1) : null ;
                                ei.next_bound = null ;
                                ei.bside[CLIP] = (op == OperationType.GPC_DIFF) ? RIGHT : LEFT;
                                ei.bside[SUBJ] = LEFT ;
                            }
                            insert_bound( bound_list(lmt_table, edge_table.getNode(min).vertex.Y), e);
            #if DEBUG
                                Console.WriteLine("fwd");
                                lmt_table.print();
            #endif
                            e_index += num_edges;
                        }
                    }

                    /* Do the contour reverse pass */
                    for ( int min= 0; min < num_vertices; min++)
                    {
                        /* If a reverse local minimum... */
                        if ( edge_table.REV_MIN( min ) )
                        {
                            /* Search for the previous local maximum... */
                            int num_edges= 1;
                            int max = PREV_INDEX(min, num_vertices);
                            while( edge_table.NOT_RMAX( max ) )
                            {
                                num_edges++;
                                max = PREV_INDEX(max, num_vertices);
                            }

                            /* Build the previous edge list */
                            int v = min;
                            EdgeNode e = edge_table.getNode( e_index );
                            e.bstate[BELOW] = BundleState.UNBUNDLED;
                            e.bundle[BELOW, CLIP] = 0;
                            e.bundle[BELOW, SUBJ] = 0;

                            for (int i= 0; i < num_edges; i++)
                            {
                                EdgeNode ei = edge_table.getNode( e_index+i );
                                EdgeNode ev = edge_table.getNode( v );

                                ei.xb    = ev.vertex.X;
                                ei.bot.X = ev.vertex.X;
                                ei.bot.Y = ev.vertex.Y;

                                v= PREV_INDEX(v, num_vertices);
                                ev = edge_table.getNode( v );

                                ei.top.X = ev.vertex.X;
                                ei.top.Y = ev.vertex.Y;
                                ei.dx = (ev.vertex.X - ei.bot.X) / (ei.top.Y - ei.bot.Y);
                                ei.type = type;
                                ei.outp[ABOVE] = null;
                                ei.outp[BELOW] = null;
                                ei.next = null ;
                                ei.prev = null;
                                ei.succ = ((num_edges > 1) && (i < (num_edges - 1))) ? edge_table.getNode(e_index+i+1) : null;
                                ei.pred = ((num_edges > 1) && (i > 0)) ? edge_table.getNode(e_index+i-1) : null ;
                                ei.next_bound = null ;
                                ei.bside[CLIP] = (op == OperationType.GPC_DIFF) ? RIGHT : LEFT;
                                ei.bside[SUBJ] = LEFT;
                            }
                            insert_bound( bound_list(lmt_table, edge_table.getNode(min).vertex.Y), e);
            #if DEBUG
                                Console.WriteLine("rev");
                                lmt_table.print();
            #endif
                            e_index+= num_edges;
                        }
                    }
                }
            }
            return edge_table;
        }
Пример #2
0
        private static RectangleF[] create_contour_bboxes( IPoly p )
        {
            RectangleF[] box = new RectangleF[p.InnerPolygonCount] ;

            /* Construct contour bounding boxes */
            for ( int c= 0; c < p.InnerPolygonCount; c++)
            {
                IPoly inner_poly = p.GetInnerPoly(c);
                box[c] = inner_poly.Bounds;
            }
            return box;
        }