本文整理汇总了C++中Polygons类的典型用法代码示例。如果您正苦于以下问题:C++ Polygons类的具体用法?C++ Polygons怎么用?C++ Polygons使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Polygons类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: polygons_append
inline void polygons_append(Polygons &dst, const ExPolygon &src)
{
dst.reserve(dst.size() + src.holes.size() + 1);
dst.push_back(src.contour);
dst.insert(dst.end(), src.holes.begin(), src.holes.end());
}
示例2: loadCOCO
list loadCOCO( const std::string & name, int fold ) {
using namespace rapidjson;
// Load the annotations
char buf[1024];
sprintf( buf, COCO_ANNOT.c_str(), name.c_str() );
// Read the json file
Document doc;
std::ifstream t(buf);
std::string json_str = std::string(std::istreambuf_iterator<char>(t),std::istreambuf_iterator<char>());
doc.Parse( (char*)json_str.c_str() );
// Go through all instance labels
std::unordered_map< uint64_t, std::vector<int> > categories;
std::unordered_map< uint64_t, std::vector<float> > areas;
std::unordered_map< uint64_t, std::vector<Polygons> > segments;
const Value & instances = doc["instances"];
for ( Value::ConstValueIterator i = instances.Begin(); i != instances.End(); i++ ) {
// Get the image id
Value::ConstMemberIterator cmi_image_id = i->FindMember("image_id");
eassert( cmi_image_id != i->MemberEnd() );
const int image_id = cmi_image_id->value.GetInt();
// Get the category id
Value::ConstMemberIterator cmi_category_id = i->FindMember("category_id");
eassert( cmi_category_id != i->MemberEnd() );
const int category_id = cmi_category_id->value.GetInt();
// Get the category id
Value::ConstMemberIterator cmi_area = i->FindMember("area");
eassert( cmi_area != i->MemberEnd() );
const float area = cmi_area->value.GetDouble();
// Read the polygon
Value::ConstMemberIterator cmi_segmentation = i->FindMember("segmentation");
eassert( cmi_segmentation != i->MemberEnd() );
const Value & segmentations = cmi_segmentation->value;
// For now just use the first segmentation for each object
Polygons polygons;
for( Value::ConstValueIterator segmentation = segmentations.Begin(); segmentation!=segmentations.End(); segmentation++ ){
Polygon polygon = RMatrixXf( segmentation->Size() / 2, 2 );
float * ppolygon = polygon.data();
for ( Value::ConstValueIterator j = segmentation->Begin(); j != segmentation->End(); j++ )
*(ppolygon++) = j->GetDouble();
polygons.push_back( polygon );
}
if( !ONLY_CONNECTED || polygons.size() == 1 ) {
categories[ image_id ].push_back( category_id );
segments[ image_id ].push_back( polygons );
areas[ image_id ].push_back( area );
}
}
// Load all images
Value::ConstValueIterator B = doc["images"].Begin(), E = doc["images"].End();
const int N = E-B;
Value::ConstValueIterator i0 = B+(fold*N/N_FOLDS), i1 = B+((fold+1)*N/N_FOLDS);
std::vector< std::shared_ptr<Image8u> > images( i1 - i0 );
#pragma omp parallel for
for ( int k=0; k<i1-i0; k++ ) {
Value::ConstValueIterator i = i0+k;
// Get the file name and path
Value::ConstMemberIterator cmi_file_name = i->FindMember("file_name");
eassert( cmi_file_name != i->MemberEnd() );
const std::string file_name = cmi_file_name->value.GetString();
Value::ConstMemberIterator cmi_file_path = i->FindMember("file_path");
eassert( cmi_file_path != i->MemberEnd() );
const std::string file_path = cmi_file_path->value.GetString();
// Add the image entry
images[i-i0] = imreadShared( coco_dir+"/"+file_path+"/"+file_name );
}
// Create the python struct with the result
list r;
for ( Value::ConstValueIterator i = i0; i != i1; i++ ) {
// Get the image id
Value::ConstMemberIterator cmi_image_id = i->FindMember("id");
eassert( cmi_image_id != i->MemberEnd() );
const int image_id = cmi_image_id->value.GetInt();
// Add the image entry
const int N = categories[ image_id ].size();
if( N > 0 ){
dict entry;
entry["id"] = image_id;
entry["image"] = images[i - i0];
entry["categories"] = categories[ image_id ];
entry["areas"] = areas[ image_id ];
entry["segmentation"] = segments[ image_id ];
r.append( entry );
}
// else
// printf("Image '%d' doesn't have any annotations!\n", image_id );
}
return r;
}
示例3: DrawPolygon
void DrawPolygon(Polygons &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 (Polygons::size_type i = 0; i < pgs.size(); ++i)
{
gluTessBeginContour(tess);
for (ClipperLib::Polygon::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 (Polygons::size_type i = 0; i < pgs.size(); ++i)
{
gluTessBeginPolygon(tess, NULL);
gluTessBeginContour(tess);
for (ClipperLib::Polygon::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();
}
示例4: getFirstLayerOutline
void SkirtBrim::getFirstLayerOutline(SliceDataStorage& storage, const size_t primary_line_count, const bool is_skirt, Polygons& first_layer_outline)
{
const ExtruderTrain& train = Application::getInstance().current_slice->scene.current_mesh_group->settings.get<ExtruderTrain&>("adhesion_extruder_nr");
const ExtruderTrain& support_infill_extruder = Application::getInstance().current_slice->scene.current_mesh_group->settings.get<ExtruderTrain&>("support_infill_extruder_nr");
const bool external_only = is_skirt || train.settings.get<bool>("brim_outside_only"); //Whether to include holes or not. Skirt doesn't have any holes.
const LayerIndex layer_nr = 0;
if (is_skirt)
{
constexpr bool include_support = true;
constexpr bool include_prime_tower = true;
first_layer_outline = storage.getLayerOutlines(layer_nr, include_support, include_prime_tower, external_only);
first_layer_outline = first_layer_outline.approxConvexHull();
}
else
{ // add brim underneath support by removing support where there's brim around the model
constexpr bool include_support = false; //Include manually below.
constexpr bool include_prime_tower = false; //Include manually below.
constexpr bool external_outlines_only = false; //Remove manually below.
first_layer_outline = storage.getLayerOutlines(layer_nr, include_support, include_prime_tower, external_outlines_only);
first_layer_outline = first_layer_outline.unionPolygons(); //To guard against overlapping outlines, which would produce holes according to the even-odd rule.
Polygons first_layer_empty_holes;
if (external_only)
{
first_layer_empty_holes = first_layer_outline.getEmptyHoles();
first_layer_outline = first_layer_outline.removeEmptyHoles();
}
if (storage.support.generated && primary_line_count > 0 && !storage.support.supportLayers.empty())
{ // remove model-brim from support
SupportLayer& support_layer = storage.support.supportLayers[0];
if (support_infill_extruder.settings.get<bool>("brim_replaces_support"))
{
// avoid gap in the middle
// V
// +---+ +----+
// |+-+| |+--+|
// || || ||[]|| > expand to fit an extra brim line
// |+-+| |+--+|
// +---+ +----+
const coord_t primary_extruder_skirt_brim_line_width = train.settings.get<coord_t>("skirt_brim_line_width") * train.settings.get<Ratio>("initial_layer_line_width_factor");
Polygons model_brim_covered_area = first_layer_outline.offset(primary_extruder_skirt_brim_line_width * (primary_line_count + primary_line_count % 2), ClipperLib::jtRound); // always leave a gap of an even number of brim lines, so that it fits if it's generating brim from both sides
if (external_only)
{ // don't remove support within empty holes where no brim is generated.
model_brim_covered_area.add(first_layer_empty_holes);
}
AABB model_brim_covered_area_boundary_box(model_brim_covered_area);
support_layer.excludeAreasFromSupportInfillAreas(model_brim_covered_area, model_brim_covered_area_boundary_box);
}
for (const SupportInfillPart& support_infill_part : support_layer.support_infill_parts)
{
first_layer_outline.add(support_infill_part.outline);
}
first_layer_outline.add(support_layer.support_bottom);
first_layer_outline.add(support_layer.support_roof);
}
if (storage.primeTower.enabled)
{
first_layer_outline.add(storage.primeTower.outer_poly_first_layer); // don't remove parts of the prime tower, but make a brim for it
}
}
constexpr coord_t join_distance = 20;
first_layer_outline = first_layer_outline.offset(join_distance).offset(-join_distance); // merge adjacent models into single polygon
constexpr coord_t smallest_line_length = 200;
constexpr coord_t largest_error_of_removed_point = 50;
first_layer_outline.simplify(smallest_line_length, largest_error_of_removed_point); // simplify for faster processing of the brim lines
if (first_layer_outline.size() == 0)
{
logError("Couldn't generate skirt / brim! No polygons on first layer.\n");
}
}
示例5: moveInside
unsigned int moveInside(Polygons& polygons, Point& from, int distance, int64_t maxDist2)
{
Point ret = from;
int64_t bestDist2 = maxDist2;
unsigned int bestPoly = NO_INDEX;
for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++)
{
PolygonRef poly = polygons[poly_idx];
if (poly.size() < 2)
continue;
Point p0 = poly[poly.size()-2];
Point p1 = poly.back();
bool projected_p_beyond_prev_segment = dot(p1 - p0, from - p0) > vSize2(p1 - p0);
for(Point& p2 : poly)
{
// X = A + Normal( B - A ) * ((( B - A ) dot ( P - A )) / VSize( A - B ));
// X = P projected on AB
Point& a = p1;
Point& b = p2;
Point& p = from;
Point ab = b - a;
Point ap = p - a;
int64_t ab_length = vSize(ab);
int64_t ax_length = dot(ab, ap) / ab_length;
if (ax_length < 0) // x is projected to before ab
{
if (projected_p_beyond_prev_segment)
{ // case which looks like: > .
projected_p_beyond_prev_segment = false;
Point& x = p1;
int64_t dist2 = vSize2(x - p);
if (dist2 < bestDist2)
{
bestDist2 = dist2;
if (distance == 0) { ret = x; }
else { ret = x + normal(crossZ(normal(a, distance*4) + normal(p1 - p0, distance*4)), distance); } // *4 to retain more precision for the eventual normalization
bestPoly = poly_idx;
}
}
else
{
projected_p_beyond_prev_segment = false;
p0 = p1;
p1 = p2;
continue;
}
}
else if (ax_length > ab_length) // x is projected to beyond ab
{
projected_p_beyond_prev_segment = true;
p0 = p1;
p1 = p2;
continue;
}
else
{
projected_p_beyond_prev_segment = false;
Point x = a + ab * ax_length / ab_length;
int64_t dist2 = vSize2(x - from);
if (dist2 < bestDist2)
{
bestDist2 = dist2;
if (distance == 0) { ret = x; }
else { ret = x + crossZ(normal(ab, distance)); }
bestPoly = poly_idx;
}
}
p0 = p1;
p1 = p2;
}
}
if (bestDist2 < maxDist2)
{
from = ret;
return bestPoly;
}
return NO_INDEX;
}
示例6:
void
SVG::draw(const Polygons &polygons, std::string fill)
{
for (Polygons::const_iterator it = polygons.begin(); it != polygons.end(); ++it)
this->draw(*it, fill);
}
示例7: logWarning
void Weaver::weave(MeshGroup* meshgroup)
{
wireFrame.meshgroup = meshgroup;
int maxz = meshgroup->max().z;
int layer_count = (maxz - initial_layer_thickness) / connectionHeight + 1;
std::vector<AdaptiveLayer> layer_thicknesses;
std::cerr << "Layer count: " << layer_count << "\n";
std::vector<cura::Slicer*> slicerList;
for(Mesh& mesh : meshgroup->meshes)
{
cura::Slicer* slicer = new cura::Slicer(&mesh, initial_layer_thickness, connectionHeight, layer_count,
mesh.getSettingBoolean("meshfix_keep_open_polygons"),
mesh.getSettingBoolean("meshfix_extensive_stitching"),
false, &layer_thicknesses);
slicerList.push_back(slicer);
}
int starting_layer_idx;
{ // find first non-empty layer
for (starting_layer_idx = 0; starting_layer_idx < layer_count; starting_layer_idx++)
{
Polygons parts;
for (cura::Slicer* slicer : slicerList)
parts.add(slicer->layers[starting_layer_idx].polygons);
if (parts.size() > 0)
break;
}
if (starting_layer_idx > 0)
{
logWarning("First %i layers are empty!\n", starting_layer_idx);
}
}
std::cerr<< "chainifying layers..." << std::endl;
{
int starting_z = -1;
for (cura::Slicer* slicer : slicerList)
wireFrame.bottom_outline.add(slicer->layers[starting_layer_idx].polygons);
CommandSocket::sendPolygons(PrintFeatureType::OuterWall, /*0,*/ wireFrame.bottom_outline, 1, 1, 1);
if (slicerList.empty()) //Wait, there is nothing to slice.
{
wireFrame.z_bottom = 0;
}
else
{
wireFrame.z_bottom = slicerList[0]->layers[starting_layer_idx].z;
}
Point starting_point_in_layer;
if (wireFrame.bottom_outline.size() > 0)
starting_point_in_layer = (wireFrame.bottom_outline.max() + wireFrame.bottom_outline.min()) / 2;
else
starting_point_in_layer = (Point(0,0) + meshgroup->max() + meshgroup->min()) / 2;
Progress::messageProgressStage(Progress::Stage::INSET_SKIN, nullptr);
for (int layer_idx = starting_layer_idx + 1; layer_idx < layer_count; layer_idx++)
{
Progress::messageProgress(Progress::Stage::INSET_SKIN, layer_idx+1, layer_count); // abuse the progress system of the normal mode of CuraEngine
Polygons parts1;
for (cura::Slicer* slicer : slicerList)
parts1.add(slicer->layers[layer_idx].polygons);
Polygons chainified;
chainify_polygons(parts1, starting_point_in_layer, chainified);
CommandSocket::sendPolygons(PrintFeatureType::OuterWall, /*layer_idx - starting_layer_idx,*/ chainified, 1, 1, 1);
if (chainified.size() > 0)
{
if (starting_z == -1) starting_z = slicerList[0]->layers[layer_idx-1].z;
wireFrame.layers.emplace_back();
WeaveLayer& layer = wireFrame.layers.back();
layer.z0 = slicerList[0]->layers[layer_idx-1].z - starting_z;
layer.z1 = slicerList[0]->layers[layer_idx].z - starting_z;
layer.supported = chainified;
starting_point_in_layer = layer.supported.back().back();
}
}
}
std::cerr<< "finding horizontal parts..." << std::endl;
{
Progress::messageProgressStage(Progress::Stage::SUPPORT, nullptr);
for (unsigned int layer_idx = 0; layer_idx < wireFrame.layers.size(); layer_idx++)
{
//.........这里部分代码省略.........
示例8: fillRoofs
void Weaver::fillRoofs(Polygons& supporting, Polygons& to_be_supported, int direction, int z, WeaveRoof& horizontals)
{
std::vector<WeaveRoofPart>& insets = horizontals.roof_insets;
if (supporting.size() == 0) return; // no parts to start the roof from!
Polygons roofs = supporting.difference(to_be_supported);
roofs = roofs.offset(-roof_inset).offset(roof_inset);
if (roofs.size() == 0) return;
Polygons roof_outlines;
Polygons roof_holes;
{ // split roofs into outlines and holes
std::vector<PolygonsPart> roof_parts = roofs.splitIntoParts();
for (PolygonsPart& roof_part : roof_parts)
{
roof_outlines.add(roof_part[0]);
for (unsigned int hole_idx = 1; hole_idx < roof_part.size(); hole_idx++)
{
roof_holes.add(roof_part[hole_idx]);
roof_holes.back().reverse();
}
}
}
Polygons supporting_outlines;
std::vector<PolygonsPart> supporting_parts = supporting.splitIntoParts();
for (PolygonsPart& supporting_part : supporting_parts)
supporting_outlines.add(supporting_part[0]); // only add outlines, not the holes
Polygons inset1;
Polygons last_inset;
Polygons last_supported = supporting;
for (Polygons inset0 = supporting_outlines; inset0.size() > 0; inset0 = last_inset)
{
last_inset = inset0.offset(direction * roof_inset, ClipperLib::jtRound);
inset1 = last_inset.intersection(roof_outlines); // stay within roof area
inset1 = inset1.unionPolygons(roof_holes);// make insets go around holes
if (inset1.size() == 0) break;
insets.emplace_back();
connect(last_supported, z, inset1, z, insets.back(), true);
inset1 = inset1.remove(roof_holes); // throw away holes which appear in every intersection
inset1 = inset1.remove(roof_outlines);// throw away fully filled regions
last_supported = insets.back().supported; // chainified
}
horizontals.roof_outlines.add(roofs); // TODO just add the new lines, not the lines of the roofs which are already supported ==> make outlines into a connection from which we only print the top, not the connection
}
示例9: generateSkirt
void generateSkirt(SliceDataStorage& storage, int distance, int extrusionWidth, int count, int minLength)
{
if (count == 0) return;
bool externalOnly = (distance > 0);
Polygons support;
if (storage.support.generated)
support = storage.support.supportLayers[0].supportAreas;
{ // get support polygons
for(SliceMeshStorage& mesh : storage.meshes)
{
if (mesh.layers.size() < 1) continue;
SliceLayer* layer = &mesh.layers[0];
for(unsigned int i=0; i<layer->parts.size(); i++)
support = support.difference(layer->parts[i].outline);
}
// expand and contract to smooth the final polygon
if (count == 1 && distance > 0)
{
int dist = extrusionWidth * 5;
support = support.offset(dist).offset(-dist);
}
}
int overshoot = 0; // distance by which to expand and contract the skirt to approximate the convex hull of the first layer
if (count == 1 && distance > 0)
{
overshoot = 100000; // 10 cm
}
for(int skirtNr=0; skirtNr<count;skirtNr++)
{
int offsetDistance = distance + extrusionWidth * skirtNr + extrusionWidth / 2 + overshoot;
Polygons skirtPolygons(storage.wipeTower.offset(offsetDistance));
for(SliceMeshStorage& mesh : storage.meshes)
{
if (mesh.layers.size() < 1) continue;
for(SliceLayerPart& part : mesh.layers[0].parts)
{
if (externalOnly)
{
Polygons p;
p.add(part.outline.outerPolygon());
skirtPolygons = skirtPolygons.unionPolygons(p.offset(offsetDistance, ClipperLib::jtRound));
}
else
{
skirtPolygons = skirtPolygons.unionPolygons(part.outline.offset(offsetDistance, ClipperLib::jtRound));
}
}
}
skirtPolygons = skirtPolygons.unionPolygons(support.offset(offsetDistance, ClipperLib::jtRound));
//Remove small inner skirt holes. Holes have a negative area, remove anything smaller then 100x extrusion "area"
for(unsigned int n=0; n<skirtPolygons.size(); n++)
{
double area = skirtPolygons[n].area();
if (area < 0 && area > -extrusionWidth * extrusionWidth * 100)
skirtPolygons.remove(n--);
}
storage.skirt.add(skirtPolygons);
int lenght = storage.skirt.polygonLength();
if (skirtNr + 1 >= count && lenght > 0 && lenght < minLength) // make brim have more lines when total length is too small
count++;
}
//Add a skirt under the wipetower to make it stick better.
Polygons wipe_tower = storage.wipeTower.offset(-extrusionWidth / 2);
while(wipe_tower.size() > 0)
{
storage.skirt.add(wipe_tower);
wipe_tower = wipe_tower.offset(-extrusionWidth);
}
if (overshoot > 0)
{
storage.skirt = storage.skirt.offset(-overshoot, ClipperLib::jtRound);
}
}
示例10: rand
void FffPolygonGenerator::processFuzzyWalls(SliceMeshStorage& mesh)
{
if (mesh.getSettingAsCount("wall_line_count") == 0)
{
return;
}
int64_t fuzziness = mesh.getSettingInMicrons("magic_fuzzy_skin_thickness");
int64_t avg_dist_between_points = mesh.getSettingInMicrons("magic_fuzzy_skin_point_dist");
int64_t min_dist_between_points = avg_dist_between_points * 3 / 4; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value
int64_t range_random_point_dist = avg_dist_between_points / 2;
for (unsigned int layer_nr = 0; layer_nr < mesh.layers.size(); layer_nr++)
{
SliceLayer& layer = mesh.layers[layer_nr];
for (SliceLayerPart& part : layer.parts)
{
Polygons results;
Polygons& skin = (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") == ESurfaceMode::SURFACE)? part.outline : part.insets[0];
for (PolygonRef poly : skin)
{
// generate points in between p0 and p1
PolygonRef result = results.newPoly();
int64_t dist_left_over = rand() % (min_dist_between_points / 2); // the distance to be traversed on the line before making the first new point
Point* p0 = &poly.back();
for (Point& p1 : poly)
{ // 'a' is the (next) new point between p0 and p1
Point p0p1 = p1 - *p0;
int64_t p0p1_size = vSize(p0p1);
int64_t dist_last_point = dist_left_over + p0p1_size * 2; // so that p0p1_size - dist_last_point evaulates to dist_left_over - p0p1_size
for (int64_t p0pa_dist = dist_left_over; p0pa_dist < p0p1_size; p0pa_dist += min_dist_between_points + rand() % range_random_point_dist)
{
int r = rand() % (fuzziness * 2) - fuzziness;
Point perp_to_p0p1 = crossZ(p0p1);
Point fuzz = normal(perp_to_p0p1, r);
Point pa = *p0 + normal(p0p1, p0pa_dist) + fuzz;
result.add(pa);
dist_last_point = p0pa_dist;
}
dist_left_over = p0p1_size - dist_last_point;
p0 = &p1;
}
while (result.size() < 3 )
{
unsigned int point_idx = poly.size() - 2;
result.add(poly[point_idx]);
if (point_idx == 0) { break; }
point_idx--;
}
if (result.size() < 3)
{
result.clear();
for (Point& p : poly)
result.add(p);
}
}
skin = results;
sendPolygons(Inset0Type, layer_nr, skin, mesh.getSettingInMicrons("wall_line_width_0"));
}
}
}
示例11: generateZigZagIninfill_noEndPieces
void generateZigZagIninfill_noEndPieces(const Polygons& in_outline, Polygons& result, int extrusionWidth, int lineSpacing, double infillOverlap, double rotation)
{
if (in_outline.size() == 0) return;
Polygons outline = in_outline.offset(extrusionWidth * infillOverlap / 100 - extrusionWidth / 2);
if (outline.size() == 0) return;
PointMatrix matrix(rotation);
outline.applyMatrix(matrix);
auto addLine = [&](Point from, Point to)
{
PolygonRef p = result.newPoly();
p.add(matrix.unapply(from));
p.add(matrix.unapply(to));
};
AABB boundary(outline);
int scanline_min_idx = boundary.min.X / lineSpacing;
int lineCount = (boundary.max.X + (lineSpacing - 1)) / lineSpacing - scanline_min_idx;
std::vector<std::vector<int64_t> > cutList; // mapping from scanline to all intersections with polygon segments
for(int n=0; n<lineCount; n++)
cutList.push_back(std::vector<int64_t>());
for(unsigned int polyNr=0; polyNr < outline.size(); polyNr++)
{
std::vector<Point> firstBoundarySegment;
std::vector<Point> boundarySegment;
bool isFirstBoundarySegment = true;
bool firstBoundarySegmentEndsInEven;
bool isEvenScanSegment = false;
Point p0 = outline[polyNr][outline[polyNr].size()-1];
for(unsigned int i=0; i < outline[polyNr].size(); i++)
{
Point p1 = outline[polyNr][i];
int64_t xMin = p1.X, xMax = p0.X;
if (xMin == xMax) {
p0 = p1;
continue;
}
if (xMin > xMax) { xMin = p0.X; xMax = p1.X; }
int scanline_idx0 = (p0.X + ((p0.X > 0)? -1 : -lineSpacing)) / lineSpacing; // -1 cause a linesegment on scanline x counts as belonging to scansegment x-1 ...
int scanline_idx1 = (p1.X + ((p1.X > 0)? -1 : -lineSpacing)) / lineSpacing; // -linespacing because a line between scanline -n and -n-1 belongs to scansegment -n-1 (for n=positive natural number)
int direction = 1;
if (p0.X > p1.X)
{
direction = -1;
scanline_idx1 += 1; // only consider the scanlines in between the scansegments
} else scanline_idx0 += 1; // only consider the scanlines in between the scansegments
if (isFirstBoundarySegment) firstBoundarySegment.push_back(p0);
else boundarySegment.push_back(p0);
for(int scanline_idx = scanline_idx0; scanline_idx != scanline_idx1+direction; scanline_idx+=direction)
{
int x = scanline_idx * lineSpacing;
int y = p1.Y + (p0.Y - p1.Y) * (x - p1.X) / (p0.X - p1.X);
cutList[scanline_idx - scanline_min_idx].push_back(y);
bool last_isEvenScanSegment = isEvenScanSegment;
if (scanline_idx % 2 == 0) isEvenScanSegment = true;
else isEvenScanSegment = false;
if (!isFirstBoundarySegment)
{
if (last_isEvenScanSegment && !isEvenScanSegment)
{ // add whole boundarySegment (including the just obtained point)
for (unsigned int p = 1; p < boundarySegment.size(); p++)
{
addLine(boundarySegment[p-1], boundarySegment[p]);
}
addLine(boundarySegment[boundarySegment.size()-1], Point(x,y));
boundarySegment.clear();
}
else if (isEvenScanSegment) // we are either in an end piece or an uneven boundary segment
{
boundarySegment.clear();
boundarySegment.emplace_back(x,y);
} else
boundarySegment.clear();
}
if (isFirstBoundarySegment)
{
firstBoundarySegment.emplace_back(x,y);
firstBoundarySegmentEndsInEven = isEvenScanSegment;
isFirstBoundarySegment = false;
boundarySegment.emplace_back(x,y);
}
}
//.........这里部分代码省略.........
示例12: generateZigZagIninfill_endPieces
/*!
* adapted from generateLineInfill(.)
*
* generate lines within the area of [in_outline], at regular intervals of [lineSpacing]
* idea:
* intersect a regular grid of 'scanlines' with the area inside [in_outline]
* sigzag:
* include pieces of boundary, connecting the lines, forming an accordion like zigzag instead of separate lines |_|^|_|
*
* we call the areas between two consecutive scanlines a 'scansegment'
*
* algorithm:
* 1. for each line segment of each polygon:
* store the intersections of that line segment with all scanlines in a mapping (vector of vectors) from scanline to intersections
* (zigzag): add boundary segments to result
* 2. for each scanline:
* sort the associated intersections
* and connect them using the even-odd rule
*
* zigzag algorithm:
* while walking around (each) polygon (1.)
* if polygon intersects with even scanline
* start boundary segment (add each following segment to the [result])
* when polygon intersects with a scanline again
* stop boundary segment (stop adding segments to the [result])
* if polygon intersects with even scanline again (instead of odd)
* dont add the last line segment to the boundary (unless [connect_zigzags])
*
*
* <--
* ___
* | | |
* | | |
* | |___|
* -->
*
* ^ = even scanline
*
* start boundary from even scanline! :D
*
*
* _____
* | | | ,
* | | | |
* |_____| |__/
*
* ^ ^ ^ scanlines
* ^ disconnected end piece
*/
void generateZigZagIninfill_endPieces(const Polygons& in_outline, Polygons& result, int extrusionWidth, int lineSpacing, double infillOverlap, double rotation, bool connect_zigzags)
{
// if (in_outline.size() == 0) return;
// Polygons outline = in_outline.offset(extrusionWidth * infillOverlap / 100 - extrusionWidth / 2);
Polygons empty;
Polygons outline = in_outline.difference(empty); // copy
if (outline.size() == 0) return;
PointMatrix matrix(rotation);
outline.applyMatrix(matrix);
auto addLine = [&](Point from, Point to)
{
PolygonRef p = result.newPoly();
p.add(matrix.unapply(from));
p.add(matrix.unapply(to));
};
AABB boundary(outline);
int scanline_min_idx = boundary.min.X / lineSpacing;
int lineCount = (boundary.max.X + (lineSpacing - 1)) / lineSpacing - scanline_min_idx;
std::vector<std::vector<int64_t> > cutList; // mapping from scanline to all intersections with polygon segments
for(int n=0; n<lineCount; n++)
cutList.push_back(std::vector<int64_t>());
for(unsigned int polyNr=0; polyNr < outline.size(); polyNr++)
{
std::vector<Point> firstBoundarySegment;
std::vector<Point> unevenBoundarySegment; // stored cause for connected_zigzags a boundary segment which ends in an uneven scanline needs to be included
bool isFirstBoundarySegment = true;
bool firstBoundarySegmentEndsInEven;
bool isEvenScanSegment = false;
Point p0 = outline[polyNr][outline[polyNr].size()-1];
Point lastPoint = p0;
for(unsigned int i=0; i < outline[polyNr].size(); i++)
{
Point p1 = outline[polyNr][i];
int64_t xMin = p1.X, xMax = p0.X;
if (xMin == xMax) {
lastPoint = p1;
p0 = p1;
continue;
}
if (xMin > xMax) { xMin = p0.X; xMax = p1.X; }
//.........这里部分代码省略.........
示例13: generateSkinAreas
void generateSkinAreas(int layer_nr, SliceMeshStorage& storage, int innermost_wall_extrusion_width, int downSkinCount, int upSkinCount, int wall_line_count, bool no_small_gaps_heuristic)
{
SliceLayer& layer = storage.layers[layer_nr];
if (downSkinCount == 0 && upSkinCount == 0)
{
return;
}
for(unsigned int partNr = 0; partNr < layer.parts.size(); partNr++)
{
SliceLayerPart& part = layer.parts[partNr];
if (int(part.insets.size()) < wall_line_count)
{
continue; // the last wall is not present, the part should only get inter preimeter gaps, but no skin.
}
Polygons upskin = part.insets.back().offset(-innermost_wall_extrusion_width/2);
Polygons downskin = (downSkinCount == 0)? Polygons() : upskin;
if (upSkinCount == 0) upskin = Polygons();
auto getInsidePolygons = [&part](SliceLayer& layer2)
{
Polygons result;
for(SliceLayerPart& part2 : layer2.parts)
{
if (part.boundaryBox.hit(part2.boundaryBox))
result.add(part2.insets.back());
}
return result;
};
if (no_small_gaps_heuristic)
{
if (static_cast<int>(layer_nr - downSkinCount) >= 0)
{
downskin = downskin.difference(getInsidePolygons(storage.layers[layer_nr - downSkinCount])); // skin overlaps with the walls
}
if (static_cast<int>(layer_nr + upSkinCount) < static_cast<int>(storage.layers.size()))
{
upskin = upskin.difference(getInsidePolygons(storage.layers[layer_nr + upSkinCount])); // skin overlaps with the walls
}
}
else
{
if (layer_nr > 0 && downSkinCount > 0)
{
Polygons not_air = getInsidePolygons(storage.layers[layer_nr - 1]);
for (int downskin_layer_nr = std::max(0, layer_nr - downSkinCount); downskin_layer_nr < layer_nr - 1; downskin_layer_nr++)
{
not_air = not_air.intersection(getInsidePolygons(storage.layers[downskin_layer_nr]));
}
downskin = downskin.difference(not_air); // skin overlaps with the walls
}
if (layer_nr < static_cast<int>(storage.layers.size()) - 1 && upSkinCount > 0)
{
Polygons not_air = getInsidePolygons(storage.layers[layer_nr + 1]);
for (int upskin_layer_nr = layer_nr + 2; upskin_layer_nr < std::min(static_cast<int>(storage.layers.size()) - 1, layer_nr + upSkinCount); upskin_layer_nr++)
{
not_air = not_air.intersection(getInsidePolygons(storage.layers[upskin_layer_nr]));
}
upskin = upskin.difference(not_air); // skin overlaps with the walls
}
}
Polygons skin = upskin.unionPolygons(downskin);
skin.removeSmallAreas(MIN_AREA_SIZE);
for (PolygonsPart& skin_area_part : skin.splitIntoParts())
{
part.skin_parts.emplace_back();
part.skin_parts.back().outline = skin_area_part;
}
}
}
示例14: clipPolygon
static AS3_Val clipPolygon(void* self, AS3_Val args) {
AS3_Val asSubjectVertices;
AS3_Val asClipVertices;
int subjectVerticeCount, clipVerticeCount, clipTypeArg, subjectFillTypeArg, clipFillTypeArg;
// Get the function arguments (subjectVertices:Array, subjectVerticeCount:int, extractVertices:Array,
// extractVerticeCount:int, clipType:int, subjectFillType:int, clipFillType:int)
AS3_ArrayValue(
args,
"AS3ValType, IntType, AS3ValType, IntType, IntType, IntType, IntType",
&asSubjectVertices, &subjectVerticeCount, &asClipVertices, &clipVerticeCount,
&clipTypeArg, &subjectFillTypeArg, &clipFillTypeArg
);
Polygon subjectPolygon(subjectVerticeCount / 2), clipPolygon(clipVerticeCount / 2);
Polygons solution;
// Populate the subject polygon
for (int i = 0; i < subjectVerticeCount; i += 2) {
subjectPolygon[i / 2] = IntPoint(
AS3_IntValue(AS3_Get( asSubjectVertices, AS3_Int(i) )),
AS3_IntValue(AS3_Get( asSubjectVertices, AS3_Int(i+1) ))
);
}
// Populate the clip polygon
for (int i = 0; i < clipVerticeCount; i += 2) {
clipPolygon[i / 2] = IntPoint(
AS3_IntValue(AS3_Get( asClipVertices, AS3_Int(i) )),
AS3_IntValue(AS3_Get( asClipVertices, AS3_Int(i+1) ))
);
}
// Create the AS3 return array
AS3_Val returnArray = AS3_Array("");
ClipType clipType;
switch (clipTypeArg) {
default:
case 0: clipType = ctIntersection; break;
case 1: clipType = ctUnion; break;
case 2: clipType = ctDifference; break;
case 3: clipType = ctXor; break;
}
PolyFillType subjectFillType, clipFillType;
switch (subjectFillTypeArg) {
default:
case 0: subjectFillType = pftEvenOdd; break;
case 1: subjectFillType = pftNonZero; break;
}
switch (clipFillTypeArg) {
default:
case 0: clipFillType = pftEvenOdd; break;
case 1: clipFillType = pftNonZero; break;
}
Clipper c;
c.AddPolygon(subjectPolygon, ptSubject);
c.AddPolygon(clipPolygon, ptClip);
if (c.Execute(clipType, solution, subjectFillType, clipFillType)) {
for (int i = 0; i < (int)solution.size(); i++) {
// Create a new AS3 array
AS3_Val verticeArray = AS3_Array("");
for (int j = 0; j < (int)solution[i].size(); j++) {
// Push all the vertices into the array
AS3_Set(verticeArray, AS3_Int(j * 2), AS3_Int(solution[i][j].X));
AS3_Set(verticeArray, AS3_Int(j * 2 + 1), AS3_Int(solution[i][j].Y));
}
// Insert the array into the returnArray
AS3_Set(returnArray, AS3_Int(i), verticeArray);
}
}
// Cleanup
AS3_Release(asSubjectVertices);
AS3_Release(asClipVertices);
return returnArray;
}
示例15: DEBUG_SHOW
void Weaver::weave(PrintObject* object, CommandSocket* commandSocket)
{
int maxz = object->max().z;
int layer_count = (maxz - initial_layer_thickness) / connectionHeight + 1;
DEBUG_SHOW(layer_count);
std::vector<cura::Slicer*> slicerList;
for(Mesh& mesh : object->meshes)
{
cura::Slicer* slicer = new cura::Slicer(&mesh, initial_layer_thickness, connectionHeight, layer_count, mesh.getSettingBoolean("meshfix_keep_open_polygons"), mesh.getSettingBoolean("meshfix_extensive_stitching"));
slicerList.push_back(slicer);
}
int starting_layer_idx;
{ // find first non-empty layer
for (starting_layer_idx = 0; starting_layer_idx < layer_count; starting_layer_idx++)
{
Polygons parts;
for (cura::Slicer* slicer : slicerList)
parts.add(slicer->layers[starting_layer_idx].polygonList);
if (parts.size() > 0)
break;
}
if (starting_layer_idx > 0)
{
logError("First %i layers are empty!\n", starting_layer_idx);
}
}
std::cerr<< "chainifying layers..." << std::endl;
{
int starting_z = -1;
for (cura::Slicer* slicer : slicerList)
wireFrame.bottom_outline.add(slicer->layers[starting_layer_idx].polygonList);
if (commandSocket)
commandSocket->sendPolygons(Inset0Type, 0, wireFrame.bottom_outline);
wireFrame.z_bottom = slicerList[0]->layers[starting_layer_idx].z;
Point starting_point_in_layer;
if (wireFrame.bottom_outline.size() > 0)
starting_point_in_layer = (wireFrame.bottom_outline.max() + wireFrame.bottom_outline.min()) / 2;
else
starting_point_in_layer = (Point(0,0) + object->max() + object->min()) / 2;
for (int layer_idx = starting_layer_idx + 1; layer_idx < layer_count; layer_idx++)
{
logProgress("inset", layer_idx+1, layer_count); // abuse the progress system of the normal mode of CuraEngine
Polygons parts1;
for (cura::Slicer* slicer : slicerList)
parts1.add(slicer->layers[layer_idx].polygonList);
Polygons chainified;
chainify_polygons(parts1, starting_point_in_layer, chainified, false);
if (commandSocket)
commandSocket->sendPolygons(Inset0Type, layer_idx - starting_layer_idx, chainified);
if (chainified.size() > 0)
{
if (starting_z == -1) starting_z = slicerList[0]->layers[layer_idx-1].z;
wireFrame.layers.emplace_back();
WeaveLayer& layer = wireFrame.layers.back();
layer.z0 = slicerList[0]->layers[layer_idx-1].z - starting_z;
layer.z1 = slicerList[0]->layers[layer_idx].z - starting_z;
layer.supported = chainified;
starting_point_in_layer = layer.supported.back().back();
}
}
}
std::cerr<< "finding horizontal parts..." << std::endl;
{
Polygons* lower_top_parts = &wireFrame.bottom_outline;
for (unsigned int layer_idx = 0; layer_idx < wireFrame.layers.size(); layer_idx++)
{
logProgress("skin", layer_idx+1, wireFrame.layers.size()); // abuse the progress system of the normal mode of CuraEngine
WeaveLayer& layer = wireFrame.layers[layer_idx];
Polygons empty;
Polygons& layer_above = (layer_idx+1 < wireFrame.layers.size())? wireFrame.layers[layer_idx+1].supported : empty;
createHorizontalFill(*lower_top_parts, layer, layer_above, layer.z1);
lower_top_parts = &layer.supported;
}
//.........这里部分代码省略.........