Author: Jonio, Dennis
The next and last items on the list ...
This is the class that interacts with Autodesk Map3d. (I have removed a few things that are not importtant to the discussion here.)
First, as time has gone on I have grown weary of parseing out Autodesk/Map3d objects and manipulating them. I gravitated toward AppendLoopFromBoundary() and BalanceTree() for MPolygon construction. Just a lot less code on my part. If it isn't a Point type I force just about everything to a Polyline at one time or the other. If you really need true 3D objects you shouldn't be reading this anyway.
Just some things of note:
I will read them and write them as Autdesk objects but after this they loose their identity as such.
This is the last post on this topic. I have decided NOT to post the working source and project. If you are interested in the final work leave a comment with your email address.
Since I produce only VALIDATED geometry I will be working on the post of my latest iteration of my IO class for doing validation against the database.
Source code (C#):
using MDADDrawAbles;
using SDO = MDADDrawAbles.DrawAbleSdoGeometryUtil;
using NetSdoGeometry;
namespace MDADDrawAbleDwg
{
public class DrawAbleDwg
{
//
// POINT
//
public static DrawAble PointDrawAbleFromPoint(Point3d p3d, int _dimensionality)
{
DrawAble dp = new DrawAble(DrawAbleType.Point, _dimensionality);
DrawAbleSubComponent dpc = new DrawAbleSubComponent();
dpc.Etype = DrawAbleSubComponentEType.Point;
int len = (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D) ? DrawAbleSdoGeometry.DefaultDimensionality3D : DrawAbleSdoGeometry.DefaultDimensionality2D;
dpc.Ords = new decimal[len];
dpc.Ords[0] = System.Convert.ToDecimal(p3d.X);
dpc.Ords[1] = System.Convert.ToDecimal(p3d.Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dpc.Ords[2] = System.Convert.ToDecimal(p3d.Z);
dp.SubComponents.Add(dpc);
return dp;
}
public static DrawAble PointDrawAbleFromPoint(DBPoint dbp, int _dimensionality)
{
DrawAble dp = new DrawAble(DrawAbleType.Point, _dimensionality);
DrawAbleSubComponent dpc = new DrawAbleSubComponent();
dpc.Etype = DrawAbleSubComponentEType.Point;
int len = (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D) ? DrawAbleSdoGeometry.DefaultDimensionality3D : DrawAbleSdoGeometry.DefaultDimensionality2D;
dpc.Ords = new decimal[len];
dpc.Ords[0] = System.Convert.ToDecimal(dbp.Position.X);
dpc.Ords[1] = System.Convert.ToDecimal(dbp.Position.Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dpc.Ords[2] = System.Convert.ToDecimal(dbp.Position.Z);
dp.SubComponents.Add(dpc);
return dp;
}
//
// POINT CLUSTER
//
public static DrawAble PointClusterDrawAbleFromPointList(Listp3dList, int _dimensionality)
{
DrawAble dp = new DrawAble(DrawAbleType.Point, _dimensionality);
DrawAbleSubComponent dpc = new DrawAbleSubComponent();
dpc.Etype = DrawAbleSubComponentEType.PointCluster;
int len = (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D) ? DrawAbleSdoGeometry.DefaultDimensionality3D : DrawAbleSdoGeometry.DefaultDimensionality2D;
dpc.Ords = new decimal[len * p3dList.Count];
int p3d_counter = 0;
for (int _k = 0; _k < dpc.Ords.Length; )
{
dpc.Ords[_k] = System.Convert.ToDecimal(p3dList[p3d_counter].X);
dpc.Ords[_k + 1] = System.Convert.ToDecimal(p3dList[p3d_counter].Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dpc.Ords[_k + 2] = System.Convert.ToDecimal(p3dList[p3d_counter].Z);
_k = _k + len;
p3d_counter = p3d_counter + 1;
}
dpc.Elem = new int[] { 0, 1, p3dList.Count };
dp.SubComponents.Add(dpc);
return dp;
}
//
// LINES
//
public static DrawAble LineCurveDrawAbleFromPolyline(Polyline pl, Polyline2d pl2d, Polyline3d pl3d, int _dimensionality)
{
DrawAble dl = new DrawAble(DrawAbleType.Line, _dimensionality);
int hasBulgesCount = 0;
Point3dCollection tmppts = null;
DoubleCollection tmpblgs = null;
Point3d[] pts = null;
double[] blgs = null;
if (pl != null)
{
tmppts = new Point3dCollection();
tmpblgs = new DoubleCollection();
int i = 0;
for (; i < pl.NumberOfVertices; i++)
{
switch (pl.GetSegmentType(i))
{
case SegmentType.Arc:
CircularArc2d ca2d = pl.GetArcSegment2dAt(i);
double bulge = GetBulge2d(ca2d);
tmpblgs.Add(bulge);
tmppts.Add(new Point3d(ca2d.StartPoint.X, ca2d.StartPoint.Y, pl.GetPoint3dAt(i).Z));
hasBulgesCount++;
ca2d.Dispose();
break;
default:
tmpblgs.Add(0.0);
tmppts.Add(new Point3d(pl.GetPoint3dAt(i).X, pl.GetPoint3dAt(i).Y, pl.GetPoint3dAt(i).Z));
break;
}
}
// Do NOT duplicate any point ... this appears to have different behavior for
// the 2D and 3D polylines so we will check them all.
if (pl.Closed && (tmppts[0].IsEqualTo(tmppts[tmppts.Count - 1]) == false))
{
//tmppts.Add(new Point3d(pl.GetPoint2dAt(0).X, pl.GetPoint2dAt(0).Y, 0.0));
tmppts.Add(new Point3d(pl.GetPoint3dAt(0).X, pl.GetPoint3dAt(0).Y, pl.GetPoint3dAt(0).Z));
tmpblgs.Add(0.0);
}
// Now we can dimensions our array stuctures and fill them up
pts = new Point3d[tmppts.Count];
blgs = new double[tmppts.Count];
for (int z = 0; z < tmppts.Count; z++)
{
pts[z] = new Point3d(tmppts[z].X, tmppts[z].Y, tmppts[z].Z);
blgs[z] = tmpblgs[z];
}
tmppts.Clear();
tmppts.Dispose();
tmpblgs.Clear();
}
//END OF POLYLINE
//START OF POLYLINE2D
if (pl2d != null)
{
// No way of knowing how many we have so we need this to collect the points
tmppts = new Point3dCollection();
tmpblgs = new DoubleCollection();
if (pl2d.PolyType == Poly2dType.SimplePoly)
{
Transaction t = pl2d.Database.TransactionManager.StartTransaction();
IEnumerator iterate = pl2d.GetEnumerator();
while (iterate.MoveNext())
{
ObjectId id = (ObjectId)iterate.Current;
Vertex2d vertex = (Vertex2d)t.GetObject(id, OpenMode.ForRead);
tmppts.Add(vertex.Position);
tmpblgs.Add(vertex.Bulge);
if (vertex.Bulge != 0.0)
hasBulgesCount++;
}
t.Abort();
t.Dispose();
}
else
{
DBObjectCollection collection = new DBObjectCollection();
pl2d.Explode(collection);
foreach (Line line in collection)
{
tmppts.Add(line.StartPoint);
tmpblgs.Add(0.0);
tmppts.Add(line.EndPoint);
tmpblgs.Add(0.0);
}
collection.Dispose();
}
// Do NOT duplicate any point
if (pl2d.Closed && (tmppts[0].IsEqualTo(tmppts[tmppts.Count - 1]) == false))
{
tmppts.Add(tmppts[0]);
tmpblgs.Add(0.0);
}
// Now we can dimensions our array stuctures and fill them up
pts = new Point3d[tmppts.Count];
blgs = new double[tmppts.Count];
for (int z = 0; z < tmppts.Count; z++)
{
pts[z] = new Point3d(tmppts[z].X, tmppts[z].Y, tmppts[z].Z);
blgs[z] = tmpblgs[z];
}
tmppts.Clear();
tmppts.Dispose();
tmpblgs.Clear();
}
//END OF POLYLINE2D
//START OF POLYLINE3D
if (pl3d != null)
{
tmppts = new Point3dCollection();
tmpblgs = new DoubleCollection();
if (pl3d.PolyType == Poly3dType.SimplePoly)
{
Transaction t = pl3d.Database.TransactionManager.StartTransaction();
IEnumerator iterator = pl3d.GetEnumerator();
while (iterator.MoveNext())
{
ObjectId id = (ObjectId)iterator.Current;
PolylineVertex3d vertex3d = (PolylineVertex3d)t.GetObject(id, OpenMode.ForRead);
tmppts.Add(vertex3d.Position);
tmpblgs.Add(0.0);
}
t.Abort();
t.Dispose();
}
else
{
DBObjectCollection collection = new DBObjectCollection();
pl3d.Explode(collection);
foreach (Line line in collection)
{
tmppts.Add(line.StartPoint);
tmpblgs.Add(0.0);
tmppts.Add(line.EndPoint);
tmpblgs.Add(0.0);
}
collection.Dispose();
}
// Do NOT duplicate any point
if (pl3d.Closed && (tmppts[0].IsEqualTo(tmppts[tmppts.Count - 1]) == false))
{
tmppts.Add(tmppts[0]);
tmpblgs.Add(0.0);
}
// Now we can dimensions our array stuctures and fill them up
pts = new Point3d[tmppts.Count];
blgs = new double[tmppts.Count];
for (int z = 0; z < tmppts.Count; z++)
{
pts[z] = new Point3d(tmppts[z].X, tmppts[z].Y, tmppts[z].Z);
blgs[z] = tmpblgs[z];
}
tmppts.Clear();
tmppts.Dispose();
tmpblgs.Clear();
}
//END OF POLYLINE3D
//
// Finished getting all the ordinates and bulges for this linecurve
//
DrawAbleSubComponent dlc = new DrawAbleSubComponent();
if (hasBulgesCount == 0)
{
dlc.Etype = DrawAbleSubComponentEType.SimpleLine;
int len = (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D) ? DrawAbleSdoGeometry.DefaultDimensionality3D : DrawAbleSdoGeometry.DefaultDimensionality2D;
dlc.Ords = new decimal[len * pts.Length];
int pts_counter = 0;
for (int _k = 0; _k < dlc.Ords.Length; )
{
dlc.Ords[_k] = System.Convert.ToDecimal(pts[pts_counter].X);
dlc.Ords[_k + 1] = System.Convert.ToDecimal(pts[pts_counter].Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dlc.Ords[_k + 2] = System.Convert.ToDecimal(pts[pts_counter].Z);
_k = _k + len;
pts_counter = pts_counter + 1;
}
dl.SubComponents.Add(dlc);
}
else if (hasBulgesCount == pts.Length - 1)
{
dlc.Etype = DrawAbleSubComponentEType.SimpleLineAllCurves;
int len = (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D) ? DrawAbleSdoGeometry.DefaultDimensionality3D : DrawAbleSdoGeometry.DefaultDimensionality2D;
dlc.Ords = new decimal[(len * pts.Length) + (hasBulgesCount * len)];
int ords_counter = 0;
Point3d arc_endpoint;
for (int j = 0; j < pts.Length; j++)
{
double theBulge = blgs[j];
arc_endpoint = pts[j + 1];
CircularArc2d ca2d = new CircularArc2d(
new Point2d(pts[j].X, pts[j].Y),
new Point2d(arc_endpoint.X, arc_endpoint.Y), theBulge, false);
Interval interval_of_arc = ca2d.GetInterval();
Point2d somePointOnArc = ca2d.EvaluatePoint(interval_of_arc.Element / 2);
//Start
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].X);
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Z);
//Center point on arc
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(somePointOnArc.X);
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(somePointOnArc.Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Z);
//Because of LOOK-AHEAD we now check for the end
if (j == (pts.Length - 2))
{
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(arc_endpoint.X);
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(arc_endpoint.Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(arc_endpoint.Z);
j = pts.Length; //End the loop
}
}
dl.SubComponents.Add(dlc);
}
else
{
//DIM_ELEMENTS are required
dlc.Etype = DrawAbleSubComponentEType.CompoundLine;
int len = (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D) ? DrawAbleSdoGeometry.DefaultDimensionality3D : DrawAbleSdoGeometry.DefaultDimensionality2D;
dlc.Ords = new decimal[(len * pts.Length) + (hasBulgesCount * len)];
int ords_counter = 0;
Point3d arc_endpoint;
TriInts elmHeader = new TriInts(ords_counter, SDO.BasicETYPE(DrawAbleSubComponentEType.CompoundLine), 0);
ListelmList = new List ();
TriInts wrkrElm = null;
int nxtINTERP = 0;
int lstINTERP = 0;
for (int j = 0; j < pts.Length; j++)
{
if (j < pts.Length - 1)
nxtINTERP = (blgs[j] == 0.0) ? (int)SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleLine) : (int)SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleLineAllCurves);
if (lstINTERP != nxtINTERP)
{
if (wrkrElm != null)
elmList.Add(wrkrElm);
wrkrElm = new TriInts(ords_counter, SDO.BasicETYPE(DrawAbleSubComponentEType.SimpleLineAllCurves), nxtINTERP);
lstINTERP = nxtINTERP;
}
double theBulge = blgs[j];
if (theBulge != 0.0)
{
arc_endpoint = pts[j + 1];
CircularArc2d ca2d = new CircularArc2d(
new Point2d(pts[j].X, pts[j].Y),
new Point2d(arc_endpoint.X, arc_endpoint.Y), theBulge, false);
Interval interval_of_arc = ca2d.GetInterval();
Point2d somePointOnArc = ca2d.EvaluatePoint(interval_of_arc.Element / 2);
//Start
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].X);
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Z);
//Center point on arc
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(somePointOnArc.X);
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(somePointOnArc.Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Z);
}
else
{
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].X);
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Z);
}
}//for loop
elmList.Add(wrkrElm);
elmHeader.INTERP = elmList.Count;
dlc.Elem = new int[(elmList.Count + 1) * 3];
int cntr = 0;
dlc.Elem[cntr++] = elmHeader.OFFSET;
dlc.Elem[cntr++] = elmHeader.ETYPE;
dlc.Elem[cntr++] = elmHeader.INTERP;
for (int _i = 0; _i < elmList.Count; _i++)
{
dlc.Elem[cntr++] = elmList[_i].OFFSET;
dlc.Elem[cntr++] = elmList[_i].ETYPE;
dlc.Elem[cntr++] = elmList[_i].INTERP;
}
dl.SubComponents.Add(dlc);
}
return dl;
}
public static DrawAble LineCurveDrawAbleFromArc(Arc a, int _dimensionality)
{
DrawAble d = new DrawAble(DrawAbleType.Line, _dimensionality);
DrawAbleSubComponent dc = new DrawAbleSubComponent();
dc.Etype = DrawAbleSubComponentEType.SimpleLineAllCurves;
int len = (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D) ? DrawAbleSdoGeometry.DefaultDimensionality3D : DrawAbleSdoGeometry.DefaultDimensionality2D;
dc.Ords = new decimal[len * 3];
double length = a.GetDistAtPoint(a.EndPoint);
Point3d mid = a.GetPointAtDist(length / 2.0);
int ords_counter = 0;
//Start
dc.Ords[ords_counter++] = System.Convert.ToDecimal(a.StartPoint.X);
dc.Ords[ords_counter++] = System.Convert.ToDecimal(a.StartPoint.Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dc.Ords[ords_counter++] = System.Convert.ToDecimal(a.StartPoint.Z);
//Mid
dc.Ords[ords_counter++] = System.Convert.ToDecimal(mid.X);
dc.Ords[ords_counter++] = System.Convert.ToDecimal(mid.Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dc.Ords[ords_counter++] = System.Convert.ToDecimal(mid.Z);
//End
dc.Ords[ords_counter++] = System.Convert.ToDecimal(a.EndPoint.X);
dc.Ords[ords_counter++] = System.Convert.ToDecimal(a.EndPoint.Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dc.Ords[ords_counter++] = System.Convert.ToDecimal(a.EndPoint.Z);
d.SubComponents.Add(dc);
return d;
}
public static DrawAble LineCurveDrawAbleFromLine(Line l, int _dimensionality)
{
DrawAble d = new DrawAble(DrawAbleType.Line, _dimensionality);
DrawAbleSubComponent dc = new DrawAbleSubComponent();
dc.Etype = DrawAbleSubComponentEType.SimpleLine;
int len = (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D) ? DrawAbleSdoGeometry.DefaultDimensionality3D : DrawAbleSdoGeometry.DefaultDimensionality2D;
dc.Ords = new decimal[len * 2];
int ords_counter = 0;
//Start
dc.Ords[ords_counter++] = System.Convert.ToDecimal(l.StartPoint.X);
dc.Ords[ords_counter++] = System.Convert.ToDecimal(l.StartPoint.Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dc.Ords[ords_counter++] = System.Convert.ToDecimal(l.StartPoint.Z);
//End
dc.Ords[ords_counter++] = System.Convert.ToDecimal(l.EndPoint.X);
dc.Ords[ords_counter++] = System.Convert.ToDecimal(l.EndPoint.Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dc.Ords[ords_counter++] = System.Convert.ToDecimal(l.EndPoint.Z);
d.SubComponents.Add(dc);
return d;
}
public static DrawAble LineCurveDrawAbleFromCircle(Circle circ, int _dimensionality)
{
DrawAble d = new DrawAble(DrawAbleType.Line, _dimensionality);
DrawAbleSubComponent dc = new DrawAbleSubComponent();
dc.Etype = DrawAbleSubComponentEType.SimpleLineAllCurves;
int len = (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D) ? 15 : 10;
dc.Ords = new decimal[len];
int ords_counter = 0;
double length = circ.Circumference;
Point3d firstarc_endpoint = circ.GetPointAtDist(length / 2.0);
Point3d firstarc_midpoint = circ.GetPointAtDist((length / 2.0) / 2.0);
Point3d secondarc_midpoint = circ.GetPointAtDist(length * .75);
//Start
dc.Ords[ords_counter++] = System.Convert.ToDecimal(circ.StartPoint.X);
dc.Ords[ords_counter++] = System.Convert.ToDecimal(circ.StartPoint.Y);
if (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D)
dc.Ords[ords_counter++] = System.Convert.ToDecimal(circ.StartPoint.Z);
//mid 1
dc.Ords[ords_counter++] = System.Convert.ToDecimal(firstarc_midpoint.X);
dc.Ords[ords_counter++] = System.Convert.ToDecimal(firstarc_midpoint.Y);
if (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D)
dc.Ords[ords_counter++] = System.Convert.ToDecimal(firstarc_midpoint.Z);
//End
dc.Ords[ords_counter++] = System.Convert.ToDecimal(firstarc_endpoint.X);
dc.Ords[ords_counter++] = System.Convert.ToDecimal(firstarc_endpoint.Y);
if (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D)
dc.Ords[ords_counter++] = System.Convert.ToDecimal(firstarc_endpoint.Z);
//mid 2
dc.Ords[ords_counter++] = System.Convert.ToDecimal(secondarc_midpoint.X);
dc.Ords[ords_counter++] = System.Convert.ToDecimal(secondarc_midpoint.Y);
if (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D)
dc.Ords[ords_counter++] = System.Convert.ToDecimal(secondarc_midpoint.Z);
//End
dc.Ords[ords_counter++] = System.Convert.ToDecimal(circ.EndPoint.X);
dc.Ords[ords_counter++] = System.Convert.ToDecimal(circ.EndPoint.Y);
if (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D)
dc.Ords[ords_counter++] = System.Convert.ToDecimal(circ.EndPoint.Z);
d.SubComponents.Add(dc);
return d;
}
//
// SURFACES
//
public static DrawAble PolygonDrawAbleFromMPolygon(MPolygon mpoly, int _dimensionality)
{
DrawAble dl = new DrawAble(DrawAbleType.Surface, _dimensionality);
Point3dCollection p3dColl = new Point3dCollection();
LoopDirection loopdirection;
int ords_counter = 0; // The total ordinates in the array
int hasBulgesCount = 0;
int loops = mpoly.NumMPolygonLoops;
for (int i = 0; i < loops; i++)
{
// Gather up points and bulges for this loop
MPolygonLoop mPolygonLoop = mpoly.GetMPolygonLoopAt(i);
loopdirection = mpoly.GetLoopDirection(i);
hasBulgesCount = 0;
ords_counter = 0;
// Remove duplicate verticies
for (int d = 1; d < mPolygonLoop.Count - 1; d++)
{
if (mPolygonLoop[d].Vertex.IsEqualTo(mPolygonLoop[d + 1].Vertex))
{
mPolygonLoop.RemoveAt(d + 1);
}
}
//
Point3d[] pts = new Point3d[mPolygonLoop.Count];
double[] blgs = new double[mPolygonLoop.Count];
for (int z = 0; z < mPolygonLoop.Count; z++)
{
if (z == mPolygonLoop.Count - 1)
{
pts[z] = pts[0];
}
else
{
double X = Math.Round(mPolygonLoop[z].Vertex.X, 10, MidpointRounding.AwayFromZero);
double Y = Math.Round(mPolygonLoop[z].Vertex.Y, 10, MidpointRounding.AwayFromZero);
double Z = Math.Round(mpoly.Elevation, 10, MidpointRounding.AwayFromZero);
pts[z] = new Point3d(X, Y, Z);
}
blgs[z] = mPolygonLoop[z].Bulge;
if (blgs[z] != 0.0)
hasBulgesCount = hasBulgesCount + 1;
}
//
// Suspect code here ......
//
if (blgs[0] == blgs[mPolygonLoop.Count - 1] && blgs[0] != 0.0)
{
blgs[mPolygonLoop.Count - 1] = 0.0;
hasBulgesCount--;
}
//
//DO THE STUFF
//
DrawAbleSubComponent dlc = new DrawAbleSubComponent();
TriInts headerElem = new TriInts(ords_counter, 0, 0);
if (hasBulgesCount == 0)
{
headerElem.INTERP = SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleSurfaceInnerRingLine);
}
//else if (hasBulgesCount == pts.Length)
else if (hasBulgesCount == pts.Length - 1)
{
headerElem.INTERP = SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleSurfaceInnerRingAllCurves);
}
if (loopdirection == LoopDirection.Exterior)
{
if (headerElem.INTERP == SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleSurfaceOuterRingLine) ||
headerElem.INTERP == SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleSurfaceOuterRingAllCurves))
{
headerElem.ETYPE = SDO.BasicETYPE(DrawAbleSubComponentEType.SimpleSurfaceOuterRingLine);
if (headerElem.INTERP == SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleSurfaceOuterRingLine))
dlc.Etype = DrawAbleSubComponentEType.SimpleSurfaceOuterRingLine;
else
dlc.Etype = DrawAbleSubComponentEType.SimpleSurfaceOuterRingAllCurves;
}
}
else
{
if (headerElem.INTERP == SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleSurfaceInnerRingLine) ||
headerElem.INTERP == SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleSurfaceInnerRingAllCurves))
{
headerElem.ETYPE = SDO.BasicETYPE(DrawAbleSubComponentEType.SimpleSurfaceInnerRingLine);
if (headerElem.INTERP == SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleSurfaceInnerRingLine))
dlc.Etype = DrawAbleSubComponentEType.SimpleSurfaceInnerRingLine;
else
dlc.Etype = DrawAbleSubComponentEType.SimpleSurfaceInnerRingAllCurves;
}
}
// If we have not set the etype it must be a 1005 0R 2005 - compound polygon
if (headerElem.ETYPE == 0 && hasBulgesCount > 0)
{
if (loopdirection == LoopDirection.Exterior)
{
headerElem.ETYPE = SDO.BasicETYPE(DrawAbleSubComponentEType.CompoundSurfaceOuterRingLine);
dlc.Etype = DrawAbleSubComponentEType.CompoundSurfaceOuterRingLine;
}
else
{
headerElem.ETYPE = SDO.BasicETYPE(DrawAbleSubComponentEType.CompoundSurfaceInnerRingLine);
dlc.Etype = DrawAbleSubComponentEType.CompoundSurfaceInnerRingLine;
}
headerElem.INTERP = 0; // to be set later with count
}
//Now we are ready to build the elem and ords
int len = (_dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D) ? DrawAbleSdoGeometry.DefaultDimensionality3D : DrawAbleSdoGeometry.DefaultDimensionality2D;
dlc.Ords = new decimal[(len * pts.Length) + (hasBulgesCount * len)];
ListelmList = new List ();
TriInts wrkrElm = null;
int nxtINTERP = 0;
int lstINTERP = 0;
Point3d arc_endpoint;
for (int j = 0; j < pts.Length; j++)
{
if (j < pts.Length - 1)
nxtINTERP = (blgs[j] == 0.0) ? SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleLine) : SDO.BasicINTERPRETATION(DrawAbleSubComponentEType.SimpleLineAllCurves);
if (lstINTERP != nxtINTERP)
{
if (wrkrElm != null)
elmList.Add(wrkrElm);
wrkrElm = new TriInts(ords_counter,
SDO.BasicETYPE((blgs[j] == 0.0) ? DrawAbleSubComponentEType.SimpleLine : DrawAbleSubComponentEType.SimpleLineAllCurves),
nxtINTERP);
lstINTERP = nxtINTERP;
}
double theBulge = blgs[j];
if (theBulge != 0.0)
{
arc_endpoint = pts[j + 1];
CircularArc2d ca2d = new CircularArc2d(
new Point2d(pts[j].X, pts[j].Y),
new Point2d(arc_endpoint.X, arc_endpoint.Y), theBulge, false);
Interval interval_of_arc = ca2d.GetInterval();
Point2d somePointOnArc = ca2d.EvaluatePoint(interval_of_arc.Element / 2);
//Start
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].X);
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Z);
//Center point on arc
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(somePointOnArc.X);
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(somePointOnArc.Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Z);
}
else
{
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].X);
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Y);
if (len == DrawAbleSdoGeometry.DefaultDimensionality3D)
dlc.Ords[ords_counter++] = System.Convert.ToDecimal(pts[j].Z);
}
}//for loop of ordinates
int elem_cntr = 0;
if (headerElem.ETYPE == SDO.BasicETYPE(DrawAbleSubComponentEType.CompoundSurfaceInnerRingLine) ||
headerElem.ETYPE == SDO.BasicETYPE(DrawAbleSubComponentEType.CompoundSurfaceOuterRingLine))
{
//Add our last worker element
elmList.Add(wrkrElm);
//Update the count in the header
headerElem.INTERP = elmList.Count;
//Dimension the array = element list count + one(1) for header "times" three(3)
dlc.Elem = new int[(elmList.Count + 1) * 3];
dlc.Elem[elem_cntr++] = headerElem.OFFSET;
dlc.Elem[elem_cntr++] = headerElem.ETYPE;
dlc.Elem[elem_cntr++] = headerElem.INTERP;
for (int _i = 0; _i < elmList.Count; _i++)
{
dlc.Elem[elem_cntr++] = elmList[_i].OFFSET;
dlc.Elem[elem_cntr++] = elmList[_i].ETYPE;
dlc.Elem[elem_cntr++] = elmList[_i].INTERP;
}
}
else
{
dlc.Elem = new int[3];
dlc.Elem[elem_cntr++] = headerElem.OFFSET;
dlc.Elem[elem_cntr++] = headerElem.ETYPE;
dlc.Elem[elem_cntr++] = headerElem.INTERP;
}
dl.SubComponents.Add(dlc);
}//next ring in the MPolygon
return dl;
}
//
// Returns: List, DBPoint, Polyline, MPolygon
//
public static object DrawAbleDwgObj(DrawAble drawable)
{
bool firstPointFlag = false;
int IncrementFor3d = 0;
if (drawable.Dimensionality == MDADDrawAbles.DrawAbleSdoGeometry.DefaultDimensionality3D)
IncrementFor3d = 1;
MPolygon dbMpoly = null;
Polyline plineCurves = null;
Polyline plineCompound = null;
Polyline plineLine = null;
DBPoint dbPoint = null;
ListdbPointList = null;
//Turn the dim elements into triplets for easy use
ListelmsList = null;
int CountOfComponents = drawable.SubComponents.Count;
foreach (DrawAbleSubComponent cmp in drawable.SubComponents)
{
if (cmp.Elem != null)
{
elmsList = new List();
for (int _i = 0; _i < cmp.Elem.Length; )
{
TriInts t = new TriInts(cmp.Elem[_i + 0], cmp.Elem[_i + 1], cmp.Elem[_i + 2]);
elmsList.Add(t);
_i = _i + 3;
}
}
else
elmsList = null;
//Turn all the decimals into doubles
double[] ords = new double[cmp.Ords.Length];
for (int j = 0; j < cmp.Ords.Length; j++)
ords[j] = System.Convert.ToDouble(cmp.Ords[j]);
DrawAbleSubComponentEType etype = cmp.Etype;
firstPointFlag = false;
//
//Compound components
//These require a header and fixup of the components dim element array
//
if (cmp.Etype == DrawAbleSubComponentEType.CompoundLine ||
cmp.Etype == DrawAbleSubComponentEType.CompoundSurfaceInnerRingLine ||
cmp.Etype == DrawAbleSubComponentEType.CompoundSurfaceOuterRingLine)
{
CircularArc2d ca2d;
Point2d firstPoint2d = new Point2d();
Point2d begPoint2d = new Point2d();
Point2d arrowPoint2d, endPoint2d;
plineCompound = new Polyline();
//We know what it is because of Etype. We just really need the INTERPs and OFFSETs. Skip to one(1)
for (int _k = 1; _k < elmsList.Count; )
{
TriInts t = elmsList[_k]; int OFFSET = t.OFFSET; int ETYPE = t.ETYPE; int INTERP = t.INTERP;
int nxtOFFSET = 0;
if (_k < elmsList.Count - 1)
nxtOFFSET = elmsList[_k + 1].OFFSET;
else
nxtOFFSET = ords.Length;
for (int x = OFFSET; x < nxtOFFSET; )
{
double bulgeValue = 0.0;
if (firstPointFlag == false) { firstPoint2d = new Point2d(ords[x], ords[x + 1]); firstPointFlag = true; }
if (INTERP == 2)
{
begPoint2d = new Point2d(ords[x++], ords[x++]); x = x + IncrementFor3d;
//Only if we are not at the end. We ended the line with an arc.
if (x < nxtOFFSET)
{
arrowPoint2d = new Point2d(ords[x++], ords[x++]); x = x + IncrementFor3d;
endPoint2d = new Point2d(ords[x], ords[x + 1]);
ca2d = new CircularArc2d(begPoint2d, arrowPoint2d, endPoint2d);
bulgeValue = GetBulge2d(ca2d);
ca2d.Dispose();
}
plineCompound.AddVertexAt(plineCompound.NumberOfVertices, begPoint2d, bulgeValue, 0, 0);
if (drawable.Dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D)
plineCompound.Elevation = ords[x - 1];
}
else
{
begPoint2d = new Point2d(ords[x++], ords[x++]); x = x + IncrementFor3d;
plineCompound.AddVertexAt(plineCompound.NumberOfVertices, begPoint2d, 0.0, 0.0, 0.0);
if (drawable.Dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D)
plineCompound.Elevation = ords[x - 1];
}
}
_k = _k + 1;
}
if (firstPoint2d == begPoint2d)
plineCompound.Closed = true;
if (cmp.Etype == DrawAbleSubComponentEType.CompoundSurfaceInnerRingLine ||
cmp.Etype == DrawAbleSubComponentEType.CompoundSurfaceOuterRingLine)
{
if (dbMpoly == null)
{
dbMpoly = new MPolygon();
}
dbMpoly.AppendLoopFromBoundary(plineCompound, false, 0.005);
dbMpoly.BalanceTree();
plineCompound.Dispose();
plineCompound = null;
}
}
//
//Point and PointCluster
//
if (cmp.Etype == DrawAbleSubComponentEType.Point)
{
Point3d p3d;
if (IncrementFor3d == 1)
p3d = new Point3d(ords[0], ords[1], ords[2]);
else
p3d = new Point3d(ords[0], ords[1], 0.0);
dbPoint = new DBPoint(p3d);
}
else if (cmp.Etype == DrawAbleSubComponentEType.PointCluster)
{
Point3d p3d;
dbPointList = new List();
for (int _x = 0; _x < ords.Length; )
{
if (IncrementFor3d == 1)
p3d = new Point3d(ords[_x++], ords[_x++], ords[_x++]);
else
p3d = new Point3d(ords[_x++], ords[_x++], 0.0);
dbPoint = new DBPoint(p3d);
dbPointList.Add(dbPoint);
}
}
//
//Simple lines
//
if (cmp.Etype == DrawAbleSubComponentEType.SimpleLine ||
cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceInnerRingLine ||
cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceOuterRingLine)
{
Point2d begPoint2d = new Point2d();
Point2d firstPoint2d = new Point2d();
plineLine = new Polyline();
for (int _x = 0; _x < ords.Length; )
{
if (firstPointFlag == false) { firstPoint2d = new Point2d(ords[0], ords[1]); firstPointFlag = true; }
begPoint2d = new Point2d(ords[_x++], ords[_x++]); _x = _x + IncrementFor3d;
plineLine.AddVertexAt(plineLine.NumberOfVertices, begPoint2d, 0.0, 0.0, 0.0);
if (drawable.Dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D)
plineLine.Elevation = ords[_x - 1];
}
if (firstPoint2d == begPoint2d)
plineLine.Closed = true;
if (cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceInnerRingLine ||
cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceOuterRingLine)
{
if (dbMpoly == null)
{
dbMpoly = new MPolygon();
}
dbMpoly.AppendLoopFromBoundary(plineLine, false, 0.005);
dbMpoly.BalanceTree();
plineLine.Dispose();
plineLine = null;
}
}
//
//Simple Curves
//
if (cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceInnerRingAllCurves ||
cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceOuterRingAllCurves ||
cmp.Etype == DrawAbleSubComponentEType.SimpleLineAllCurves)
{
CircularArc2d ca2d;
Point2d begPoint2d = new Point2d();
Point2d firstPoint2d = new Point2d();
Point2d arrowPoint2d, endPoint2d;
plineCurves = new Polyline();
//We know what it is because of Etype. We just really need the INTERPs and OFFSETs. Skip to one(1)
for (int _x = 0; _x < ords.Length; )
{
if (firstPointFlag == false) { firstPoint2d = new Point2d(ords[0], ords[1]); firstPointFlag = true; }
begPoint2d = new Point2d(ords[_x++], ords[_x++]); _x = _x + IncrementFor3d;
double bulgeValue = 0.0;
if (_x < ords.Length)
{
arrowPoint2d = new Point2d(ords[_x++], ords[_x++]); _x = _x + IncrementFor3d;
endPoint2d = new Point2d(ords[_x], ords[_x + 1]);
ca2d = new CircularArc2d(begPoint2d, arrowPoint2d, endPoint2d);
bulgeValue = GetBulge2d(ca2d);
ca2d.Dispose();
}
plineCurves.AddVertexAt(plineCurves.NumberOfVertices, begPoint2d, bulgeValue, 0, 0);
if (drawable.Dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D)
plineCurves.Elevation = ords[_x - 1];
}
if (firstPoint2d == begPoint2d)
plineCurves.Closed = true;
if (cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceInnerRingAllCurves ||
cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceOuterRingAllCurves)
{
if (dbMpoly == null)
{
dbMpoly = new MPolygon();
}
dbMpoly.AppendLoopFromBoundary(plineCurves, false, 0.005);
dbMpoly.BalanceTree();
plineCurves.Dispose();
plineCurves = null;
}
}
//
// Circle
//
if (cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceInnerRingCircle ||
cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceOuterRingCircle)
{
Circle circleSurf = null;
Point2d a = new Point2d(ords[0], ords[1]);
Point2d b = new Point2d(ords[2 + IncrementFor3d], ords[3 + IncrementFor3d]);
Point2d c = new Point2d(ords[4 + IncrementFor3d + IncrementFor3d], ords[5 + IncrementFor3d + IncrementFor3d]);
double A = b.X - a.X;
double B = b.Y - a.Y;
double C = c.X - a.X;
double D = c.Y - a.Y;
double E = A * (a.X + b.X) + B * (a.Y + b.Y);
double F = C * (a.X + c.X) + D * (a.Y + c.Y);
double G = 2.0 * (A * (c.Y - b.Y) - B * (c.X - b.X));
if (G != 0)
{
double pX = (D * E - B * F) / G;
double pY = (A * F - C * E) / G;
// r^2 = (a.X - pX) ^ 2.0 + (a.Y - pY) ^ 2.0
double radiusSqd = Math.Pow((a.X - pX), 2.0) + Math.Pow((a.Y - pY), 2.0);
double radius = Math.Sqrt(radiusSqd);
Point3d p3d_center = new Point3d(pX, pY, 0.0);
circleSurf = new Circle(p3d_center, new Vector3d(0.0, 0.0, 1.0), radius);
}
if (dbMpoly == null)
{
dbMpoly = new MPolygon();
}
dbMpoly.AppendLoopFromBoundary(circleSurf, false, 0.005);
dbMpoly.BalanceTree();
circleSurf.Dispose();
circleSurf = null;
}
//
//Rectangle
//
if (cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceInnerRingRectangle ||
cmp.Etype == DrawAbleSubComponentEType.SimpleSurfaceOuterRingRectangle)
{
Polyline plineRect = new Polyline();
Point2d sw2d = new Point2d(ords[0], ords[1]);
Point2d se2d = new Point2d(ords[2 + IncrementFor3d], ords[1]);
Point2d ne2d = new Point2d(ords[2 + IncrementFor3d], ords[3 + IncrementFor3d]);
Point2d nw2d = new Point2d(ords[0], ords[3 + IncrementFor3d]);
Point2d closer2d = new Point2d(ords[0], ords[1]);
plineRect.AddVertexAt(plineRect.NumberOfVertices, sw2d, 0.0, 0.0, 0.0);
plineRect.AddVertexAt(plineRect.NumberOfVertices, se2d, 0.0, 0.0, 0.0);
plineRect.AddVertexAt(plineRect.NumberOfVertices, ne2d, 0.0, 0.0, 0.0);
plineRect.AddVertexAt(plineRect.NumberOfVertices, nw2d, 0.0, 0.0, 0.0);
plineRect.AddVertexAt(plineRect.NumberOfVertices, closer2d, 0.0, 0.0, 0.0);
plineRect.Closed = true;
if (drawable.Dimensionality == DrawAbleSdoGeometry.DefaultDimensionality3D)
plineRect.Elevation = ords[2];
if (dbMpoly == null)
{
dbMpoly = new MPolygon();
}
dbMpoly.AppendLoopFromBoundary(plineRect, false, 0.005);
dbMpoly.BalanceTree();
plineRect.Dispose();
plineRect = null;
}
}//Do the next subcomponent
if (dbMpoly != null)
return (object)dbMpoly;
else if (dbPointList != null)
return (object)dbPointList;
else if (dbPoint != null)
return (object)dbPoint;
else if (plineLine != null)
return (object)plineLine;
else if (plineCurves != null)
return (object)plineCurves;
else if (plineCompound != null)
return (object)plineCompound;
else
return null;
}
public static double GetBulge2d(CircularArc2d ca2d)
{
double theBulge = 0.0;
if (ca2d.IsClockWise == true)
{
theBulge = -Math.Tan((ca2d.EndAngle - ca2d.StartAngle) / 4);
}
else
{
theBulge = Math.Tan((ca2d.EndAngle - ca2d.StartAngle) / 4);
}
return theBulge;
}
}//eoc DrawAbleDwg
}//eons