@@ -921,6 +921,8 @@ function placeParts(sheets, parts, config, nestindex) {
921
921
922
922
var allbounds ;
923
923
var partbounds ;
924
+ var hull = null ;
925
+
924
926
if ( config . placementType == 'gravity' || config . placementType == 'box' ) {
925
927
allbounds = GeometryUtil . getPolygonBounds ( allpoints ) ;
926
928
@@ -930,14 +932,15 @@ function placeParts(sheets, parts, config, nestindex) {
930
932
}
931
933
partbounds = GeometryUtil . getPolygonBounds ( partpoints ) ;
932
934
}
933
- else {
934
- allpoints = getHull ( allpoints ) ;
935
+ else if ( config . placementType == 'convexhull' && allpoints . length > 0 ) {
936
+ // Calculate the hull of all already placed parts once
937
+ hull = getHull ( allpoints ) ;
935
938
}
939
+
936
940
for ( let j = 0 ; j < finalNfp . length ; j ++ ) {
937
941
nf = finalNfp [ j ] ;
938
- //console.log('evalnf',nf.length);
942
+
939
943
for ( let k = 0 ; k < nf . length ; k ++ ) {
940
-
941
944
shiftvector = {
942
945
x : nf [ k ] . x - part [ 0 ] . x ,
943
946
y : nf [ k ] . y - part [ 0 ] . y ,
@@ -947,8 +950,7 @@ function placeParts(sheets, parts, config, nestindex) {
947
950
filename : part . filename
948
951
} ;
949
952
950
- // ENHANCEMENT: Add a more rigorous overlap check before considering this position
951
- // First, create a theoretical placement of the part at this position
953
+ // ENHANCEMENT: Add a more rigorous overlap check before considering this position
952
954
const theoreticPlacement = [ ] ;
953
955
for ( let m = 0 ; m < part . length ; m ++ ) {
954
956
theoreticPlacement . push ( {
@@ -957,7 +959,6 @@ function placeParts(sheets, parts, config, nestindex) {
957
959
} ) ;
958
960
}
959
961
960
- // Then check for overlaps with all previously placed parts
961
962
let hasOverlap = false ;
962
963
for ( let m = 0 ; m < placed . length ; m ++ ) {
963
964
const placedPart = [ ] ;
@@ -968,21 +969,16 @@ function placeParts(sheets, parts, config, nestindex) {
968
969
} ) ;
969
970
}
970
971
971
- // Use our enhanced overlap detector with additional safety margin
972
972
if ( checkPlacementOverlap ( theoreticPlacement , placedPart , config . overlapTolerance || 0.0001 ) ) {
973
973
hasOverlap = true ;
974
974
break ;
975
975
}
976
976
}
977
977
978
- // Skip this position if any overlap was detected
979
978
if ( hasOverlap ) {
980
979
continue ;
981
980
}
982
981
983
- /*for(m=0; m<part.length; m++){
984
- localpoints.push({x: part[m].x+shiftvector.x, y:part[m].y+shiftvector.y});
985
- }*/
986
982
//console.time('evalbounds');
987
983
988
984
if ( config . placementType == 'gravity' || config . placementType == 'box' ) {
@@ -1008,22 +1004,40 @@ function placeParts(sheets, parts, config, nestindex) {
1008
1004
area = rectbounds . width * rectbounds . height ;
1009
1005
}
1010
1006
}
1011
- else {
1012
- // must be convex hull
1013
- var localpoints = clone ( allpoints ) ;
1014
-
1007
+ else if ( config . placementType == 'convexhull' ) {
1008
+ // Create points for the part at this candidate position
1009
+ var partPoints = [ ] ;
1015
1010
for ( let m = 0 ; m < part . length ; m ++ ) {
1016
- localpoints . push ( { x : part [ m ] . x + shiftvector . x , y : part [ m ] . y + shiftvector . y } ) ;
1011
+ partPoints . push ( {
1012
+ x : part [ m ] . x + shiftvector . x ,
1013
+ y : part [ m ] . y + shiftvector . y
1014
+ } ) ;
1017
1015
}
1018
-
1019
- area = Math . abs ( GeometryUtil . polygonArea ( getHull ( localpoints ) ) ) ;
1020
- shiftvector . hull = getHull ( localpoints ) ;
1021
- shiftvector . hullsheet = getHull ( sheet ) ;
1016
+
1017
+ var combinedHull ;
1018
+
1019
+ // If this is the first part, the hull is just the part itself
1020
+ if ( allpoints . length === 0 ) {
1021
+ combinedHull = getHull ( partPoints ) ;
1022
+ } else {
1023
+ // Merge the points of the part with the points of the hull
1024
+ // and recalculate the combined hull (more efficient than using all points)
1025
+ var hullPoints = hull . concat ( partPoints ) ;
1026
+ combinedHull = getHull ( hullPoints ) ;
1027
+ }
1028
+
1029
+ if ( ! combinedHull ) {
1030
+ console . warn ( "Failed to calculate convex hull" ) ;
1031
+ continue ;
1032
+ }
1033
+
1034
+ // Calculate area of the convex hull
1035
+ area = Math . abs ( GeometryUtil . polygonArea ( combinedHull ) ) ;
1036
+
1037
+ // Store for later use
1038
+ shiftvector . hull = combinedHull ;
1022
1039
}
1023
1040
1024
- //console.timeEnd('evalbounds');
1025
- //console.time('evalmerge');
1026
-
1027
1041
if ( config . mergeLines ) {
1028
1042
// if lines can be merged, subtract savings from area calculation
1029
1043
var shiftedpart = shiftPolygon ( part , shiftvector ) ;
@@ -1039,8 +1053,6 @@ function placeParts(sheets, parts, config, nestindex) {
1039
1053
area -= merged . totalLength * config . timeRatio ;
1040
1054
}
1041
1055
1042
- //console.timeEnd('evalmerge');
1043
-
1044
1056
if (
1045
1057
minarea === null ||
1046
1058
( config . placementType == 'gravity' && (
@@ -1053,7 +1065,9 @@ function placeParts(sheets, parts, config, nestindex) {
1053
1065
// ENHANCEMENT: Add final verification before accepting position
1054
1066
if ( ! hasOverlap ) {
1055
1067
minarea = area ;
1056
- minwidth = rectbounds . width ;
1068
+ if ( config . placementType == 'gravity' || config . placementType == 'box' ) {
1069
+ minwidth = rectbounds . width ;
1070
+ }
1057
1071
position = shiftvector ;
1058
1072
minx = shiftvector . x ;
1059
1073
miny = shiftvector . y ;
0 commit comments