Reorganized how clipper is included and deleted example files

This commit is contained in:
Magne Sjaastad 2017-01-24 15:39:39 +01:00
parent 827f0d670c
commit 405cd382af
32 changed files with 19 additions and 2986 deletions

View File

@ -302,7 +302,6 @@ set( LINK_LIBRARIES
${ERT_LIBRARIES}
${THIRD_PARTY_LIBRARIES}
custom-clipper
${OPENGL_LIBRARIES}
${QT_LIBRARIES}

View File

@ -44,7 +44,7 @@
#include "cvfMatrix4.h"
#include "cvfPlane.h"
#include "custom-clipper/clipper/clipper.hpp"
#include "clipper/clipper.hpp"

View File

@ -242,7 +242,11 @@ list(APPEND THIRD_PARTY_LIBRARIES
# clipper
################################################################################
add_subdirectory(ThirdParty/custom-clipper)
add_subdirectory(ThirdParty/clipper)
list(APPEND THIRD_PARTY_LIBRARIES
clipper
)
################################################################################

13
ThirdParty/clipper/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,13 @@
cmake_minimum_required (VERSION 2.8)
project (clipper)
set(project_source_files
clipper.cpp
)
add_library(${PROJECT_NAME}
STATIC
${project_source_files}
)

View File

@ -1,22 +0,0 @@
cmake_minimum_required (VERSION 2.8)
project (custom-clipper)
include_directories(
clipper
)
#include (opm-flowdiagnostics/CMakeLists_files.cmake)
set(project_source_files
clipper.cpp
)
foreach (file ${project_source_files} )
list(APPEND project_source_files_complete_path "clipper/${file}" )
endforeach()
add_library(${PROJECT_NAME}
${project_source_files_complete_path}
)

View File

@ -1,21 +0,0 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0)
PROJECT(polyclipping)
SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Release type")
# The header name clipper.hpp is too generic, so install in a subdirectory
SET(CMAKE_INSTALL_INCDIR "${CMAKE_INSTALL_PREFIX}/include/polyclipping")
SET(CMAKE_INSTALL_LIBDIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
SET(CMAKE_INSTALL_PKGCONFIGDIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig")
SET(PCFILE "${CMAKE_CURRENT_BINARY_DIR}/polyclipping.pc")
SET(BUILD_SHARED_LIBS ON CACHE BOOL
"Build shared libraries (.dll/.so) instead of static ones (.lib/.a)")
ADD_LIBRARY(polyclipping clipper.cpp)
CONFIGURE_FILE (polyclipping.pc.cmakein "${PCFILE}" @ONLY)
INSTALL (FILES clipper.hpp DESTINATION "${CMAKE_INSTALL_INCDIR}")
INSTALL (TARGETS polyclipping LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
INSTALL (FILES "${PCFILE}" DESTINATION "${CMAKE_INSTALL_PKGCONFIGDIR}")
SET_TARGET_PROPERTIES(polyclipping PROPERTIES VERSION 22.0.0 SOVERSION 22 )

View File

@ -1,295 +0,0 @@
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 1.1 *
* Date : 4 April 2011 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2011 *
* *
* License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt *
* *
*******************************************************************************/
#ifndef AGG_CONV_CLIPPER_INCLUDED
#define AGG_CONV_CLIPPER_INCLUDED
#include <cmath>
#include "agg_basics.h"
#include "agg_array.h"
#include "../clipper.hpp"
namespace agg
{
enum clipper_op_e { clipper_or,
clipper_and, clipper_xor, clipper_a_minus_b, clipper_b_minus_a };
enum clipper_PolyFillType {clipper_even_odd, clipper_non_zero, clipper_positive, clipper_negative};
template<class VSA, class VSB> class conv_clipper
{
enum status { status_move_to, status_line_to, status_stop };
typedef VSA source_a_type;
typedef VSB source_b_type;
typedef conv_clipper<source_a_type, source_b_type> self_type;
private:
source_a_type* m_src_a;
source_b_type* m_src_b;
status m_status;
int m_vertex;
int m_contour;
int m_scaling_factor;
clipper_op_e m_operation;
pod_bvector<ClipperLib::IntPoint, 8> m_vertex_accumulator;
ClipperLib::Paths m_poly_a;
ClipperLib::Paths m_poly_b;
ClipperLib::Paths m_result;
ClipperLib::Clipper m_clipper;
clipper_PolyFillType m_subjFillType;
clipper_PolyFillType m_clipFillType;
int Round(double val)
{
if ((val < 0)) return (int)(val - 0.5); else return (int)(val + 0.5);
}
public:
conv_clipper(source_a_type &a, source_b_type &b,
clipper_op_e op = clipper_or,
clipper_PolyFillType subjFillType = clipper_even_odd,
clipper_PolyFillType clipFillType = clipper_even_odd,
int scaling_factor = 2) :
m_src_a(&a),
m_src_b(&b),
m_status(status_move_to),
m_vertex(-1),
m_contour(-1),
m_operation(op),
m_subjFillType(subjFillType),
m_clipFillType(clipFillType)
{
m_scaling_factor = std::max(std::min(scaling_factor, 6),0);
m_scaling_factor = Round(std::pow((double)10, m_scaling_factor));
}
~conv_clipper()
{
}
void attach1(VSA &source, clipper_PolyFillType subjFillType = clipper_even_odd)
{ m_src_a = &source; m_subjFillType = subjFillType; }
void attach2(VSB &source, clipper_PolyFillType clipFillType = clipper_even_odd)
{ m_src_b = &source; m_clipFillType = clipFillType; }
void operation(clipper_op_e v) { m_operation = v; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
bool next_contour();
bool next_vertex(double* x, double* y);
void start_extracting();
void add_vertex_(double &x, double &y);
void end_contour(ClipperLib::Paths &p);
template<class VS> void add(VS &src, ClipperLib::Paths &p){
unsigned cmd;
double x; double y; double start_x; double start_y;
bool starting_first_line;
start_x = 0.0;
start_y = 0.0;
starting_first_line = true;
p.resize(0);
cmd = src->vertex( &x , &y );
while(!is_stop(cmd))
{
if(is_vertex(cmd))
{
if(is_move_to(cmd))
{
if(!starting_first_line ) end_contour(p);
start_x = x;
start_y = y;
}
add_vertex_( x, y );
starting_first_line = false;
}
else if(is_end_poly(cmd))
{
if(!starting_first_line && is_closed(cmd))
add_vertex_( start_x, start_y );
}
cmd = src->vertex( &x, &y );
}
end_contour(p);
}
};
//------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::start_extracting()
{
m_status = status_move_to;
m_contour = -1;
m_vertex = -1;
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::rewind(unsigned path_id)
{
m_src_a->rewind( path_id );
m_src_b->rewind( path_id );
add( m_src_a , m_poly_a );
add( m_src_b , m_poly_b );
m_result.resize(0);
ClipperLib::PolyFillType pftSubj, pftClip;
switch (m_subjFillType)
{
case clipper_even_odd: pftSubj = ClipperLib::pftEvenOdd; break;
case clipper_non_zero: pftSubj = ClipperLib::pftNonZero; break;
case clipper_positive: pftSubj = ClipperLib::pftPositive; break;
default: pftSubj = ClipperLib::pftNegative;
}
switch (m_clipFillType)
{
case clipper_even_odd: pftClip = ClipperLib::pftEvenOdd; break;
case clipper_non_zero: pftClip = ClipperLib::pftNonZero; break;
case clipper_positive: pftClip = ClipperLib::pftPositive; break;
default: pftClip = ClipperLib::pftNegative;
}
m_clipper.Clear();
switch( m_operation ) {
case clipper_or:
{
m_clipper.AddPaths( m_poly_a , ClipperLib::ptSubject, true );
m_clipper.AddPaths( m_poly_b , ClipperLib::ptClip, true );
m_clipper.Execute( ClipperLib::ctUnion , m_result , pftSubj, pftClip);
break;
}
case clipper_and:
{
m_clipper.AddPaths( m_poly_a , ClipperLib::ptSubject, true );
m_clipper.AddPaths( m_poly_b , ClipperLib::ptClip, true );
m_clipper.Execute( ClipperLib::ctIntersection , m_result, pftSubj, pftClip );
break;
}
case clipper_xor:
{
m_clipper.AddPaths( m_poly_a , ClipperLib::ptSubject, true );
m_clipper.AddPaths( m_poly_b , ClipperLib::ptClip, true );
m_clipper.Execute( ClipperLib::ctXor , m_result, pftSubj, pftClip );
break;
}
case clipper_a_minus_b:
{
m_clipper.AddPaths( m_poly_a , ClipperLib::ptSubject, true );
m_clipper.AddPaths( m_poly_b , ClipperLib::ptClip, true );
m_clipper.Execute( ClipperLib::ctDifference , m_result, pftSubj, pftClip );
break;
}
case clipper_b_minus_a:
{
m_clipper.AddPaths( m_poly_b , ClipperLib::ptSubject, true );
m_clipper.AddPaths( m_poly_a , ClipperLib::ptClip, true );
m_clipper.Execute( ClipperLib::ctDifference , m_result, pftSubj, pftClip );
break;
}
}
start_extracting();
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::end_contour( ClipperLib::Paths &p)
{
unsigned i, len;
if( m_vertex_accumulator.size() < 3 ) return;
len = p.size();
p.resize(len+1);
p[len].resize(m_vertex_accumulator.size());
for( i = 0 ; i < m_vertex_accumulator.size() ; i++ )
p[len][i] = m_vertex_accumulator[i];
m_vertex_accumulator.remove_all();
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_clipper<VSA, VSB>::add_vertex_(double &x, double &y)
{
ClipperLib::IntPoint v;
v.X = Round(x * m_scaling_factor);
v.Y = Round(y * m_scaling_factor);
m_vertex_accumulator.add( v );
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
bool conv_clipper<VSA, VSB>::next_contour()
{
m_contour++;
if(m_contour >= (int)m_result.size()) return false;
m_vertex =-1;
return true;
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
bool conv_clipper<VSA, VSB>::next_vertex(double *x, double *y)
{
m_vertex++;
if(m_vertex >= (int)m_result[m_contour].size()) return false;
*x = (double)m_result[ m_contour ][ m_vertex ].X / m_scaling_factor;
*y = (double)m_result[ m_contour ][ m_vertex ].Y / m_scaling_factor;
return true;
}
//------------------------------------------------------------------------------
template<class VSA, class VSB>
unsigned conv_clipper<VSA, VSB>::vertex(double *x, double *y)
{
if( m_status == status_move_to )
{
if( next_contour() )
{
if( next_vertex( x, y ) )
{
m_status =status_line_to;
return path_cmd_move_to;
}
else
{
m_status = status_stop;
return path_cmd_end_poly | path_flags_close;
}
}
else
return path_cmd_stop;
}
else
{
if( next_vertex( x, y ) )
{
return path_cmd_line_to;
}
else
{
m_status = status_move_to;
return path_cmd_end_poly | path_flags_close;
}
}
}
//------------------------------------------------------------------------------
} //namespace agg
#endif //AGG_CONV_CLIPPER_INCLUDED

View File

@ -1,574 +0,0 @@
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_renderer_primitives.h"
#include "agg_conv_curve.h"
#include "agg_conv_stroke.h"
#include "agg_conv_clip_polygon.h"
#include "agg_gsv_text.h"
#include "agg_pixfmt_rgb.h"
#include "agg_platform_support.h"
#include "agg_slider_ctrl.h"
#include "agg_cbox_ctrl.h"
#include "agg_rbox_ctrl.h"
#include "agg_conv_clipper.h"
#include "windows.h"
enum flip_y_e { flip_y = true };
class spiral
{
public:
spiral(double x, double y, double r1, double r2, double step, double start_angle=0) :
m_x(x),
m_y(y),
m_r1(r1),
m_r2(r2),
m_step(step),
m_start_angle(start_angle),
m_angle(start_angle),
m_da(agg::deg2rad(4.0)),
m_dr(m_step / 90.0)
{
}
void rewind(unsigned)
{
m_angle = m_start_angle;
m_curr_r = m_r1;
m_start = true;
}
unsigned vertex(double* x, double* y)
{
if(m_curr_r > m_r2) return agg::path_cmd_stop;
*x = m_x + cos(m_angle) * m_curr_r;
*y = m_y + sin(m_angle) * m_curr_r;
m_curr_r += m_dr;
m_angle += m_da;
if(m_start)
{
m_start = false;
return agg::path_cmd_move_to;
}
return agg::path_cmd_line_to;
}
private:
double m_x;
double m_y;
double m_r1;
double m_r2;
double m_step;
double m_start_angle;
double m_angle;
double m_curr_r;
double m_da;
double m_dr;
bool m_start;
};
namespace agg
{
// A simple counter of points and contours
template<class Src> struct conv_poly_counter
{
unsigned m_contours;
unsigned m_points;
conv_poly_counter(Src& src) : m_src(&src), m_contours(0), m_points(0) {}
void rewind(unsigned path_id)
{
m_contours = 0;
m_points = 0;
m_src->rewind(path_id);
}
unsigned vertex(double* x, double* y)
{
unsigned cmd = m_src->vertex(x, y);
if(is_vertex(cmd)) ++m_points;
if(is_move_to(cmd)) ++m_contours;
return cmd;
}
private:
Src* m_src;
};
}
void make_gb_poly(agg::path_storage& ps);
void make_arrows(agg::path_storage& ps);
class the_application : public agg::platform_support
{
agg::rbox_ctrl<agg::rgba8> m_polygons;
agg::rbox_ctrl<agg::rgba8> m_operation;
double m_x;
double m_y;
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == agg::key_escape) exit(0);
}
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_polygons (5.0, 5.0, 5.0+205.0, 110.0, !flip_y),
m_operation(555.0, 5.0, 555.0+80.0, 130.0, !flip_y)
{
m_operation.add_item("None");
m_operation.add_item("OR");
m_operation.add_item("AND");
m_operation.add_item("XOR");
m_operation.add_item("A-B");
m_operation.add_item("B-A");
m_operation.cur_item(2);
add_ctrl(m_operation);
m_polygons.add_item("Two Simple Paths");
m_polygons.add_item("Closed Stroke");
m_polygons.add_item("Great Britain and Arrows");
m_polygons.add_item("Great Britain and Spiral");
m_polygons.add_item("Spiral and Glyph");
m_polygons.cur_item(3);
add_ctrl(m_polygons);
}
template<class Scanline, class Ras, class Ren, class Clp>
void perform_rendering(Scanline &sl, Ras &ras, Ren &ren, Clp &clp)
{
if(m_operation.cur_item() > 0)
{
ras.reset();
switch(m_operation.cur_item())
{
case 1: clp.operation(agg::clipper_or); break;
case 2: clp.operation(agg::clipper_and); break;
case 3: clp.operation(agg::clipper_xor); break;
case 4: clp.operation(agg::clipper_a_minus_b); break;
case 5: clp.operation(agg::clipper_b_minus_a); break;
}
agg::conv_poly_counter<Clp> counter(clp);
start_timer();
counter.rewind(0);
double t1 = elapsed_time();
agg::path_storage ps;
double x;
double y;
unsigned cmd;
start_timer();
while(!agg::is_stop(cmd = counter.vertex(&x, &y)))
{
if(agg::is_move_to(cmd))
ps.move_to(x, y);
else if(agg::is_line_to(cmd))
ps.line_to(x, y);
else if(agg::is_close(cmd))
ps.close_polygon();
}
ras.add_path(ps);
ren.color(agg::rgba(0.25, 0.9, 0.25, 0.65));
agg::render_scanlines(ras, sl, ren);
double t2 = elapsed_time();
agg::conv_stroke<agg::path_storage> stroke(ps);
stroke.width(0.4);
ras.add_path(stroke);
ren.color(agg::rgba(0, 0, 0));
agg::render_scanlines(ras, sl, ren);
char buf[100];
sprintf_s(buf, "Contours: %d Points: %d", counter.m_contours, counter.m_points);
agg::gsv_text txt;
agg::conv_stroke<agg::gsv_text> txt_stroke(txt);
txt_stroke.width(1.5);
txt_stroke.line_cap(agg::round_cap);
txt.size(10.0);
txt.start_point(250, 5);
txt.text(buf);
ras.add_path(txt_stroke);
ren.color(agg::rgba(0.0, 0.0, 0.0));
agg::render_scanlines(ras, sl, ren);
sprintf_s(buf, "Clipper=%.3fms Render=%.3fms", t1, t2);
txt.start_point(250, 20);
txt.text(buf);
ras.add_path(txt_stroke);
ren.color(agg::rgba(0.0, 0.0, 0.0));
agg::render_scanlines(ras, sl, ren);
}
}
template<class Scanline, class Ras>
unsigned render_clipper(Scanline& sl, Ras& ras)
{
agg::pixfmt_bgr24 pf(rbuf_window());
agg::renderer_base<agg::pixfmt_bgr24> rb(pf);
agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgr24> > ren(rb);
switch(m_polygons.cur_item())
{
case 0:
{
//------------------------------------
// Two simple paths
//
agg::path_storage ps1;
agg::path_storage ps2;
agg::conv_clipper<agg::path_storage, agg::path_storage> clp(ps1, ps2, agg::clipper_or, agg::clipper_non_zero, agg::clipper_non_zero);
double x = m_x - initial_width()/2 + 100;
double y = m_y - initial_height()/2 + 100;
ps1.move_to(x+140, y+145);
ps1.line_to(x+225, y+44);
ps1.line_to(x+296, y+219);
ps1.close_polygon();
ps1.line_to(x+226, y+289);
ps1.line_to(x+82, y+292);
ps1.move_to(x+220, y+222);
ps1.line_to(x+363, y+249);
ps1.line_to(x+265, y+331);
ps1.move_to(x+242, y+243);
ps1.line_to(x+268, y+309);
ps1.line_to(x+325, y+261);
ps1.move_to(x+259, y+259);
ps1.line_to(x+273, y+288);
ps1.line_to(x+298, y+266);
ps2.move_to(100+32, 100+77);
ps2.line_to(100+473, 100+263);
ps2.line_to(100+351, 100+290);
ps2.line_to(100+354, 100+374);
ras.reset();
ras.add_path(ps1);
ren.color(agg::rgba(0, 0, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
ras.reset();
ras.add_path(ps2);
ren.color(agg::rgba(0, 0.6, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
perform_rendering(sl, ras, ren, clp);
}
break;
case 1:
{
//------------------------------------
// Closed stroke
//
agg::path_storage ps1;
agg::path_storage ps2;
agg::conv_stroke<agg::path_storage> stroke(ps2);
stroke.width(10.0);
agg::conv_clipper<agg::path_storage,
agg::conv_stroke<agg::path_storage> > clp(ps1, stroke, agg::clipper_or, agg::clipper_non_zero, agg::clipper_non_zero);
double x = m_x - initial_width()/2 + 100;
double y = m_y - initial_height()/2 + 100;
ps1.move_to(x+140, y+145);
ps1.line_to(x+225, y+44);
ps1.line_to(x+296, y+219);
ps1.close_polygon();
ps1.line_to(x+226, y+289);
ps1.line_to(x+82, y+292);
ps1.move_to(x+220-50, y+222);
ps1.line_to(x+265-50, y+331);
ps1.line_to(x+363-50, y+249);
ps1.close_polygon(agg::path_flags_ccw);
ps2.move_to(100+32, 100+77);
ps2.line_to(100+473, 100+263);
ps2.line_to(100+351, 100+290);
ps2.line_to(100+354, 100+374);
ps2.close_polygon();
ras.reset();
ras.add_path(ps1);
ren.color(agg::rgba(0, 0, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
ras.reset();
ras.add_path(stroke);
ren.color(agg::rgba(0, 0.6, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
perform_rendering(sl, ras, ren, clp);
}
break;
case 2:
{
//------------------------------------
// Great Britain and Arrows
//
agg::path_storage gb_poly;
agg::path_storage arrows;
make_gb_poly(gb_poly);
make_arrows(arrows);
agg::trans_affine mtx1;
agg::trans_affine mtx2;
mtx1 *= agg::trans_affine_translation(-1150, -1150);
mtx1 *= agg::trans_affine_scaling(2.0);
mtx2 = mtx1;
mtx2 *= agg::trans_affine_translation(m_x - initial_width()/2,
m_y - initial_height()/2);
agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx1);
agg::conv_transform<agg::path_storage> trans_arrows(arrows, mtx2);
agg::conv_clipper<agg::conv_transform<agg::path_storage>,
agg::conv_transform<agg::path_storage> > clp(trans_gb_poly, trans_arrows, agg::clipper_or, agg::clipper_non_zero, agg::clipper_non_zero);
ras.add_path(trans_gb_poly);
ren.color(agg::rgba(0.5, 0.5, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly);
stroke_gb_poly.width(0.1);
ras.add_path(stroke_gb_poly);
ren.color(agg::rgba(0, 0, 0));
agg::render_scanlines(ras, sl, ren);
ras.add_path(trans_arrows);
ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1));
agg::render_scanlines(ras, sl, ren);
perform_rendering(sl, ras, ren, clp);
}
break;
case 3:
{
//------------------------------------
// Great Britain and a Spiral
//
spiral sp(m_x, m_y, 10, 150, 30, 0.0);
agg::conv_stroke<spiral> stroke(sp);
stroke.width(15.0);
agg::path_storage gb_poly;
make_gb_poly(gb_poly);
agg::trans_affine mtx;
mtx *= agg::trans_affine_translation(-1150, -1150);
mtx *= agg::trans_affine_scaling(2.0);
agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx);
agg::conv_clipper<agg::conv_transform<agg::path_storage>,
agg::conv_stroke<spiral> > clp(trans_gb_poly, stroke, agg::clipper_or, agg::clipper_non_zero, agg::clipper_non_zero);
ras.add_path(trans_gb_poly);
ren.color(agg::rgba(0.5, 0.5, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly);
stroke_gb_poly.width(0.1);
ras.add_path(stroke_gb_poly);
ren.color(agg::rgba(0, 0, 0));
agg::render_scanlines(ras, sl, ren);
ras.add_path(stroke);
ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1));
agg::render_scanlines(ras, sl, ren);
perform_rendering(sl, ras, ren, clp);
}
break;
case 4:
{
//------------------------------------
// Spiral and glyph
//
spiral sp(m_x, m_y, 10, 150, 30, 0.0);
agg::conv_stroke<spiral> stroke(sp);
stroke.width(15.0);
agg::path_storage glyph;
glyph.move_to(28.47, 6.45);
glyph.curve3(21.58, 1.12, 19.82, 0.29);
glyph.curve3(17.19, -0.93, 14.21, -0.93);
glyph.curve3(9.57, -0.93, 6.57, 2.25);
glyph.curve3(3.56, 5.42, 3.56, 10.60);
glyph.curve3(3.56, 13.87, 5.03, 16.26);
glyph.curve3(7.03, 19.58, 11.99, 22.51);
glyph.curve3(16.94, 25.44, 28.47, 29.64);
glyph.line_to(28.47, 31.40);
glyph.curve3(28.47, 38.09, 26.34, 40.58);
glyph.curve3(24.22, 43.07, 20.17, 43.07);
glyph.curve3(17.09, 43.07, 15.28, 41.41);
glyph.curve3(13.43, 39.75, 13.43, 37.60);
glyph.line_to(13.53, 34.77);
glyph.curve3(13.53, 32.52, 12.38, 31.30);
glyph.curve3(11.23, 30.08, 9.38, 30.08);
glyph.curve3(7.57, 30.08, 6.42, 31.35);
glyph.curve3(5.27, 32.62, 5.27, 34.81);
glyph.curve3(5.27, 39.01, 9.57, 42.53);
glyph.curve3(13.87, 46.04, 21.63, 46.04);
glyph.curve3(27.59, 46.04, 31.40, 44.04);
glyph.curve3(34.28, 42.53, 35.64, 39.31);
glyph.curve3(36.52, 37.21, 36.52, 30.71);
glyph.line_to(36.52, 15.53);
glyph.curve3(36.52, 9.13, 36.77, 7.69);
glyph.curve3(37.01, 6.25, 37.57, 5.76);
glyph.curve3(38.13, 5.27, 38.87, 5.27);
glyph.curve3(39.65, 5.27, 40.23, 5.62);
glyph.curve3(41.26, 6.25, 44.19, 9.18);
glyph.line_to(44.19, 6.45);
glyph.curve3(38.72, -0.88, 33.74, -0.88);
glyph.curve3(31.35, -0.88, 29.93, 0.78);
glyph.curve3(28.52, 2.44, 28.47, 6.45);
glyph.close_polygon();
glyph.move_to(28.47, 9.62);
glyph.line_to(28.47, 26.66);
glyph.curve3(21.09, 23.73, 18.95, 22.51);
glyph.curve3(15.09, 20.36, 13.43, 18.02);
glyph.curve3(11.77, 15.67, 11.77, 12.89);
glyph.curve3(11.77, 9.38, 13.87, 7.06);
glyph.curve3(15.97, 4.74, 18.70, 4.74);
glyph.curve3(22.41, 4.74, 28.47, 9.62);
glyph.close_polygon();
agg::trans_affine mtx;
mtx *= agg::trans_affine_scaling(4.0);
mtx *= agg::trans_affine_translation(220, 200);
agg::conv_transform<agg::path_storage> trans(glyph, mtx);
agg::conv_curve<agg::conv_transform<agg::path_storage> > curve(trans);
agg::conv_clipper<agg::conv_stroke<spiral>,
agg::conv_curve<
agg::conv_transform<
agg::path_storage> > > clp(stroke, curve, agg::clipper_or, agg::clipper_non_zero, agg::clipper_non_zero);
ras.reset();
ras.add_path(stroke);
ren.color(agg::rgba(0, 0, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
ras.reset();
ras.add_path(curve);
ren.color(agg::rgba(0, 0.6, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
perform_rendering(sl, ras, ren, clp);
}
break;
}
return 0;
}
virtual void on_init()
{
m_x = width() / 2.0;
m_y = height() / 2.0;
}
virtual void on_draw()
{
typedef agg::renderer_base<agg::pixfmt_bgr24> base_ren_type;
agg::pixfmt_bgr24 pf(rbuf_window());
base_ren_type ren_base(pf);
ren_base.clear(agg::rgba(1,1,1));
agg::scanline_u8 sl;
agg::rasterizer_scanline_aa<> ras;
render_clipper(sl, ras);
agg::render_ctrl(ras, sl, ren_base, m_polygons);
agg::render_ctrl(ras, sl, ren_base, m_operation);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
m_x = x;
m_y = y;
force_redraw();
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
m_x = x;
m_y = y;
force_redraw();
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(agg::pix_format_bgr24, flip_y);
app.caption("AGG Example. Clipper");
if(app.init(640, 520, agg::window_resize))
{
//replace the main window icon with Resource Icon #1 ...
HWND w = GetActiveWindow();
HMODULE m = GetModuleHandle(0); //hInstance
HANDLE small_ico = LoadImage(m, MAKEINTRESOURCE(1), IMAGE_ICON, 16, 16, 0);
HANDLE big_ico = LoadImage(m, MAKEINTRESOURCE(1), IMAGE_ICON, 32, 32, 0);
SendMessage(w, WM_SETICON, ICON_SMALL, (LPARAM)small_ico);
SendMessage(w, WM_SETICON, ICON_BIG, (LPARAM)big_ico);
//main message loop ...
return app.run();
}
return 0;
}

View File

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clipper_test", "clipper_test.vcxproj", "{4DF13A7A-6137-E76C-8C62-F591D0E4B69F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4DF13A7A-6137-E76C-8C62-F591D0E4B69F}.Debug|Win32.ActiveCfg = Debug|Win32
{4DF13A7A-6137-E76C-8C62-F591D0E4B69F}.Debug|Win32.Build.0 = Debug|Win32
{4DF13A7A-6137-E76C-8C62-F591D0E4B69F}.Release|Win32.ActiveCfg = Release|Win32
{4DF13A7A-6137-E76C-8C62-F591D0E4B69F}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,114 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
<ProjectName>clipper_test</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>C:\Program Files (x86)\Borland\agg-2.5\include;C:\Program Files (x86)\Borland\agg-2.5\include\platform;C:\Program Files (x86)\Borland\agg-2.5\include\platform\win32;C:\Program Files (x86)\Borland\agg-2.5\include\ctrl;C:\Program Files (x86)\Borland\agg-2.5\include\util;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>C:\Program Files (x86)\Borland\agg-2.5\include;C:\Program Files (x86)\Borland\agg-2.5\include\platform;C:\Program Files (x86)\Borland\agg-2.5\include\platform\win32;C:\Program Files (x86)\Borland\agg-2.5\include\ctrl;C:\Program Files (x86)\Borland\agg-2.5\include\util;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\agg_src\examples\make_arrows.cpp" />
<ClCompile Include="..\agg_src\examples\make_gb_poly.cpp" />
<ClCompile Include="..\agg_src\src\agg_arc.cpp" />
<ClCompile Include="..\agg_src\src\agg_arrowhead.cpp" />
<ClCompile Include="..\agg_src\src\agg_bezier_arc.cpp" />
<ClCompile Include="..\agg_src\src\agg_bspline.cpp" />
<ClCompile Include="..\agg_src\src\agg_curves.cpp" />
<ClCompile Include="..\agg_src\src\agg_embedded_raster_fonts.cpp" />
<ClCompile Include="..\agg_src\src\agg_gsv_text.cpp" />
<ClCompile Include="..\agg_src\src\agg_image_filters.cpp" />
<ClCompile Include="..\agg_src\src\agg_line_aa_basics.cpp" />
<ClCompile Include="..\agg_src\src\agg_line_profile_aa.cpp" />
<ClCompile Include="..\agg_src\src\agg_rounded_rect.cpp" />
<ClCompile Include="..\agg_src\src\agg_sqrt_tables.cpp" />
<ClCompile Include="..\agg_src\src\agg_trans_affine.cpp" />
<ClCompile Include="..\agg_src\src\agg_trans_double_path.cpp" />
<ClCompile Include="..\agg_src\src\agg_trans_single_path.cpp" />
<ClCompile Include="..\agg_src\src\agg_trans_warp_magnifier.cpp" />
<ClCompile Include="..\agg_src\src\agg_vcgen_bspline.cpp" />
<ClCompile Include="..\agg_src\src\agg_vcgen_contour.cpp" />
<ClCompile Include="..\agg_src\src\agg_vcgen_dash.cpp" />
<ClCompile Include="..\agg_src\src\agg_vcgen_markers_term.cpp" />
<ClCompile Include="..\agg_src\src\agg_vcgen_smooth_poly1.cpp" />
<ClCompile Include="..\agg_src\src\agg_vcgen_stroke.cpp" />
<ClCompile Include="..\agg_src\src\agg_vpgen_clip_polygon.cpp" />
<ClCompile Include="..\agg_src\src\agg_vpgen_clip_polyline.cpp" />
<ClCompile Include="..\agg_src\src\agg_vpgen_segmentator.cpp" />
<ClCompile Include="..\agg_src\src\ctrl\agg_rbox_ctrl.cpp" />
<ClCompile Include="..\agg_src\src\platform\win32\agg_platform_support.cpp" />
<ClCompile Include="..\agg_src\src\platform\win32\agg_win32_bmp.cpp" />
<ClCompile Include="..\clipper.cpp" />
<ClCompile Include="clipper_test.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\clipper.hpp" />
<ClInclude Include="agg_conv_clipper.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,118 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="clipper_test.cpp" />
<ClCompile Include="..\clipper.cpp">
<Filter>ClipperLib</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_arc.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_arrowhead.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_bezier_arc.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_bspline.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_curves.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_embedded_raster_fonts.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_gsv_text.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_image_filters.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_line_aa_basics.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_line_profile_aa.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_rounded_rect.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_sqrt_tables.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_trans_affine.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_trans_double_path.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_trans_single_path.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_trans_warp_magnifier.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_vcgen_bspline.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_vcgen_contour.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_vcgen_dash.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_vcgen_markers_term.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_vcgen_smooth_poly1.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_vcgen_stroke.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_vpgen_clip_polygon.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_vpgen_clip_polyline.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\agg_vpgen_segmentator.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\ctrl\agg_rbox_ctrl.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\platform\win32\agg_platform_support.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\src\platform\win32\agg_win32_bmp.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\examples\make_arrows.cpp">
<Filter>agg_src</Filter>
</ClCompile>
<ClCompile Include="..\agg_src\examples\make_gb_poly.cpp">
<Filter>agg_src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="agg_src">
<UniqueIdentifier>{31703eea-b46a-4b7c-93fe-7b3889404c6f}</UniqueIdentifier>
</Filter>
<Filter Include="ClipperLib">
<UniqueIdentifier>{0d7823fd-c31f-4f5d-b1f5-3f3c91751bf3}</UniqueIdentifier>
</Filter>
<Filter Include="agg_clipper">
<UniqueIdentifier>{0ea31d0f-7e25-4f22-964b-8c74b5ced2fd}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\clipper.hpp">
<Filter>ClipperLib</Filter>
</ClInclude>
<ClInclude Include="agg_conv_clipper.h">
<Filter>agg_clipper</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -1,6 +0,0 @@
http://cairographics.org/
The Windows dynamic linked libraries necessary to run Cairo can be downloaded from
http://www.gtk.org/download/win32.php
All the dlls listed under the heading "Required third party dependencies" are
required except gettext-runtime.dll.

View File

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cairo", "cairo.vcxproj", "{6AFBCA2B-9262-6D28-7506-E13747347388}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6AFBCA2B-9262-6D28-7506-E13747347388}.Debug|Win32.ActiveCfg = Debug|Win32
{6AFBCA2B-9262-6D28-7506-E13747347388}.Debug|Win32.Build.0 = Debug|Win32
{6AFBCA2B-9262-6D28-7506-E13747347388}.Release|Win32.ActiveCfg = Release|Win32
{6AFBCA2B-9262-6D28-7506-E13747347388}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,93 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>C:\Program Files %28x86%29\Borland\Clipper\PreReleaseTesting\cpp\cairo_src;$(IncludePath)</IncludePath>
<SourcePath>C:\Program Files %28x86%29\Borland\Clipper\PreReleaseTesting\cpp\cairo_src;C:\Program Files %28x86%29\Borland\graphics32\Examples\Vcl\Drawing\Clipper\PreReleaseTesting\cpp\cairo_src;$(SourcePath)</SourcePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>C:\Program Files (x86)\Borland\graphics32\Examples\Vcl\Drawing\Clipper\PreReleaseTesting\cpp\cairo_src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<UseUnicodeForAssemblerListing>
</UseUnicodeForAssemblerListing>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>C:\Program Files (x86)\Borland\graphics32\Examples\Vcl\Drawing\Clipper\PreReleaseTesting\cpp\cairo_src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\clipper.cpp" />
<ClCompile Include="cairo_clipper.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\cairo_src\cairo.h" />
<ClInclude Include="..\clipper.hpp" />
<ClInclude Include="cairo_clipper.hpp" />
</ItemGroup>
<ItemGroup>
<Library Include="libcairo-2.lib" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,134 +0,0 @@
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 1.1 *
* Date : 4 April 2011 *
* Copyright : Angus Johnson 2010-2011 *
* *
* License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt *
* *
* Modified by Mike Owens to support coordinate transformation *
*******************************************************************************/
#include <stdexcept>
#include <cmath>
#include <cairo.h>
#include "clipper.hpp"
#include "cairo_clipper.hpp"
namespace ClipperLib {
namespace cairo {
namespace {
inline cInt Round(double val)
{
if ((val < 0)) return (cInt)(val - 0.5); else return (cInt)(val + 0.5);
}
void transform_point(cairo_t* pen, Transform transform, cInt* x, cInt* y)
{
double _x = (double)*x, _y = (double)*y;
switch (transform)
{
case tDeviceToUser:
cairo_device_to_user(pen, &_x, &_y);
break;
case tUserToDevice:
cairo_user_to_device(pen, &_x, &_y);
break;
default:
;
}
*x = Round(_x); *y = Round(_y);
}
}
void cairo_to_clipper(cairo_t* cr,
Paths &pg,
int scaling_factor,
Transform transform)
{
if (scaling_factor > 8 || scaling_factor < 0)
throw clipperCairoException("cairo_to_clipper: invalid scaling factor");
double scaling = std::pow((double)10, scaling_factor);
pg.clear();
cairo_path_t *path = cairo_copy_path_flat(cr);
int poly_count = 0;
for (int i = 0; i < path->num_data; i += path->data[i].header.length) {
if( path->data[i].header.type == CAIRO_PATH_CLOSE_PATH) poly_count++;
}
pg.resize(poly_count);
int i = 0, pc = 0;
while (pc < poly_count)
{
int vert_count = 1;
int j = i;
while(j < path->num_data &&
path->data[j].header.type != CAIRO_PATH_CLOSE_PATH)
{
if (path->data[j].header.type == CAIRO_PATH_LINE_TO)
vert_count++;
j += path->data[j].header.length;
}
pg[pc].resize(vert_count);
if (path->data[i].header.type != CAIRO_PATH_MOVE_TO) {
pg.resize(pc);
break;
}
pg[pc][0].X = Round(path->data[i+1].point.x *scaling);
pg[pc][0].Y = Round(path->data[i+1].point.y *scaling);
if (transform != tNone)
transform_point(cr, transform, &pg[pc][0].X, &pg[pc][0].Y);
i += path->data[i].header.length;
j = 1;
while (j < vert_count && i < path->num_data &&
path->data[i].header.type == CAIRO_PATH_LINE_TO) {
pg[pc][j].X = Round(path->data[i+1].point.x *scaling);
pg[pc][j].Y = Round(path->data[i+1].point.y *scaling);
if (transform != tNone)
transform_point(cr, transform, &pg[pc][j].X, &pg[pc][j].Y);
j++;
i += path->data[i].header.length;
}
pc++;
i += path->data[i].header.length;
}
cairo_path_destroy(path);
}
//--------------------------------------------------------------------------
void clipper_to_cairo(const Paths &pg,
cairo_t* cr,
int scaling_factor,
Transform transform)
{
if (scaling_factor > 8 || scaling_factor < 0)
throw clipperCairoException("clipper_to_cairo: invalid scaling factor");
double scaling = std::pow((double)10, scaling_factor);
for (size_t i = 0; i < pg.size(); ++i)
{
size_t sz = pg[i].size();
if (sz < 3)
continue;
cairo_new_sub_path(cr);
for (size_t j = 0; j < sz; ++j) {
cInt x = pg[i][j].X, y = pg[i][j].Y;
if (transform != tNone)
transform_point(cr, transform, &x, &y);
cairo_line_to(cr, (double)x / scaling, (double)y / scaling);
}
cairo_close_path(cr);
}
}
//--------------------------------------------------------------------------
}
}

View File

@ -1,59 +0,0 @@
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 1.1 *
* Date : 4 April 2011 *
* Copyright : Angus Johnson 2010-2011 *
* *
* License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt *
* *
* Modified by Mike Owens to support coordinate transformation *
*******************************************************************************/
#ifndef CLIPPER_CAIRO_CLIPPER_HPP
#define CLIPPER_CAIRO_CLIPPER_HPP
#include "clipper.hpp"
typedef struct _cairo cairo_t;
namespace ClipperLib {
namespace cairo {
enum Transform {
tNone,
tUserToDevice,
tDeviceToUser
};
//nb: Since Clipper only accepts integer coordinates, fractional values have to
//be scaled up and down when being passed to and from Clipper. This is easily
//accomplished by setting the scaling factor (10^x) in the following functions.
//When scaling, remember that on most platforms, integer is only a 32bit value.
void cairo_to_clipper(cairo_t* cr,
ClipperLib::Paths &pg,
int scaling_factor = 0,
Transform transform = tNone);
void clipper_to_cairo(const ClipperLib::Paths &pg,
cairo_t* cr,
int scaling_factor = 0,
Transform transform = tNone);
}
class clipperCairoException : public std::exception
{
public:
clipperCairoException(const char* description)
throw(): std::exception(), m_description (description) {}
virtual ~clipperCairoException() throw() {}
virtual const char* what() const throw() {return m_description.c_str();}
private:
std::string m_description;
};
}
#endif

View File

@ -1,182 +0,0 @@
//---------------------------------------------------------------------------
#include <windows.h>
#include <cstring>
#include <cmath>
#include <sstream>
#pragma hdrstop
#include "clipper.hpp"
#include "cairo.h"
#include "cairo-win32.h"
#include "cairo_clipper.hpp"
//---------------------------------------------------------------------------
int offsetVal;
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int CALLBACK wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
WCHAR* ClsName = L"CairoApp";
WCHAR* WndName = L"A Simple Cairo Clipper Demo";
offsetVal = 0;
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProcedure;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName, WndName, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
NULL, NULL, hInstance, NULL);
if( !hWnd ) return 0;
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
//------------------------------------------------------------------------------
void OnPaint(HWND hWnd, HDC dc)
{
RECT rec;
GetClientRect(hWnd, &rec);
cairo_surface_t* surface = cairo_win32_surface_create(dc);
cairo_t* cr = cairo_create(surface);
cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
cairo_set_line_width (cr, 2.0);
//fill background with white ...
cairo_rectangle(cr, 0, 0, rec.right, rec.bottom);
cairo_set_source_rgba(cr, 1, 1, 1, 1);
cairo_fill(cr);
using namespace ClipperLib;
const int scaling = 2;
Clipper clpr; //clipper class
Paths pg; //std::vector for polygon(s) storage
//create a circular pattern, add the path to clipper and then draw it ...
cairo_arc(cr, 170,110,70,0,2*3.1415926);
cairo_close_path(cr);
cairo::cairo_to_clipper(cr, pg, scaling);
clpr.AddPaths(pg, ptSubject, true);
cairo_set_source_rgba(cr, 0, 0, 1, 0.25);
cairo_fill_preserve (cr);
cairo_set_source_rgba(cr, 0, 0, 0, 0.5);
cairo_stroke (cr);
//draw a star and another circle, add them to clipper and draw ...
cairo_move_to(cr, 60,110);
cairo_line_to (cr, 240,70);
cairo_line_to (cr, 110,210);
cairo_line_to (cr, 140,25);
cairo_line_to (cr, 230,200);
cairo_close_path(cr);
cairo_new_sub_path(cr);
cairo_arc(cr, 190,50,20,0,2*3.1415926);
cairo_close_path(cr);
cairo::cairo_to_clipper(cr, pg, scaling);
clpr.AddPaths(pg, ptClip, true);
cairo_set_source_rgba(cr, 1, 0, 0, 0.25);
cairo_fill_preserve (cr);
cairo_set_source_rgba(cr, 0, 0, 0, 0.5);
cairo_stroke (cr);
clpr.Execute(ctIntersection, pg, pftNonZero, pftNonZero);
//now do something fancy with the returned polygons ...
OffsetPaths(pg, pg, offsetVal * std::pow((double)10,scaling), jtMiter, etClosed);
//finally copy the clipped path back to the cairo context and draw it ...
cairo::clipper_to_cairo(pg, cr, scaling);
cairo_set_source_rgba(cr, 1, 1, 0, 1);
cairo_fill_preserve (cr);
cairo_set_source_rgba(cr, 0, 0, 0, 1);
cairo_stroke (cr);
cairo_text_extents_t extent;
cairo_set_font_size(cr,11);
std::stringstream ss;
ss << "Polygon offset = " << offsetVal << ". (Adjust with arrow keys)";
std::string s = ss.str();
cairo_text_extents(cr, s.c_str(), &extent);
cairo_move_to(cr, 10, rec.bottom - extent.height);
cairo_show_text(cr, s.c_str());
cairo_destroy (cr);
cairo_surface_destroy (surface);
}
//------------------------------------------------------------------------------
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC Handle;
switch(Msg)
{
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
return 0;
case WM_PAINT:
Handle = BeginPaint(hWnd, &ps);
OnPaint(hWnd, Handle);
EndPaint(hWnd, &ps);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
case VK_RIGHT:
case VK_UP:
if (offsetVal < 20) offsetVal++;
InvalidateRect(hWnd, 0, false);
return 0;
case VK_LEFT:
case VK_DOWN:
if (offsetVal > -20) offsetVal--;
InvalidateRect(hWnd, 0, false);
return 0;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
}
//---------------------------------------------------------------------------

View File

@ -1,461 +0,0 @@
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <cmath>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include "clipper.hpp"
using namespace std;
using namespace ClipperLib;
//---------------------------------------------------------------------------
// SVGBuilder class
// a very simple class that creates an SVG image file
//---------------------------------------------------------------------------
class SVGBuilder
{
static string ColorToHtml(unsigned clr)
{
stringstream ss;
ss << '#' << hex << std::setfill('0') << setw(6) << (clr & 0xFFFFFF);
return ss.str();
}
//------------------------------------------------------------------------------
static float GetAlphaAsFrac(unsigned clr)
{
return ((float)(clr >> 24) / 255);
}
//------------------------------------------------------------------------------
class StyleInfo
{
public:
PolyFillType pft;
unsigned brushClr;
unsigned penClr;
double penWidth;
bool showCoords;
StyleInfo()
{
pft = pftNonZero;
brushClr = 0xFFFFFFCC;
penClr = 0xFF000000;
penWidth = 0.8;
showCoords = false;
}
};
class PolyInfo
{
public:
Paths paths;
StyleInfo si;
PolyInfo(Paths paths, StyleInfo style)
{
this->paths = paths;
this->si = style;
}
};
typedef std::vector<PolyInfo> PolyInfoList;
private:
PolyInfoList polyInfos;
static const std::string svg_xml_start[];
static const std::string poly_end[];
public:
StyleInfo style;
void AddPaths(Paths& poly)
{
if (poly.size() == 0) return;
polyInfos.push_back(PolyInfo(poly, style));
}
bool SaveToFile(const string& filename, double scale = 1.0, int margin = 10)
{
//calculate the bounding rect ...
PolyInfoList::size_type i = 0;
Paths::size_type j;
while (i < polyInfos.size())
{
j = 0;
while (j < polyInfos[i].paths.size() &&
polyInfos[i].paths[j].size() == 0) j++;
if (j < polyInfos[i].paths.size()) break;
i++;
}
if (i == polyInfos.size()) return false;
IntRect rec;
rec.left = polyInfos[i].paths[j][0].X;
rec.right = rec.left;
rec.top = polyInfos[i].paths[j][0].Y;
rec.bottom = rec.top;
for ( ; i < polyInfos.size(); ++i)
for (Paths::size_type j = 0; j < polyInfos[i].paths.size(); ++j)
for (Path::size_type k = 0; k < polyInfos[i].paths[j].size(); ++k)
{
IntPoint ip = polyInfos[i].paths[j][k];
if (ip.X < rec.left) rec.left = ip.X;
else if (ip.X > rec.right) rec.right = ip.X;
if (ip.Y < rec.top) rec.top = ip.Y;
else if (ip.Y > rec.bottom) rec.bottom = ip.Y;
}
if (scale == 0) scale = 1.0;
if (margin < 0) margin = 0;
rec.left = (cInt)((double)rec.left * scale);
rec.top = (cInt)((double)rec.top * scale);
rec.right = (cInt)((double)rec.right * scale);
rec.bottom = (cInt)((double)rec.bottom * scale);
cInt offsetX = -rec.left + margin;
cInt offsetY = -rec.top + margin;
ofstream file;
file.open(filename);
if (!file.is_open()) return false;
file.setf(ios::fixed);
file.precision(0);
file << svg_xml_start[0] <<
((rec.right - rec.left) + margin*2) << "px" << svg_xml_start[1] <<
((rec.bottom - rec.top) + margin*2) << "px" << svg_xml_start[2] <<
((rec.right - rec.left) + margin*2) << " " <<
((rec.bottom - rec.top) + margin*2) << svg_xml_start[3];
setlocale(LC_NUMERIC, "C");
file.precision(2);
for (PolyInfoList::size_type i = 0; i < polyInfos.size(); ++i)
{
file << " <path d=\"";
for (Paths::size_type j = 0; j < polyInfos[i].paths.size(); ++j)
{
if (polyInfos[i].paths[j].size() < 3) continue;
file << " M " << ((double)polyInfos[i].paths[j][0].X * scale + offsetX) <<
" " << ((double)polyInfos[i].paths[j][0].Y * scale + offsetY);
for (Path::size_type k = 1; k < polyInfos[i].paths[j].size(); ++k)
{
IntPoint ip = polyInfos[i].paths[j][k];
double x = (double)ip.X * scale;
double y = (double)ip.Y * scale;
file << " L " << (x + offsetX) << " " << (y + offsetY);
}
file << " z";
}
file << poly_end[0] << ColorToHtml(polyInfos[i].si.brushClr) <<
poly_end[1] << GetAlphaAsFrac(polyInfos[i].si.brushClr) <<
poly_end[2] <<
(polyInfos[i].si.pft == pftEvenOdd ? "evenodd" : "nonzero") <<
poly_end[3] << ColorToHtml(polyInfos[i].si.penClr) <<
poly_end[4] << GetAlphaAsFrac(polyInfos[i].si.penClr) <<
poly_end[5] << polyInfos[i].si.penWidth << poly_end[6];
if (polyInfos[i].si.showCoords)
{
file << "<g font-family=\"Verdana\" font-size=\"11\" fill=\"black\">\n\n";
for (Paths::size_type j = 0; j < polyInfos[i].paths.size(); ++j)
{
if (polyInfos[i].paths[j].size() < 3) continue;
for (Path::size_type k = 0; k < polyInfos[i].paths[j].size(); ++k)
{
IntPoint ip = polyInfos[i].paths[j][k];
file << "<text x=\"" << (int)(ip.X * scale + offsetX) <<
"\" y=\"" << (int)(ip.Y * scale + offsetY) << "\">" <<
ip.X << "," << ip.Y << "</text>\n";
file << "\n";
}
}
file << "</g>\n";
}
}
file << "</svg>\n";
file.close();
setlocale(LC_NUMERIC, "");
return true;
}
}; //SVGBuilder
//------------------------------------------------------------------------------
const std::string SVGBuilder::svg_xml_start [] =
{"<?xml version=\"1.0\" standalone=\"no\"?>\n"
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n"
"\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n\n"
"<svg width=\"",
"\" height=\"",
"\" viewBox=\"0 0 ",
"\" version=\"1.0\" xmlns=\"http://www.w3.org/2000/svg\">\n\n"
};
const std::string SVGBuilder::poly_end [] =
{"\"\n style=\"fill:",
"; fill-opacity:",
"; fill-rule:",
"; stroke:",
"; stroke-opacity:",
"; stroke-width:",
";\"/>\n\n"
};
//------------------------------------------------------------------------------
// Miscellaneous function ...
//------------------------------------------------------------------------------
bool SaveToFile(const string& filename, Paths &ppg, double scale = 1.0, unsigned decimal_places = 0)
{
ofstream ofs(filename);
if (!ofs) return false;
if (decimal_places > 8) decimal_places = 8;
ofs << setprecision(decimal_places) << std::fixed;
Path pg;
for (size_t i = 0; i < ppg.size(); ++i)
{
for (size_t j = 0; j < ppg[i].size(); ++j)
ofs << ppg[i][j].X / scale << ", " << ppg[i][j].Y / scale << "," << std::endl;
ofs << std::endl;
}
ofs.close();
return true;
}
//------------------------------------------------------------------------------
bool LoadFromFile(Paths &ppg, const string& filename, double scale)
{
//file format assumes:
// 1. path coordinates (x,y) are comma separated (+/- spaces) and
// each coordinate is on a separate line
// 2. each path is separated by one or more blank lines
ppg.clear();
ifstream ifs(filename);
if (!ifs) return false;
string line;
Path pg;
while (std::getline(ifs, line))
{
stringstream ss(line);
double X = 0.0, Y = 0.0;
if (!(ss >> X))
{
//ie blank lines => flag start of next polygon
if (pg.size() > 0) ppg.push_back(pg);
pg.clear();
continue;
}
char c = ss.peek();
while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces before comma
if (c == ',') {ss.read(&c, 1); c = ss.peek();} //gobble comma
while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces after comma
if (!(ss >> Y)) break; //oops!
pg.push_back(IntPoint((cInt)(X * scale),(cInt)(Y * scale)));
}
if (pg.size() > 0) ppg.push_back(pg);
ifs.close();
return true;
}
//------------------------------------------------------------------------------
void MakeRandomPoly(int edgeCount, int width, int height, Paths & poly)
{
poly.resize(1);
poly[0].resize(edgeCount);
for (int i = 0; i < edgeCount; i++){
poly[0][i].X = rand() % width;
poly[0][i].Y = rand() % height;
}
}
//------------------------------------------------------------------------------
bool ASCII_icompare(const char* str1, const char* str2)
{
//case insensitive compare for ASCII chars only
while (*str1)
{
if (toupper(*str1) != toupper(*str2)) return false;
str1++;
str2++;
}
return (!*str2);
}
//------------------------------------------------------------------------------
// Main entry point ...
//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
if (argc > 1 &&
(strcmp(argv[1], "-b") == 0 || strcmp(argv[1], "--benchmark") == 0))
{
//do a benchmark test that creates a subject and a clip polygon both with
//100 vertices randomly placed in a 400 * 400 space. Then perform an
//intersection operation based on even-odd filling. Repeat all this X times.
int loop_cnt = 1000;
char * dummy;
if (argc > 2) loop_cnt = strtol(argv[2], &dummy, 10);
if (loop_cnt == 0) loop_cnt = 1000;
cout << "\nPerforming " << loop_cnt << " random intersection operations ... ";
srand((int)time(0));
int error_cnt = 0;
Paths subject, clip, solution;
Clipper clpr;
time_t time_start = clock();
for (int i = 0; i < loop_cnt; i++) {
MakeRandomPoly(100, 400, 400, subject);
MakeRandomPoly(100, 400, 400, clip);
clpr.Clear();
clpr.AddPaths(subject, ptSubject, true);
clpr.AddPaths(clip, ptClip, true);
if (!clpr.Execute(ctIntersection, solution, pftEvenOdd, pftEvenOdd))
error_cnt++;
}
double time_elapsed = double(clock() - time_start)/CLOCKS_PER_SEC;
cout << "\nFinished in " << time_elapsed << " secs with ";
cout << error_cnt << " errors.\n\n";
//let's save the very last result ...
SaveToFile("Subject.txt", subject);
SaveToFile("Clip.txt", clip);
SaveToFile("Solution.txt", solution);
//and see the final clipping op as an image too ...
SVGBuilder svg;
svg.style.penWidth = 0.8;
svg.style.pft = pftEvenOdd;
svg.style.brushClr = 0x1200009C;
svg.style.penClr = 0xCCD3D3DA;
svg.AddPaths(subject);
svg.style.brushClr = 0x129C0000;
svg.style.penClr = 0xCCFFA07A;
svg.AddPaths(clip);
svg.style.brushClr = 0x6080ff9C;
svg.style.penClr = 0xFF003300;
svg.style.pft = pftNonZero;
svg.AddPaths(solution);
svg.SaveToFile("solution.svg");
return 0;
}
if (argc < 3)
{
cout << "\nUsage:\n"
<< " clipper_console_demo S_FILE C_FILE CT [S_FILL C_FILL] [PRECISION] [SVG_SCALE]\n"
<< "or\n"
<< " clipper_console_demo --benchmark [LOOP_COUNT]\n\n"
<< "Legend: [optional parameters in square braces]; {comments in curly braces}\n\n"
<< "Parameters:\n"
<< " S_FILE & C_FILE are the subject and clip input files (see format below)\n"
<< " CT: cliptype, either INTERSECTION or UNION or DIFFERENCE or XOR\n"
<< " SUBJECT_FILL & CLIP_FILL: either EVENODD or NONZERO. Default: NONZERO\n"
<< " PRECISION (in decimal places) for input data. Default = 0\n"
<< " SVG_SCALE: scale of the output svg image. Default = 1.0\n"
<< " LOOP_COUNT is the number of random clipping operations. Default = 1000\n\n"
<< "\nFile format for input and output files:\n"
<< " X, Y[,] {first vertex of first path}\n"
<< " X, Y[,] {next vertex of first path}\n"
<< " {etc.}\n"
<< " X, Y[,] {last vertex of first path}\n"
<< " {blank line(s) between paths}\n"
<< " X, Y[,] {first vertex of second path}\n"
<< " X, Y[,] {next vertex of second path}\n"
<< " {etc.}\n\n"
<< "Examples:\n"
<< " clipper_console_demo \"subj.txt\" \"clip.txt\" INTERSECTION EVENODD EVENODD\n"
<< " clipper_console_demo --benchmark 1000\n";
return 1;
}
int scale_log10 = 0;
char* dummy;
if (argc > 6) scale_log10 = strtol(argv[6], &dummy, 10);
double scale = std::pow(double(10), scale_log10);
double svg_scale = 1.0;
if (argc > 7) svg_scale = strtod(argv[7], &dummy);
svg_scale /= scale;
Paths subject, clip;
if (!LoadFromFile(subject, argv[1], scale))
{
cerr << "\nCan't open the file " << argv[1]
<< " or the file format is invalid.\n";
return 1;
}
if (!LoadFromFile(clip, argv[2], scale))
{
cerr << "\nCan't open the file " << argv[2]
<< " or the file format is invalid.\n";
return 1;
}
ClipType clipType = ctIntersection;
const string sClipType[] = {"INTERSECTION", "UNION", "DIFFERENCE", "XOR"};
if (argc > 3)
{
if (ASCII_icompare(argv[3], "XOR")) clipType = ctXor;
else if (ASCII_icompare(argv[3], "UNION")) clipType = ctUnion;
else if (ASCII_icompare(argv[3], "DIFFERENCE")) clipType = ctDifference;
else clipType = ctIntersection;
}
PolyFillType subj_pft = pftNonZero, clip_pft = pftNonZero;
if (argc > 5)
{
if (ASCII_icompare(argv[4], "EVENODD")) subj_pft = pftEvenOdd;
if (ASCII_icompare(argv[5], "EVENODD")) clip_pft = pftEvenOdd;
}
Clipper c;
c.AddPaths(subject, ptSubject, true);
c.AddPaths(clip, ptClip, true);
Paths solution;
if (!c.Execute(clipType, solution, subj_pft, clip_pft))
{
cout << (sClipType[clipType] + " failed!\n\n");
return 1;
}
cout << "\nFinished!\n\n";
SaveToFile("solution.txt", solution, scale);
//let's see the result too ...
SVGBuilder svg;
svg.style.penWidth = 0.8;
svg.style.brushClr = 0x1200009C;
svg.style.penClr = 0xCCD3D3DA;
svg.style.pft = subj_pft;
svg.AddPaths(subject);
svg.style.brushClr = 0x129C0000;
svg.style.penClr = 0xCCFFA07A;
svg.style.pft = clip_pft;
svg.AddPaths(clip);
svg.style.brushClr = 0x6080ff9C;
svg.style.penClr = 0xFF003300;
svg.style.pft = pftNonZero;
svg.AddPaths(solution);
svg.SaveToFile("solution.svg", svg_scale);
//finally, show the svg image in the default viewing application
system("solution.svg");
return 0;
}
//---------------------------------------------------------------------------

View File

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clipper_console_demo", "clipper_console_demo.vcxproj", "{0710EFB8-6D8B-4DF1-9D14-907AE3857FE4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0710EFB8-6D8B-4DF1-9D14-907AE3857FE4}.Debug|Win32.ActiveCfg = Debug|Win32
{0710EFB8-6D8B-4DF1-9D14-907AE3857FE4}.Debug|Win32.Build.0 = Debug|Win32
{0710EFB8-6D8B-4DF1-9D14-907AE3857FE4}.Release|Win32.ActiveCfg = Release|Win32
{0710EFB8-6D8B-4DF1-9D14-907AE3857FE4}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,92 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0710EFB8-6D8B-4DF1-9D14-907AE3857FE4}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>clipper_console_demo</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="clipper.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="clipper.cpp" />
<ClCompile Include="clipper_console_demo.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeaderFile>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clipper_demo", "clipper_demo.vcxproj", "{4D48A928-F288-40F9-9FA0-4AC650602636}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4D48A928-F288-40F9-9FA0-4AC650602636}.Debug|Win32.ActiveCfg = Debug|Win32
{4D48A928-F288-40F9-9FA0-4AC650602636}.Debug|Win32.Build.0 = Debug|Win32
{4D48A928-F288-40F9-9FA0-4AC650602636}.Release|Win32.ActiveCfg = Release|Win32
{4D48A928-F288-40F9-9FA0-4AC650602636}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4D48A928-F288-40F9-9FA0-4AC650602636}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>opengl_app</RootNamespace>
<ProjectName>clipper_demo</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<SourcePath>$(SourcePath)</SourcePath>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>opengl32.lib;glu32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>opengl32.lib;glu32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\clipper.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\clipper.hpp" />
</ItemGroup>
<ItemGroup>
<Resource Include="icon.res" />
<Resource Include="menu.res" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,621 +0,0 @@
#include <windows.h>
#include <commctrl.h>
#include <gl/gl.h>
#include <gl/glu.h>
//#include <gl/glut.h>
#include <ctime>
#include <cmath>
#include <sstream>
#include <fstream>
#include <iomanip>
#include "../clipper.hpp"
using namespace std;
using namespace ClipperLib;
enum poly_color_type { pctSubject, pctClip, pctSolution };
//global vars ...
HWND hWnd;
HWND hStatus;
HDC hDC;
HGLRC hRC;
ClipType ct = ctIntersection;
PolyFillType pft = pftEvenOdd;
JoinType jt = jtRound;
bool show_clipping = true;
Paths sub, clp, sol;
int VertCount = 5;
int scale = 10;
double delta = 0.0;
const LPCWSTR helpText =
L"Clipper Demo tips...\n\n"
L"I - for Intersection operations.\n"
L"U - for Union operations.\n"
L"D - for Difference operations.\n"
L"X - for XOR operations.\n"
L"------------------------------\n"
L"Q - Toggle clipping on/off.\n"
L"------------------------------\n"
L"E - for EvenOdd fills.\n"
L"Z - for NonZero fills.\n"
L"P - for Positive fills.\n"
L"N - for Negative fills.\n"
L"------------------------------\n"
L"nn<ENTER> - number of vertices (3..50).\n"
L"------------------------------\n"
L"UP arrow - Expand Solution.\n"
L"DN arrow - Contract Solution.\n"
L"LT or RT arrow - Reset Solution.\n"
L"------------------------------\n"
L"M - Miter OffsetPolygons.\n"
L"S - Square OffsetPolygons.\n"
L"R - Round OffsetPolygons.\n"
L"------------------------------\n"
L"SPACE, ENTER or click to refresh.\n"
L"F1 - to see this help dialog again.\n"
L"Esc - to quit.\n";
typedef std::vector< GLdouble* > Vectors;
Vectors vectors;
//------------------------------------------------------------------------------
// heap memory management for GLUtesselator ...
//------------------------------------------------------------------------------
GLdouble* NewVector(GLdouble x, GLdouble y)
{
GLdouble *vert = new GLdouble[3];
vert[0] = x;
vert[1] = y;
vert[2] = 0;
vectors.push_back(vert);
return vert;
}
//------------------------------------------------------------------------------
void ClearVectors()
{
for (Vectors::size_type i = 0; i < vectors.size(); ++i)
delete[] vectors[i];
vectors.clear();
}
//------------------------------------------------------------------------------
// GLUtesselator callback functions ...
//------------------------------------------------------------------------------
void CALLBACK BeginCallback(GLenum type)
{
glBegin(type);
}
//------------------------------------------------------------------------------
void CALLBACK EndCallback()
{
glEnd();
}
//------------------------------------------------------------------------------
void CALLBACK VertexCallback(GLvoid *vertex)
{
glVertex3dv( (const double *)vertex );
}
//------------------------------------------------------------------------------
void CALLBACK CombineCallback(GLdouble coords[3],
GLdouble*[4], GLfloat[4], GLdouble **dataOut )
{
GLdouble *vert = NewVector(coords[0], coords[1]);
*dataOut = vert;
}
//------------------------------------------------------------------------------
wstring str2wstr(const std::string &s) {
int slength = (int)s.length() + 1;
int len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
//------------------------------------------------------------------------------
void CALLBACK ErrorCallback(GLenum errorCode)
{
std::wstring s = str2wstr( (char *)gluErrorString(errorCode) );
SetWindowText(hWnd, s.c_str());
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Set up pixel format for graphics initialization
void SetupPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory( &pfd, sizeof(pfd));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
int pfIdx = ChoosePixelFormat(hDC, &pfd);
if (pfIdx != 0) SetPixelFormat(hDC, pfIdx, &pfd);
}
//------------------------------------------------------------------------------
// Initialize OpenGL graphics
void InitGraphics()
{
hDC = GetDC(hWnd);
SetupPixelFormat();
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTranslatef (0.375, 0.375, 0);
}
//------------------------------------------------------------------------------
void MakeRandomPoly(Path &p, int width, int height, int edgeCount)
{
p.resize(edgeCount);
for (int i = 0; i < edgeCount; i++)
{
p[i].X = (rand()%(width -20) +10)*scale;
p[i].Y = (rand()%(height -20) +10)*scale;
}
}
//------------------------------------------------------------------------------
void ResizeGraphics(int width, int height)
{
//setup 2D projection with origin at top-left corner ...
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);
glViewport(0, 0, width, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//------------------------------------------------------------------------------
void DrawPolygon(Paths &pgs, poly_color_type pct)
{
switch (pct)
{
case pctSubject: glColor4f(0.0f, 0.0f, 1.0f, 0.062f); break;
case pctClip: glColor4f(1.0f, 1.0f, 0.0f, 0.062f); break;
default: glColor4f(0.0f, 1.0f, 0.0f, 0.25f);
}
GLUtesselator* tess = gluNewTess();
gluTessCallback(tess, GLU_TESS_BEGIN, (void (CALLBACK*)())&BeginCallback);
gluTessCallback(tess, GLU_TESS_VERTEX, (void (CALLBACK*)())&VertexCallback);
gluTessCallback(tess, GLU_TESS_END, (void (CALLBACK*)())&EndCallback);
gluTessCallback(tess, GLU_TESS_COMBINE, (void (CALLBACK*)())&CombineCallback);
gluTessCallback(tess, GLU_TESS_ERROR, (void (CALLBACK*)())&ErrorCallback);
gluTessNormal(tess, 0.0, 0.0, 1.0);
switch (pft)
{
case pftEvenOdd:
gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
break;
case pftNonZero:
gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
break;
case pftPositive:
gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE);
break;
default: //case pftNegative
if (pct == pctSolution)
gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
else
gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NEGATIVE);
}
gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); //GL_FALSE
gluTessBeginPolygon(tess, NULL);
for (Paths::size_type i = 0; i < pgs.size(); ++i)
{
gluTessBeginContour(tess);
for (Path::size_type j = 0; j < pgs[i].size(); ++j)
{
GLdouble *vert =
NewVector((GLdouble)pgs[i][j].X/scale, (GLdouble)pgs[i][j].Y/scale);
gluTessVertex(tess, vert, vert);
}
gluTessEndContour(tess);
}
gluTessEndPolygon(tess);
ClearVectors();
switch (pct)
{
case pctSubject:
glColor4f(0.0f, 0.6f, 1.0f, 0.5f);
break;
case pctClip:
glColor4f(1.0f, 0.6f, 0.0f, 0.5f);
break;
default:
glColor4f(0.0f, 0.4f, 0.0f, 1.0f);
}
if (pct == pctSolution) glLineWidth(1.0f); else glLineWidth(0.8f);
gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE);
for (Paths::size_type i = 0; i < pgs.size(); ++i)
{
gluTessBeginPolygon(tess, NULL);
gluTessBeginContour(tess);
for (Path::size_type j = 0; j < pgs[i].size(); ++j)
{
GLdouble *vert =
NewVector((GLdouble)pgs[i][j].X/scale, (GLdouble)pgs[i][j].Y/scale);
gluTessVertex(tess, vert, vert);
}
switch (pct)
{
case pctSubject:
glColor4f(0.0f, 0.0f, 0.8f, 0.5f);
break;
case pctClip:
glColor4f(0.6f, 0.0f, 0.0f, 0.5f);
}
gluTessEndContour(tess);
gluTessEndPolygon(tess);
}
//final cleanup ...
gluDeleteTess(tess);
ClearVectors();
}
//------------------------------------------------------------------------------
void DrawGraphics()
{
//this can take a few moments ...
HCURSOR hWaitCursor = LoadCursor(NULL, IDC_WAIT);
SetCursor(hWaitCursor);
SetClassLong(hWnd, GCL_HCURSOR, (DWORD)hWaitCursor);
//fill background with a light off-gray color ...
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);
//glRasterPos2f(110, 340);
//glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
//char * text = "Positive Fills";
//for (int i = 0; i < strlen(text); ++i)
// glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, text[i]);
DrawPolygon(sub, pctSubject);
DrawPolygon(clp, pctClip);
if (show_clipping)
DrawPolygon(sol, pctSolution);
wstringstream ss;
if (!show_clipping)
ss << L"Clipper Demo - NO CLIPPING";
else
switch (ct)
{
case ctUnion:
ss << L"Clipper Demo - UNION";
break;
case ctDifference:
ss << L"Clipper Demo - DIFFERENCE";
break;
case ctXor:
ss << L"Clipper Demo - XOR";
break;
default:
ss << L"Clipper Demo - INTERSECTION";
}
switch(pft)
{
case pftEvenOdd:
ss << L" (EvenOdd filled polygons with ";
break;
case pftNonZero:
ss << L" (NonZero filled polygons with ";
break;
case pftPositive:
ss << L" (Positive filled polygons with ";
break;
default:
ss << L" (Negative filled polygons with ";
}
ss << VertCount << " vertices each.)";
SetWindowText(hWnd, ss.str().c_str());
HCURSOR hArrowCursor = LoadCursor(NULL, IDC_ARROW);
SetCursor(hArrowCursor);
SetClassLong(hWnd, GCL_HCURSOR, (DWORD)hArrowCursor);
}
//------------------------------------------------------------------------------
inline long64 Round(double val)
{
if ((val < 0)) return (long64)(val - 0.5); else return (long64)(val + 0.5);
}
//------------------------------------------------------------------------------
//bool LoadFromFile(Polygons &ppg, char * filename, double scale= 1,
// int xOffset = 0, int yOffset = 0)
//{
// ppg.clear();
// ifstream infile(filename);
// if (!infile.is_open()) return false;
// int polyCnt, vertCnt;
// double X, Y;
//
// infile >> polyCnt;
// infile.ignore(80, '\n');
// if (infile.good() && polyCnt > 0)
// {
// ppg.resize(polyCnt);
// for (int i = 0; i < polyCnt; i++)
// {
// infile >> vertCnt;
// infile.ignore(80, '\n');
// if (!infile.good() || vertCnt < 0) break;
// ppg[i].resize(vertCnt);
// for (int j = 0; infile.good() && j < vertCnt; j++)
// {
// infile >> X;
// while (infile.peek() == ' ') infile.ignore();
// if (infile.peek() == ',') infile.ignore();
// while (infile.peek() == ' ') infile.ignore();
// infile >> Y;
// ppg[i][j].X = Round((X + xOffset) * scale);
// ppg[i][j].Y = Round((Y + yOffset) * scale);
// infile.ignore(80, '\n');
// }
// }
// }
// infile.close();
// return true;
//}
//------------------------------------------------------------------------------
void SaveToFile(const char *filename, Paths &pp, double scale = 1)
{
ofstream of(filename);
if (!of.is_open()) return;
of << pp.size() << "\n";
for (Paths::size_type i = 0; i < pp.size(); ++i)
{
of << pp[i].size() << "\n";
if (scale > 1.01 || scale < 0.99)
of << fixed << setprecision(6);
for (Path::size_type j = 0; j < pp[i].size(); ++j)
of << (double)pp[i][j].X /scale << ", " << (double)pp[i][j].Y /scale << ",\n";
}
of.close();
}
//---------------------------------------------------------------------------
void UpdatePolygons(bool updateSolutionOnly)
{
if (VertCount < 0) VertCount = -VertCount;
if (VertCount > 50) VertCount = 50;
if (VertCount < 3) VertCount = 3;
Clipper c;
if (!updateSolutionOnly)
{
delta = 0.0;
RECT r;
GetWindowRect(hStatus, &r);
int statusHeight = r.bottom - r.top;
GetClientRect(hWnd, &r);
sub.resize(1);
clp.resize(1);
MakeRandomPoly(sub[0], r.right, r.bottom - statusHeight, VertCount);
MakeRandomPoly(clp[0], r.right, r.bottom - statusHeight, VertCount);
//SaveToFile("subj.txt", sub);
//SaveToFile("clip.txt", clp);
}
c.AddPaths(sub, ptSubject, true);
c.AddPaths(clp, ptClip, true);
c.Execute(ct, sol, pft, pft);
SaveToFile("solution.txt", sol);
if (delta != 0.0)
{
ClipperOffset co;
co.AddPaths(sol, jt, etClosedPolygon);
co.Execute(sol, delta);
}
InvalidateRect(hWnd, NULL, false);
}
//------------------------------------------------------------------------------
void DoNumericKeyPress(int num)
{
if (VertCount >= 0) VertCount = -num;
else if (VertCount > -10) VertCount = VertCount*10 - num;
else Beep(1000, 100);
}
//------------------------------------------------------------------------------
LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int clientwidth, clientheight;
switch (uMsg)
{
case WM_SIZE:
clientwidth = LOWORD(lParam);
clientheight = HIWORD(lParam);
ResizeGraphics(clientwidth, clientheight);
SetWindowPos(hStatus, NULL, 0,
clientheight, clientwidth, 0, SWP_NOACTIVATE | SWP_NOZORDER);
return 0;
case WM_PAINT:
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
//do the drawing ...
DrawGraphics();
SwapBuffers(hdc);
EndPaint(hWnd, &ps);
return 0;
case WM_CLOSE:
DestroyWindow(hWnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_HELP:
MessageBox(hWnd, helpText, L"Clipper Demo - Help", 0);
return 0;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case 1: case 27: PostQuitMessage(0); break; //escape
case 98: MessageBox(hWnd, helpText, L"Clipper Demo - Help", 0); break;
case 99: MessageBox(hWnd, L"After closing this dialog,\ntype the required number of vertices (3-50) then <Enter> ...", L"Clipper Demo", 0);
case 101: show_clipping = true; ct = ctIntersection; UpdatePolygons(true); break;
case 102: show_clipping = true; ct = ctUnion; UpdatePolygons(true); break;
case 103: show_clipping = true; ct = ctDifference; UpdatePolygons(true); break;
case 104: show_clipping = true; ct = ctXor; UpdatePolygons(true); break;
case 105: pft = pftEvenOdd; UpdatePolygons(true); break;
case 106: pft = pftNonZero; UpdatePolygons(true); break;
case 107: pft = pftPositive; UpdatePolygons(true); break;
case 108: pft = pftNegative; UpdatePolygons(true); break;
case 109: show_clipping = !show_clipping; UpdatePolygons(true); break;
case 110: case 111: case 112: case 113: case 114:
case 115: case 116: case 117: case 118: case 119:
DoNumericKeyPress(LOWORD(wParam) - 110);
break;
case 120: UpdatePolygons(false); break; //space, return
case 131: if (delta < 20*scale) {delta += scale; UpdatePolygons(true);} break;
case 132: if (delta > -20*scale) {delta -= scale; UpdatePolygons(true);} break;
case 133: if (delta != 0.0) {delta = 0.0; UpdatePolygons(true);} break;
case 141: {jt = jtMiter; if (delta != 0.0) UpdatePolygons(true);} break;
case 142: {jt = jtSquare; if (delta != 0.0) UpdatePolygons(true);} break;
case 143: {jt = jtRound; if (delta != 0.0) UpdatePolygons(true);} break;
default: return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
return 0;
case WM_LBUTTONUP:
UpdatePolygons(false);
return 0;
// Default event handler
default: return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
}
//------------------------------------------------------------------------------
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE, LPSTR, int nCmdShow)
{
const LPCWSTR appname = TEXT("Clipper Demo");
WNDCLASS wndclass;
MSG msg;
// Define the window class
wndclass.style = 0;
wndclass.lpfnWndProc = (WNDPROC)MainWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, appname);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wndclass.lpszMenuName = appname;
wndclass.lpszClassName = appname;
// Register the window class
if (!RegisterClass(&wndclass)) return FALSE;
HMENU menu = LoadMenu(hInstance, MAKEINTRESOURCE(1));
HACCEL accel = LoadAccelerators(hInstance, MAKEINTRESOURCE(1));
int windowSizeX = 540, windowSizeY = 400;
int dx = GetSystemMetrics(SM_XVIRTUALSCREEN);
int dy = GetSystemMetrics(SM_YVIRTUALSCREEN);
dx += ((GetSystemMetrics(SM_CXSCREEN) -windowSizeX) /2);
dy += ((GetSystemMetrics(SM_CYSCREEN) -windowSizeY) /2);
// Create the window
hWnd = CreateWindow(
appname,
appname,
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
dx, dy, windowSizeX, windowSizeY,
NULL,
menu,
hInstance,
NULL);
if (!hWnd) return FALSE;
//replace the main window icon with Resource Icon #1 ...
HANDLE small_ico = LoadImage(hInstance, MAKEINTRESOURCE(1), IMAGE_ICON, 16, 16, 0);
HANDLE big_ico = LoadImage(hInstance, MAKEINTRESOURCE(1), IMAGE_ICON, 32, 32, 0);
SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)small_ico);
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)big_ico);
InitCommonControls();
hStatus = CreateWindowEx(0, L"msctls_statusbar32", NULL, WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, hWnd, (HMENU)0, hInstance, NULL);
SetWindowText(hStatus, L" Copyright © Angus Johnson 2011");
// Initialize OpenGL
InitGraphics();
srand((unsigned)time(0));
UpdatePolygons(false);
// Display the window
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Event loop
for (;;)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE)
{
if (!GetMessage(&msg, NULL, 0, 0)) break;
if (!TranslateAccelerator(hWnd, accel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
ReleaseDC(hWnd, hDC);
return TRUE;
}
//------------------------------------------------------------------------------

View File

@ -1,13 +0,0 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@CMAKE_INSTALL_LIBDIR@
sharedlibdir=@CMAKE_INSTALL_LIBDIR@
includedir=@CMAKE_INSTALL_INCDIR@
Name: polyclipping
Description: polygon clipping library
Version: @VERSION@
Requires:
Libs: -L${libdir} -L${sharedlibdir} -lpolyclipping
Cflags: -I${includedir}