30/05/2013
Получение нормали к грани 3D-тела с помощью BREP .NET API
Следующая C#-статья иллюстрирует как получить нормаль к грани 3D-тела с помощью функционала BRep .NET API:
Код - C#: [Выделить]
- // Возвращаем вектор нормали к грани 3D-тела [Philippe Leefsma, 7/11/2012]
- [CommandMethod("FaceNormal")]
- public void FaceNormal()
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- Database db = doc.Database;
- Editor ed = doc.Editor;
- PromptEntityOptions peo = new PromptEntityOptions(
- "\nВыберите 3D-тело: ");
- peo.SetRejectMessage("\nОшибочный выбор...");
- peo.AddAllowedClass(typeof(Solid3d), true);
- PromptEntityResult per = ed.GetEntity(peo);
- if (per.Status != PromptStatus.OK)
- return;
- PromptPointOptions ppo = new PromptPointOptions(
- "\nВыберите точку на грани: ");
- ppo.AllowArbitraryInput = false;
- PromptPointResult ppr = ed.GetPoint(ppo);
- if (ppr.Status != PromptStatus.OK)
- return;
- Point3d point = ppr.Value;
- using (Transaction Tx = db.TransactionManager.StartTransaction())
- {
- Solid3d solid = Tx.GetObject(per.ObjectId, OpenMode.ForRead)
- as Solid3d;
- ObjectId[] ids = new ObjectId[] { per.ObjectId };
- FullSubentityPath path = new FullSubentityPath(
- ids, new SubentityId(SubentityType.Null, IntPtr.Zero));
- using (Brep brep = new Brep(path))
- {
- foreach (Autodesk.AutoCAD.BoundaryRepresentation.Face face in
- brep.Faces)
- {
- PointContainment ptContainment = new PointContainment();
- using (BrepEntity brepEnt = face.GetPointContainment(
- point,
- out ptContainment))
- {
- if (ptContainment == PointContainment.Inside ||
- ptContainment == PointContainment.OnBoundary)
- {
- ed.WriteMessage("\nНормаль к грани в точке " +
- PointToStr(point) + " = " +
- VectToStr(GetFaceNormal(face, point)));
- }
- }
- }
- }
- Tx.Commit();
- }
- }
- // Небольшие вспомогательные методы
- private string VectToStr(Vector3d v)
- {
- return "[" +
- v.X.ToString("F2") + ", " +
- v.Y.ToString("F2") + ", " +
- v.Z.ToString("F2")
- + "]";
- }
- Vector3d GetFaceNormal(
- Autodesk.AutoCAD.BoundaryRepresentation.Face face,
- Point3d point)
- {
- PointOnSurface ptOnSurf = face.Surface.GetClosestPointTo(point);
- Point2d param = ptOnSurf.Parameter;
- Vector3d normal = ptOnSurf.GetNormal(param);
- // Похоже, что мы не можем доверять свойству
- // face.Surface.IsNormalReversed property,
- // так что я сделал небольшое смещение точки от поверхности
- // и проверяю, что смещенная точка внутри 3D-тела
- // В случае если точка внутри (или на поверхности),
- // нормаль должна быть инвертирована
- Vector3d normalTest = normal.MultiplyBy(1E-6 / normal.Length);
- Point3d ptTest = point.Add(normalTest);
- PointContainment ptContainment = new PointContainment();
- bool reverse = false;
- using(BrepEntity brepEnt =
- face.Brep.GetPointContainment(
- ptTest,
- out ptContainment))
- {
- if(ptContainment != PointContainment.Outside)
- {
- reverse = true;
- }
- }
- return normal.MultiplyBy(reverse ? -1.0 : 1.0);
- }
Источник: http://adndevblog.typepad.com/autocad/2012/07/retrieving-a-solid3d-face-normal-through-brep-api.html
Обсуждение: http://adn-cis.org/forum/index.php?topic=71.0
Опубликовано 30.05.2013
Отредактировано 08.06.2013 в 01:18:47
Отредактировано 08.06.2013 в 01:18:47