Revit API SetPointElementReference(PointOnPlane) - 错误的工作平面

时间:2018-02-28 09:16:39

标签: revit-api

我尝试使用CreateAdaptiveComponentInstance创建一个族实例,并尝试将其托管在一个参考点上,该参考点也是CurveByPoints(样条曲线)的控制点。 系列正确连接到参考点,但参考点工作平面的旋转完全被忽略。

试试这个独立的例子。移动参考点P2 - > P1的横截面不会旋转。 现在,重建并更改>> if(true)<< '假'。现在你看到了我想要的东西。但是一旦你移动点P2,P2的坐标和家族之间的链接就会被打破。

        CurveByPoints spl = null;
        ReferencePointArray pts = null;
        // create ref points
        var p1 = doc.FamilyCreate.NewReferencePoint(new XYZ( 0, 0, 0)); p1.Name = "P1";
        var p2 = doc.FamilyCreate.NewReferencePoint(new XYZ(10,10, 0)); p2.Name = "P2";
        var p3 = doc.FamilyCreate.NewReferencePoint(new XYZ(30,20, 0)); p3.Name = "P3";
        pts = new ReferencePointArray();
        pts.Append(p1); pts.Append(p2); pts.Append(p3);
        // create a spline
        spl = doc.FamilyCreate.NewCurveByPoints(pts);
        spl.Visible = true;
        spl.IsReferenceLine = false; // MOdelliinie

        // change points to adaptive points
        foreach(ReferencePoint p in pts)
        {
            AdaptiveComponentFamilyUtils.MakeAdaptivePoint(doc, p.Id, AdaptivePointType.PlacementPoint);
            p.CoordinatePlaneVisibility = CoordinatePlaneVisibility.Always;
            p.ShowNormalReferencePlaneOnly = true;
        }

        // find an adaptive family to place at the points
        FamilySymbol fam_sym = null;
        var filter = new FilteredElementCollector(doc);
        ICollection<Element> col = filter.OfClass(typeof(FamilySymbol)).ToElements();
        if(col!=null)
        {
            foreach(FamilySymbol ele in col)
            {
                if(ele == null || !AdaptiveComponentInstanceUtils.IsAdaptiveFamilySymbol(ele) ) {continue;}
                if(fam_sym == null)
                {
                    fam_sym=ele;
                }
                if(ele.Name == "profil_adapt_offset_einfach2") // use a special one instead of the first matching
                {
                    fam_sym = ele as FamilySymbol;
                    break;
                }
            }
        }

        // create family instances
        if(fam_sym != null)
        {
            if(true) // this is waht I want. Try "false" to see what I expect
            {
                foreach (ReferencePoint p in pts)
                {
                    var inst = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(doc, fam_sym);
                    var placements = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(inst);
                    ReferencePoint fam_pt = doc.GetElement(placements.FirstOrDefault()) as ReferencePoint;

                    var pl = Plane.CreateByNormalAndOrigin(new XYZ(1,0,0), p.Position);

                    // #### I THINK HERE IS MY PROBLEM ####
                    // "plane" just points to the reference POINT,
                    // and not the XZ-PLANE of the reference point.
                    Reference plane = p.GetCoordinatePlaneReferenceYZ();

                    PointOnPlane pop = doc.Application.Create.NewPointOnPlane(plane, UV.Zero, UV.BasisU, 0.0);
                    fam_pt.SetPointElementReference(pop);
                }
            }
            else
            {
                // create family instances and place along the path
                // -> looks good until you move a reference point
                double ltot=0.0;
                for(var i=0; i<pts.Size-1; ++i)
                {
                    ltot += pts.get_Item(i).Position.DistanceTo(pts.get_Item(i+1).Position);
                }

                double lfromstart=0;
                for(var i=0; i<pts.Size; ++i)
                {
                    if(i>0)
                    {
                        lfromstart += pts.get_Item(i).Position.DistanceTo(pts.get_Item(i-1).Position);
                    }
                    var inst = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(doc, fam_sym);
                    var placements = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(inst);

                    var location = new PointLocationOnCurve(PointOnCurveMeasurementType.NormalizedCurveParameter, lfromstart / ltot, PointOnCurveMeasureFrom.Beginning);
                    PointOnEdge po = doc.Application.Create.NewPointOnEdge(spl.GeometryCurve.Reference, location);
                    // attach first adaptive point to ref point
                    var firstPoint = doc.GetElement(placements.FirstOrDefault()) as ReferencePoint;
                    firstPoint.SetPointElementReference(po);
                }
            }
        }

