Просмотр исходного кода

Fixed print object label positioning in skip objects modal

maziggy 4 месяцев назад
Родитель
Сommit
50a5f5473b
4 измененных файлов с 22 добавлено и 18 удалено
  1. 9 6
      backend/app/services/archive.py
  2. 12 11
      frontend/src/pages/PrintersPage.tsx
  3. 0 0
      static/assets/index-yp9aZph0.js
  4. 1 1
      static/index.html

+ 9 - 6
backend/app/services/archive.py

@@ -396,8 +396,8 @@ def extract_printable_objects_from_3mf(
                     break
                     break
 
 
             # Load position data from plate_N.json if we need positions
             # Load position data from plate_N.json if we need positions
-            # Build a lookup by name since bbox_objects.id != slice_info identify_id
-            bbox_by_name: dict[str, list] = {}
+            # Build a lookup by name - use list to handle duplicate names
+            bbox_by_name: dict[str, list[list]] = {}
             if include_positions:
             if include_positions:
                 plate_json_path = f"Metadata/plate_{plate_idx}.json"
                 plate_json_path = f"Metadata/plate_{plate_idx}.json"
                 if plate_json_path in zf.namelist():
                 if plate_json_path in zf.namelist():
@@ -409,7 +409,9 @@ def extract_printable_objects_from_3mf(
                             obj_name = bbox_obj.get("name")
                             obj_name = bbox_obj.get("name")
                             bbox = bbox_obj.get("bbox", [])
                             bbox = bbox_obj.get("bbox", [])
                             if obj_name and len(bbox) >= 4:
                             if obj_name and len(bbox) >= 4:
-                                bbox_by_name[obj_name] = bbox
+                                if obj_name not in bbox_by_name:
+                                    bbox_by_name[obj_name] = []
+                                bbox_by_name[obj_name].append(bbox)
                     except (json.JSONDecodeError, KeyError):
                     except (json.JSONDecodeError, KeyError):
                         pass
                         pass
 
 
@@ -424,9 +426,10 @@ def extract_printable_objects_from_3mf(
                         obj_id = int(identify_id)
                         obj_id = int(identify_id)
                         if include_positions:
                         if include_positions:
                             x, y = None, None
                             x, y = None, None
-                            # Match by name to get bbox coordinates
-                            bbox = bbox_by_name.get(name)
-                            if bbox:
+                            # Match by name - pop first bbox to handle duplicates
+                            bboxes = bbox_by_name.get(name)
+                            if bboxes:
+                                bbox = bboxes.pop(0)
                                 # Calculate center from bbox [x_min, y_min, x_max, y_max]
                                 # Calculate center from bbox [x_min, y_min, x_max, y_max]
                                 x = (bbox[0] + bbox[2]) / 2
                                 x = (bbox[0] + bbox[2]) / 2
                                 y = (bbox[1] + bbox[3]) / 2
                                 y = (bbox[1] + bbox[3]) / 2

+ 12 - 11
frontend/src/pages/PrintersPage.tsx

@@ -2580,30 +2580,31 @@ function PrinterCard({
 
 
                           // Use position data if available, otherwise fall back to grid
                           // Use position data if available, otherwise fall back to grid
                           if (obj.x != null && obj.y != null && objectsData.bbox_all) {
                           if (obj.x != null && obj.y != null && objectsData.bbox_all) {
-                            // bbox_all is [x_min, y_min, x_max, y_max] - the bounds of all objects
-                            // The top_N.png image is rendered to show this area with ~10% padding
+                            // bbox_all defines the visible area in the top_N.png image
+                            // Format: [x_min, y_min, x_max, y_max] in mm
                             const [xMin, yMin, xMax, yMax] = objectsData.bbox_all;
                             const [xMin, yMin, xMax, yMax] = objectsData.bbox_all;
                             const bboxWidth = xMax - xMin;
                             const bboxWidth = xMax - xMin;
                             const bboxHeight = yMax - yMin;
                             const bboxHeight = yMax - yMin;
 
 
-                            // Calculate position relative to bbox, with padding
-                            // The image has roughly 10% padding on each side
-                            const padding = 10;
+                            // The image shows bbox_all area with some padding (~5-10%)
+                            const padding = 8;
                             const contentArea = 100 - (padding * 2);
                             const contentArea = 100 - (padding * 2);
 
 
+                            // Map object position to image percentage
                             x = padding + ((obj.x - xMin) / bboxWidth) * contentArea;
                             x = padding + ((obj.x - xMin) / bboxWidth) * contentArea;
-                            // Y axis: in 3D coords Y increases toward back, in image Y increases down
-                            // So we need to flip: high Y in 3D = low Y in image (top)
+                            // Y axis: image Y increases downward, but 3D Y increases toward back
                             y = padding + ((yMax - obj.y) / bboxHeight) * contentArea;
                             y = padding + ((yMax - obj.y) / bboxHeight) * contentArea;
 
 
                             // Clamp to valid range
                             // Clamp to valid range
                             x = Math.max(5, Math.min(95, x));
                             x = Math.max(5, Math.min(95, x));
                             y = Math.max(5, Math.min(95, y));
                             y = Math.max(5, Math.min(95, y));
                           } else if (obj.x != null && obj.y != null) {
                           } else if (obj.x != null && obj.y != null) {
-                            // Fallback: use full build plate (256mm for X1C)
-                            const buildPlateSize = 256;
-                            x = Math.max(10, Math.min(90, (obj.x / buildPlateSize) * 100));
-                            y = Math.max(10, Math.min(90, 100 - (obj.y / buildPlateSize) * 100));
+                            // Fallback: use full build plate (256mm)
+                            const buildPlate = 256;
+                            x = (obj.x / buildPlate) * 100;
+                            y = 100 - (obj.y / buildPlate) * 100;
+                            x = Math.max(5, Math.min(95, x));
+                            y = Math.max(5, Math.min(95, y));
                           } else {
                           } else {
                             // Fallback: arrange in a grid pattern over the build plate area
                             // Fallback: arrange in a grid pattern over the build plate area
                             const cols = Math.ceil(Math.sqrt(objectsData.objects.length));
                             const cols = Math.ceil(Math.sqrt(objectsData.objects.length));

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
static/assets/index-yp9aZph0.js


+ 1 - 1
static/index.html

@@ -23,7 +23,7 @@
 
 
     <!-- Splash screens for iOS -->
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="/assets/index-BqMRkLQa.js"></script>
+    <script type="module" crossorigin src="/assets/index-yp9aZph0.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-DIdbNfsf.css">
     <link rel="stylesheet" crossorigin href="/assets/index-DIdbNfsf.css">
   </head>
   </head>
   <body>
   <body>

Некоторые файлы не были показаны из-за большого количества измененных файлов