RevitAPI:如何用API实现两条管道按中心线(Center Line)对齐

有客户问道如何用API实现两条管道在中心线(Center Line)上对齐,我觉得应该是有办法的,就像这样:

  1. 通过获取到中心线的几何信息
  2. 使用Document.Create.NewAlignment()方法创建这个对齐约束

结果碰到了莫名其妙异常:ArgumentException: One of the conditions for the inputs was not satisfied. Consult the documentation for requirements for each argument.

头疼了一会...

在开发部Phil的帮助下找到了原因,我需要先把管道移动到物理上是对齐的,然后才能再创建约束

再仔细看说明文档,确实有这样一句话:

These references must be already geometrically aligned (this function will not force them to become aligned).

于是问题愉快的解决了!

下面是几个关键的技术要点:

  1. 确保参数options的属性ComputeReferences被设置为true, 这样我们拿到的几何对象是有Reference的,Reference是创建约束必要的参数之一.
  2. 确保参数options的属性IncludeNonVisibleObjects 被设置为true,同时确保View属性是一个平面视图, 这样我们才可以拿到隐藏的中心线.
  3. 创建约束之前,确保两个管道在物理上是对齐的。可以调用ElementTransformUtils.MoveElement()方法来移动管道.

下面是完整代码

//这里假定两个管道是平行的
//假定当前视图是平面视图
private static Dimension
    Align2PipesViaCenterline(Pipe pipeBase, Pipe pipe)
{
    Dimension dimension = null;
    Document doc = pipeBase.Document;
    View view = doc.ActiveView;
    Line baseLine = GetCenterline(pipeBase);
    if (baseLine == null) return null;
    Line line = GetCenterline(pipe);
    if (line == null) return null;
    var clone = line.Clone();
    clone.MakeUnbound();
    IntersectionResult result = clone.Project(baseLine.Origin);
    if (result != null)
    {
        var point = result.XYZPoint;
        var translate = baseLine.Origin - point;
        using (Transaction transaction = new Transaction(doc))
        {
            try
            {
                transaction.Start("Align pipes");
                ElementTransformUtils.MoveElement(
                    doc, pipe.Id, translate);
                dimension = doc.Create.NewAlignment(view, 
                    baseLine.Reference, line.Reference);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
                transaction.RollBack();
            }
        }
    }
    return dimension;
}

private static Line GetCenterline(Pipe pipe)
{
    Options options = new Options();
    options.ComputeReferences = true; //!!!
    options.IncludeNonVisibleObjects = true; //!!! 
    if (pipe.Document.ActiveView != null)
        options.View = pipe.Document.ActiveView;
    else
        options.DetailLevel = ViewDetailLevel.Fine;<br />
    var geoElem = pipe.get_Geometry(options);
    foreach (var item in geoElem)
    {
        Line lineObj = item as Line;
        if (lineObj != null)
        {
            return lineObj;
        }
    }
    return null;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值