feat(python): add scripts for CAD to PDF conversion and block finding
This commit introduces two new feature scripts to the Aspose_CAD_Python project: - print_cad_to_pdf.py: A script to export CAD drawings to PDF format, providing a direct way to generate printable documents. - step1_find_block_coordinates.py: A utility to find and list the coordinates of specific blocks within a CAD file, which is a crucial first step for automated plotting and data extraction. Additionally, relevant documentation in .specstory has been added to reflect these new capabilities.
This commit is contained in:
parent
03ddec8caa
commit
fc79d59e53
4168
.specstory/history/2025-09-10_09-01Z-打印dxf图纸时文本缺失.md
Normal file
4168
.specstory/history/2025-09-10_09-01Z-打印dxf图纸时文本缺失.md
Normal file
File diff suppressed because it is too large
Load Diff
1121
.specstory/history/2025-09-10_10-21Z-分析报错原因.md
Normal file
1121
.specstory/history/2025-09-10_10-21Z-分析报错原因.md
Normal file
File diff suppressed because it is too large
Load Diff
6357
.specstory/history/2025-09-10_12-16Z-使用aposecad打印pdf图纸脚本.md
Normal file
6357
.specstory/history/2025-09-10_12-16Z-使用aposecad打印pdf图纸脚本.md
Normal file
File diff suppressed because it is too large
Load Diff
6004
.specstory/history/2025-09-11_03-16Z-实现aposecad功能的步骤.md
Normal file
6004
.specstory/history/2025-09-11_03-16Z-实现aposecad功能的步骤.md
Normal file
File diff suppressed because it is too large
Load Diff
6848
.specstory/history/2025-09-11_04-12Z-查找指定坐标打印pdf的示例.md
Normal file
6848
.specstory/history/2025-09-11_04-12Z-查找指定坐标打印pdf的示例.md
Normal file
File diff suppressed because it is too large
Load Diff
94
01_Aspose_CAD_Python/print_cad_to_pdf.py
Normal file
94
01_Aspose_CAD_Python/print_cad_to_pdf.py
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import aspose.cad as cad
|
||||||
|
import os
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
def find_shx_files(fonts_dir):
|
||||||
|
"""Finds all .shx files in a directory."""
|
||||||
|
shx_files = []
|
||||||
|
for root, _, files in os.walk(fonts_dir):
|
||||||
|
for file in files:
|
||||||
|
if file.lower().endswith('.shx'):
|
||||||
|
shx_files.append(os.path.join(root, file))
|
||||||
|
return shx_files
|
||||||
|
|
||||||
|
def print_cad_to_pdf(input_dwg, output_pdf, fonts_dir):
|
||||||
|
"""
|
||||||
|
Converts a CAD drawing (DWG) to a PDF file, using specified custom fonts.
|
||||||
|
|
||||||
|
:param input_dwg: Path to the input DWG file.
|
||||||
|
:param output_pdf: Path to save the output PDF file.
|
||||||
|
:param fonts_dir: Directory containing custom SHX fonts.
|
||||||
|
"""
|
||||||
|
print(f"Input DWG: {input_dwg}")
|
||||||
|
print(f"Output PDF: {output_pdf}")
|
||||||
|
print(f"Fonts directory: {fonts_dir}")
|
||||||
|
|
||||||
|
# Load the DWG file
|
||||||
|
try:
|
||||||
|
image = cad.Image.load(input_dwg)
|
||||||
|
print("Successfully loaded DWG file.")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error loading DWG file: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Create an instance of CadRasterizationOptions
|
||||||
|
rasterization_options = cad.imageoptions.CadRasterizationOptions()
|
||||||
|
|
||||||
|
# Set page size to match drawing size and disable scaling to preserve coordinates
|
||||||
|
rasterization_options.no_scaling = True
|
||||||
|
rasterization_options.page_width = float(image.width)
|
||||||
|
rasterization_options.page_height = float(image.height)
|
||||||
|
|
||||||
|
rasterization_options.layouts = ["Model"]
|
||||||
|
|
||||||
|
# Set to color mode. 1 corresponds to USE_OBJECT_COLOR.
|
||||||
|
# We use the integer value directly as the enum type is not exposed in a public module.
|
||||||
|
rasterization_options.draw_type = 1
|
||||||
|
|
||||||
|
# Find and set SHX fonts
|
||||||
|
shx_font_files = find_shx_files(fonts_dir)
|
||||||
|
if shx_font_files:
|
||||||
|
print(f"Found {len(shx_font_files)} SHX font files.")
|
||||||
|
rasterization_options.shx_fonts = shx_font_files
|
||||||
|
else:
|
||||||
|
print("Warning: No SHX font files found in the specified directory.")
|
||||||
|
|
||||||
|
# Create an instance of PdfOptions
|
||||||
|
pdf_options = cad.imageoptions.PdfOptions()
|
||||||
|
pdf_options.vector_rasterization_options = rasterization_options
|
||||||
|
|
||||||
|
# Save the PDF
|
||||||
|
try:
|
||||||
|
image.save(output_pdf, pdf_options)
|
||||||
|
print(f"Successfully converted to PDF: {output_pdf}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error saving PDF file: {e}")
|
||||||
|
finally:
|
||||||
|
# Dispose image - The python wrapper seems to handle this automatically.
|
||||||
|
# image.dispose()
|
||||||
|
print("Image resources are managed automatically.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description="Convert CAD drawing to PDF with custom fonts.")
|
||||||
|
parser.add_argument("input_file", help="Path to the input CAD file (e.g., DWG, DXF).")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
input_file_path = args.input_file
|
||||||
|
|
||||||
|
# Define other paths
|
||||||
|
workspace_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
fonts_folder_path = os.path.join(workspace_root, '03_Python_OpenSource_DXF', 'fonts')
|
||||||
|
|
||||||
|
# Generate output file path based on input file name
|
||||||
|
base_name = os.path.basename(input_file_path)
|
||||||
|
file_name, _ = os.path.splitext(base_name)
|
||||||
|
output_file_path = os.path.join(os.path.dirname(__file__), f'{file_name}_output.pdf')
|
||||||
|
|
||||||
|
|
||||||
|
# Check if files/folders exist
|
||||||
|
if not os.path.exists(input_file_path):
|
||||||
|
print(f"Error: Input file not found at {input_file_path}")
|
||||||
|
elif not os.path.isdir(fonts_folder_path):
|
||||||
|
print(f"Error: Fonts directory not found at {fonts_folder_path}")
|
||||||
|
else:
|
||||||
|
print_cad_to_pdf(input_file_path, output_file_path, fonts_folder_path)
|
||||||
107
01_Aspose_CAD_Python/step1_find_block_coordinates.py
Normal file
107
01_Aspose_CAD_Python/step1_find_block_coordinates.py
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import aspose.cad as cad
|
||||||
|
import os
|
||||||
|
from aspose.cad.fileformats.cad import CadImage
|
||||||
|
from aspose.cad.fileformats.cad.cadobjects import CadInsertObject
|
||||||
|
|
||||||
|
def set_license():
|
||||||
|
"""
|
||||||
|
Tries to find and apply an Aspose.CAD license.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
from aspose.cad import License
|
||||||
|
license = License()
|
||||||
|
# The SetLicense method expects the name of the license file.
|
||||||
|
# Common names are Aspose.CAD.lic or Aspose.Total.lic.
|
||||||
|
# It should be placed in the folder with the script, or you can specify a full path.
|
||||||
|
# As we don't have the license file, this will likely fail silently
|
||||||
|
# or work if the user has placed it correctly.
|
||||||
|
license.set_license("Aspose.CAD.lic")
|
||||||
|
print("License set successfully (if found).")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"License not set or error: {e}. Running in evaluation mode.")
|
||||||
|
|
||||||
|
def find_block_coordinates(dwg_path, printable_blocks):
|
||||||
|
"""
|
||||||
|
Finds specified blocks in a DWG file and returns their coordinates and layout.
|
||||||
|
|
||||||
|
:param dwg_path: Path to the DWG file.
|
||||||
|
:param printable_blocks: A dictionary of block names to find.
|
||||||
|
:return: A list of dictionaries, each containing block info.
|
||||||
|
"""
|
||||||
|
if not os.path.exists(dwg_path):
|
||||||
|
print(f"Error: File not found at {dwg_path}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
found_blocks = []
|
||||||
|
|
||||||
|
with cad.Image.load(dwg_path) as image:
|
||||||
|
# Based on the file `extract_lines_correct.py`, the correct object is returned directly.
|
||||||
|
# The issue might be specific to the environment or the DWG file itself.
|
||||||
|
# Let's use the exact loading method from the working example.
|
||||||
|
cad_image = cad.fileformats.cad.CadImage.load(dwg_path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(f"Successfully loaded image. Type: {type(cad_image).__name__}")
|
||||||
|
|
||||||
|
# A DWG's paper space layouts are stored in blocks with names like "*Paper_Space"
|
||||||
|
# Model space is in "*Model_Space"
|
||||||
|
# We iterate through these special blocks to find the block insertions.
|
||||||
|
if hasattr(cad_image, 'blocks'):
|
||||||
|
print("Iterating through cad_image.blocks...")
|
||||||
|
for block in cad_image.blocks:
|
||||||
|
# Layout blocks often start with '*'
|
||||||
|
if block.name.startswith('*'):
|
||||||
|
layout_name = block.name
|
||||||
|
for entity in block.entities:
|
||||||
|
if isinstance(entity, CadInsertObject):
|
||||||
|
block_name = entity.name
|
||||||
|
if block_name in printable_blocks:
|
||||||
|
min_point = entity.min_point
|
||||||
|
max_point = entity.max_point
|
||||||
|
|
||||||
|
block_info = {
|
||||||
|
"block_name": block_name,
|
||||||
|
"layout": layout_name,
|
||||||
|
"min_point": (min_point.x, min_point.y),
|
||||||
|
"max_point": (max_point.x, max_point.y)
|
||||||
|
}
|
||||||
|
found_blocks.append(block_info)
|
||||||
|
print(f" Found block '{block_name}' in layout/block '{layout_name}'")
|
||||||
|
else:
|
||||||
|
print("Attribute 'blocks' not found on CadImage object.")
|
||||||
|
finally:
|
||||||
|
# Manually dispose of the image if CadImage.load was used
|
||||||
|
cad_image.dispose()
|
||||||
|
|
||||||
|
return found_blocks
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# It's a good practice to set the license at the start of the application
|
||||||
|
set_license()
|
||||||
|
|
||||||
|
# Define the blocks we are interested in, based on 思路.MD
|
||||||
|
PRINTABLE_BLOCKS = {
|
||||||
|
"A$C2EB80DB8": ("A1", "portrait"),
|
||||||
|
"A$C1CC9093B": ("A1", "landscape"),
|
||||||
|
"A$C6D564680": ("A2", "portrait"),
|
||||||
|
"新块": ("A3", "landscape"),
|
||||||
|
"新块1": ("A4", "portrait"),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Path to the test DWG file
|
||||||
|
dwg_file_path = os.path.join("04_Test_Files", "图签测试.dwg")
|
||||||
|
|
||||||
|
print(f"Loading DWG file: {dwg_file_path}")
|
||||||
|
|
||||||
|
blocks_data = find_block_coordinates(dwg_file_path, PRINTABLE_BLOCKS)
|
||||||
|
|
||||||
|
print("\n--- Found Blocks Summary ---")
|
||||||
|
if blocks_data:
|
||||||
|
for block in blocks_data:
|
||||||
|
print(f"Block: {block['block_name']}")
|
||||||
|
print(f" Layout: {block['layout']}")
|
||||||
|
print(f" Min Point: {block['min_point']}")
|
||||||
|
print(f" Max Point: {block['max_point']}")
|
||||||
|
print("-" * 20)
|
||||||
|
else:
|
||||||
|
print("No specified blocks were found in the DWG file.")
|
||||||
BIN
01_Aspose_CAD_Python/图签测试_output.pdf
Normal file
BIN
01_Aspose_CAD_Python/图签测试_output.pdf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user