التقاط الكائنات (OSNAP)
تشرح هذه الصفحة كيفية عمل OSNAP في cad-viewer مع البيانات من realdwg-web.
الخلفية
في AutoCAD/ObjectARX، يمكن لكل كيان تجاوز getOsnapPoints(...) لإرجاع نقاط التقاط مرشحة لوضع التقاط معين.
في realdwg-web، نستخدم نمطًا مشابهًا مع subGetOsnapPoints(...) في كل فئة كيان.
يستهلك cad-viewer تلك النقاط المُعادة لتنفيذ الالتقاط في واجهة المستخدم.
المرجع:
- AutoCAD ObjectARX
getOsnapPoints: https://help.autodesk.com/view/OARX/2024/ENU/?guid=OARX-RefGuide-__OVERLOADED_getOsnapPoints_AcDbEntity
الواجهة الأساسية في realdwg-web
التعريف الأساسي:
AcDbEntity.subGetOsnapPoints(osnapMode, pickPoint, lastPoint, snapPoints, gsMark?)
المعاملات:
osnapMode: وضع واحد في كل استدعاءpickPoint: نقطة مؤشر الفأرة الحالية في العالمlastPoint: النقطة المُثبَّتة السابقة في تدفق الأمرsnapPoints: مصفوفة الإخراج لإلحاق النقاط المرشحةgsMark(اختياري): معرّف الكيان الفرعي، وهو مهم حاليًا لالتقاط الكيانات الفرعية لـINSERT(AcDbBlockReference)
أوضاع OSNAP المدعومة
معرّفة في AcDbOsnapMode:
EndPoint = 1MidPoint = 2Center = 3Node = 4Quadrant = 5Insertion = 7Perpendicular = 8Tangent = 9Nearest = 10Centroid = 11
مهم:
- هذه القيم معرّفات ترتيبية، وليست أعلام بتات.
- استخدم
acdbOsnapModesToMask(...)وacdbMaskToOsnapModes(...)لتحويل القناع.
ما تعرضه واجهة cad-viewer الحالية
يعرض شريط الحالة (MlOsnapButton.vue) حاليًا:
- EndPoint
- MidPoint
- Center
- Node
- Quadrant
- Insertion
غير معروض في واجهة المستخدم بعد (معلّق):
- Perpendicular
- Tangent
- Nearest
- Centroid
القناع المُمكَّن افتراضيًا في الإعدادات (AcApSettingManager):
- EndPoint + MidPoint + Center
التدفق في وقت التشغيل في cad-simple-viewer
- يستدعي
AcEdFloatingInput.getPosition()الدالةgetOsnapPoint(). - تستدعي
getOsnapPoint()الدالةgetOsnapPoints(). - تشغّل
getOsnapPoints()الدالةview.pick(point, hitRadius). - لكل عنصر مُنتقى:
- حل كيان مساحة النموذج بواسطة
item.id - إذا كان
item.childrenموجودًا، فاستدعِ osnap الكيان معgsMark = child.id - وإلا فاستدعِ osnap الكيان بدون
gsMark
- لكل وضع نشط في القناع الحالي، استدعِ
entity.subGetOsnapPoints(...). - اختر أقرب نقطة مُعادة إلى المؤشر.
- طبّق حد المسافة في العالم المحوَّل من
hitRadiusعلى الشاشة (افتراضيًا 20 بكسل). - إذا تم القبول، فالتقط المؤشر واعرض العلامة.
لمحة عن تنفيذ الكيانات (من شيفرة realdwg-web)
AcDbLine: EndPoint، MidPoint، Nearest، Perpendicular (فرعTangentموجود لكن دون نقطة)AcDbArc: EndPoint، MidPoint، Nearest، Tangent (فرعPerpendicularموجود لكن دون نقطة)AcDbCircle: Center، Centroid، Quadrant، Nearest، TangentAcDbEllipse: EndPoint (القوس المفتوح فقط)، MidPoint (القوس المفتوح فقط)، Quadrant (القطع الناقص المغلق فقط)AcDbPolyline: EndPointAcDb2dPolyline: EndPointAcDb3dPolyline: EndPointAcDbPoint: NodeAcDbText: InsertionAcDbMText: InsertionAcDbBlockReference(INSERT): Insertion + التقاط الكيانات الفرعية المفوَّض عبرgsMark- كيانات إضافية بدعم محدود:
AcDbRay: EndPoint (النقطة الأساسية)AcDbFace: EndPoint (الرؤوس)AcDbTrace: EndPoint (الرؤوس)AcDbSpline: EndPoint
منطق OSNAP لـ INSERT (AcDbBlockReference)
لـ subGetOsnapPoints مساران:
- وضع
Insertion:
- يدفع مباشرةً نقطة إدراج مرجع الكتلة (
this._position)
- الأوضاع الأخرى:
- تعمل فقط عند توفير
gsMark - تُفوَّض إلى
subEntityGetOsnapPoints(...)
تدفق التفويض (subEntityGetOsnapPoints):
- حارس: إذا كان
gsMark === this.objectId، فأرجِع (لتجنب التكرار) - حل الكيان بواسطة
blockTable.getEntityById(gsMark) - استدعِ
subGetOsnapPoints(...)لذلك الكيان الفرعي - حوّل النقاط المُعادة بواسطة
blockTransformلمرجع الكتلة هذا - ادفع النقاط المحوَّلة إلى الإخراج
لماذا قد يفشل التقاط INSERT (السلوك الحالي)
- لا يوجد
gsMark:
- بالنسبة للأوضاع غير
Insertion، لا يعيدAcDbBlockReferenceشيئًا إذا كانgsMarkمفقودًا.
- نموذج
gsMarkمبسّط:
gsMarkالحالي هو معرّف كائن الكيان الفرعي من إصابات الأبناء المكانية، وليس دلالات علامة GS الكاملة في AutoCAD.
- العرض المُجمَّع حسب الطبقات لـ INSERT:
- قد يقسّم العرض INSERT واحدًا إلى عدة مجموعات عرض قائمة على الطبقات مع معرّف الكائن الأب نفسه.
- يعتمد الانتقاء على صناديق الأبناء الهرمية لاستعادة معرّفات الكيانات الفرعية.
- التحويلات المعقدة/المتداخلة/الحافية:
- يطبّق التفويض
blockTransformالخاص بـ INSERT الحالي. - قد تظل الحالات الحافية (مثل سيناريوهات الكتل المتداخلة أو حالات الاتجاه/البثق غير الافتراضية) تنتج نقاط التقاط غير صحيحة أو مفقودة.
هذا يطابق ملاحظة خريطة الطريق المعروفة في README.md:
- التقاط نقطة النهاية لـ INSERT ليس موثوقًا بالكامل بعد.
القيود المعروفة / المهام المطلوبة
- تغطية OSNAP تعتمد على الكيان؛ كثير من تركيبات الوضع/الكيان غير منفَّذة عمدًا بعد.
- التقاط INSERT غير المتعلق بـ Insertion يعتمد على نشر صحيح لإصابة الابن ->
gsMark. - آلية العلامة الحالية قائمة على معرّف الكائن وليست سلوك علامة GS الكامل في AutoCAD.
- هناك حاجة إلى مزيد من اختبارات الانحدار لـ INSERT، خصوصًا الكتل المتداخلة والكتل المحوَّلة.
اتجاه المساهمة الموصى به
- تحسين متانة ربط إصابة الابن بـ
gsMarkلـ INSERT. - إضافة اختبارات انحدار للكتل المتداخلة لحالات EndPoint/MidPoint/Center/Nearest/Tangent.
- توسيع تغطية الأوضاع لكل كيان تدريجيًا.
- تقريب نموذج العلامة من دلالات علامة GS في AutoCAD قدر الإمكان.