alle Bogen sind neu angepasst wegen cps.

This commit is contained in:
2025-09-19 13:56:35 +02:00
parent 317fa75e61
commit 9fb6954858
169 changed files with 3381 additions and 2976 deletions
@@ -22,63 +22,53 @@ def process_json_item(item):
item["center_line_height_mm"] = float(item["center_line_height_mm"])
item["Objekt_width_mm"] = float(item["Objekt_width_mm"])
item["Objekt_height_mm"] = float(item["Objekt_height_mm"])
item["calculated_objekt_width_mm"] = float(item["calculated_objekt_width_mm"])
item["calculated_objekt_height_mm"] = float(item["calculated_objekt_height_mm"])
# Calculate the direct mm to px conversions (requested additions)
item["Objekt_width_px"] = round((item["Objekt_width_mm"] * 3.779527592),4)
item["Objekt_height_px"] = round((item["Objekt_height_mm"] * 3.779527592),4)
winkel_rad = math.radians(item["Winkel"])
sin_value = math.sin(winkel_rad)
cos_value = math.cos(winkel_rad)
profilebreit = 42.0782
# Determine which dimension is larger
if item["Objekt_width_mm"] == item["Objekt_height_mm"]:
# "Width =Height"
scale = round(1000 / item["Objekt_width_mm"], 6)
scale = round(1000 / item["Objekt_width_mm"], 7)
item["calculated_SVG_width_px"] = 1000
item["calculated_SVG_height_px"] = round(item["Objekt_height_mm"] * scale, 3)
scale_RD_H = 1000 / item["calculated_SVG_height_px"]
item["calculated_SVG_height_px"] = 1000
scale_RD_H = 1
scale_RD_W = 1
elif item["Objekt_width_mm"] > item["Objekt_height_mm"]:
# Width is larger, set calculated_SVG width to 1000px
scale = round(1000 / item["Objekt_width_mm"], 7)
item["calculated_SVG_width_px"] = 1000
if item["Winkel"]==180:
item["calculated_SVG_height_px"] = round(item["Objekt_height_mm"] * scale+3.7795/2, 3)
else:
item["calculated_SVG_height_px"] = round(item["Objekt_height_mm"] * scale+3.7795/2/sin_value, 3)
scale_RD_H = round(1000 / item["calculated_SVG_height_px"], 6)
item["calculated_SVG_width_px"] = 1000
item["calculated_SVG_height_px"] = round(item["Objekt_height_mm"] * scale, 4)
scale_RD_H = round(1000 / item["calculated_SVG_height_px"], 7)
scale_RD_W = 1
else:
# Height is larger, set calculated_SVG height to 1000px
scale = round(1000 / item["Objekt_height_mm"], 7)
item["calculated_SVG_height_px"] = 1000
if item["Winkel"]==180:
item["calculated_SVG_width_px"] = round(item["Objekt_width_mm"] * scale+3.7795/2, 3)
else:
item["calculated_SVG_width_px"] = round(item["Objekt_width_mm"] * scale+3.7795/2/sin_value, 3)
scale_RD_W = round(1000 / item["calculated_SVG_width_px"], 6)
item["calculated_SVG_width_px"] = round(item["Objekt_width_mm"] * scale, 4)
scale_RD_W = round(1000 / item["calculated_SVG_width_px"], 7)
scale_RD_H = 1
item["scale_factor"] = scale # Add scale factor
# Calculate connection points
cp1_y = round(21.040 * scale*scale_RD_H, 3)
cp1_y = round(profilebreit/2 * scale*scale_RD_H, 3)
cp2_y = round((profilebreit/2+item["center_line_height_mm"]) * scale * scale_RD_H, 3)
if item["calculated_SVG_height_px"] == item["calculated_SVG_width_px"]:
cp2_x = round(item["center_line_width_mm"] * scale * scale_RD_W, 3)
cp2_y = round((21.040 + item["center_line_height_mm"]) * scale * scale_RD_H, 3)
elif item["calculated_SVG_height_px"] == 1000 and item["calculated_SVG_width_px"] != 1000:
if item["Winkel"]==180:
cp2_x = 0
else:
cp2_x = round((1000/item["Objekt_width_mm"]*item["center_line_width_mm"]), 3)
cp2_y = round(((21.040 + item["center_line_height_mm"]) * scale) * scale_RD_H, 3)
cp2_x = round((item["center_line_width_mm"] * scale) * scale_RD_W, 3)
else:
cp2_x = round((item["center_line_width_mm"] * scale) * scale_RD_W, 3)
cp2_y = round(((21.040 + item["center_line_height_mm"]) * scale) * scale_RD_H, 3)
cp2_direction = round(90 + item["Winkel"], 1) # Keep 1 decimal place
@@ -169,8 +159,9 @@ def process_json_file(input_file, output_file):
# Example usage
if __name__ == "__main__":
json_path=os.environ.get("JSON_PATH","JSON")
input_filename = os.path.join(json_path,"1_SVGErfassung_updated_new_output.json")
#json_path=r"C:\Users\y.wang\Documents\SSG-Ruledesigner-Konfigurator\SVGs\Omniflo\lib\OFBogen\json\1_SVGErfassung_updated_new_input.json"
json_path=os.environ.get("JSON_PATH_BOGEN","JSON")
input_filename = os.path.join(json_path,"1_SVGErfassung_updated_new_input.json")
output_filename =os.path.join(json_path,"2_calculated_px_cps_output.json")
process_json_file(input_filename, output_filename)
@@ -158,10 +158,10 @@ def process_files(json_file_path, txt_files_dir):
# Example usage
if __name__ == "__main__":
json_path = os.environ.get("JSON_PATH", "JSON")
json_path = os.environ.get("JSON_PATH_OFBOGEN", "JSON")
json_file_path = os.path.join(json_path, "2_calculated_px_cps_output.json")
txt_files_dir = r"C:\Program Files\RuleDesigner\RDConfigurator Fusion\WebApi\Editor2D\SSG\shapes\props"
# 确保目录存在
txt_files_dir = os.environ.get("PROPS_PATH", "props")
os.makedirs(txt_files_dir, exist_ok=True)
process_files(json_file_path, txt_files_dir)
print("\nProcessing complete!")
@@ -0,0 +1,386 @@
import os
import re
import xml.etree.ElementTree as ET
from xml.dom import minidom
import argparse
def analyze_and_normalize_path(d, path_type, path_id=""):
"""Strictly normalize path direction and generate detailed report"""
original_d = d
report = []
normalized = []
changed = False
# First check if path contains any arc commands
if 'A' in d or 'a' in d:
report.append(" Path contains arc commands - leaving unchanged")
return original_d, report, False
# Ensure path starts with M command
if not d.strip().startswith('M'):
d = 'M' + d[1:] if d.startswith('L') else 'M ' + d
report.append(" Fix: Added M command at path start")
changed = True
# Parse path commands
commands = []
current_cmd = None
for token in re.split('([A-Za-z])', d):
if not token:
continue
if token in 'MLAZHVCSQTa-z':
current_cmd = token
else:
if current_cmd:
commands.append((current_cmd, token.strip()))
prev_x, prev_y = None, None
for cmd, params in commands:
params = [float(p) for p in re.split('[, ]+', params.strip()) if p]
if cmd == 'M':
if len(params) >= 2:
x, y = params[0], params[1]
normalized.append(f"M {x} {y}")
prev_x, prev_y = x, y
continue
if path_type == 'Line segment' and cmd == 'L':
if len(params) >= 2 and prev_x is not None:
x, y = params[0], params[1]
need_swap = x < prev_x or (x == prev_x and y < prev_y)
if need_swap:
new_segment = [f"M {x} {y}", f"L {prev_x} {prev_y}"]
report.append(f" Need to swap start/end → New path: {' '.join(new_segment)}")
normalized = new_segment
changed = True
else:
normalized.append(f"L {x} {y}")
report.append(" Path direction already correct, no changes made")
prev_x, prev_y = x, y
continue
if path_type == 'Arc' and cmd == 'A':
if len(params) >= 7 and prev_x is not None:
rx, ry, xrot, large, sweep, x, y = params[0], params[1], params[2], int(params[3]), int(params[4]), params[5], params[6]
# Force left-to-right clockwise
need_swap = x < prev_x
new_sweep = 1
if need_swap:
new_segment = [f"M {x} {y}", f"A {rx} {ry} {xrot} {large} {new_sweep} {prev_x} {prev_y}"]
report.append(f" Need to swap start/end → New path: {' '.join(new_segment)}")
normalized = new_segment
changed = True
else:
if sweep != new_sweep:
new_segment = [f"A {rx} {ry} {xrot} {large} {new_sweep} {x} {y}"]
report.append(f" Need to adjust sweep to 1 → New path: {' '.join(new_segment)}")
normalized.extend(new_segment)
changed = True
else:
normalized.append(f"A {rx} {ry} {xrot} {large} {sweep} {x} {y}")
report.append(" Arc direction already correct, no changes made")
prev_x, prev_y = x, y
continue
normalized.append(f"{cmd} {' '.join(map(str, params))}")
new_d = ' '.join(normalized)
report_header = f"[{path_id}-Analysis] Type: {path_type}"
full_report = [report_header, f"Original path: {original_d}"] + report
if changed:
full_report.append(f"Modified path: {new_d}")
else:
full_report.append("Path not modified")
return new_d, '\n'.join(full_report)
def analyze_and_normalize_path(d, path_type, path_id=""):
"""Strictly normalize path direction and generate detailed report"""
original_d = d
report = []
normalized = []
changed = False
# First check if path contains any arc commands
if 'A' in d or 'a' in d:
report_header = f"[{path_id}-Analysis] Type: {path_type} (contains arcs)"
full_report = [report_header,
f"Original path: {original_d}",
" Path contains arc commands - leaving unchanged",
"Path not modified"]
return original_d, '\n'.join(full_report)
# Ensure path starts with M command
if not d.strip().startswith('M'):
d = 'M' + d[1:] if d.startswith('L') else 'M ' + d
report.append(" Fix: Added M command at path start")
changed = True
# Parse path commands
commands = []
current_cmd = None
for token in re.split('([A-Za-z])', d):
if not token:
continue
if token in 'MLAZHVCSQTa-z':
current_cmd = token
else:
if current_cmd:
commands.append((current_cmd, token.strip()))
prev_x, prev_y = None, None
for cmd, params in commands:
params = [float(p) for p in re.split('[, ]+', params.strip()) if p]
if cmd == 'M':
if len(params) >= 2:
x, y = params[0], params[1]
normalized.append(f"M {x} {y}")
prev_x, prev_y = x, y
continue
if path_type == 'Line segment' and cmd == 'L':
if len(params) >= 2 and prev_x is not None:
x, y = params[0], params[1]
need_swap = x < prev_x or (x == prev_x and y < prev_y)
if need_swap:
new_segment = [f"M {x} {y}", f"L {prev_x} {prev_y}"]
report.append(f" Need to swap start/end → New path: {' '.join(new_segment)}")
normalized = new_segment
changed = True
else:
normalized.append(f"L {x} {y}")
report.append(" Path direction already correct, no changes made")
prev_x, prev_y = x, y
continue
normalized.append(f"{cmd} {' '.join(map(str, params))}")
new_d = ' '.join(normalized)
report_header = f"[{path_id}-Analysis] Type: {path_type}"
full_report = [report_header, f"Original path: {original_d}"] + report
if changed:
full_report.append(f"Modified path: {new_d}")
else:
full_report.append("Path not modified")
return new_d, '\n'.join(full_report)
def optimize_svg(input_path, output_path):
"""Process single SVG file with all optimizations"""
try:
# Register namespace
ET.register_namespace('', 'http://www.w3.org/2000/svg')
# Parse SVG file
tree = ET.parse(input_path)
root = tree.getroot()
print(f"\nProcessing file: {os.path.basename(input_path)}")
print("="*60)
# Create parent map
parent_map = {c: p for p in tree.iter() for c in p}
# 1. Remove xlink namespace
for attr in list(root.attrib):
if 'xlink' in attr:
del root.attrib[attr]
# 2. Set standard dimensions
root.set('width', '1e3')
root.set('height', '1e3')
root.set('viewBox', '0 0 1e3 1e3')
# 3. Remove all clipPath definitions and references
defs = root.find('{http://www.w3.org/2000/svg}defs')
if defs is not None:
clip_paths = defs.findall('{http://www.w3.org/2000/svg}clipPath')
for cp in clip_paths:
defs.remove(cp)
if len(defs) == 0:
root.remove(defs)
# 4. Remove clip-path attributes
for elem in tree.iter():
if 'clip-path' in elem.attrib:
del elem.attrib['clip-path']
# 5. Force square line caps
for g in root.findall('.//{http://www.w3.org/2000/svg}g'):
g.set('stroke-linecap', 'square')
# 6. Remove dashed line styles
for elem in tree.iter():
if 'stroke-dasharray' in elem.attrib:
del elem.attrib['stroke-dasharray']
# 7. Completely remove empty groups
removed_groups = True
while removed_groups:
removed_groups = False
for g in root.findall('.//{http://www.w3.org/2000/svg}g'):
is_empty = (
len(g) == 0 and
not (g.text or '').strip() and
not (g.tail or '').strip() and
all(not k.startswith('{') for k in g.attrib))
if is_empty:
parent = parent_map.get(g)
if parent is not None:
parent.remove(g)
removed_groups = True
parent_map = {c: p for p in tree.iter() for c in p}
# 8. Convert polylines to paths
for polyline in root.findall('.//{http://www.w3.org/2000/svg}polyline'):
points = polyline.get('points', '').strip()
if points:
coords = [p for p in re.split(r'[\s,]', points) if p]
path_data = []
for i in range(0, len(coords), 2):
if i == 0:
path_data.append(f"M {coords[i]} {coords[i+1]}")
else:
path_data.append(f"L {coords[i]} {coords[i+1]}")
path = ET.Element('{http://www.w3.org/2000/svg}path')
new_d, analysis_report = analyze_and_normalize_path(
' '.join(path_data),
'Line segment',
"Polyline conversion"
)
path.set('d', new_d)
print(f"\n[Polyline conversion analysis]\n{analysis_report}")
for attr, value in polyline.attrib.items():
if attr not in ('points', 'stroke-dasharray'):
path.set(attr, value)
parent = parent_map.get(polyline)
if parent is not None:
parent.remove(polyline)
parent.append(path)
# 9. Normalize path directions (final step)
group_num = 0
for g in root.findall('.//{http://www.w3.org/2000/svg}g'):
group_num += 1
path_num = 0
group_report = []
for path in g.findall('.//{http://www.w3.org/2000/svg}path'):
path_num += 1
if 'd' not in path.attrib:
continue
# Auto-detect path type
path_type = 'Arc' if 'A' in path.get('d') else 'Line segment'
path_id = f"Group{group_num}-Path{path_num}"
new_d, analysis_report = analyze_and_normalize_path(
path.get('d'),
path_type,
path_id
)
if new_d != path.get('d'):
path.set('d', new_d)
group_report.append(analysis_report)
# Print all path reports for current group
if group_report:
print(f"\n=== Group {group_num} Path Analysis ===")
print('\n\n'.join(group_report))
# 10. Update colors and line width
for elem in root.findall('.//*[@stroke]'):
stroke = elem.get('stroke', '').lower()
if stroke == '#0ff' or stroke == 'rgb(0,255,255)':
elem.set('stroke', '#ffe31b')
elif stroke == '#000' or stroke == 'rgb(255,0,0)'or stroke == 'rgb(0,0,0)':
elem.set('stroke', '#ffe31b')
elem.set('stroke-width', f'{1}px')
# Generate final XML
rough_string = ET.tostring(root, encoding='utf-8', xml_declaration=True)
rough_string = rough_string.replace(b'standalone="no"', b'')
# Format output (remove empty lines)
reparsed = minidom.parseString(rough_string)
pretty_svg = reparsed.toprettyxml(indent=' ', encoding='utf-8')
pretty_svg = b'\n'.join(
line for line in pretty_svg.splitlines()
if line.strip()
).replace(b'<?xml version="1.0" ?>', b'<?xml version="1.0" encoding="utf-8"?>')
with open(output_path, 'wb') as f:
f.write(pretty_svg)
print("\n" + "="*60)
return True
except Exception as e:
print(f"\nProcessing error: {str(e)}")
print("="*60)
return False
def batch_process_svgs(input_dir, output_dir):
if not os.path.exists(output_dir):
os.makedirs(output_dir)
success_count = 0
failure_count = 0
for filename in os.listdir(input_dir):
if os.path.isdir(os.path.join(input_dir, filename)):
continue
if filename.lower().endswith('.svg') or '_new.svg' in filename.lower():
input_path = os.path.join(input_dir, filename)
output_filename = filename.replace('_new.svg', '_optimized.svg')
output_path = os.path.join(output_dir, output_filename)
if optimize_svg(input_path, output_path):
success_count += 1
print(f"✓ Processed successfully: {filename}{output_filename}")
else:
failure_count += 1
print(f"✗ Processing failed: {filename}")
print("\n" + "="*60 + "\n")
print("\nProcessing summary:")
print(f"Successfully processed: {success_count} files")
print(f"Failed to process: {failure_count} files")
if __name__ == '__main__':
input_dir = os.environ.get('RD_CONF_OFBOGEN')
output_dir = os.environ.get('RD_CONF_WORK')
if not input_dir or not output_dir:
print("Error: Environment variable RD_CONF_WORK is not set")
exit(1)
if not os.path.exists(input_dir):
print(f"Error: Input directory '{input_dir}' does not exist")
exit(1)
print(f"Starting SVG file processing, working directory: {input_dir}")
print("=" * 50)
batch_process_svgs(input_dir, output_dir)
print("Processing completed!")
@@ -0,0 +1,247 @@
import os
from lxml import etree
import re
from math import sqrt, isclose
from collections import defaultdict
# Constants
WEICHEN_PROFILE_WIDTH = 42.000
L_R_TARGET_LENGTH = 55.7237
DELTA_TARGET_LENGTH = 53.5437
MATCH_TOLERANCE = 0.1 # Matching tolerance 0.1mm
def process_svg_files(directory):
print(f"🔍 Scanning directory: {directory}")
print("-" * 60)
result_stats = {
'total_files': 0,
'L_R_files': {'with_pairs': [], 'no_pairs': [], 'excess_pairs': []},
'Delta_files': {'with_triples': [], 'no_triples': [], 'excess_triples': []}
}
for filename in os.listdir(directory):
if not filename.endswith('.svg'):
continue
filepath = os.path.join(directory, filename)
result_stats['total_files'] += 1
if '_L_' in filename or '_R_' in filename:
print(f"\n📄 Processing L/R file: {filename}")
process_lr_file(filepath, filename, result_stats)
elif 'DeltaWeiche' in filename:
print(f"\n📄 Processing DeltaWeiche file: {filename}")
process_delta_file(filepath, filename, result_stats)
# Print final statistics
print("\n" + "="*60)
print("📊 Final processing statistics:")
print(f"Total files processed: {result_stats['total_files']}")
print("\nL/R type files results:")
print(f"✅ Files with matching path pairs: {len(result_stats['L_R_files']['with_pairs'])}")
print(f" {result_stats['L_R_files']['with_pairs']}")
print(f"⚠️ Files with no matching paths: {len(result_stats['L_R_files']['no_pairs'])}")
print(f" {result_stats['L_R_files']['no_pairs']}")
print(f"❌ Files with >2 matching paths: {len(result_stats['L_R_files']['excess_pairs'])}")
print(f" {result_stats['L_R_files']['excess_pairs']}")
print("\nDeltaWeiche type files results:")
print(f"✅ Files with matching path triples: {len(result_stats['Delta_files']['with_triples'])}")
print(f" {result_stats['Delta_files']['with_triples']}")
print(f"⚠️ Files with no matching paths: {len(result_stats['Delta_files']['no_triples'])}")
print(f" {result_stats['Delta_files']['no_triples']}")
print(f"❌ Files with ≠3 matching paths: {len(result_stats['Delta_files']['excess_triples'])}")
print(f" {result_stats['Delta_files']['excess_triples']}")
print("\n✨ Processing complete!")
def process_lr_file(filepath, filename, stats):
try:
tree = etree.parse(filepath)
root = tree.getroot()
# Find all straight line paths
straight_lines = find_straight_lines(root)
print(f" 📊 Found {len(straight_lines)} straight paths")
# Print all straight paths
print("\n 🔍 All straight path details:")
for line in straight_lines:
print(f" Path{line['index']}: ({line['p1'][0]:.2f},{line['p1'][1]:.2f})→"
f"({line['p2'][0]:.2f},{line['p2'][1]:.2f}) length={line['length']:.4f}mm")
# Group by length
length_groups = group_lines_by_length(straight_lines)
# Only print groups with exactly 2 paths
print("\n 🔍 Same-length path groups (2 paths):")
perfect_pairs = [group for group in length_groups.values() if len(group) == 2]
for group in perfect_pairs:
print(f" ┌ Length group ({group[0]['length']:.4f}mm, 2 paths)")
for line in group:
print(f" │ Path{line['index']}: ({line['p1'][0]:.2f},{line['p1'][1]:.2f})→"
f"({line['p2'][0]:.2f},{line['p2'][1]:.2f})")
print("" + "" * 40)
if len(perfect_pairs) == 1:
pair = perfect_pairs[0]
original_length = pair[0]['length']
scale_factor = WEICHEN_PROFILE_WIDTH / original_length
print(f"\n 🔄 Scaling calculation (based on length {original_length:.4f}mm):")
print(f" Scale factor: {scale_factor:.4f}")
# Print scaled lengths
print("\n 🔍 Scaled path lengths:")
for line in straight_lines:
scaled_len = line['length'] * scale_factor
print(f" Path{line['index']}: {line['length']:.4f}mm → {scaled_len:.4f}mm")
# Find path matching target length (within tolerance)
target_path = find_target_path(straight_lines, scale_factor, L_R_TARGET_LENGTH)
if target_path:
target_path['element'].set('style', 'stroke:none;fill:none;')
tree.write(filepath, encoding='utf-8', xml_declaration=True)
print(f"\n ✅ Hid path{target_path['index']} matching target length {L_R_TARGET_LENGTH:.4f}mm (±{MATCH_TOLERANCE}mm)")
stats['L_R_files']['with_pairs'].append(filename)
else:
print(f"\n ❌ No path found matching {L_R_TARGET_LENGTH:.4f}mm (±{MATCH_TOLERANCE}mm)")
stats['L_R_files']['no_pairs'].append(filename)
elif len(perfect_pairs) > 1:
print(f"\n ❗ Found multiple same-length path groups: {[len(g) for g in length_groups.values()]}")
stats['L_R_files']['excess_pairs'].append(filename)
else:
print("\n ❌ No same-length path pairs found")
stats['L_R_files']['no_pairs'].append(filename)
except Exception as e:
print(f" ❌ Processing failed: {str(e)}")
def process_delta_file(filepath, filename, stats):
try:
tree = etree.parse(filepath)
root = tree.getroot()
# Find all straight line paths
straight_lines = find_straight_lines(root)
print(f" 📊 Found {len(straight_lines)} straight paths")
# Print all straight paths
print("\n 🔍 All straight path details:")
for line in straight_lines:
print(f" Path{line['index']}: ({line['p1'][0]:.2f},{line['p1'][1]:.2f})→"
f"({line['p2'][0]:.2f},{line['p2'][1]:.2f}) length={line['length']:.4f}mm")
# Group by length
length_groups = group_lines_by_length(straight_lines)
# Only print groups with exactly 3 paths
print("\n 🔍 Same-length path groups (3 paths):")
perfect_triples = [group for group in length_groups.values() if len(group) == 3]
for group in perfect_triples:
print(f" ┌ Length group ({group[0]['length']:.4f}mm, 3 paths)")
for line in group:
print(f" │ Path{line['index']}: ({line['p1'][0]:.2f},{line['p1'][1]:.2f})→"
f"({line['p2'][0]:.2f},{line['p2'][1]:.2f})")
print("" + "" * 40)
if len(perfect_triples) == 1:
triple = perfect_triples[0]
original_length = triple[0]['length']
scale_factor = WEICHEN_PROFILE_WIDTH / original_length
print(f"\n 🔄 Scaling calculation (based on length {original_length:.4f}mm):")
print(f" Scale factor: {scale_factor:.4f}")
# Print scaled lengths
print("\n 🔍 Scaled path lengths:")
for line in straight_lines:
scaled_len = line['length'] * scale_factor
print(f" Path{line['index']}: {line['length']:.4f}mm → {scaled_len:.4f}mm")
# Find all paths matching target length (there might be multiple)
target_paths = [line for line in straight_lines
if abs(line['length'] * scale_factor - DELTA_TARGET_LENGTH) < MATCH_TOLERANCE]
if target_paths:
for target in target_paths:
target['element'].set('style', 'stroke:none;fill:none;')
tree.write(filepath, encoding='utf-8', xml_declaration=True)
print(f"\n ✅ Hid {len(target_paths)} paths matching target length {DELTA_TARGET_LENGTH:.4f}mm (±{MATCH_TOLERANCE}mm):")
for target in target_paths:
print(f" - Path{target['index']}")
stats['Delta_files']['with_triples'].append(filename)
else:
print(f"\n ❌ No path found matching {DELTA_TARGET_LENGTH:.4f}mm (±{MATCH_TOLERANCE}mm)")
stats['Delta_files']['no_triples'].append(filename)
elif len(perfect_triples) > 1:
print(f"\n ❗ Found multiple same-length path groups: {[len(g) for g in length_groups.values()]}")
stats['Delta_files']['excess_triples'].append(filename)
else:
print("\n ❌ No same-length path groups (3 paths) found")
stats['Delta_files']['no_triples'].append(filename)
except Exception as e:
print(f" ❌ Processing failed: {str(e)}")
def find_straight_lines(root):
"""Find all straight line paths"""
lines = []
paths = root.xpath('.//svg:path|.//svg:g//svg:path',
namespaces={'svg': 'http://www.w3.org/2000/svg'})
for i, path in enumerate(paths, 1):
d = path.get('d', '').strip()
if not d:
continue
if is_straight_line(d):
length, (p1, p2) = calculate_line_length(d)
if length > 0:
lines.append({
'index': i,
'element': path,
'length': round(length, 4), # Keep 4 decimal places
'p1': (round(p1[0], 2), round(p1[1], 2)), # Coordinates rounded to 2 decimals
'p2': (round(p2[0], 2), round(p2[1], 2))
})
return lines
def group_lines_by_length(lines):
"""Group straight paths by length"""
groups = defaultdict(list)
for line in lines:
groups[line['length']].append(line)
return groups
def find_target_path(lines, scale_factor, target_length):
"""Find path that matches target length after scaling (within tolerance)"""
for line in lines:
scaled_length = line['length'] * scale_factor
if abs(scaled_length - target_length) < MATCH_TOLERANCE:
return line
return None
def is_straight_line(d):
"""Check if path is strictly a straight line"""
commands = [cmd[0].upper() for cmd in re.findall('([A-Za-z])', d)]
return len(commands) == 2 and commands[0] == 'M' and commands[1] == 'L'
def calculate_line_length(d):
"""Calculate line length and return endpoints"""
points = []
for cmd, params in re.findall('([A-Za-z])([^A-Za-z]*)', d):
if cmd.upper() in ('M', 'L'):
coords = [float(p) for p in re.findall('[-+]?\d*\.\d+|[-+]?\d+', params)]
points.append((coords[0], coords[1]))
if len(points) != 2:
return 0, ((0,0), (0,0))
length = sqrt((points[1][0]-points[0][0])**2 + (points[1][1]-points[0][1])**2)
return round(length, 4), (points[0], points[1]) # Length rounded to 4 decimals
if __name__ == '__main__':
# Set SVG files directory path
# svg_directory = r'C:\Users\y.wang\Documents\SSG-Ruledesigner-Konfigurator\SVGs\Omniflo\work'
svg_directory =os.environ.get('RD_CONF_WORK')
process_svg_files(svg_directory)
@@ -0,0 +1,158 @@
import os
import re
import xml.etree.ElementTree as ET
from typing import Tuple, List
def parse_svg_path(d: str) -> List[Tuple[float, float]]:
"""Extract all coordinates from SVG path data (including curve control points)"""
points = []
commands = re.findall(
r'([MmLlCcQqAaHhVvZz])([^MmLlCcQqAaHhVvZz]*)',
d.strip().replace(',', ' ')
)
current_pos = (0.0, 0.0)
for cmd, args in commands:
args = list(map(float, re.findall(r'[-+]?\d*\.?\d+', args)))
if cmd in ('M', 'm', 'L', 'l'): # Move/line commands
for i in range(0, len(args), 2):
x, y = args[i], args[i+1]
if cmd.islower(): # Relative coordinates
x += current_pos[0]
y += current_pos[1]
points.append((x, y))
current_pos = (x, y)
elif cmd in ('C', 'c'): # Cubic Bezier curves
for i in range(0, len(args), 6):
x1, y1, x2, y2, x, y = args[i:i+6]
if cmd.islower():
x1 += current_pos[0]; y1 += current_pos[1]
x2 += current_pos[0]; y2 += current_pos[1]
x += current_pos[0]; y += current_pos[1]
points.extend([(x1, y1), (x2, y2), (x, y)])
current_pos = (x, y)
elif cmd in ('A', 'a'): # Arc commands (start/end points only)
for i in range(0, len(args), 7):
x, y = args[i+5], args[i+6]
if cmd.islower():
x += current_pos[0]
y += current_pos[1]
points.append((x, y))
current_pos = (x, y)
return points
def calculate_bounding_box(svg_file: str) -> Tuple[float, float, float, float]:
"""Calculate true bounding box of all paths in SVG"""
tree = ET.parse(svg_file)
root = tree.getroot()
all_points = []
for path in root.findall('.//{http://www.w3.org/2000/svg}path'):
d = path.get('d', '')
all_points.extend(parse_svg_path(d))
if not all_points:
return (0, 0, 0, 0)
x_min = min(p[0] for p in all_points)
x_max = max(p[0] for p in all_points)
y_min = min(p[1] for p in all_points)
y_max = max(p[1] for p in all_points)
return (x_min, y_min, x_max, y_max)
def normalize_stroke_widths2(root, scale):
"""Normalize stroke widths to ensure consistent appearance after scaling"""
for elem in root.iter():
if 'stroke-width' in elem.attrib:
# Remove existing stroke-width
del elem.attrib['stroke-width']
# Apply scaled stroke width (e.g., 1px → 1/scale)
elem.set('stroke-width', f'{1/scale:.6f}px')
def apply_non_scaling_stroke(root):
for elem in root.iter():
if 'stroke' in elem.attrib and elem.attrib['stroke'] != 'none':
# set stroke-width=1no unit
elem.set('stroke-width', '1')
# set vector-effect
elem.set('vector-effect', 'non-scaling-stroke')
def scale_svg_file(input_path: str, output_path: str):
"""Scale SVG file with consistent stroke widths"""
print(f"\nProcessing: {os.path.basename(input_path)}")
tree = ET.parse(input_path)
root = tree.getroot()
# Calculate original bounding box
x_min, y_min, x_max, y_max = calculate_bounding_box(input_path)
width = x_max - x_min
height = y_max - y_min
print(f"Original bounding box: ({x_min:.3f}, {y_min:.3f}) to ({x_max:.3f}, {y_max:.3f})")
print(f"Original dimensions: {width:.3f} (w) × {height:.3f} (h)")
# Determine scaling base (larger dimension → 1000px)
if width > height:
scale = 1000.0 / width
new_width = 1000.0
new_height = round(height * scale,3)
print(f"Scaling base: Width (larger dimension)")
else:
scale = 1000.0 / height
new_height = 1000.0
new_width = round(width * scale,3)
print(f"Scaling base: Height (larger dimension)")
print(f"Scale factor: {scale:.6f}")
print(f"New dimensions: {new_width:.3f}px × {new_height:.3f}px")
print(f"ViewBox: 0 0 {new_width:.3f} {new_height:.3f}")
normalize_stroke_widths2(root, scale)
#apply_non_scaling_stroke(root)
#
# Update SVG attributes
root.set('viewBox', f'0 0 {new_width:.3f} {new_height:.3f}')
root.set('width', f'{new_width:.3f}')
root.set('height', f'{new_height:.3f}')
# Apply translation and scaling
for g in root.findall('{http://www.w3.org/2000/svg}g'):
transform = g.get('transform', '')
new_transform = f'translate({-x_min*scale},{-y_min*scale}) scale({scale})'
if transform:
new_transform = f'{transform} {new_transform}'
g.set('transform', new_transform)
# Save modified SVG
tree.write(output_path, encoding='utf-8', xml_declaration=True)
print(f"Finished processing: {os.path.basename(input_path)}")
def batch_process_svg(input_dir: str, output_dir: str):
"""Batch process SVG files in directory (non-recursive)"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
svg_files = [
f for f in os.listdir(input_dir)
if f.lower().endswith('.svg') and os.path.isfile(os.path.join(input_dir, f))
]
if not svg_files:
print("No SVG files found in the input directory!")
return
print(f"\nFound {len(svg_files)} SVG files to process")
for filename in svg_files:
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
scale_svg_file(input_path, output_path)
print("\nAll files processed successfully!")
if __name__ == '__main__':
input_dir = os.environ.get('RD_CONF_WORK')
output_dir = os.environ.get('RD_CONF_WORK')
batch_process_svg(input_dir, output_dir)
@@ -0,0 +1,160 @@
import re
import os
import xml.etree.ElementTree as ET
from typing import List, Dict, Tuple
def process_svg_file(input_path: str, output_path: str) -> bool:
"""Process SVG file while preserving original dimensions and viewBox"""
try:
# Parse SVG file
tree = ET.parse(input_path)
root = tree.getroot()
# Store original dimensions and viewBox
original_attrs = {
'width': root.attrib.get('width', '100%'),
'height': root.attrib.get('height', '100%'),
'viewBox': root.attrib.get('viewBox', '')
}
# Remove namespace prefixes
for elem in root.iter():
if '}' in elem.tag:
elem.tag = elem.tag.split('}', 1)[1]
for attr in list(elem.attrib):
if '}' in attr:
new_attr = attr.split('}', 1)[1]
elem.attrib[new_attr] = elem.attrib[attr]
del elem.attrib[attr]
# Process all groups with transforms
for g in root.findall('g'):
if 'transform' in g.attrib:
# Parse transform and convert to matrix
transform = g.attrib['transform']
matrix_str = convert_transform_to_matrix(transform)
# Update group attributes
g.attrib['transform'] = matrix_str
g.attrib['stroke'] = '#ffe31b' # Force stroke color
g.attrib['fill'] = 'none'
g.attrib['stroke-linecap'] = 'square'
g.attrib['vector-effect'] = 'non-scaling-stroke'
# Format paths within group
for path in g.findall('path'):
path.attrib['d'] = simplify_path_data(path.attrib.get('d', ''))
path.tail = '\n ' # Maintain consistent indentation
# Set root attributes while preserving original dimensions
root.attrib.update({
'version': '1.1',
'xmlns': 'http://www.w3.org/2000/svg',
'width': original_attrs['width'],
'height': original_attrs['height'],
'viewBox': original_attrs['viewBox'],
'fill-rule': 'evenodd',
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
'space': 'preserve'
})
# Format XML with proper indentation
indent(root)
# Generate XML string
xml_str = ET.tostring(root, encoding='unicode')
xml_str = '<?xml version="1.0" encoding="UTF-8"?>\n' + xml_str
# Clean up formatting
xml_str = re.sub(r'\n\s*\n', '\n', xml_str)
xml_str = re.sub(r'>\s+<', '>\n<', xml_str)
# Write to file
with open(output_path, 'w', encoding='utf-8') as f:
f.write(xml_str)
print(f"Processed: {os.path.basename(input_path)}")
return True
except Exception as e:
print(f"Failed {os.path.basename(input_path)}: {str(e)}")
return False
def convert_transform_to_matrix(transform: str) -> str:
"""Convert transform string to matrix notation with 4 decimal places"""
tx = ty = 0.0
translate_match = re.search(r'translate\(([^,]+),\s*([^)]+)\)', transform)
if translate_match:
tx = float(translate_match.group(1))
ty = float(translate_match.group(2))
scale = 1.0
scale_match = re.search(r'scale\(([^)]+)\)', transform)
if scale_match:
scale = float(scale_match.group(1))
return f"matrix({scale:.4f} 0 0 {scale:.4f} {tx:.2f} {ty:.2f})"
def simplify_path_data(d: str) -> str:
"""Simplify path data while maintaining relative commands"""
d = re.sub(r'\s+', ' ', d.strip())
def format_number(num_str: str) -> str:
try:
num = float(num_str)
if abs(num) < 0.001 and num != 0:
return f"{num:.0e}".replace('e-0', 'e-')
if abs(num - 1000) < 0.1:
return '1e3'
if abs(num - round(num, 3)) < 0.0001:
return f"{round(num, 3):g}"
return num_str
except ValueError:
return num_str
parts = []
for part in re.split(r'([ ,])', d):
if re.match(r'^[-+]?\d*\.?\d+$', part):
parts.append(format_number(part))
else:
parts.append(part)
return ''.join(parts).replace(' ,', ',')
def indent(elem: ET.Element, level: int = 0):
"""Properly indent XML elements"""
indent_str = "\n" + level * " "
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = indent_str + " "
if not elem.tail or not elem.tail.strip():
elem.tail = indent_str
for child in elem:
indent(child, level + 1)
if not elem.tail or not elem.tail.strip():
elem.tail = indent_str
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = indent_str
def batch_process_svgs(input_dir: str, output_dir: str):
"""Process all SVG files in a directory"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
success_count = 0
for filename in sorted(os.listdir(input_dir)):
if filename.lower().endswith('.svg'):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
if process_svg_file(input_path, output_path):
success_count += 1
print(f"\nCompleted: {success_count} files processed")
if __name__ == '__main__':
input_dir = os.environ.get('RD_CONF_WORK')
output_dir = os.environ.get('RD_CONF_OUTPUT_OFBOGEN')
# Example usage:
batch_process_svgs(input_dir, output_dir)
@@ -0,0 +1,194 @@
import os
import re
import json
from xml.etree import ElementTree as ET
from xml.dom import minidom
def extract_sivasnr(filename):
"""Extract numeric ID from filename"""
match = re.search(r'(\d+)\.svg$', filename)
return match.group(1) if match else None
def should_skip_stroke_width(element_attrib):
"""Check if element should skip stroke-width setting"""
# Check style attribute
if 'style' in element_attrib:
style = element_attrib['style'].lower()
if 'stroke:none' in style and 'fill:none' in style:
return True
# Check separate stroke and fill attributes
stroke = element_attrib.get('stroke', '').lower()
fill = element_attrib.get('fill', '').lower()
return stroke == 'none' and fill == 'none'
def create_xml_structure(svg_root):
"""Create target XML structure preserving all elements"""
# Create base structure
new_root = ET.Element("svg", xmlns="http://www.w3.org/2000/svg")
g_layer = ET.SubElement(new_root, "g", transform="rotate(0)")
# Add inner SVG container
inner_svg = ET.SubElement(g_layer, "svg", {
"viewBox": svg_root.attrib.get("viewBox", "0 0 1000 1000"),
"preserveAspectRatio": "none",
"position": "absolute",
"overflow": "visible"
})
# Transfer all content
for elem in svg_root:
if elem.tag.endswith("}g"):
# Process group with namespace
new_g = ET.SubElement(inner_svg, "g", attrib={
k: v for k, v in elem.attrib.items()
if not k.startswith("xmlns")
})
# Process all elements within group
for child in elem:
child_tag = child.tag.split("}")[-1] # Remove namespace
child_attrib = {}
# Preserve all original attributes (except namespace)
for k, v in child.attrib.items():
if not k.startswith("xmlns"):
child_attrib[k] = v
# Only add stroke-width if not stroke:none;fill:none
if not should_skip_stroke_width(child.attrib):
child_attrib["stroke-width"] = "1px"
# Create element with preserved attributes
ET.SubElement(new_g, child_tag, attrib=child_attrib)
else:
# Process standalone elements (path, circle, etc.)
elem_tag = elem.tag.split("}")[-1] # Remove namespace
elem_attrib = {}
# Preserve all original attributes (except namespace)
for k, v in elem.attrib.items():
if not k.startswith("xmlns"):
elem_attrib[k] = v
# Only add stroke-width if not stroke:none;fill:none
if not should_skip_stroke_width(elem.attrib):
elem_attrib["stroke-width"] = "1px"
ET.SubElement(inner_svg, elem_tag, attrib=elem_attrib)
return new_root
def format_xml(element):
"""Generate formatted XML string"""
# Generate XML with declaration
xml_str = ET.tostring(element, encoding="UTF-8", xml_declaration=True)
# Pretty format with 2-space indent
dom = minidom.parseString(xml_str)
pretty_xml = dom.toprettyxml(indent=" ", encoding="UTF-8").decode("UTF-8")
# Remove extra empty lines (preserve structure)
lines = []
for line in pretty_xml.split("\n"):
if line.strip() or line.lstrip().startswith("</"):
lines.append(line)
return "\n".join(lines)
def convert_svg_to_xml(svg_path, output_dir):
"""Convert SVG to target XML format"""
sivasnr = extract_sivasnr(os.path.basename(svg_path))
if not sivasnr:
raise ValueError(f"Invalid filename format: {os.path.basename(svg_path)}")
# Parse original SVG
try:
tree = ET.parse(svg_path)
svg_root = tree.getroot()
except Exception as e:
raise ValueError(f"SVG parsing error: {str(e)}")
# Build new structure
new_xml = create_xml_structure(svg_root)
formatted_xml = format_xml(new_xml)
# Ensure output directory exists
os.makedirs(output_dir, exist_ok=True)
output_path = os.path.join(output_dir, f"{sivasnr}.xml")
# Write file (UTF-8 encoding)
with open(output_path, "w", encoding="UTF-8") as f:
f.write(formatted_xml)
return f"SSG/shapes/svg/{sivasnr}.xml"
def update_txt_file(txt_path, xml_rel_path):
"""Update path in TXT file"""
try:
with open(txt_path, "r", encoding="UTF-8-sig") as f:
data = json.load(f)
if "srcSVG" not in data:
raise ValueError("Missing srcSVG field")
data["srcSVG"] = xml_rel_path
with open(txt_path, "w", encoding="UTF-8") as f:
json.dump(data, f, indent=4, ensure_ascii=False)
return True
except Exception as e:
print(f"Update failed {os.path.basename(txt_path)}: {str(e)}")
return False
def process_files(svg_dir, txt_dir, output_dir):
"""Batch process files"""
if not all(map(os.path.exists, [svg_dir, txt_dir])):
raise FileNotFoundError("Input directory not found")
results = {"success": 0, "failed": 0}
for svg_file in os.listdir(svg_dir):
if not svg_file.endswith(".svg"):
continue
svg_path = os.path.join(svg_dir, svg_file)
sivasnr = extract_sivasnr(svg_file)
if not sivasnr:
print(f"Skipping invalid file: {svg_file}")
results["failed"] += 1
continue
try:
# Convert file
xml_rel_path = convert_svg_to_xml(svg_path, output_dir)
# Update TXT
txt_path = os.path.join(txt_dir, f"{sivasnr}.txt")
if not os.path.exists(txt_path):
raise FileNotFoundError(f"Corresponding TXT file not found: {sivasnr}.txt")
if update_txt_file(txt_path, xml_rel_path):
print(f"Success: {svg_file}{sivasnr}.xml")
results["success"] += 1
else:
results["failed"] += 1
except Exception as e:
print(f"Processing failed {svg_file}: {str(e)}")
results["failed"] += 1
# Output report
print(f"\nProcessing complete: {results['success']} succeeded, {results['failed']} failed")
if __name__ == "__main__":
# Configuration - modify these paths as needed
SVG_INPUT_FOLDER = os.environ.get('RD_CONF_OUTPUT_OFBOGEN') # Folder containing SVG files
SVG_OUTPUT_FOLDER = os.environ.get("SVG_PATH","svg")
PRORPS_FOLDER = os.environ.get("PROPS_PATH", "props") # Folder containing txt files
# Start processing
process_files(SVG_INPUT_FOLDER, PRORPS_FOLDER, SVG_OUTPUT_FOLDER)
print("\nProcessing complete.")
@@ -1,154 +0,0 @@
''' Key Analysis Points:
Data Safety:
Uses safe_float() to handle potential data conversion issues
Creates copies of items to avoid modifying original data
Geometric Calculations:
Converts angles to radians for trigonometric functions
Performs width/height calculations based on center line measurements and angles
Rounds results to 3 decimal places for consistency
Validation:
Compares calculated values with original values
Flags discrepancies with "Please verify" status
Provides detailed difference metrics
Error Handling:
Preserves original data when processing fails
Tracks and reports all errors
Provides comprehensive statistics
Output:
Generates a new JSON file with calculated fields
Provides detailed console output for verification
Maintains original structure while adding new calculated fields
The script is designed to process SVG measurement data, perform geometric validations, and produce an enhanced dataset while providing thorough feedback about the processing results. '''
import json
import math
import os
def safe_float(value, default=0.0):
"""Safely convert value to float, return default if conversion fails"""
try:
return float(value) if value != '' else default
except (ValueError, TypeError):
return default
def calculate_attributes(item):
"""Calculate and add new attributes to the item based on geometric calculations"""
# Create a copy of the item to avoid modifying the original
processed_item = item.copy()
# Ensure all numeric fields have valid values using safe_float
processed_item["center_line_width_mm"] = safe_float(item.get("center_line_width_mm", 0))
processed_item["center_line_height_mm"] = safe_float(item.get("center_line_height_mm", 0))
processed_item["Objekt_width_mm"] = safe_float(item.get("Objekt_width_mm", 0))
processed_item["Objekt_height_mm"] = safe_float(item.get("Objekt_height_mm", 0))
processed_item["Winkel"] = safe_float(item.get("Winkel", 0))
# Convert angle to radians for trigonometric calculations
winkel_rad = math.radians(processed_item["Winkel"])
sin_value = math.sin(winkel_rad)
cos_value = math.cos(winkel_rad)
# Calculate new dimensions with 3 decimal places precision
if processed_item["Winkel"]!=180:
calculated_width = processed_item["center_line_width_mm"]
calculated_height = processed_item["center_line_height_mm"] + 21.040*2
else:
calculated_width = processed_item["center_line_width_mm"]+21.040
calculated_height = processed_item["center_line_height_mm"]+ 21.040 + 21.040
processed_item["calculated_objekt_width_mm"] = round(calculated_width, 3)
processed_item["calculated_objekt_height_mm"] = round(calculated_height, 3)
# Calculate differences between original and calculated values
width_diff = round(processed_item["Objekt_width_mm"] - processed_item["calculated_objekt_width_mm"], 3)
height_diff = round(processed_item["Objekt_height_mm"] - processed_item["calculated_objekt_height_mm"], 3)
# Prepare comparison results for console output (not saved to JSON)
comparison_results = {
"width": {
"calculated": processed_item["calculated_objekt_width_mm"],
"original": processed_item["Objekt_width_mm"],
"difference": width_diff,
"status": "OK" if abs(width_diff) < 0.001 else "Please verify"
},
"height": {
"calculated": processed_item["calculated_objekt_height_mm"],
"original": processed_item["Objekt_height_mm"],
"difference": height_diff,
"status": "OK" if abs(height_diff) < 0.001 else "Please verify"
}
}
return processed_item, comparison_results
def process_json_file(input_file, output_file):
"""Main function to process JSON file and generate output"""
# Read input file
try:
with open(input_file, 'r', encoding='utf-8') as f:
data = json.load(f)
except FileNotFoundError:
print(f"Error: Input file '{input_file}' not found")
return
except json.JSONDecodeError as e:
print(f"JSON parsing error: {e}")
return
# Verify data is a list
if not isinstance(data, list):
print("Error: JSON data should be an array")
return
# Process data
processed_data = []
error_items = []
print("\nStarting JSON data processing...\n")
for idx, item in enumerate(data, start=1):
try:
processed_item, comparison = calculate_attributes(item)
processed_data.append(processed_item)
# Print comparison results to console
print(f"Item {idx} [{item.get('SVGname', 'Unnamed')}] comparison results:")
print(f" Width: Calculated={comparison['width']['calculated']} | Original={comparison['width']['original']} | Difference={comparison['width']['difference']} | {comparison['width']['status']}")
print(f" Height: Calculated={comparison['height']['calculated']} | Original={comparison['height']['original']} | Difference={comparison['height']['difference']} | {comparison['height']['status']}")
print("-" * 60)
except Exception as e:
error_items.append((idx, str(e)))
# Preserve original data (without any processed fields)
processed_data.append(item)
# Print error message to console
print(f"Error processing item {idx} [{item.get('SVGname', 'Unnamed')}]: {str(e)}")
print("-" * 60)
# Write output file
try:
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(processed_data, f, indent=4, ensure_ascii=False)
print(f"\nProcessing complete. Results saved to {output_file}")
except IOError as e:
print(f"Error writing output file: {e}")
return
# Print statistics
total_items = len(data)
success_items = total_items - len(error_items)
print("\nProcessing statistics:")
print(f"Total items: {total_items}")
print(f"Successfully processed: {success_items}")
print(f"Failed items: {len(error_items)}")
# Example usage
if __name__ == "__main__":
json_path=os.environ.get("JSON_PATH","JSON")
input_filename = os.path.join(json_path,"1_SVGErfassung_updated_new_input.json") # Replace with your input filename
output_filename = os.path.join(json_path,"1_SVGErfassung_updated_new_output.json") # Replace with desired output filename
process_json_file(input_filename, output_filename)
@@ -1,150 +0,0 @@
"""
SVG XML Batch Modifier Script
This script:
1. Reads a JSON array of items
2. For each item, extracts the "Sivasnr" value
3. Locates and modifies the corresponding XML file
4. Provides comprehensive reporting
"""
import json
import os
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element, SubElement, tostring
def process_xml_file(xml_path):
"""
Process a single XML file with proper namespace handling
Returns modification statistics
"""
try:
tree = ET.parse(xml_path)
root = tree.getroot()
# Register and handle SVG namespace
ET.register_namespace('', 'http://www.w3.org/2000/svg')
namespaces = {'svg': 'http://www.w3.org/2000/svg'}
stats = {
'ffe31b_groups': 0,
'ec2525_groups': 0,
'elements_modified': 0,
'modified': False
}
# Process all group elements
for g in root.findall('.//svg:g', namespaces):
stroke = g.get('stroke')
if stroke == "#ffe31b":
stats['ffe31b_groups'] += 1
if 'stroke-width' in g.attrib:
del g.attrib['stroke-width']
stats['modified'] = True
if 'stroke-miterlimit' in g.attrib:
del g.attrib['stroke-miterlimit']
stats['modified'] = True
for child in g.findall('.//svg:path', namespaces):
child.set('stroke-width', '1px')
stats['elements_modified'] += 1
stats['modified'] = True
elif stroke == "#ec2525":
stats['ec2525_groups'] += 1
for attr in ['stroke', 'stroke-width', 'stroke-linejoin']:
if attr in g.attrib:
del g.attrib[attr]
stats['modified'] = True
for child in g.findall('.//svg:path[@stroke-width="1px"]', namespaces):
del child.attrib['stroke-width']
child.set('style', 'stroke:#ec2525;stroke-width:2px')
stats['elements_modified'] += 1
stats['modified'] = True
# Save changes if modified
if stats['modified']:
xml_str = ET.tostring(root, encoding='unicode')
xml_str = xml_str.replace('><', '>\n<').replace('</svg>', '\n</svg>')
with open(xml_path, 'w', encoding='utf-8') as f:
f.write(xml_str)
return stats
except Exception as e:
print(f" Error processing file: {str(e)}")
return None
def main():
"""
Main processing function
"""
json_path=os.environ.get("JSON_PATH","JSON")
json_file_path = os.path.join(json_path,"1_SVGErfassung_updated_new_output.json")
svg_folder_path = os.environ.get("XML_PATH","svg")
try:
# Read and parse JSON file
with open(json_file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
# Verify we have a list of items
if not isinstance(data, list):
print("Error: JSON data should be an array of items")
return
print(f"\nFound {len(data)} items in JSON file")
# Process each item in the JSON array
for index, item in enumerate(data, 1):
if not isinstance(item, dict):
print(f"\nItem {index}: Not a dictionary, skipping")
continue
sivasnr = item.get("Sivasnr")
if not sivasnr:
print(f"\nItem {index}: Missing 'Sivasnr' value, skipping")
continue
print(f"\nProcessing item {index}: Sivasnr = {sivasnr}")
# Build XML filename and path
xml_filename = f"{sivasnr}.xml"
xml_path = os.path.join(svg_folder_path, xml_filename)
if not os.path.exists(xml_path):
print(f" XML file not found: {xml_path}")
continue
print(f" Found XML file: {xml_path}")
# Process the XML file
stats = process_xml_file(xml_path)
if stats is None:
print(" Processing failed")
elif stats['modified']:
print(" File successfully modified")
print(f" - #ffe31b groups: {stats['ffe31b_groups']}")
print(f" - #ec2525 groups: {stats['ec2525_groups']}")
print(f" - Elements modified: {stats['elements_modified']}")
else:
print(" No modifications needed")
print("\nProcessing complete")
except FileNotFoundError:
print("\nError: JSON file not found")
except json.JSONDecodeError:
print("\nError: Invalid JSON format")
except Exception as e:
print(f"\nUnexpected error: {str(e)}")
if __name__ == "__main__":
print("SVG XML Batch Modifier - Starting execution")
main()
@@ -3,7 +3,7 @@
"SVGname": "APB_110_R400_45_400_821104021.svg",
"Sivasnr": "821104021",
"Winkel":45,
"center_line_width_mm": 669.491,
"center_line_width_mm": 669.49,
"center_line_height_mm": 399.505,
"Objekt_width_mm":684.367,
"Objekt_height_mm":435.421
@@ -23,8 +23,8 @@
"Winkel":90,
"center_line_width_mm": 500,
"center_line_height_mm": 500,
"Objekt_width_mm":521.040,
"Objekt_height_mm":521.040
"Objekt_width_mm":521.039,
"Objekt_height_mm":521.039
},
{
"SVGname": "APB_110_R500_90_550_550_821104030.svg",
@@ -32,8 +32,8 @@
"Winkel":90,
"center_line_width_mm": 550,
"center_line_height_mm": 550,
"Objekt_width_mm":571.040,
"Objekt_height_mm":571.040
"Objekt_width_mm":571.039,
"Objekt_height_mm":571.039
},
{
"SVGname": "APB_110_R550_22_5_84_821104025.svg",
@@ -42,7 +42,7 @@
"center_line_width_mm": 514.491,
"center_line_height_mm": 122.230,
"Objekt_width_mm":522.542,
"Objekt_height_mm":162.707
"Objekt_height_mm":162.706
},
{
"SVGname": "APB_110_R550_22_5_84_821104025.svg",
@@ -51,7 +51,7 @@
"center_line_width_mm": 514.491,
"center_line_height_mm": 122.230,
"Objekt_width_mm":522.542,
"Objekt_height_mm":162.707
"Objekt_height_mm":162.706
},
{
"SVGname": "APB_110_R550_45_191_821104029.svg",
@@ -60,7 +60,7 @@
"center_line_width_mm": 551.606,
"center_line_height_mm": 190.792 ,
"Objekt_width_mm":566.483,
"Objekt_height_mm":226.709
"Objekt_height_mm":226.708
},
{
"SVGname": "APB_110_R550_45_205_821104037.svg",
@@ -69,7 +69,7 @@
"center_line_width_mm": 537.249,
"center_line_height_mm": 204.932,
"Objekt_width_mm":552.126,
"Objekt_height_mm":240.849
"Objekt_height_mm":240.848
},
{
"SVGname": "APB_110_R550_45_232_821104026.svg",
@@ -113,7 +113,7 @@
"Winkel":67.5,
"center_line_width_mm": 758.190,
"center_line_height_mm": 496.584,
"Objekt_width_mm":777.628,
"Objekt_width_mm":777.627,
"Objekt_height_mm":525.674
},
{
@@ -122,8 +122,8 @@
"Winkel":90,
"center_line_width_mm": 900,
"center_line_height_mm": 605,
"Objekt_width_mm":921.040,
"Objekt_height_mm":626.040
"Objekt_width_mm":921.039,
"Objekt_height_mm":626.039
},
{
"SVGname": "APB_110_R630_45_400_821104031.svg",
@@ -131,7 +131,7 @@
"Winkel":45,
"center_line_width_mm": 865.613,
"center_line_height_mm": 300.559,
"Objekt_width_mm":880.491,
"Objekt_width_mm":880.49,
"Objekt_height_mm":336.475
},
{
@@ -140,7 +140,7 @@
"Winkel":45,
"center_line_width_mm": 865.613,
"center_line_height_mm": 300.559,
"Objekt_width_mm":880.491,
"Objekt_width_mm":880.49,
"Objekt_height_mm":336.475
},
{
@@ -149,8 +149,8 @@
"Winkel":90,
"center_line_width_mm": 800,
"center_line_height_mm": 800,
"Objekt_width_mm":821.040,
"Objekt_height_mm":821.040
"Objekt_width_mm":821.039,
"Objekt_height_mm":821.039
},
{
"SVGname": "APB_110_R630_90_800_800_821104033.svg",
@@ -158,8 +158,8 @@
"Winkel":90,
"center_line_width_mm": 800,
"center_line_height_mm": 800,
"Objekt_width_mm":821.040,
"Objekt_height_mm":821.040
"Objekt_width_mm":821.039,
"Objekt_height_mm":821.039
},
{
@@ -168,8 +168,8 @@
"Winkel":90,
"center_line_width_mm": 690,
"center_line_height_mm": 850,
"Objekt_width_mm":711.040,
"Objekt_height_mm":871.040
"Objekt_width_mm":711.039,
"Objekt_height_mm":871.039
},
{
"SVGname": "APB_110_R630_90_850_870_821104035.svg",
@@ -177,8 +177,8 @@
"Winkel":90,
"center_line_width_mm": 850,
"center_line_height_mm": 870,
"Objekt_width_mm":871.04,
"Objekt_height_mm":891.04
"Objekt_width_mm":871.039,
"Objekt_height_mm":891.039
},
{
"SVGname": "APB_110_R630_90_850_890_821104034.svg",
@@ -186,8 +186,8 @@
"Winkel":90,
"center_line_width_mm": 890,
"center_line_height_mm": 850,
"Objekt_width_mm":911.040,
"Objekt_height_mm":871.040
"Objekt_width_mm":911.039,
"Objekt_height_mm":871.039
},
{
"SVGname": "APB_110_R650_180_L_150_821104043.svg",
@@ -196,7 +196,7 @@
"center_line_width_mm": 800,
"center_line_height_mm": 1300,
"Objekt_width_mm":800,
"Objekt_height_mm":1342.080
"Objekt_height_mm":1342.078
},
{
"SVGname": "APB_110_R650_180_L_150_821104043.svg",
@@ -204,8 +204,8 @@
"Winkel":180,
"center_line_width_mm": 800,
"center_line_height_mm": 1300,
"Objekt_width_mm":821.040,
"Objekt_height_mm":1342.080
"Objekt_width_mm":800,
"Objekt_height_mm":1342.078
},
{
"SVGname": "APB_60_R515_90_650_821094040.svg",
@@ -213,8 +213,8 @@
"Winkel":90,
"center_line_width_mm": 650.0,
"center_line_height_mm": 650.0,
"Objekt_width_mm": 671.040,
"Objekt_height_mm": 671.040
"Objekt_width_mm": 671.039,
"Objekt_height_mm": 671.039
},
{
"SVGname": "APB_60_R515_90_810_821094101.svg",
@@ -222,7 +222,7 @@
"Winkel":90,
"center_line_width_mm": 810.0,
"center_line_height_mm": 810.0,
"Objekt_width_mm": 831.04,
"Objekt_height_mm": 831.04
"Objekt_width_mm": 831.039,
"Objekt_height_mm": 831.039
}
]
@@ -1,277 +0,0 @@
[
{
"SVGname": "APB_110_R400_45_400_821104021.svg",
"Sivasnr": "821104021",
"Winkel": 45.0,
"center_line_width_mm": 669.491,
"center_line_height_mm": 399.505,
"Objekt_width_mm": 684.367,
"Objekt_height_mm": 435.421,
"calculated_objekt_width_mm": 684.369,
"calculated_objekt_height_mm": 435.423
},
{
"SVGname": "APB_110_R400_67_5_339_821104024.svg",
"Sivasnr": "821104024",
"Winkel": 67.5,
"center_line_width_mm": 507.82,
"center_line_height_mm": 339.315,
"Objekt_width_mm": 527.258,
"Objekt_height_mm": 368.405,
"calculated_objekt_width_mm": 527.258,
"calculated_objekt_height_mm": 368.407
},
{
"SVGname": "APB_110_R400_90_500_821104022.svg",
"Sivasnr": "821104022",
"Winkel": 90.0,
"center_line_width_mm": 500.0,
"center_line_height_mm": 500.0,
"Objekt_width_mm": 521.04,
"Objekt_height_mm": 521.04,
"calculated_objekt_width_mm": 521.04,
"calculated_objekt_height_mm": 521.04
},
{
"SVGname": "APB_110_R500_90_550_550_821104030.svg",
"Sivasnr": "821104030",
"Winkel": 90.0,
"center_line_width_mm": 550.0,
"center_line_height_mm": 550.0,
"Objekt_width_mm": 571.04,
"Objekt_height_mm": 571.04,
"calculated_objekt_width_mm": 571.04,
"calculated_objekt_height_mm": 571.04
},
{
"SVGname": "APB_110_R550_22_5_84_821104025.svg",
"Sivasnr": "821104025",
"Winkel": 22.5,
"center_line_width_mm": 514.491,
"center_line_height_mm": 122.23,
"Objekt_width_mm": 522.542,
"Objekt_height_mm": 162.707,
"calculated_objekt_width_mm": 522.543,
"calculated_objekt_height_mm": 162.708
},
{
"SVGname": "APB_110_R550_22_5_84_821104025.svg",
"Sivasnr": "OFBogen22",
"Winkel": 22.5,
"center_line_width_mm": 514.491,
"center_line_height_mm": 122.23,
"Objekt_width_mm": 522.542,
"Objekt_height_mm": 162.707,
"calculated_objekt_width_mm": 522.543,
"calculated_objekt_height_mm": 162.708
},
{
"SVGname": "APB_110_R550_45_191_821104029.svg",
"Sivasnr": "821104029",
"Winkel": 45.0,
"center_line_width_mm": 551.606,
"center_line_height_mm": 190.792,
"Objekt_width_mm": 566.483,
"Objekt_height_mm": 226.709,
"calculated_objekt_width_mm": 566.484,
"calculated_objekt_height_mm": 226.71
},
{
"SVGname": "APB_110_R550_45_205_821104037.svg",
"Sivasnr": "821104037",
"Winkel": 45.0,
"center_line_width_mm": 537.249,
"center_line_height_mm": 204.932,
"Objekt_width_mm": 552.126,
"Objekt_height_mm": 240.849,
"calculated_objekt_width_mm": 552.127,
"calculated_objekt_height_mm": 240.85
},
{
"SVGname": "APB_110_R550_45_232_821104026.svg",
"Sivasnr": "821104026",
"Winkel": 45.0,
"center_line_width_mm": 595.265,
"center_line_height_mm": 265.998,
"Objekt_width_mm": 610.142,
"Objekt_height_mm": 301.914,
"calculated_objekt_width_mm": 610.143,
"calculated_objekt_height_mm": 301.916
},
{
"SVGname": "APB_110_R550_67_5_420_821104028.svg",
"Sivasnr": "821104028",
"Winkel": 67.5,
"center_line_width_mm": 582.427,
"center_line_height_mm": 419.902,
"Objekt_width_mm": 601.865,
"Objekt_height_mm": 448.992,
"calculated_objekt_width_mm": 601.865,
"calculated_objekt_height_mm": 448.994
},
{
"SVGname": "APB_110_R550_67_5_432_821104027.svg",
"Sivasnr": "821104027",
"Winkel": 67.5,
"center_line_width_mm": 748.658,
"center_line_height_mm": 530.305,
"Objekt_width_mm": 768.095,
"Objekt_height_mm": 559.396,
"calculated_objekt_width_mm": 768.096,
"calculated_objekt_height_mm": 559.397
},
{
"SVGname": "APB_110_R550_67_5_432_821104027.svg",
"Sivasnr": "OFBogen67",
"Winkel": 67.5,
"center_line_width_mm": 748.658,
"center_line_height_mm": 530.305,
"Objekt_width_mm": 768.095,
"Objekt_height_mm": 559.396,
"calculated_objekt_width_mm": 768.096,
"calculated_objekt_height_mm": 559.397
},
{
"SVGname": "APB_110_R550_67_5_L_185_170_821104065.svg",
"Sivasnr": "821104065",
"Winkel": 67.5,
"center_line_width_mm": 758.19,
"center_line_height_mm": 496.584,
"Objekt_width_mm": 777.628,
"Objekt_height_mm": 525.674,
"calculated_objekt_width_mm": 777.628,
"calculated_objekt_height_mm": 525.676
},
{
"SVGname": "APB_110_R550_90_900_605_821104066.svg",
"Sivasnr": "821104066",
"Winkel": 90.0,
"center_line_width_mm": 900.0,
"center_line_height_mm": 605.0,
"Objekt_width_mm": 921.04,
"Objekt_height_mm": 626.04,
"calculated_objekt_width_mm": 921.04,
"calculated_objekt_height_mm": 626.04
},
{
"SVGname": "APB_110_R630_45_400_821104031.svg",
"Sivasnr": "821104031",
"Winkel": 45.0,
"center_line_width_mm": 865.613,
"center_line_height_mm": 300.559,
"Objekt_width_mm": 880.491,
"Objekt_height_mm": 336.475,
"calculated_objekt_width_mm": 880.491,
"calculated_objekt_height_mm": 336.477
},
{
"SVGname": "APB_110_R630_45_400_821104031.svg",
"Sivasnr": "OFBogen45",
"Winkel": 45.0,
"center_line_width_mm": 865.613,
"center_line_height_mm": 300.559,
"Objekt_width_mm": 880.491,
"Objekt_height_mm": 336.475,
"calculated_objekt_width_mm": 880.491,
"calculated_objekt_height_mm": 336.477
},
{
"SVGname": "APB_110_R630_90_800_800_821104033.svg",
"Sivasnr": "821104033",
"Winkel": 90.0,
"center_line_width_mm": 800.0,
"center_line_height_mm": 800.0,
"Objekt_width_mm": 821.04,
"Objekt_height_mm": 821.04,
"calculated_objekt_width_mm": 821.04,
"calculated_objekt_height_mm": 821.04
},
{
"SVGname": "APB_110_R630_90_800_800_821104033.svg",
"Sivasnr": "OFBogen90",
"Winkel": 90.0,
"center_line_width_mm": 800.0,
"center_line_height_mm": 800.0,
"Objekt_width_mm": 821.04,
"Objekt_height_mm": 821.04,
"calculated_objekt_width_mm": 821.04,
"calculated_objekt_height_mm": 821.04
},
{
"SVGname": "APB_110_R630_90_850_690_821104041.svg",
"Sivasnr": "821104041",
"Winkel": 90.0,
"center_line_width_mm": 690.0,
"center_line_height_mm": 850.0,
"Objekt_width_mm": 711.04,
"Objekt_height_mm": 871.04,
"calculated_objekt_width_mm": 711.04,
"calculated_objekt_height_mm": 871.04
},
{
"SVGname": "APB_110_R630_90_850_870_821104035.svg",
"Sivasnr": "821104035",
"Winkel": 90.0,
"center_line_width_mm": 850.0,
"center_line_height_mm": 870.0,
"Objekt_width_mm": 871.04,
"Objekt_height_mm": 891.04,
"calculated_objekt_width_mm": 871.04,
"calculated_objekt_height_mm": 891.04
},
{
"SVGname": "APB_110_R630_90_850_890_821104034.svg",
"Sivasnr": "821104034",
"Winkel": 90.0,
"center_line_width_mm": 890.0,
"center_line_height_mm": 850.0,
"Objekt_width_mm": 911.04,
"Objekt_height_mm": 871.04,
"calculated_objekt_width_mm": 911.04,
"calculated_objekt_height_mm": 871.04
},
{
"SVGname": "APB_110_R650_180_L_150_821104043.svg",
"Sivasnr": "821104043",
"Winkel": 180.0,
"center_line_width_mm": 800.0,
"center_line_height_mm": 1300.0,
"Objekt_width_mm": 800,
"Objekt_height_mm": 1342.08,
"calculated_objekt_width_mm": 800,
"calculated_objekt_height_mm": 1342.08
},
{
"SVGname": "APB_110_R650_180_L_150_821104043.svg",
"Sivasnr": "OFBogen180",
"Winkel": 180.0,
"center_line_width_mm": 800.0,
"center_line_height_mm": 1300.0,
"Objekt_width_mm": 800.0,
"Objekt_height_mm": 1342.08,
"calculated_objekt_width_mm": 800.0,
"calculated_objekt_height_mm": 1342.08
},
{
"SVGname": "APB_60_R515_90_650_821094040.svg",
"Sivasnr": "821094040",
"Winkel": 90.0,
"center_line_width_mm": 650.0,
"center_line_height_mm": 650.0,
"Objekt_width_mm": 671.04,
"Objekt_height_mm": 671.04,
"calculated_objekt_width_mm": 671.04,
"calculated_objekt_height_mm": 671.04
},
{
"SVGname": "APB_60_R515_90_810_821094101.svg",
"Sivasnr": "821094101",
"Winkel": 90.0,
"center_line_width_mm": 810.0,
"center_line_height_mm": 810.0,
"Objekt_width_mm": 831.04,
"Objekt_height_mm": 831.04,
"calculated_objekt_width_mm": 831.04,
"calculated_objekt_height_mm": 831.04
}
]
@@ -3,28 +3,26 @@
"SVGname": "APB_110_R400_45_400_821104021.svg",
"Sivasnr": "821104021",
"Winkel": 45.0,
"center_line_width_mm": 669.491,
"center_line_width_mm": 669.49,
"center_line_height_mm": 399.505,
"Objekt_width_mm": 684.367,
"Objekt_height_mm": 435.421,
"calculated_objekt_width_mm": 684.369,
"calculated_objekt_height_mm": 435.423,
"Objekt_width_px": 2586.584,
"Objekt_height_px": 1645.6857,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 638.912,
"calculated_SVG_height_px": 636.239,
"scale_factor": 1.4612043,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 48.119,
"y": 48.319,
"direction": 270.0
},
{
"id": "cp2",
"x": 978.263,
"y": 961.795,
"x": 978.262,
"y": 965.833,
"direction": 135.0
}
]
@@ -37,24 +35,22 @@
"center_line_height_mm": 339.315,
"Objekt_width_mm": 527.258,
"Objekt_height_mm": 368.405,
"calculated_objekt_width_mm": 527.258,
"calculated_objekt_height_mm": 368.407,
"Objekt_width_px": 1992.7862,
"Objekt_height_px": 1392.3969,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 700.764,
"calculated_SVG_height_px": 698.7187,
"scale_factor": 1.8966047,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 56.944,
"y": 57.109,
"direction": 270.0
},
{
"id": "cp2",
"x": 963.134,
"y": 975.294,
"y": 978.147,
"direction": 157.5
}
]
@@ -65,25 +61,23 @@
"Winkel": 90.0,
"center_line_width_mm": 500.0,
"center_line_height_mm": 500.0,
"Objekt_width_mm": 521.04,
"Objekt_height_mm": 521.04,
"calculated_objekt_width_mm": 521.04,
"calculated_objekt_height_mm": 521.04,
"Objekt_width_px": 1969.2851,
"Objekt_height_px": 1969.2851,
"Objekt_width_mm": 521.039,
"Objekt_height_mm": 521.039,
"Objekt_width_px": 1969.2813,
"Objekt_height_px": 1969.2813,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 1000.0,
"scale_factor": 1.919238,
"calculated_SVG_height_px": 1000,
"scale_factor": 1.9192421,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 40.381,
"y": 40.379,
"direction": 270.0
},
{
"id": "cp2",
"x": 959.619,
"x": 959.621,
"y": 1000.0,
"direction": 180.0
}
@@ -95,25 +89,23 @@
"Winkel": 90.0,
"center_line_width_mm": 550.0,
"center_line_height_mm": 550.0,
"Objekt_width_mm": 571.04,
"Objekt_height_mm": 571.04,
"calculated_objekt_width_mm": 571.04,
"calculated_objekt_height_mm": 571.04,
"Objekt_width_px": 2158.2614,
"Objekt_height_px": 2158.2614,
"Objekt_width_mm": 571.039,
"Objekt_height_mm": 571.039,
"Objekt_width_px": 2158.2577,
"Objekt_height_px": 2158.2577,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 1000.0,
"scale_factor": 1.751191,
"calculated_SVG_height_px": 1000,
"scale_factor": 1.7511939,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 36.845,
"y": 36.844,
"direction": 270.0
},
{
"id": "cp2",
"x": 963.155,
"x": 963.157,
"y": 1000.0,
"direction": 180.0
}
@@ -126,25 +118,23 @@
"center_line_width_mm": 514.491,
"center_line_height_mm": 122.23,
"Objekt_width_mm": 522.542,
"Objekt_height_mm": 162.707,
"calculated_objekt_width_mm": 522.543,
"calculated_objekt_height_mm": 162.708,
"Objekt_height_mm": 162.706,
"Objekt_width_px": 1974.9619,
"Objekt_height_px": 614.9556,
"Objekt_height_px": 614.9518,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 316.314,
"calculated_SVG_height_px": 311.374,
"scale_factor": 1.9137218,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 127.293,
"y": 129.307,
"direction": 270.0
},
{
"id": "cp2",
"x": 984.593,
"y": 866.794,
"y": 880.54,
"direction": 112.5
}
]
@@ -156,25 +146,23 @@
"center_line_width_mm": 514.491,
"center_line_height_mm": 122.23,
"Objekt_width_mm": 522.542,
"Objekt_height_mm": 162.707,
"calculated_objekt_width_mm": 522.543,
"calculated_objekt_height_mm": 162.708,
"Objekt_height_mm": 162.706,
"Objekt_width_px": 1974.9619,
"Objekt_height_px": 614.9556,
"Objekt_height_px": 614.9518,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 316.314,
"calculated_SVG_height_px": 311.374,
"scale_factor": 1.9137218,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 127.293,
"y": 129.307,
"direction": 270.0
},
{
"id": "cp2",
"x": 984.593,
"y": 866.794,
"y": 880.54,
"direction": 112.5
}
]
@@ -186,25 +174,23 @@
"center_line_width_mm": 551.606,
"center_line_height_mm": 190.792,
"Objekt_width_mm": 566.483,
"Objekt_height_mm": 226.709,
"calculated_objekt_width_mm": 566.484,
"calculated_objekt_height_mm": 226.71,
"Objekt_height_mm": 226.708,
"Objekt_width_px": 2141.0381,
"Objekt_height_px": 856.8529,
"Objekt_height_px": 856.8491,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 402.877,
"calculated_SVG_height_px": 400.2026,
"scale_factor": 1.765278,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 92.191,
"y": 92.803,
"direction": 270.0
},
{
"id": "cp2",
"x": 973.738,
"y": 928.18,
"y": 934.379,
"direction": 135.0
}
]
@@ -216,25 +202,23 @@
"center_line_width_mm": 537.249,
"center_line_height_mm": 204.932,
"Objekt_width_mm": 552.126,
"Objekt_height_mm": 240.849,
"calculated_objekt_width_mm": 552.127,
"calculated_objekt_height_mm": 240.85,
"Objekt_height_mm": 240.848,
"Objekt_width_px": 2086.7755,
"Objekt_height_px": 910.2954,
"Objekt_height_px": 910.2917,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 438.894,
"calculated_SVG_height_px": 436.2193,
"scale_factor": 1.8111808,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 86.826,
"y": 87.354,
"direction": 270.0
},
{
"id": "cp2",
"x": 973.055,
"y": 932.517,
"y": 938.231,
"direction": 135.0
}
]
@@ -247,24 +231,22 @@
"center_line_height_mm": 265.998,
"Objekt_width_mm": 610.142,
"Objekt_height_mm": 301.914,
"calculated_objekt_width_mm": 610.143,
"calculated_objekt_height_mm": 301.916,
"Objekt_width_px": 2306.0485,
"Objekt_height_px": 1141.0923,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 497.498,
"calculated_SVG_height_px": 494.8258,
"scale_factor": 1.6389627,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 69.314,
"y": 69.686,
"direction": 270.0
},
{
"id": "cp2",
"x": 975.617,
"y": 945.621,
"y": 950.725,
"direction": 135.0
}
]
@@ -277,24 +259,22 @@
"center_line_height_mm": 419.902,
"Objekt_width_mm": 601.865,
"Objekt_height_mm": 448.992,
"calculated_objekt_width_mm": 601.865,
"calculated_objekt_height_mm": 448.994,
"Objekt_width_px": 2274.7654,
"Objekt_height_px": 1696.9777,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 748.047,
"calculated_SVG_height_px": 746.0012,
"scale_factor": 1.6615022,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 46.732,
"y": 46.859,
"direction": 270.0
},
{
"id": "cp2",
"x": 967.704,
"y": 979.385,
"y": 982.069,
"direction": 157.5
}
]
@@ -307,24 +287,22 @@
"center_line_height_mm": 530.305,
"Objekt_width_mm": 768.095,
"Objekt_height_mm": 559.396,
"calculated_objekt_width_mm": 768.096,
"calculated_objekt_height_mm": 559.397,
"Objekt_width_px": 2903.0362,
"Objekt_height_px": 2114.2526,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 730.336,
"calculated_SVG_height_px": 728.2901,
"scale_factor": 1.3019223,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 37.507,
"y": 37.61,
"direction": 270.0
},
{
"id": "cp2",
"x": 974.695,
"y": 982.847,
"y": 985.606,
"direction": 157.5
}
]
@@ -337,24 +315,22 @@
"center_line_height_mm": 530.305,
"Objekt_width_mm": 768.095,
"Objekt_height_mm": 559.396,
"calculated_objekt_width_mm": 768.096,
"calculated_objekt_height_mm": 559.397,
"Objekt_width_px": 2903.0362,
"Objekt_height_px": 2114.2526,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 730.336,
"calculated_SVG_height_px": 728.2901,
"scale_factor": 1.3019223,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 37.507,
"y": 37.61,
"direction": 270.0
},
{
"id": "cp2",
"x": 974.695,
"y": 982.847,
"y": 985.606,
"direction": 157.5
}
]
@@ -365,26 +341,24 @@
"Winkel": 67.5,
"center_line_width_mm": 758.19,
"center_line_height_mm": 496.584,
"Objekt_width_mm": 777.628,
"Objekt_width_mm": 777.627,
"Objekt_height_mm": 525.674,
"calculated_objekt_width_mm": 777.628,
"calculated_objekt_height_mm": 525.676,
"Objekt_width_px": 2939.0665,
"Objekt_width_px": 2939.0627,
"Objekt_height_px": 1986.7994,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 678.042,
"scale_factor": 1.2859619,
"calculated_SVG_height_px": 675.9976,
"scale_factor": 1.2859636,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 39.904,
"y": 40.023,
"direction": 270.0
},
{
"id": "cp2",
"x": 975.003,
"y": 981.716,
"x": 975.005,
"y": 984.685,
"direction": 157.5
}
]
@@ -395,26 +369,24 @@
"Winkel": 90.0,
"center_line_width_mm": 900.0,
"center_line_height_mm": 605.0,
"Objekt_width_mm": 921.04,
"Objekt_height_mm": 626.04,
"calculated_objekt_width_mm": 921.04,
"calculated_objekt_height_mm": 626.04,
"Objekt_width_px": 3481.0961,
"Objekt_height_px": 2366.1355,
"Objekt_width_mm": 921.039,
"Objekt_height_mm": 626.039,
"Objekt_width_px": 3481.0923,
"Objekt_height_px": 2366.1317,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 681.6,
"scale_factor": 1.0857292,
"calculated_SVG_height_px": 679.7096,
"scale_factor": 1.0857304,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 33.515,
"y": 33.607,
"direction": 270.0
},
{
"id": "cp2",
"x": 977.156,
"y": 997.227,
"x": 977.157,
"y": 1000.0,
"direction": 180.0
}
]
@@ -425,26 +397,24 @@
"Winkel": 45.0,
"center_line_width_mm": 865.613,
"center_line_height_mm": 300.559,
"Objekt_width_mm": 880.491,
"Objekt_width_mm": 880.49,
"Objekt_height_mm": 336.475,
"calculated_objekt_width_mm": 880.491,
"calculated_objekt_height_mm": 336.477,
"Objekt_width_px": 3327.84,
"Objekt_width_px": 3327.8362,
"Objekt_height_px": 1271.7165,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 384.817,
"scale_factor": 1.13573,
"calculated_SVG_height_px": 382.1452,
"scale_factor": 1.1357312,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 62.096,
"y": 62.528,
"direction": 270.0
},
{
"id": "cp2",
"x": 983.103,
"y": 949.152,
"x": 983.104,
"y": 955.786,
"direction": 135.0
}
]
@@ -455,26 +425,24 @@
"Winkel": 45.0,
"center_line_width_mm": 865.613,
"center_line_height_mm": 300.559,
"Objekt_width_mm": 880.491,
"Objekt_width_mm": 880.49,
"Objekt_height_mm": 336.475,
"calculated_objekt_width_mm": 880.491,
"calculated_objekt_height_mm": 336.477,
"Objekt_width_px": 3327.84,
"Objekt_width_px": 3327.8362,
"Objekt_height_px": 1271.7165,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 384.817,
"scale_factor": 1.13573,
"calculated_SVG_height_px": 382.1452,
"scale_factor": 1.1357312,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 62.096,
"y": 62.528,
"direction": 270.0
},
{
"id": "cp2",
"x": 983.103,
"y": 949.152,
"x": 983.104,
"y": 955.786,
"direction": 135.0
}
]
@@ -485,25 +453,23 @@
"Winkel": 90.0,
"center_line_width_mm": 800.0,
"center_line_height_mm": 800.0,
"Objekt_width_mm": 821.04,
"Objekt_height_mm": 821.04,
"calculated_objekt_width_mm": 821.04,
"calculated_objekt_height_mm": 821.04,
"Objekt_width_px": 3103.1433,
"Objekt_height_px": 3103.1433,
"Objekt_width_mm": 821.039,
"Objekt_height_mm": 821.039,
"Objekt_width_px": 3103.1396,
"Objekt_height_px": 3103.1396,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 1000.0,
"scale_factor": 1.217967,
"calculated_SVG_height_px": 1000,
"scale_factor": 1.2179689,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 25.626,
"y": 25.625,
"direction": 270.0
},
{
"id": "cp2",
"x": 974.374,
"x": 974.375,
"y": 1000.0,
"direction": 180.0
}
@@ -515,25 +481,23 @@
"Winkel": 90.0,
"center_line_width_mm": 800.0,
"center_line_height_mm": 800.0,
"Objekt_width_mm": 821.04,
"Objekt_height_mm": 821.04,
"calculated_objekt_width_mm": 821.04,
"calculated_objekt_height_mm": 821.04,
"Objekt_width_px": 3103.1433,
"Objekt_height_px": 3103.1433,
"Objekt_width_mm": 821.039,
"Objekt_height_mm": 821.039,
"Objekt_width_px": 3103.1396,
"Objekt_height_px": 3103.1396,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 1000.0,
"scale_factor": 1.217967,
"calculated_SVG_height_px": 1000,
"scale_factor": 1.2179689,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 25.626,
"y": 25.625,
"direction": 270.0
},
{
"id": "cp2",
"x": 974.374,
"x": 974.375,
"y": 1000.0,
"direction": 180.0
}
@@ -545,25 +509,23 @@
"Winkel": 90.0,
"center_line_width_mm": 690.0,
"center_line_height_mm": 850.0,
"Objekt_width_mm": 711.04,
"Objekt_height_mm": 871.04,
"calculated_objekt_width_mm": 711.04,
"calculated_objekt_height_mm": 871.04,
"Objekt_width_px": 2687.3953,
"Objekt_height_px": 3292.1197,
"Objekt_width_mm": 711.039,
"Objekt_height_mm": 871.039,
"Objekt_width_px": 2687.3915,
"Objekt_height_px": 3292.1159,
"calculated_SVG_height_px": 1000,
"calculated_SVG_width_px": 818.201,
"scale_factor": 1.1480529,
"calculated_SVG_width_px": 816.3113,
"scale_factor": 1.1480542,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 24.155,
"y": 24.154,
"direction": 270.0
},
{
"id": "cp2",
"x": 970.41,
"x": 970.411,
"y": 1000.0,
"direction": 180.0
}
@@ -575,25 +537,23 @@
"Winkel": 90.0,
"center_line_width_mm": 850.0,
"center_line_height_mm": 870.0,
"Objekt_width_mm": 871.04,
"Objekt_height_mm": 891.04,
"calculated_objekt_width_mm": 871.04,
"calculated_objekt_height_mm": 891.04,
"Objekt_width_px": 3292.1197,
"Objekt_height_px": 3367.7103,
"Objekt_width_mm": 871.039,
"Objekt_height_mm": 891.039,
"Objekt_width_px": 3292.1159,
"Objekt_height_px": 3367.7065,
"calculated_SVG_height_px": 1000,
"calculated_SVG_width_px": 979.444,
"scale_factor": 1.1222841,
"calculated_SVG_width_px": 977.5543,
"scale_factor": 1.1222853,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 23.613,
"y": 23.612,
"direction": 270.0
},
{
"id": "cp2",
"x": 975.845,
"x": 975.846,
"y": 1000.0,
"direction": 180.0
}
@@ -605,26 +565,24 @@
"Winkel": 90.0,
"center_line_width_mm": 890.0,
"center_line_height_mm": 850.0,
"Objekt_width_mm": 911.04,
"Objekt_height_mm": 871.04,
"calculated_objekt_width_mm": 911.04,
"calculated_objekt_height_mm": 871.04,
"Objekt_width_px": 3443.3008,
"Objekt_height_px": 3292.1197,
"Objekt_width_mm": 911.039,
"Objekt_height_mm": 871.039,
"Objekt_width_px": 3443.297,
"Objekt_height_px": 3292.1159,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 957.984,
"scale_factor": 1.0976466,
"calculated_SVG_height_px": 956.0941,
"scale_factor": 1.0976479,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 24.107,
"y": 24.154,
"direction": 270.0
},
{
"id": "cp2",
"x": 976.905,
"y": 998.027,
"x": 976.907,
"y": 1000.0,
"direction": 180.0
}
]
@@ -636,14 +594,12 @@
"center_line_width_mm": 800.0,
"center_line_height_mm": 1300.0,
"Objekt_width_mm": 800.0,
"Objekt_height_mm": 1342.08,
"calculated_objekt_width_mm": 800.0,
"calculated_objekt_height_mm": 1342.08,
"Objekt_height_mm": 1342.078,
"Objekt_width_px": 3023.6221,
"Objekt_height_px": 5072.4284,
"Objekt_height_px": 5072.4208,
"calculated_SVG_height_px": 1000,
"calculated_SVG_width_px": 597.979,
"scale_factor": 0.7451121,
"calculated_SVG_width_px": 596.0906,
"scale_factor": 0.7451132,
"connectionPoints": [
{
"id": "cp1",
@@ -654,7 +610,7 @@
{
"id": "cp2",
"x": 0,
"y": 984.323,
"y": 984.324,
"direction": 270.0
}
]
@@ -666,14 +622,12 @@
"center_line_width_mm": 800.0,
"center_line_height_mm": 1300.0,
"Objekt_width_mm": 800.0,
"Objekt_height_mm": 1342.08,
"calculated_objekt_width_mm": 800.0,
"calculated_objekt_height_mm": 1342.08,
"Objekt_height_mm": 1342.078,
"Objekt_width_px": 3023.6221,
"Objekt_height_px": 5072.4284,
"Objekt_height_px": 5072.4208,
"calculated_SVG_height_px": 1000,
"calculated_SVG_width_px": 597.979,
"scale_factor": 0.7451121,
"calculated_SVG_width_px": 596.0906,
"scale_factor": 0.7451132,
"connectionPoints": [
{
"id": "cp1",
@@ -684,7 +638,7 @@
{
"id": "cp2",
"x": 0,
"y": 984.323,
"y": 984.324,
"direction": 270.0
}
]
@@ -695,25 +649,23 @@
"Winkel": 90.0,
"center_line_width_mm": 650.0,
"center_line_height_mm": 650.0,
"Objekt_width_mm": 671.04,
"Objekt_height_mm": 671.04,
"calculated_objekt_width_mm": 671.04,
"calculated_objekt_height_mm": 671.04,
"Objekt_width_px": 2536.2142,
"Objekt_height_px": 2536.2142,
"Objekt_width_mm": 671.039,
"Objekt_height_mm": 671.039,
"Objekt_width_px": 2536.2104,
"Objekt_height_px": 2536.2104,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 1000.0,
"scale_factor": 1.490224,
"calculated_SVG_height_px": 1000,
"scale_factor": 1.4902264,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 31.354,
"y": 31.353,
"direction": 270.0
},
{
"id": "cp2",
"x": 968.646,
"x": 968.647,
"y": 1000.0,
"direction": 180.0
}
@@ -725,25 +677,23 @@
"Winkel": 90.0,
"center_line_width_mm": 810.0,
"center_line_height_mm": 810.0,
"Objekt_width_mm": 831.04,
"Objekt_height_mm": 831.04,
"calculated_objekt_width_mm": 831.04,
"calculated_objekt_height_mm": 831.04,
"Objekt_width_px": 3140.9386,
"Objekt_height_px": 3140.9386,
"Objekt_width_mm": 831.039,
"Objekt_height_mm": 831.039,
"Objekt_width_px": 3140.9348,
"Objekt_height_px": 3140.9348,
"calculated_SVG_width_px": 1000,
"calculated_SVG_height_px": 1000.0,
"scale_factor": 1.203312,
"calculated_SVG_height_px": 1000,
"scale_factor": 1.203313,
"connectionPoints": [
{
"id": "cp1",
"x": 0,
"y": 25.318,
"y": 25.317,
"direction": 270.0
},
{
"id": "cp2",
"x": 974.683,
"x": 974.684,
"y": 1000.0,
"direction": 180.0
}
@@ -1,12 +0,0 @@
@echo off
set OFBogen_PATH=%~dp0
set XML_PATH=C:\Program Files\RuleDesigner\RDConfigurator Fusion\WebApi\Editor2D\SSG\shapes\svg
set JSON_PATH=%OFBogen_PATH%JSON
python 4_OFBogen_SVG_XML_Modifier_Script.py
pause
+11 -4
View File
@@ -3,10 +3,17 @@
set OFBogen_PATH=%~dp0
set PROPS_PATH=C:\Program Files\RuleDesigner\RDConfigurator Fusion\WebApi\Editor2D\SSG\shapes\props
set JSON_PATH=%OFBogen_PATH%JSON
set JSON_PATH_BOGEN=%OFBogen_PATH%JSON
python 1_calculate_ture_width_and_height_dimensions_with_profile_width.py
python 2_calculations_to_standardize_the_dimensions_and_add_connection_points.py
python 3_update_dimensions_and_connection_points_in_props.py
python 01_props_step1_calculations_to_standardize_the_dimensions_and_add_connection_points.py
python 01_props_step2_update_dimensions_and_connection_points_in_props.py
:: Check if Python script succeeded
if %ERRORLEVEL% equ 0 (
echo update dimensions and connection points in props completed successfully
) else (
echo update dimensions and connection points in props failed with error %ERRORLEVEL%
)
pause