我在这里使用Revit 2018.2。

人们也可能会搜索:GetCoordinatePlaneReferenceXZ,GetCoordinatePlaneReferenceXY。

[edit1]

  • NewReferencePoint()不会创建SketchPlanes
  • 当我手动移动生成的参考点时 - &gt;现在生成此ReferencePoint的SketchPlane。但是如何用API创建呢?

[edi2]   - 我发现,例如手动更改ReferencePoint.CoordinatePlaneVisibility = true将创建我需要的SketchPlane。但我不能在代码中这样做:

        var sel = new List<ElementId>();
        foreach (ReferencePoint p in pts)
        {
            sel.Add(p.Id);
            // make plane visible
            p.CoordinatePlaneVisibility = CoordinatePlaneVisibility.Always;
            // shake point
            ElementTransformUtils.MoveElement(doc, p.Id, XYZ.BasisX);
            ElementTransformUtils.MoveElement(doc, p.Id, XYZ.BasisX.Negate());
        }
        ui_doc.Selection.SetElementIds(sel);
        doc.Regenerate();
        ui_doc.RefreshActiveView();

2 个答案:

答案 0 :(得分:0)

如果您使用import React, { Component } from 'react'; import Select from 'react-select'; import 'react-select/dist/react-select.css'; import Api from '../../Api' import DatePicker from 'material-ui/DatePicker'; import RaisedButton from 'material-ui/RaisedButton'; import { Recharts } from 'recharts'; const { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend } = Recharts; const data = [ { name: 'Page A', uv: 4000, pv: 2400, amt: 2400 }, { name: 'Page B', uv: 3000, pv: 1398, amt: 2210 }, { name: 'Page C', uv: 2000, pv: 9800, amt: 2290 }, { name: 'Page D', uv: 2780, pv: 3908, amt: 2000 }, { name: 'Page E', uv: 1890, pv: 4800, amt: 2181 }, { name: 'Page F', uv: 2390, pv: 3800, amt: 2500 }, { name: 'Page G', uv: 3490, pv: 4300, amt: 2100 }, ]; render() { return ( <div className="container"> <LineChart width={600} height={300} data={this.data} margin={{top: 5, right: 30, left: 20, bottom: 5}}> <XAxis dataKey="name"/> <YAxis yAxisId="left" /> <YAxis yAxisId="right" orientation="right" /> <CartesianGrid strokeDasharray="3 3"/> <Tooltip/> <Legend /> <Line yAxisId="left" type="monotone" dataKey="pv" stroke="#8884d8" activeDot={{r: 8}}/> <Line yAxisId="right" type="monotone" dataKey="uv" stroke="#82ca9d" /> </LineChart> </div> ); } } 重载使用NewReferencePoint参数,请参阅NewReferencePoint Method (Transform)?这可能会为您定义所需的平面并将其与该点相关联。

答案 1 :(得分:0)

开发团队回复了附件ZIP文件中提供的详细说明和测试项目:

开发人员似乎需要一些我们尚未公开的API。 PointElement的API是在RIDL之前编写的,因此整个用户界面不会暴露给API。他们需要一个API来获得与其正在驱动的曲线垂直的参考平面。这个平面与API PointElement.GetCoordinatePlaneReferenceYZ()(暴露给API的三个平面之一)所暴露的平面不同。

根据SketchPlanes没有创建(在链接的zip文件中看到的宏),是的,这是正确的并且与UI匹配。 SketchPlanes是元素,与Autodesk.Revit.DB.Reference不同。在我们必须之前,我们不会创建它们。他们也收集了垃圾。在描述的最后,我看到一些应该工作的代码(假设它们将它包装在事务中)。通常,仅选择点将触发从UI创建SketchPlane。除此之外,我仍然不建议将SketchPlane用于他们想要做的事情。

虽然他们想要的东西在API中不存在,但它仍然并不意味着他们想要实现的目标没有解决方法。如果Selection或Reference API公开元素Autodesk.Revit.DB.Reference上的可选/可见引用,则可以迭代这些引用并托管该点。这是通用的Element / Reference API。

我希望这可以澄清。