声明:以上是我的测试数据,不一定适用于所有情况
AI工具豆包,能读取CAD图纸的结构化数据,支持重绘、算量和建模。详细教程来了
首先我们打开DWG转Excle软件,这个软件是德国的,名字太长,我把名字放评论区,通过插件把DWG图纸转换成结构化数据,具体打开是这样的,里面包含了图层、坐标、ID等480项信息,把这个EXCEL表格上传至豆包,复制黏贴Python代码让它重绘图纸,他是根据图层和墙构件的子父集关系及坐标绘制折线图,这个是绘制好的样子,输入新的代码,他就可以根据绘制好的图进行面积值的添加,这个是生成好的样子,再次输入代码,他就根据墙的情况绘制空间坐标,接着,输入更多代码,按步骤执行绘制坐标和图形命令,最终生成3D模型。Python代码可以根据所题问题让AI自动生成,我把提示词和我的代码放公众号了,你可以去看一看,以上是我的测试数据,不一定适用于所有情况
Python代码生成提示词样例
第一段代码的提示词如下:
首先,检查数据框是否包含特定的列:'Layer'、'ID'、'ParentID' 和 'Point'。
接着,从 'Layer' 列中筛选出包含字符串 'wall' 的 ID。
在 'ParentID' 列中查找与这些 ID 匹配的元素。
定义一个函数来清理和拆分 'Point' 列中的数据。这包括去除括号并将值拆分为 'x'、'y' 和 'z' 坐标。
使用 matplotlib 绘制数据。对于每个唯一的 'ParentID',绘制一条单独的折线连接 'Point' 坐标。如果存在,确保首尾点相连。
适当设置图表的标签和标题,并确保 x 轴和 y 轴的比例相等。
我所使用的Python代码
第一段:
import matplotlib.pyplot as plt# Check if the necessary columns ('Layer', 'ID', 'ParentID', 'Point') exist in the dataframerequired_columns = {'Layer', 'ID', 'ParentID', 'Point'}if not required_columns.issubset(df.columns): missing_columns = required_columns - set(df.columns) raise ValueError(f"Missing required columns: {missing_columns}")# Filter IDs from 'Layer' column that contain the string 'wall'ids_with_wall = df[df['Layer'].str.contains("wall", na=False)]['ID']# Find elements in 'ParentID' matching these IDselements_with_matching_parent_ids = df[df['ParentID'].isin(ids_with_wall)]# Function to clean and split pointsdef clean_and_split_points(points): points_cleaned = points.str.replace('[', '', regex=False).str.replace(']', '', regex=False) split_points = points_cleaned.str.split(' ', expand=True).astype(float) split_points.columns = ['x', 'y', 'z'] return split_points# Plottingplt.figure(figsize=(40, 20))# Draw separate polylines for each group based on 'ParentID'for parent_id, group in elements_with_matching_parent_ids.groupby('ParentID'): # Check if there are any non-empty 'Point' values in the group if group['Point'].dropna().empty: continue # Skip this group if 'Point' column is empty split_points = clean_and_split_points(group['Point'].dropna()) plt.plot(split_points['x'], split_points['y'], marker='o') # Draw the polyline # Connect the first and last points if available if len(split_points) > 0: first_point = split_points.iloc[0] last_point = split_points.iloc[-1] plt.plot([first_point['x'], last_point['x']], [first_point['y'], last_point['y']], 'ro-')# Final plot settingsplt.xlabel('X Koordinate')plt.ylabel('Y Koordinate')plt.title('Separate Polylinien nach ParentID mit verbundenem ersten und letzten Punkt')plt.axis('equal') # Set equal scaling on x and y axesplt.show()
第二段:
if 'Area' not in df.columns: raise ValueError("Missing required column: 'Area'")# Updating the plot with the new requirementsplt.figure(figsize=(40, 20))# Iterate over each group and plotfor parent_id, group in elements_with_matching_parent_ids.groupby('ParentID'): # Check if there are any non-empty 'Point' values in the group if group['Point'].dropna().empty: continue # Skip this group if 'Point' column is empty split_points = clean_and_split_points(group['Point'].dropna()) plt.plot(split_points['x'], split_points['y'], marker='o') # Draw the polyline # Connect the first and last points if available if len(split_points) > 0: first_point = split_points.iloc[0] last_point = split_points.iloc[-1] plt.plot([first_point['x'], last_point['x']], [first_point['y'], last_point['y']], 'ro-') # Find the 'Area' for this 'ParentID', divide by 1000000, and annotate on the plot area_value = df[df['ID'] == parent_id]['Area'].iloc[0] / 1000000 mid_point = split_points.mean() # A point to place the annotation plt.annotate(f"{area_value:.2f}", (mid_point['x'], mid_point['y']), textcoords="offset points", xytext=(0,10), ha='center')# Final plot settingsplt.xlabel('X Koordinate')plt.ylabel('Y Koordinate')plt.title('Separate Polylinien nach ParentID mit verbundenem ersten und letzten Punkt und Fl"achenangaben')plt.axis('equal') # Set equal scaling on x and y axesplt.show()
第三段:
import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport ast# Filter the DataFrame to get the IDs where the "Layer" value is "wall"wall_ids = df[df['Layer'] == 'wall']['ID'].tolist()# Find corresponding entries in the "ParentID" columnwall_lines = df[df['ParentID'].isin(wall_ids)]# Correcting the parsing method for the 'Point' column to handle the specific formatdef parse_custom_point_format(point_str): if pd.notna(point_str): try: # Replacing spaces with commas to create a valid list format formatted_str = point_str.replace(' ', ', ') return ast.literal_eval(formatted_str) except (ValueError, SyntaxError): return None else: return Nonewall_lines['Point'] = wall_lines['Point'].apply(parse_custom_point_format)# Grouping and forming polylinesgrouped_lines = wall_lines.groupby('ParentID').apply(lambda x: x.sort_values('ID'))polylines = {}for parent_id, group in grouped_lines.groupby(level=0): points = group['Point'].tolist() if all(points) and len(points) > 1: segments = [] current_x = 0 for i in range(len(points) - 1): start_point = points[i] end_point = points[i + 1] distance = np.sqrt((end_point[0] - start_point[0]) ** 2 + (end_point[1] - start_point[1]) ** 2) segments.append((current_x, current_x + distance)) current_x += distance polylines[parent_id] = segments# Function to plot a single polyline and its parallel line 3000 units higher# Updated function to plot a single polyline with segment length labelsdef plot_polyline_with_labels(ax, segments): for segment in segments: # Plotting the segment on the lower line ax.plot(segment, [0, 0], 'b-o') # Plotting the segment on the parallel line 3000 units higher ax.plot(segment, [3000, 3000], 'r-o') # Connecting the corresponding points of the upper and lower lines ax.plot([segment[0], segment[0]], [0, 3000], 'g--') # Start point vertical line ax.plot([segment[1], segment[1]], [0, 3000], 'g--') # End point vertical line # Calculating the segment length and adding a label segment_length = segment[1] - segment[0] label = f"{segment_length / 1000:.2f} m." mid_point = (segment[0] + segment[1]) / 2 ax.text(mid_point, 0, label, ha='center', va='bottom', color='blue')# Creating subplots for the first 5 polylines with labelsfig, axes = plt.subplots(5, 1, figsize=(10, 20))for i, (parent_id, segments) in enumerate(list(polylines.items())[:5]): plot_polyline_with_labels(axes[i], segments) axes[i].set_title(f"Polyline: {int(parent_id)}") axes[i].set_xlabel("Horizontal Distance, mm.") axes[i].set_ylabel("Vertical Distance, mm.") axes[i].axis('equal')plt.tight_layout()plt.show()
第四段;
import pandas as pdimport numpy as npimport matplotlib.pyplot as pltfrom mpl_toolkits.mplot3d.art3d import Poly3DCollectionimport matplotlib.colors as mcolors# Filtern der IDs von Elementen, die 'wall' in der 'Layer'-Spalte enthaltenids_with_wall = df[df['Layer'].str.contains("wall", na=False)]['ID']# Finden aller Elemente, die diese IDs in der 'ParentID'-Spalte habenelements_with_matching_parent_ids = df[df['ParentID'].isin(ids_with_wall)]# Funktion zum Bereinigen und Trennen der 'Point'-Spalte in x, y, z Koordinatendef clean_and_split_points(points): points_cleaned = points.str.replace('[', '', regex=False).str.replace(']', '', regex=False) split_points = points_cleaned.str.split(' ', expand=True).astype(float) split_points.columns = ['x', 'y', 'z'] return split_points# Erstellen eines neuen DataFrames für die neuen Punktenew_points_df = pd.DataFrame(columns=['ParentID', 'x', 'y', 'z'])for parent_id, group in elements_with_matching_parent_ids.groupby('ParentID'): if group['Point'].dropna().empty: continue split_points = clean_and_split_points(group['Point'].dropna()) original_points = split_points.copy() original_points['ParentID'] = parent_id new_points_df = pd.concat([new_points_df, original_points], ignore_index=True) new_z_points = split_points.copy() new_z_points['z'] += 3000 new_z_points['ParentID'] = parent_id new_points_df = pd.concat([new_points_df, new_z_points], ignore_index=True)new_points_df.head()new_points_df.reset_index(drop=True, inplace=True)# Erstellen einer 3D-Plot-Figurfig = plt.figure(figsize=(10, 10))ax = fig.add_subplot(111, projection='3d')# Generieren einer Farbpalettenum_groups = len(new_points_df['ParentID'].unique())colors = plt.cm.get_cmap('viridis', num_groups)# Bestimmen der Grenzen für alle Achsenmax_range = np.array([new_points_df['x'].max()-new_points_df['x'].min(), new_points_df['y'].max()-new_points_df['y'].min(), new_points_df['z'].max()-new_points_df['z'].min()]).max() / 2.0mid_x = (new_points_df['x'].max()+new_points_df['x'].min()) * 0.5mid_y = (new_points_df['y'].max()+new_points_df['y'].min()) * 0.5mid_z = (new_points_df['z'].max()+new_points_df['z'].min()) * 0.5ax.set_xlim(mid_x - max_range, mid_x + max_range)ax.set_ylim(mid_y - max_range, mid_y + max_range)ax.set_zlim(mid_z - max_range, mid_z + max_range)# Visualisieren der 3D-K"orperfor i, (parent_id, group) in enumerate(new_points_df.groupby('ParentID')): color = colors(i) lower_points = group[group['z'] == 0][['x', 'y', 'z']].values upper_points = group[group['z'] != 0][['x', 'y', 'z']].values if len(lower_points) < 3 or len(upper_points) < 3: continue faces = [lower_points, upper_points] for j in range(len(lower_points)): k = (j + 1) % len(lower_points) side = np.array([lower_points[j], lower_points[k], upper_points[k], upper_points[j]]) faces.append(side) body = Poly3DCollection(faces, alpha=0.8, edgecolor='k', facecolor=color) ax.add_collection3d(body) ax.scatter(lower_points[:,0], lower_points[:,1], lower_points[:,2], c=[color], marker='o') ax.scatter(upper_points[:,0], upper_points[:,1], upper_points[:,2], c=[color], marker='^')ax.set_xlabel('X Axis')ax.set_ylabel('Y Axis')ax.set_zlabel('Z Axis')plt.show()
第五段:
import pandas as pdimport numpy as npimport plotly.graph_objects as go# Filtern der IDs von Elementen, die 'wall' in der 'Layer'-Spalte enthaltenids_with_wall = df[df['Layer'].str.contains("wall", na=False)]['ID']# Finden aller Elemente, die diese IDs in der 'ParentID'-Spalte habenelements_with_matching_parent_ids = df[df['ParentID'].isin(ids_with_wall)]# Funktion zum Bereinigen und Trennen der 'Point'-Spalte in x, y, z Koordinatendef clean_and_split_points(points): points_cleaned = points.str.replace('[', '', regex=False).str.replace(']', '', regex=False) split_points = points_cleaned.str.split(' ', expand=True).astype(float) split_points.columns = ['x', 'y', 'z'] return split_points# Erstellen eines neuen DataFrames für die neuen Punktenew_points_df = pd.DataFrame(columns=['ParentID', 'x', 'y', 'z'])for parent_id, group in elements_with_matching_parent_ids.groupby('ParentID'): if group['Point'].dropna().empty: continue split_points = clean_and_split_points(group['Point'].dropna()) original_points = split_points.copy() original_points['ParentID'] = parent_id new_points_df = pd.concat([new_points_df, original_points], ignore_index=True) new_z_points = split_points.copy() new_z_points['z'] += 3000 new_z_points['ParentID'] = parent_id new_points_df = pd.concat([new_points_df, new_z_points], ignore_index=True)new_points_df.reset_index(drop=True, inplace=True)# Bestimmen der maximalen Ausdehnung für alle Achsenmax_range = np.array([new_points_df['x'].max()-new_points_df['x'].min(), new_points_df['y'].max()-new_points_df['y'].min(), new_points_df['z'].max()-new_points_df['z'].min()]).max() / 2.0mid_x = (new_points_df['x'].max()+new_points_df['x'].min()) * 0.5mid_y = (new_points_df['y'].max()+new_points_df['y'].min()) * 0.5mid_z = (new_points_df['z'].max()+new_points_df['z'].min()) * 0.5# Erstellen der 3D-Visualisierung mit Plotlyfig = go.Figure()# Generieren der 3D-K"orper in blauer Farbefor parent_id, group in new_points_df.groupby('ParentID'): lower_points = group[group['z'] == 0][['x', 'y', 'z']].values upper_points = group[group['z'] != 0][['x', 'y', 'z']].values if len(lower_points) < 3 or len(upper_points) < 3: continue x, y, z = zip(*np.concatenate([lower_points, upper_points])) fig.add_trace(go.Mesh3d(x=x, y=y, z=z, color='blue', opacity=0.5, alphahull=0))# Einstellen der gleichen Skala für alle Achsenfig.update_layout(scene=dict( xaxis=dict(nticks=4, range=[mid_x - max_range, mid_x + max_range]), yaxis=dict(nticks=4, range=[mid_y - max_range, mid_y + max_range]), zaxis=dict(nticks=4, range=[mid_z - max_range, mid_z + max_range]), aspectmode='cube' # Option, um das gleiche Verh"altnis für alle Achsen zu erzwingen))fig.show()