Hide menu
Loading...
Searching...
No Matches
nesting/nesting_computer/nesting_computer.py
Refer to the Nesting Example
1# $Id$
2
3# Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
4# Copyright (C) 2014-2026, CADEX. All rights reserved.
5
6# This file is part of the Manufacturing Toolkit software.
7
8# You may use this file under the terms of the BSD license as follows:
9
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions are met:
12# * Redistributions of source code must retain the above copyright notice,
13# this list of conditions and the following disclaimer.
14# * Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29
30import os
31import sys
32from pathlib import Path
33
34import mtk.MTKCore as mtk
35
36sys.path.append(os.path.abspath(os.path.dirname(Path(__file__).resolve()) + "/../../"))
37sys.path.append(os.path.abspath(os.path.dirname(Path(__file__).resolve()) + "/../../helpers/"))
38
39import LicenseHelper
40
41import mtk_license as license
42
43class Pattern:
44 def __init__(self, theShape: mtk.Drawing_CurveSet, theName: str, theNumber: int):
45 self.myDrawingDrawing_View = mtk.Drawing_View(mtk.Initialized())
46 self.myDrawingDrawing_View.Add(theShape)
47 self.myName = theName
48 self.myNumber = theNumber
49
50def main():
51 aKey = license.Value()
52
53 if not LicenseHelper.SetupRuntimeKey() :
54 return 1
55
56 try:
57 mtk.LicenseManager.Activate(aKey)
58 except mtk.LicenseError as anException:
59 mtk.LicenseManager.Deactivate()
60 print("Failed to activate Manufacturing Toolkit license: " + anException.what())
61 return 1
62
63 aComputer = mtk.Nesting_Computer()
64
65 # Configuring nesting parameters
66 aParams = mtk.Nesting_ComputerParameters()
67 aParams.SetIterationCount(10) # Number of iterations for optimization process
68 aParams.SetGenerationSize(10) # Initial count of random layouts; larger values may improve optimization
69 aParams.SetMutationRate(0.5) # Probability of random shape rearrangement to escape local optima
70 aParams.SetPartToPartDistance(1.0) # Minimum distance between shapes
71 aParams.SetPartToSheetBoundaryDistance(1.0) # Minimum distance between shapes and sheet edges
72 aParams.SetMirrorControl(False) # Allows mirrored shapes to improve layout efficiency
73 aParams.SetRotationCount(4) # Number of allowed rotation angles (e.g., 4 allows 0°, 90°, 180°, and 270°)
74 aParams.SetCurveTolerance(10) # Side length of squares used for polygonal approximation of curves
75
76 aComputer.SetParameters(aParams)
77
78 # Define material size and number (e.g., 1 sheets of 100x100 mm)
79 aComputer.AddMaterial(100.0, 100.0, 1)
80
81 aPatterns = [
82 Pattern(CreateRectangle(50.0, 50.0), "Rectangle 50x50", 1),
83 Pattern(CreateRectangle(20.0, 10.0), "Rectangle 20x10", 10)
84 ]
85
86 PrintPatternsInfo(aPatterns)
87
88 # Load patterns into the computer
89 for aPattern in aPatterns:
90 aComputer.AddPattern(aPattern.myDrawingDrawing_View, aPattern.myNumber)
91
92 # Start the Nesting process
93 aData = aComputer.Perform()
94
95 # Print nesting information
96 PrintNestingInfo(aData)
97
98 mtk.LicenseManager.Deactivate()
99
100
101def CreateRectangle(theWidth: float, theHeight: float) -> mtk.Drawing_CurveSet:
102 aRectangle = mtk.Drawing_CurveSet()
103
104 aL1 = mtk.Geom_Line2d(mtk.Geom_Point2d(0, 0), mtk.Geom_Direction2d(1, 0))
105 aL1.SetTrim(0, theWidth)
106
107 aL2 = mtk.Geom_Line2d(mtk.Geom_Point2d(theWidth, 0), mtk.Geom_Direction2d(0, 1))
108 aL2.SetTrim(0, theHeight)
109
110 aL3 = mtk.Geom_Line2d(mtk.Geom_Point2d(theWidth, theHeight), mtk.Geom_Direction2d(-1, 0))
111 aL3.SetTrim(0, theWidth)
112
113 aL4 = mtk.Geom_Line2d(mtk.Geom_Point2d(0, theHeight), mtk.Geom_Direction2d(0, -1))
114 aL4.SetTrim(0, theHeight)
115
116 aRectangle.AddCurve(aL1)
117 aRectangle.AddCurve(aL2)
118 aRectangle.AddCurve(aL3)
119 aRectangle.AddCurve(aL4)
120
121 return aRectangle
122
123def PrintPatternsInfo(thePatterns: list):
124 print("------- Patterns Info -------")
125 for aPattern in thePatterns:
126 print(f"{aPattern.myName}: {aPattern.myNumber}")
127
128def PrintNestingInfo(theData: mtk.Nesting_Data):
129 print("\n------- Nesting Info -------")
130
131 aTotalEfficiency = 0.0
132 aTotalScrap = 0.0
133 aSheets = theData.Sheets()
134
135 for i in range(len(aSheets)):
136 print(f"# Sheet {i}")
137 print(f" Nested Parts: {aSheets[i].NestedParts()}")
138 aTotalScrap += aSheets[i].Scrap()
139 print(f" Scrap: {aSheets[i].Scrap() * 100}%")
140 aTotalEfficiency += aSheets[i].PlacementEfficiency()
141 print(f" Placement Efficiency: {aSheets[i].PlacementEfficiency() * 100}%\n")
142
143 print(f"Average Scrap: {aTotalScrap / len(aSheets) * 100}%")
144 print(f"Average Placement Efficiency: {aTotalEfficiency / len(aSheets) * 100}%")
145
146if __name__ == "__main__":
147 main()