Arquivos
CuraEngine/skin.h
T
2013-05-17 09:20:32 +02:00

160 linhas
7.3 KiB
C

/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#ifndef SKIN_H
#define SKIN_H
void generateSkins(int layerNr, SliceVolumeStorage& storage, int extrusionWidth, int downSkinCount, int upSkinCount, int infillOverlap)
{
SliceLayer* layer = &storage.layers[layerNr];
for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
{
SliceLayerPart* part = &layer->parts[partNr];
Polygons temp;
ClipperLib::OffsetPolygons(part->insets[part->insets.size() - 1], temp, -extrusionWidth/2, ClipperLib::jtSquare, 2, false);
ClipperLib::Clipper downskinClipper;
ClipperLib::Clipper upskinClipper;
downskinClipper.AddPolygons(temp, ClipperLib::ptSubject);
upskinClipper.AddPolygons(temp, ClipperLib::ptSubject);
if (part->insets.size() > 1)
{
ClipperLib::Clipper thinWallClipper;
ClipperLib::OffsetPolygons(part->insets[0], temp, -extrusionWidth / 2 - extrusionWidth * infillOverlap / 100, ClipperLib::jtSquare, 2, false);
thinWallClipper.AddPolygons(temp, ClipperLib::ptSubject);
ClipperLib::OffsetPolygons(part->insets[1], temp, extrusionWidth * 6 / 10, ClipperLib::jtSquare, 2, false);
thinWallClipper.AddPolygons(temp, ClipperLib::ptClip);
thinWallClipper.Execute(ClipperLib::ctDifference, temp);
downskinClipper.AddPolygons(temp, ClipperLib::ptSubject);
upskinClipper.AddPolygons(temp, ClipperLib::ptSubject);
}
if (int(layerNr - downSkinCount) >= 0)
{
SliceLayer* layer2 = &storage.layers[layerNr - downSkinCount];
for(unsigned int partNr2=0; partNr2<layer2->parts.size(); partNr2++)
{
if (part->boundaryBox.hit(layer2->parts[partNr2].boundaryBox))
downskinClipper.AddPolygons(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 1], ClipperLib::ptClip);
}
}
if (int(layerNr + upSkinCount) < (int)storage.layers.size())
{
SliceLayer* layer2 = &storage.layers[layerNr + upSkinCount];
for(unsigned int partNr2=0; partNr2<layer2->parts.size(); partNr2++)
{
if (part->boundaryBox.hit(layer2->parts[partNr2].boundaryBox))
upskinClipper.AddPolygons(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 1], ClipperLib::ptClip);
}
}
ClipperLib::Polygons downSkin;
ClipperLib::Polygons upSkin;
downskinClipper.Execute(ClipperLib::ctDifference, downSkin);
upskinClipper.Execute(ClipperLib::ctDifference, upSkin);
{
ClipperLib::Clipper skinCombineClipper;
skinCombineClipper.AddPolygons(downSkin, ClipperLib::ptSubject);
skinCombineClipper.AddPolygons(upSkin, ClipperLib::ptClip);
skinCombineClipper.Execute(ClipperLib::ctUnion, part->skinOutline);
}
double minAreaSize = (2 * M_PI * (double(extrusionWidth) / 1000.0) * (double(extrusionWidth) / 1000.0)) * 0.3;
for(unsigned int i=0; i<part->skinOutline.size(); i++)
{
double area = fabs(ClipperLib::Area(part->skinOutline[i])) / 1000.0 / 1000.0;
if (area < minAreaSize) /* Only create an up/down skin if the area is large enough. So you do not create tiny blobs of "trying to fill" */
{
part->skinOutline.erase(part->skinOutline.begin() + i);
i -= 1;
}
}
}
}
void generateSparse(int layerNr, SliceVolumeStorage& storage, int extrusionWidth, int downSkinCount, int upSkinCount)
{
SliceLayer* layer = &storage.layers[layerNr];
for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
{
SliceLayerPart* part = &layer->parts[partNr];
Polygons temp;
ClipperLib::OffsetPolygons(part->insets[part->insets.size() - 1], temp, -extrusionWidth/2, ClipperLib::jtSquare, 2, false);
ClipperLib::Clipper downskinClipper;
ClipperLib::Clipper upskinClipper;
downskinClipper.AddPolygons(temp, ClipperLib::ptSubject);
upskinClipper.AddPolygons(temp, ClipperLib::ptSubject);
if (int(layerNr - downSkinCount) >= 0)
{
SliceLayer* layer2 = &storage.layers[layerNr - downSkinCount];
for(unsigned int partNr2=0; partNr2<layer2->parts.size(); partNr2++)
{
if (part->boundaryBox.hit(layer2->parts[partNr2].boundaryBox))
{
if (layer2->parts[partNr2].insets.size() > 1)
{
downskinClipper.AddPolygons(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 2], ClipperLib::ptClip);
}else{
downskinClipper.AddPolygons(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 1], ClipperLib::ptClip);
}
}
}
}
if (int(layerNr + upSkinCount) < (int)storage.layers.size())
{
SliceLayer* layer2 = &storage.layers[layerNr + upSkinCount];
for(unsigned int partNr2=0; partNr2<layer2->parts.size(); partNr2++)
{
if (part->boundaryBox.hit(layer2->parts[partNr2].boundaryBox))
{
if (layer2->parts[partNr2].insets.size() > 1)
{
upskinClipper.AddPolygons(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 2], ClipperLib::ptClip);
}else{
upskinClipper.AddPolygons(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 1], ClipperLib::ptClip);
}
}
}
}
ClipperLib::Polygons downSkin;
ClipperLib::Polygons upSkin;
ClipperLib::Polygons result;
downskinClipper.Execute(ClipperLib::ctDifference, downSkin);
upskinClipper.Execute(ClipperLib::ctDifference, upSkin);
{
ClipperLib::Clipper skinClipper;
skinClipper.AddPolygons(downSkin, ClipperLib::ptSubject);
skinClipper.AddPolygons(upSkin, ClipperLib::ptClip);
skinClipper.Execute(ClipperLib::ctUnion, result);
}
double minAreaSize = 3.0;//(2 * M_PI * (double(config.extrusionWidth) / 1000.0) * (double(config.extrusionWidth) / 1000.0)) * 3;
for(unsigned int i=0; i<result.size(); i++)
{
double area = fabs(ClipperLib::Area(result[i])) / 1000.0 / 1000.0;
if (area < minAreaSize) /* Only create an up/down skin if the area is large enough. So you do not create tiny blobs of "trying to fill" */
{
result.erase(result.begin() + i);
i -= 1;
}
}
ClipperLib::Clipper sparseClipper;
sparseClipper.AddPolygons(temp, ClipperLib::ptSubject);
sparseClipper.AddPolygons(result, ClipperLib::ptClip);
sparseClipper.Execute(ClipperLib::ctDifference, part->sparseOutline);
}
}
#endif//SKIN_H