|
|
|
""" |
|
محلل الرسومات الهندسية وملفات BIM المتقدم |
|
""" |
|
|
|
import ezdxf |
|
import cv2 |
|
import numpy as np |
|
from PIL import Image |
|
import pytesseract |
|
from shapely.geometry import Point, Polygon |
|
import json |
|
import os |
|
import logging |
|
from datetime import datetime |
|
|
|
class CADBIMAnalyzer: |
|
"""محلل الرسومات الهندسية وملفات BIM""" |
|
|
|
def __init__(self, claude_client=None): |
|
"""تهيئة المحلل""" |
|
self.claude_client = claude_client |
|
self.analysis_results = {} |
|
|
|
def analyze_drawing(self, file_path): |
|
"""تحليل الرسم الهندسي""" |
|
try: |
|
file_extension = os.path.splitext(file_path)[1].lower() |
|
|
|
if file_extension in ['.dwg', '.dxf']: |
|
return self._analyze_cad_file(file_path) |
|
elif file_extension == '.ifc': |
|
return self._analyze_bim_file(file_path) |
|
elif file_extension in ['.pdf', '.jpg', '.jpeg', '.png']: |
|
return self._analyze_image_file(file_path) |
|
else: |
|
raise ValueError(f"نوع الملف غير مدعوم: {file_extension}") |
|
|
|
except Exception as e: |
|
logging.error(f"خطأ في تحليل الرسم: {str(e)}") |
|
raise |
|
|
|
def _analyze_cad_file(self, file_path): |
|
"""تحليل ملف CAD""" |
|
doc = ezdxf.readfile(file_path) |
|
msp = doc.modelspace() |
|
|
|
|
|
elements = { |
|
'lines': len(msp.query('LINE')), |
|
'circles': len(msp.query('CIRCLE')), |
|
'arcs': len(msp.query('ARC')), |
|
'polylines': len(msp.query('LWPOLYLINE')), |
|
'dimensions': len(msp.query('DIMENSION')), |
|
'text': len(msp.query('TEXT')), |
|
'blocks': len(doc.blocks) |
|
} |
|
|
|
|
|
layers = {layer.dxf.name: { |
|
'color': layer.dxf.color, |
|
'linetype': layer.dxf.linetype, |
|
'is_on': layer.dxf.on, |
|
'is_frozen': layer.dxf.frozen |
|
} for layer in doc.layers} |
|
|
|
|
|
extents = msp.get_extents() |
|
if extents: |
|
dimensions = { |
|
'width': abs(extents.size.x), |
|
'height': abs(extents.size.y), |
|
'area': abs(extents.size.x * extents.size.y) |
|
} |
|
else: |
|
dimensions = {'width': 0, 'height': 0, 'area': 0} |
|
|
|
|
|
if self.claude_client: |
|
drawing_info = { |
|
'elements': elements, |
|
'layers': layers, |
|
'dimensions': dimensions |
|
} |
|
|
|
analysis_prompt = f""" |
|
قم بتحليل معلومات الرسم الهندسي التالية وتقديم: |
|
1. وصف عام للرسم |
|
2. تحليل العناصر والطبقات |
|
3. تحديد نوع المشروع والتخصص |
|
4. توصيات فنية |
|
5. ملاحظات هامة |
|
|
|
معلومات الرسم: |
|
{json.dumps(drawing_info, indent=2, ensure_ascii=False)} |
|
""" |
|
|
|
response = self.claude_client.messages.create( |
|
model="claude-3-sonnet-20240229", |
|
max_tokens=4000, |
|
temperature=0.7, |
|
messages=[{"role": "user", "content": analysis_prompt}] |
|
) |
|
|
|
ai_analysis = response.content[0].text |
|
else: |
|
ai_analysis = "تحليل الذكاء الاصطناعي غير متاح" |
|
|
|
return { |
|
'file_info': { |
|
'path': file_path, |
|
'type': os.path.splitext(file_path)[1], |
|
'size': os.path.getsize(file_path), |
|
'modified': datetime.fromtimestamp(os.path.getmtime(file_path)).strftime('%Y-%m-%d %H:%M:%S') |
|
}, |
|
'elements': elements, |
|
'layers': layers, |
|
'dimensions': dimensions, |
|
'ai_analysis': ai_analysis |
|
} |
|
|
|
def _analyze_bim_file(self, file_path): |
|
"""تحليل ملف BIM""" |
|
try: |
|
|
|
import ifcopenshell |
|
ifc_file = ifcopenshell.open(file_path) |
|
|
|
|
|
elements = { |
|
'structural': self._analyze_structural_elements(ifc_file), |
|
'architectural': self._analyze_architectural_elements(ifc_file), |
|
'mep': self._analyze_mep_elements(ifc_file) |
|
} |
|
|
|
|
|
dimensions = self._analyze_dimensions(ifc_file) |
|
|
|
|
|
if self.claude_client: |
|
building_info = { |
|
'elements': elements, |
|
'dimensions': dimensions, |
|
'properties': self._extract_properties(ifc_file) |
|
} |
|
|
|
analysis_prompt = f""" |
|
قم بتحليل معلومات نموذج BIM التالية وتقديم: |
|
1. تحليل شامل للنموذج |
|
2. تقييم جودة النمذجة |
|
3. توصيات للتحسين |
|
4. تقدير التكاليف |
|
5. تحليل الاستدامة |
|
|
|
معلومات النموذج: |
|
{json.dumps(building_info, indent=2, ensure_ascii=False)} |
|
""" |
|
|
|
response = self.claude_client.messages.create( |
|
model="claude-3-sonnet-20240229", |
|
max_tokens=4000, |
|
temperature=0.7, |
|
messages=[{"role": "user", "content": analysis_prompt}] |
|
) |
|
|
|
ai_analysis = response.content[0].text |
|
else: |
|
ai_analysis = "تحليل الذكاء الاصطناعي غير متاح" |
|
|
|
return { |
|
'file_info': { |
|
'path': file_path, |
|
'type': 'IFC', |
|
'schema': ifc_file.schema, |
|
'size': os.path.getsize(file_path) |
|
}, |
|
'elements': elements, |
|
'dimensions': dimensions, |
|
'analysis': ai_analysis |
|
} |
|
|
|
except Exception as e: |
|
logging.error(f"خطأ في تحليل ملف BIM: {str(e)}") |
|
raise |
|
|
|
def _analyze_image_file(self, file_path): |
|
"""تحليل ملف صورة""" |
|
|
|
if file_path.lower().endswith('.pdf'): |
|
|
|
pass |
|
else: |
|
image = cv2.imread(file_path) |
|
|
|
|
|
text = pytesseract.image_to_string(image, lang='ara+eng') |
|
|
|
|
|
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) |
|
edges = cv2.Canny(gray, 50, 150) |
|
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 100) |
|
|
|
|
|
if self.claude_client: |
|
image_info = { |
|
'dimensions': image.shape, |
|
'extracted_text': text, |
|
'detected_lines': len(lines) if lines is not None else 0 |
|
} |
|
|
|
analysis_prompt = f""" |
|
قم بتحليل معلومات الصورة الهندسية التالية وتقديم: |
|
1. وصف عام للصورة |
|
2. تحليل النص المستخرج |
|
3. تحليل الخطوط والأشكال |
|
4. تحديد نوع المشروع والتخصص |
|
5. توصيات وملاحظات |
|
|
|
معلومات الصورة: |
|
{json.dumps(image_info, indent=2, ensure_ascii=False)} |
|
""" |
|
|
|
response = self.claude_client.messages.create( |
|
model="claude-3-sonnet-20240229", |
|
max_tokens=4000, |
|
temperature=0.7, |
|
messages=[{"role": "user", "content": analysis_prompt}] |
|
) |
|
|
|
ai_analysis = response.content[0].text |
|
else: |
|
ai_analysis = "تحليل الذكاء الاصطناعي غير متاح" |
|
|
|
return { |
|
'file_info': { |
|
'path': file_path, |
|
'type': os.path.splitext(file_path)[1], |
|
'size': os.path.getsize(file_path), |
|
'modified': datetime.fromtimestamp(os.path.getmtime(file_path)).strftime('%Y-%m-%d %H:%M:%S') |
|
}, |
|
'dimensions': { |
|
'width': image.shape[1], |
|
'height': image.shape[0], |
|
'channels': image.shape[2] |
|
}, |
|
'extracted_text': text, |
|
'analysis': { |
|
'detected_lines': len(lines) if lines is not None else 0 |
|
}, |
|
'ai_analysis': ai_analysis |
|
} |
|
|