Skip to content

Commit

Permalink
fixed fill2d for complex profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
arnholm committed Sep 6, 2017
1 parent 230157c commit 164a0cb
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 12 deletions.
16 changes: 9 additions & 7 deletions xcsg/clipper_csg/clipper_profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ void clipper_profile::AddPaths(std::shared_ptr<ClipperLib::Paths> paths)
}
}

void clipper_profile::AddPath(const ClipperLib::Path& path)
{
m_paths.push_back(path);
}

std::shared_ptr<polyset2d> clipper_profile::polyset()
{
std::shared_ptr<polyset2d> pset(new polyset2d());
Expand All @@ -53,17 +58,14 @@ std::shared_ptr<polyset2d> clipper_profile::polyset()
return pset;
}


void clipper_profile::fill_holes()
void clipper_profile::positive_profiles(std::list<std::shared_ptr<clipper_profile>>& profiles )
{
// to fill the holes, we simply discard the negative paths
ClipperLib::Paths filled_paths;
filled_paths.reserve(m_paths.size());
for(size_t i=0; i<m_paths.size(); i++) {
bool positive = Orientation(m_paths[i]);
if(positive) {
filled_paths.push_back(m_paths[i]);
std::shared_ptr<clipper_profile> prof = std::make_shared<clipper_profile>();
prof->AddPath(m_paths[i]);
profiles.push_back(prof);
}
}
m_paths = filled_paths;
}
9 changes: 7 additions & 2 deletions xcsg/clipper_csg/clipper_profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "clipper_csg_config.h"
#include "clipper.hpp"
#include "polyset2d.h"
#include <list>

// A clipper_profile represents the result of successive 2d booleans
// It can represent any complex 2d profile, possibly multiple polygons with holes.
Expand All @@ -37,8 +38,12 @@ class clipper_profile {
// return a set of polygons for this profile
std::shared_ptr<polyset2d> polyset();

// fill holes in this profile
void fill_holes();
// split this profile into a number of single contour profiles containing only positive winding order paths
// negative winding order paths are discareded
void positive_profiles(std::list<std::shared_ptr<clipper_profile>>& profiles );

protected:
void AddPath( const ClipperLib::Path& path);

private:
ClipperLib::Paths m_paths;
Expand Down
2 changes: 1 addition & 1 deletion xcsg/xcsg_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ xcsg_factory::xcsg_factory()
m_shape2d_map.insert(std::make_pair("intersection2d",xcsg_factory::make_intersection2d));
m_shape2d_map.insert(std::make_pair("union2d",xcsg_factory::make_union2d));
m_shape2d_map.insert(std::make_pair("hull2d",xcsg_factory::make_hull2d));
m_shape2d_map.insert(std::make_pair("fill2d",xcsg_factory::make_hull2d));
m_shape2d_map.insert(std::make_pair("fill2d",xcsg_factory::make_fill2d));
m_shape2d_map.insert(std::make_pair("offset2d",xcsg_factory::make_offset2d));
}

Expand Down
12 changes: 10 additions & 2 deletions xcsg/xfill2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,16 @@ std::shared_ptr<clipper_profile> xfill2d ::create_clipper_profile(const carve::m
clipper_boolean csg;
for(auto i=m_incl.begin(); i!=m_incl.end(); i++) {
std::shared_ptr<clipper_profile> profile = (*i)->create_clipper_profile(t*get_transform());
profile->fill_holes();
csg.compute(profile,ClipperLib::ctUnion);

// split the profile into single path profiles with only positive winding order
std::list<std::shared_ptr<clipper_profile>> profiles;
profile->positive_profiles(profiles);

// union the profiles to obtain a single profile again
// the effect is that all holes dissapear, but outer contours remain
for(auto& p : profiles) {
csg.compute(p,ClipperLib::ctUnion);
}
}
return csg.profile();
}
Expand Down

0 comments on commit 164a0cb

Please sign in to comment.