fel88 / DeepNestPort

DeepNest C# Port
MIT License
78 stars 34 forks source link

Add a hole in NFP #4

Closed petrasvestartas closed 5 years ago

petrasvestartas commented 5 years ago

I know I asked this question but maybe you could give a direct answer by looking at example below.

Currently I can add NFP to NFP List like this:

    public void AddTrianglePart(int src, int ww = 50, int hh = 80) {
        NFP pl = new NFP();
        polygons.Add(pl);//Add current nfp to nfp list
        pl.source = src; //Source is and id?
        pl.Points = new SvgPoint[] { new SvgPoint(0, hh) , new SvgPoint(ww, 0), new SvgPoint(0 + ww, 0 + hh) };
    }

Does NFP represents only one polygon or there is an option to specify a hole inside? Or polygon with hole would require a bit more complex setup?

Also I see this line of code that represents outer loop and inner holes but I do not understand the logic behind as it becomes one polygon: DeepNestLib.LocalContour tt = raw.Outers.Union(raw.Holes).OrderByDescending(z => z.Len).First();

fel88 commented 5 years ago

Does NFP represents only one polygon or there is an option to specify a hole inside?

Yes, there is the way to specify holes inside polygon. Just add hole polygon in children list of NFP like this:

var hole = new NFP();
pl.children = new List<NFP>();
pl.children.Add(hole);
int gap = 10;
hole.Points = new SvgPoint[] { new SvgPoint(gap, hh-gap) , new SvgPoint(ww-gap, gap), new SvgPoint(ww-gap, hh-gap) };

Also I see this line of code that represents outer loop and inner holes but I do not understand the logic behind as it becomes ..

Yes, you are right. I have not completed this part of code. I'll fix it out next week.

petrasvestartas commented 5 years ago

Thank you for a reply.

I am trying also to understand the genetic algorithm behind, especially these parameters:

public class SvgNestConfig
    {
        public PlacementTypeEnum placementType = PlacementTypeEnum.box;
        public double curveTolerance = 0.72;
        public double scale = 25;
        public double clipperScale = 100000;//00
        public bool exploreConcave = true;
        public int mutationRate = 10;
        public int populationSize = 10000;
        public int rotations = 360000;
        public double spacing = 40;
        public double sheetSpacing = 0;
        public bool useHoles = false;
        public double timeRatio = 0.5;
        public bool mergeLines = false;
        public bool simplify;
    }

If I would try to explore very small increments of rotations, what would be the best populationSize and mutationSize values?

Mostly fitness values stays the same I am wondering where is the mistake:

teration: 0; fitness: 6012726.02478099; nesting time: 2441ms Iteration: 1; fitness: 5831648.7401844; nesting time: 800ms Iteration: 2; fitness: 5831648.7401844; nesting time: 225ms Iteration: 3; fitness: 5831648.7401844; nesting time: 913ms Iteration: 4; fitness: 5831648.7401844; nesting time: 656ms Iteration: 5; fitness: 5831648.7401844; nesting time: 1630ms Iteration: 6; fitness: 5831648.7401844; nesting time: 782ms Iteration: 7; fitness: 5831648.7401844; nesting time: 224ms Iteration: 8; fitness: 5831648.7401844; nesting time: 1218ms Iteration: 9; fitness: 5831648.7401844; nesting time: 257ms

fel88 commented 5 years ago
    public int rotations = 360000;

You should pull latest commit before setting such large values for rotations.

If I would try to explore very small increments of rotations, what would be the best populationSize and mutationSize values?

Hard to say.

Mostly fitness values stays the same I am wondering where is the mistake:

No, it's ok. It is just best fitness value at the moment. It remains the same until a better solution be found.

petrasvestartas commented 5 years ago

Thank you very much for the change.

Another thing I noticed is unit scale. I think this comes from clipper. If I use very small units the placement of elements seems with large gaps (two images below) How to change the scale (I tried in config but no results) that I could nest the smaller elements? check03 check00

fel88 commented 5 years ago

How to change the scale (I tried in config but no results) that I could nest the smaller elements?

Scaling is not supported now.

petrasvestartas commented 5 years ago

Rotation works really nice. I did the scaling internally. When scaling is correct it takes much longer time to compute, but the result is well packed. Thanks:)

petrasvestartas commented 5 years ago

I would like to ask once the code with holes will be implemented by your the setup to add holes as children of nfps would be something like this. Essentially NFP is class that has classes of NFP inside of it?

                //Polyline is just a list of points which end point is the same

                NFP polygon = new NFP();
                polygon.source = id;

                polygon.Points = new SvgPoint[] { };
                for (int i = 0; i < polyline.Count - 1; i++)
                    polygon.AddPoint(new SvgPoint(polyline[i].X, polyline[i].Y));

                polygon.children = new List<NFP>();

                for(int i = 0; i < holes.Length; i++) {
                    NFP hole = new NFP();
                    for (int j = 0; j < holes[i].Count - 1; j++)
                        polygon.AddPoint(new SvgPoint(polyline[i].X, polyline[i].Y));
                    polygon.children.Add(hole);
                }

                Polygons.Add(polygon);
fel88 commented 5 years ago

polygon.AddPoint(new SvgPoint(polyline[i].X, polyline[i].Y));

I think you meant it:

hole.AddPoint(new SvgPoint(polyline[i].X, polyline[i].Y));

I would like to ask once the code with holes will be implemented by your the setup to add holes as children of nfps would be something like this.

In general, yes.

Essentially NFP is class that has classes of NFP inside of it?

Yes, exactly. It is a tree structure of nested polygons.

fel88 commented 5 years ago

Try to nest new svg files. Nesting of parts with holes is possible now.

petrasvestartas commented 5 years ago

Thank you it works perfectly: nestingholes

I have a question about specifying sheet number. It is for user perspective as initially one might not know how many sheets he/she would need. What would be an approach if a user do not need to specify sheet number, and if an element cannot be nested to one sheet additional one would be added automatically?

I can internally code such option by duplicating hundred of sheets, but probably this would slow down the calculation and would not be the smartest way to solve this little problem?

The second question I have, would minkowski.dll could work on MAC ? I believe minkowski.dll has to be compiled as cross platform but they will also vary in terms of PInvoke methods for Mac and Windows. Do you have any experience in this?

fel88 commented 5 years ago

What would be an approach if a user do not need to specify sheet number, and if an element cannot be nested to one sheet additional one would be added automatically?

I can internally code such option by duplicating hundred of sheets, but probably this would slow down the calculation and would not be the smartest way to solve this little problem?

The main approach (which i use) is to define a large number of sheets at start (for example, 99). There will be no significant performance decrease. Parts are placed one by one so when all parts are placed the remaining sheets will remain empty. Then you can just delete all blank sheets.

The second question I have, would minkowski.dll could work on MAC ? I believe minkowski.dll has to be compiled as cross platform but they will also vary in terms of PInvoke methods for Mac and Windows. Do you have any experience in this?

No, but i belive there is no problem here. Maybe even you can use Mono without recompilation of exe.

petrasvestartas commented 5 years ago

Thanks for reply. What would the best way how many sheets are used?

fel88 commented 5 years ago

Look at AssignPlacement method (emptySheets list).

petrasvestartas commented 5 years ago

Thank you works like a charm:)

Jiangdaoyin commented 3 years ago

Rotation works really nice. I did the scaling internally. When scaling is correct it takes much longer time to compute, but the result is well packed. Thanks:)

When I scaling the polygon, the result is better than not scaling.Do you know the reason?