/// <summary>
/// Получить координаты границ левого нижнего и правого верхнего углов для
/// визуального "GeometricExtents" региона.
/// </summary>
/// <param name="region">Регион, для которого следует получить координаты
/// границ визуального "GeometricExtents".</param>
/// <param name="delta">Предельная арифметическая погрешность вычислений.
/// </param>
/// <param name="minPoint">Ссылка на переменную Point2d, в которой следует
/// сохранить координаты левого нижнего угла визуального
/// "GeometricExtents".</param>
/// <param name="maxPoint">Ссылка на переменную Point2d, в которой следует
/// сохранить координаты правого верхнего угла визуального
/// "GeometricExtents".</param>
internal static void GetVisualBoundary(this Db.Region region, double delta,
ref Gm.Point2d minPoint, ref Gm.Point2d maxPoint) {
if(region == null)
throw new ArgumentNullException("region");
if(region.IsDisposed)
throw new ArgumentException("region.IsDisposed == true");
if(delta <= 0)
throw new ArgumentException("delta <= 0");
using(Br.Brep brep = new Br.Brep(region)) {
// Находим min X
Double minX = Double.MinValue;
Gm.Point3d startPoint = region.GeometricExtents.MinPoint;
Gm.Point3d endPoint = new Gm.Point3d(
region.GeometricExtents.MinPoint.X,
region.GeometricExtents.MaxPoint.Y,
region.GeometricExtents.MinPoint.Z);
while(startPoint.X < region.GeometricExtents.MaxPoint.X) {
using(Gm.Line3d line = new Gm.Line3d(startPoint, endPoint)) {
Br.Hit[] hits = brep.GetLineContainment(line, 1);
if(hits != null) {
foreach(Br.Hit hit in hits) {
if(!hit.IsDisposed)
hit.Dispose();
}
// чтобы регион полностью находился в границах
minX = startPoint.X == region.GeometricExtents.MinPoint.X ?
startPoint.X : startPoint.X - delta;
break;
}
else {
startPoint = new Gm.Point3d(startPoint.X + delta, startPoint.Y,
startPoint.Z);
endPoint = new Gm.Point3d(endPoint.X + delta, endPoint.Y,
endPoint.Z);
}
}
}
// Находим min Y
Double minY = Double.MinValue;
startPoint = region.GeometricExtents.MinPoint;
endPoint = new Gm.Point3d(
region.GeometricExtents.MaxPoint.X,
region.GeometricExtents.MinPoint.Y,
region.GeometricExtents.MinPoint.Z);
while(startPoint.Y < region.GeometricExtents.MaxPoint.Y) {
using(Gm.Line3d line = new Gm.Line3d(startPoint, endPoint)) {
Br.Hit[] hits = brep.GetLineContainment(line, 1);
if(hits != null) {
foreach(Br.Hit hit in hits) {
if(!hit.IsDisposed)
hit.Dispose();
}
// чтобы регион полностью находился в границах
minY = startPoint.Y == region.GeometricExtents.MinPoint.Y ?
startPoint.Y : startPoint.Y - delta;
break;
}
else {
startPoint = new Gm.Point3d(startPoint.X, startPoint.Y + delta,
startPoint.Z);
endPoint = new Gm.Point3d(endPoint.X, endPoint.Y + delta,
endPoint.Z);
}
}
}
// Находим max X
Double maxX = Double.MinValue;
startPoint = region.GeometricExtents.MaxPoint;
endPoint = new Gm.Point3d(
region.GeometricExtents.MaxPoint.X,
region.GeometricExtents.MinPoint.Y,
region.GeometricExtents.MinPoint.Z);
while(startPoint.X > region.GeometricExtents.MinPoint.X) {
using(Gm.Line3d line = new Gm.Line3d(startPoint, endPoint)) {
Br.Hit[] hits = brep.GetLineContainment(line, 1);
if(hits != null) {
foreach(Br.Hit hit in hits) {
if(!hit.IsDisposed)
hit.Dispose();
}
// чтобы регион полностью находился в границах
maxX = startPoint.X == region.GeometricExtents.MaxPoint.X ?
startPoint.X : startPoint.X + delta;
break;
}
else {
startPoint = new Gm.Point3d(startPoint.X - delta, startPoint.Y,
startPoint.Z);
endPoint = new Gm.Point3d(endPoint.X - delta, endPoint.Y,
endPoint.Z);
}
}
}
// Находим max Y
Double maxY = Double.MinValue;
startPoint = region.GeometricExtents.MaxPoint;
endPoint = new Gm.Point3d(
region.GeometricExtents.MinPoint.X,
region.GeometricExtents.MaxPoint.Y,
region.GeometricExtents.MinPoint.Z);
while(startPoint.Y > region.GeometricExtents.MinPoint.Y) {
using(Gm.Line3d line = new Gm.Line3d(startPoint, endPoint)) {
Br.Hit[] hits = brep.GetLineContainment(line, 1);
if(hits != null) {
foreach(Br.Hit hit in hits) {
if(!hit.IsDisposed)
hit.Dispose();
}
// чтобы регион полностью находился в границах
maxY = startPoint.Y == region.GeometricExtents.MaxPoint.Y ?
startPoint.Y : startPoint.Y + delta;
break;
}
else {
startPoint = new Gm.Point3d(startPoint.X, startPoint.Y - delta,
startPoint.Z);
endPoint = new Gm.Point3d(endPoint.X, endPoint.Y - delta,
endPoint.Z);
}
}
}
// Возвращаем вычисленный результат
minPoint = new Gm.Point2d(minX, minY);
maxPoint = new Gm.Point2d(maxX, maxY);
}
}