Ok, Jeremy, here is what I did.
But I dont know how to format this thing properly:
double SplitSize = 3000,
SplitTol = 150;
private void SplitPipe(Pipe _pipe, Document doc, Transaction t)
{
if (_pipe == null)
return;
LocationCurve lc = _pipe.Location as LocationCurve;
Curve cv = lc.Curve;
ElementId _pipeMEP = new ElementId(_pipe.MEPSystem.GetTypeId().IntegerValue);
ElementId _pipeType = new ElementId(_pipe.PipeType.Id.IntegerValue);
ElementId _pipeLvl = new ElementId(_pipe.ReferenceLevel.Id.IntegerValue);
string diam_s = _pipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).AsValueString();
int i;
double leng1 = Util.FootToMm(cv.Length);
if (leng1 < (SplitSize + SplitTol))
return;
XYZ sp = cv.GetEndPoint(0), ep = cv.GetEndPoint(1);
Connector c4, conStart = null, conEnd = null;
foreach (Connector cn in _pipe.ConnectorManager.Connectors)
if (cn.IsConnected)
foreach (Connector c2 in cn.AllRefs)
if (c2.Owner.Id != _pipe.Id)
{
double d1 = c2.Origin.DistanceTo(sp);
double d2 = c2.Origin.DistanceTo(ep);
if (d1 < d2)
conStart = c2;
else
conEnd = c2;
}
doc.Delete(_pipe.Id);
List<XYZ> pts = SplitLine(cv.GetEndPoint(0), cv.GetEndPoint(1), SplitSize);
Pipe pp1 = null, pp2 = null;
for (i = 1; i < pts.Count; i += 2)
{
pp2 = Pipe.Create(doc, _pipeMEP, _pipeType, _pipeLvl, pts[i - 1], pts[i]);
pp2.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).SetValueString(diam_s);
if (pp1 != null)
{
Connector c1 = GetConnectorClosestTo(pp1, pts[i - 1]),
c2 = GetConnectorClosestTo(pp2, pts[i - 1]);
FamilyInstance luva = doc.Create.NewUnionFitting(c1, c2);
}
else if (conStart != null)
{
c4 = GetConnectorClosestTo(pp2, pts[i - 1]);
conStart.ConnectTo(c4);
}
if ((conEnd != null) && (i == (pts.Count - 1)))
{
c4 = GetConnectorClosestTo(pp2, pts[i]);
conEnd.ConnectTo(c4);
}
pp1 = pp2;
}
}
//-------------------------------------------------------------------------
List<XYZ> SplitLine(XYZ sp, XYZ ep, double leng_mm)
{
List<XYZ> rval = new List<XYZ>();
double dist = sp.DistanceTo(ep),
leng_foot = Util.MmToFoot(leng_mm),
tol = Util.MmToFoot(SplitTol);
if (dist == 0)
return rval;
rval.Add(sp);
if (dist <= leng_foot + tol)
{
rval.Add(ep);
return rval;
}
double prop = dist / leng_foot;
int n = (int)Math.Floor(prop);
XYZ gap, step, mid2, mid1 = sp;
step = ((ep - sp) / prop);
gap = 0.01 * (ep - sp) / dist;
for (int i = 0; i < n; i++)
{
mid1 = mid1 + step;
if (mid1.DistanceTo(ep) < tol)
break;
mid2 = mid1 + gap;
rval.Add(mid1);
rval.Add(mid2);
}
rval.Add(ep);
return rval;
}
//-------------------------------------------------------------------------
Connector GetConnectorClosestTo(Element e, XYZ p)
{
ConnectorManager cm = GetConnectorManager(e);
return null == cm ? null : GetConnectorClosestTo(cm.Connectors, p);
}
//-------------------------------------------------------------------------------
Connector GetConnectorClosestTo(ConnectorSet connectors, XYZ p)
{
Connector targetConnector = null;
double minDist = double.MaxValue;
foreach (Connector c in connectors)
{
double d = c.Origin.DistanceTo(p);
if (d < minDist)
{
targetConnector = c;
minDist = d;
}
}
return targetConnector;
}
//-------------------------------------------------------------------------------
ConnectorManager GetConnectorManager(Element e)
{
MEPCurve mc = e as MEPCurve;
FamilyInstance fi = e as FamilyInstance;
if (null == mc && null == fi)
throw new ArgumentException("Element is neither an MEP curve nor a fitting.");
return null == mc ? fi.MEPModel.ConnectorManager : mc.ConnectorManager;
}