乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 65|回复: 1

C#版几何约束编程实现

[复制链接]

9

主题

66

帖子

5

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
102
发表于 2014-11-24 10:08:00 | 显示全部楼层 |阅读模式
ObjectARX的几何约束功能,有时候还是很有用。
在网上找不到.Net版本的几何约束源码。我根据C++的代码,自己写了几个C#版的几何约束方法。
方法实现的约束功能很简单,复杂的约束可以根据这个代码进一步扩展。
代码在2014及2015下测试过,其它版本未经测试。
源代码如下:
class geometricalConstraints
         {
                 static public void createFixedConstraintOnMidPt4line(Line fixedLine, Database curDB, Assoc2dConstraintGroup assoc2dConsGrp)
                 {
                         Point3d fixedPt = new Point3d((fixedLine.StartPoint.X + fixedLine.EndPoint.X) / 2, (fixedLine.StartPoint.Y + fixedLine.EndPoint.Y) / 2, (fixedLine.StartPoint.Z + fixedLine.EndPoint.Z) / 2);
                         AssocPersSubentityIdPE pe = AssocPersSubentityIdPE.Create(fixedLine.QueryX(AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE))), false) as AssocPersSubentityIdPE;
                         SubentityId[] edgeIds = pe.GetAllSubentities(fixedLine, SubentityType.Edge);
                         FullSubentityPath edgeFullSubentity = new FullSubentityPath(new ObjectId[] { fixedLine.ObjectId }, edgeIds[0]);
                         assoc2dConsGrp.AddConstrainedGeometry(edgeFullSubentity);
                         FullSubentityPath closetPtFullSubentity;
                         getClosetVertexSubentityOfEdge(fixedLine, fixedPt, edgeIds[0], out closetPtFullSubentity);
                         FullSubentityPath[] vertexFullSubentityPaths = new FullSubentityPath[] { closetPtFullSubentity };
                         assoc2dConsGrp.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, vertexFullSubentityPaths);
                 }
                 static public void createFixedConstraintOnMidPt4line(ObjectId idFixedLine, Database curDB)
                 {
                         using (Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument())
                         {
                                 ObjectId consGrpId = getConstraintGroup();
                                 if (consGrpId.IsNull) return;
                                 using (Transaction trans = curDB.TransactionManager.StartTransaction())
                                 {
                                         Assoc2dConstraintGroup assoc2dConsGrp = trans.GetObject(consGrpId, OpenMode.ForWrite) as Assoc2dConstraintGroup;
                                         if (assoc2dConsGrp == null)
                                         {
                                                 return;
                                         }
                                         Line fixedLine = trans.GetObject(idFixedLine, OpenMode.ForRead) as Line;
                                         Point3d fixedPt = new Point3d((fixedLine.StartPoint.X + fixedLine.EndPoint.X) / 2, (fixedLine.StartPoint.Y + fixedLine.EndPoint.Y) / 2, (fixedLine.StartPoint.Z + fixedLine.EndPoint.Z) / 2);
                                         AssocPersSubentityIdPE pe = AssocPersSubentityIdPE.Create(fixedLine.QueryX(AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE))), false) as AssocPersSubentityIdPE;
                                         SubentityId[] edgeIds = pe.GetAllSubentities(fixedLine, SubentityType.Edge);
                                         FullSubentityPath edgeFullSubentity = new FullSubentityPath(new ObjectId[] { idFixedLine }, edgeIds[0]);
                                         assoc2dConsGrp.AddConstrainedGeometry(edgeFullSubentity);
                                         FullSubentityPath closetPtFullSubentity;
                                         getClosetVertexSubentityOfEdge(fixedLine, fixedPt, edgeIds[0], out closetPtFullSubentity);
                                         FullSubentityPath[] vertexFullSubentityPaths = new FullSubentityPath[] { closetPtFullSubentity };
                                         assoc2dConsGrp.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, vertexFullSubentityPaths);
                                         ObjectId idNetWork = AssocNetwork.GetInstanceFromDatabase(curDB, true, "");
                                         if (!idNetWork.IsValid) return;
                                         AssocNetwork network = trans.GetObject(idNetWork, OpenMode.ForWrite) as AssocNetwork;
                                         speAssocEvaluationCallback callback = new speAssocEvaluationCallback();
                                         network.Evaluate(callback);
                                         trans.Commit();
                                 }
                         }
                 }
                 static public void createFixedConstraintsOnPolylineStartAndEndPt(ObjectId idPolyline, Database curDB)
                 {
                         using (Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument())
                         {
                                 ObjectId consGrpId = getConstraintGroup();
                                 if (consGrpId.IsNull) return;
                                 using (Transaction trans = curDB.TransactionManager.StartTransaction())
                                 {
                                         Assoc2dConstraintGroup assoc2dConsGrp = trans.GetObject(consGrpId, OpenMode.ForWrite) as Assoc2dConstraintGroup;
                                         if (assoc2dConsGrp == null)
                                         {
                                                 return;
                                         }
                                         Polyline thePolyline = trans.GetObject(idPolyline, OpenMode.ForRead) as Polyline;
                                         Point3d fixedStartPt = thePolyline.GetPoint3dAt(0);
                                         Point3d fixedEndPt = thePolyline.GetPoint3dAt(thePolyline.NumberOfVertices - 1);
                                         AssocPersSubentityIdPE pe = AssocPersSubentityIdPE.Create(thePolyline.QueryX(AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE))), false) as AssocPersSubentityIdPE;
                                         SubentityId[] vertexIds = pe.GetAllSubentities(thePolyline, SubentityType.Vertex);
                                         SubentityId[] edgeIds = pe.GetAllSubentities(thePolyline, SubentityType.Edge);
                                         FullSubentityPath startPtFullSubentity;
                                         getClosetVertexFullSubentity(thePolyline, fixedStartPt, vertexIds, out startPtFullSubentity);
                                         FullSubentityPath endPtFullSubentity;
                                         getClosetVertexFullSubentity(thePolyline, fixedEndPt, vertexIds, out endPtFullSubentity);
                                         assoc2dConsGrp.AddConstrainedGeometry(new FullSubentityPath(new ObjectId[] { idPolyline }, edgeIds[0]));
                                         assoc2dConsGrp.AddConstrainedGeometry(new FullSubentityPath(new ObjectId[] { idPolyline }, edgeIds[edgeIds.Length - 1]));
                                         assoc2dConsGrp.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, new FullSubentityPath[] { startPtFullSubentity });
                                         assoc2dConsGrp.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, new FullSubentityPath[] { endPtFullSubentity });
                                         ObjectId idNetWork = AssocNetwork.GetInstanceFromDatabase(curDB, true, "");
                                         if (!idNetWork.IsValid) return;
                                         AssocNetwork network = trans.GetObject(idNetWork, OpenMode.ForWrite) as AssocNetwork;
                                         speAssocEvaluationCallback callback = new speAssocEvaluationCallback();
                                         network.Evaluate(callback);
                                         trans.Commit();
                                 }
                         }
                 }
                 static public void createFixedLine(Line fixedLine, Database curDB, Assoc2dConstraintGroup assoc2dConsGrp)
                 {
                         Point3d fixedStartPt = fixedLine.StartPoint;
                         Point3d fixedEndPt = fixedLine.EndPoint;
                         AssocPersSubentityIdPE pe = AssocPersSubentityIdPE.Create(fixedLine.QueryX(AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE))), false) as AssocPersSubentityIdPE;
                         SubentityId[] edgeIds = pe.GetAllSubentities(fixedLine, SubentityType.Edge);
                         FullSubentityPath edgeFullSubentity = new FullSubentityPath(new ObjectId[] { fixedLine.ObjectId }, edgeIds[0]);
                         assoc2dConsGrp.AddConstrainedGeometry(edgeFullSubentity);
                         FullSubentityPath closetPtFullSubentity;
                         getClosetVertexSubentityOfEdge(fixedLine, fixedStartPt, edgeIds[0], out closetPtFullSubentity);
                         FullSubentityPath[] vertexFullSubentityPaths = new FullSubentityPath[] { closetPtFullSubentity };
                         assoc2dConsGrp.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, vertexFullSubentityPaths);
                         getClosetVertexSubentityOfEdge(fixedLine, fixedEndPt, edgeIds[0], out closetPtFullSubentity);
                         vertexFullSubentityPaths = new FullSubentityPath[] { closetPtFullSubentity };
                         assoc2dConsGrp.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, vertexFullSubentityPaths);
                 }
                 static public void createFixedLine(ObjectId idFixedLine, Database curDB)
                 {
                         using (Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument())
                         {
                                 ObjectId consGrpId = getConstraintGroup();
                                 if (consGrpId.IsNull) return;
                                 using (Transaction trans = curDB.TransactionManager.StartTransaction())
                                 {
                                         Assoc2dConstraintGroup assoc2dConsGrp = trans.GetObject(consGrpId, OpenMode.ForWrite) as Assoc2dConstraintGroup;
                                         if (assoc2dConsGrp == null)
                                         {
                                                 return;
                                         }
                                         Line fixedLine = trans.GetObject(idFixedLine, OpenMode.ForRead) as Line;
                                         Point3d fixedStartPt = fixedLine.StartPoint;
                                         Point3d fixedEndPt = fixedLine.EndPoint;
                                         AssocPersSubentityIdPE pe = AssocPersSubentityIdPE.Create(fixedLine.QueryX(AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE))), false) as AssocPersSubentityIdPE;
                                         SubentityId[] edgeIds = pe.GetAllSubentities(fixedLine, SubentityType.Edge);
                                         FullSubentityPath edgeFullSubentity = new FullSubentityPath(new ObjectId[] { idFixedLine }, edgeIds[0]);
                                         assoc2dConsGrp.AddConstrainedGeometry(edgeFullSubentity);
                                         FullSubentityPath closetPtFullSubentity;
                                         getClosetVertexSubentityOfEdge(fixedLine, fixedStartPt, edgeIds[0], out closetPtFullSubentity);
                                         FullSubentityPath[] vertexFullSubentityPaths = new FullSubentityPath[] { closetPtFullSubentity };
                                         assoc2dConsGrp.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, vertexFullSubentityPaths);
                                         getClosetVertexSubentityOfEdge(fixedLine, fixedEndPt, edgeIds[0], out closetPtFullSubentity);
                                         vertexFullSubentityPaths = new FullSubentityPath[] { closetPtFullSubentity };
                                         assoc2dConsGrp.AddGeometricalConstraint(GeometricalConstraint.ConstraintType.Fix, vertexFullSubentityPaths);
                                         ObjectId idNetWork = AssocNetwork.GetInstanceFromDatabase(curDB, true, "");
                                         if (!idNetWork.IsValid) return;
                                         AssocNetwork network = trans.GetObject(idNetWork, OpenMode.ForWrite) as AssocNetwork;
                                         speAssocEvaluationCallback callback = new speAssocEvaluationCallback();
                                         network.Evaluate(callback);
                                         trans.Commit();
                                 }
                         }
                 }
                ///
                 /// 在给定的edge Subentity中,搜索距离pt最近的Vertex Subentity
                 ///
                 ///
                 ///
                 ///
                 static public void getClosetVertexSubentityOfEdge(Entity fixedLine, Point3d pt, SubentityId edgeSubentity, out FullSubentityPath closetPtFullSubentity)
                 {
                         List vertexSubentityIds = new List(4);
                         AssocPersSubentityIdPE pe = AssocPersSubentityIdPE.Create(fixedLine.QueryX(AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE))),
                                 false) as AssocPersSubentityIdPE;
                         SubentityId startVertexSubentId = SubentityId.Null; ;
                         SubentityId endVertexSubentId = SubentityId.Null;
                         SubentityId[] otherVertexSubentIds = null;
                         pe.GetEdgeVertexSubentities(fixedLine, edgeSubentity, ref startVertexSubentId, ref endVertexSubentId, ref otherVertexSubentIds);
                         vertexSubentityIds.Add(startVertexSubentId);
                         vertexSubentityIds.Add(endVertexSubentId);
                         vertexSubentityIds.AddRange(otherVertexSubentIds);
                         double minDist = -1.0;
                         SubentityId closestId = SubentityId.Null;
                         foreach (var vertexSubent in vertexSubentityIds)
                         {
                                 Point3d vertexPos;
                                 vertexPos = pe.GetVertexSubentityGeometry(fixedLine, vertexSubent);
                                 double dist = vertexPos.DistanceTo(pt);
                                 if (minDist
                 /// 获取Assoc2dConstraintGroup对象。该对象位于当前活动文档的当前坐标系的oxy平面内
                ///
                 ///
                 static public ObjectId getConstraintGroup()
                 {
                         ObjectId idConsGrp = ObjectId.Null;
                         try
                         {
                                 Editor activeEditor = AutoCadDatabaseOperate.m_activeDocument.Editor;
                                 CoordinateSystem3d cs3d = activeEditor.CurrentUserCoordinateSystem.CoordinateSystem3d;
                                 Plane currentPlane = new Plane(cs3d.Origin, cs3d.Xaxis, cs3d.Yaxis);
                                 Database curDB = HostApplicationServices.WorkingDatabase;
                                 //ObjectId spaceId = curDB.CurrentSpaceId;
                                 ObjectId idNetWork = AssocNetwork.GetInstanceFromDatabase(curDB, true, "");
                                 if (!idNetWork.IsValid) return ObjectId.Null;
                                 using (Transaction trans = curDB.TransactionManager.StartTransaction())
                                 {
                                         AssocNetwork assocNetWork = trans.GetObject(idNetWork, OpenMode.ForWrite) as AssocNetwork;
                                         foreach (ObjectId idAction in assocNetWork.GetActions)
                                         {
                                                 if (!idAction.IsValid)
                                                 {
                                                         continue;
                                                 }
                                                 Assoc2dConstraintGroup action = trans.GetObject(idAction, OpenMode.ForRead) as Assoc2dConstraintGroup;
                                                 if (action == null) continue;
                                                 if (action.WorkPlane.IsCoplanarTo(currentPlane))
                                                 {
                                                         return idAction;
                                                 }
                                         }
                                         Assoc2dConstraintGroup consGrp = new Assoc2dConstraintGroup(currentPlane);
                                         idConsGrp = curDB.AddDBObject(consGrp);
                                         trans.AddNewlyCreatedDBObject(consGrp, true);
                                         assocNetWork.AddAction(idConsGrp, true);
                                         trans.Commit();
                                 }
                                 return idConsGrp;
                         }
                         catch
                         {
                                 return idConsGrp;
                         }
                 }
         }
         ///
         /// 几何约束执行类
        ///
         internal class speAssocEvaluationCallback : AssocEvaluationCallback
         {
                 public override void BeginActionEvaluation(AssocAction action) { }
                 public override void BeginActionEvaluationUsingObject(AssocAction pAction, ObjectId objectId, bool objectIsGoingToBeUsed, bool objectIsGoingToBeModified, DBObject substituteObject) { }
                 public override bool CancelActionEvaluation()
                 {
                         return false;
                 }
                 public override void EndActionEvaluation(AssocAction action) { }
                 public override void EndActionEvaluationUsingObject(AssocAction action, ObjectId objectId, DBObject obj) { }
                 public override void SetActionEvaluationErrorStatus(AssocAction action, Autodesk.AutoCAD.Runtime.ErrorStatus errorStatus, ObjectId objectId, DBObject obj, System.IntPtr errorInfo) { }
         }
回复

使用道具 举报

0

主题

26

帖子

10

银币

初来乍到

Rank: 1

铜币
22
发表于 2019-8-29 15:15:00 | 显示全部楼层
支持一下分享!
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2024-11-22 00:22 , Processed in 0.150679 second(s), 56 queries .

© 2020-2024 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表