C# VTK OCCT 将OCCT 交线转换为 vtk 交线

因为vtkIntersectionPolyDataFilter 交线算法有问题所以改为 OCCT BRepAlgoAPI_Section交线算法。

OCCT 生成一个正方体和球体

BRepPrimAPI_MakeBox brepBox = new BRepPrimAPI_MakeBox(new Pnt(0,0,0),10,10,10);
vtkPolyData boxData = OcctConvert.TopoDsShapeToPolyData(brepBox.Shape());

BRepPrimAPI_MakeSphere brepSphere = new BRepPrimAPI_MakeSphere(new Pnt(5,5,5),6);
vtkPolyData sphereData = OcctConvert.TopoDsShapeToPolyData(brepSphere.Shape());

执行OCCT 交线算法 

BRepAlgoAPI_Section brepSection = new BRepAlgoAPI_Section(brepBox.Shape(), brepSphere.Shape());
brepSection.ComputePCurveOn1(true); 
brepSection.Approximation(true);
brepSection.Build();

OCCT  交线 转换为 vtk

因为OCCT  的 Edge 可能是无序的所以先排序,其次几何上明显是相连的Edge  Chains存储时却不是相连,Chains 可以 看做是vtk 的连通域,所以要对Edge 进行连通域的分类。

        public static vtkPolyData ChainEdgeList(TopoDS_Shape shape)
        {
            var order = new ShapeAnalysis_WireOrder();
            List<TopoDS_Edge> edges = ShapeEdges(shape);

            foreach (var edge in edges)
            {
                var first = BRep_Tool.Pnt(TopExp.FirstVertex(edge));
                var last = BRep_Tool.Pnt(TopExp.LastVertex(edge));
                if (edge.Orientation() == TopAbs_Orientation.FORWARD)
                    order.Add(first.Coord, last.Coord);
                else
                    order.Add(last.Coord, first.Coord);
            }
            order.Perform(true);

            Dictionary<int,List<TopoDS_Edge>> edgeChanis = new Dictionary<int, List<TopoDS_Edge>>();
            vtkPoints points = new vtkPoints();
            vtkCellArray cellArray = new vtkCellArray();
            if (order.IsDone())
            {
                order.SetChains(0.1);

                Pnt lastPoint = new Pnt(-9999,0,0);
                for (int chain = 1; chain <= order.NbChains(); chain++)
                {
                    int startIndex = 0, endIndex = 0;
                    order.Chain(chain, ref startIndex, ref endIndex);

                    if (startIndex > endIndex)
                        continue;

                    edgeChanis.Add(chain-1, new List<TopoDS_Edge>());
                    for (int index = startIndex; index <= endIndex; index++)
                    {
                        int orderIndex = order.Ordered(index);

                        int originalIndex = Math.Abs(orderIndex) - 1; 
                        if (orderIndex < 0)
                        {
                            edges[originalIndex] = ReverseCurveEdge(edges[originalIndex]);
                        }
               
                        TopoDS_Edge edge = edges[originalIndex];
                        edgeChanis[chain-1].Add(edge);
                    }
                }

                bool found = true;
                while(found == true)
                {
                    found = false;
                    for (int i = 0; i < edgeChanis.Keys.Count; i++)
                    {
                        if (edgeChanis.Values.ElementAt(i).Count == 0)
                        {
                            continue;
                        }

                        int keyi = edgeChanis.Keys.ElementAt(i);

                        for (int j = 0; j < edgeChanis.Keys.Count; j++)
                        {
                            if (i == j)
                            {
                                continue;
                            }
                            int keyj = edgeChanis.Keys.ElementAt(j);
                            if (edgeChanis[keyj].Count == 0)
                            {
                                continue;
                            }

                            TopoDS_Edge ife = edgeChanis[keyi].First();
                            TopoDS_Edge ile = edgeChanis[keyi].Last();

                            TopoDS_Edge jfe = edgeChanis[keyj].First();
                            TopoDS_Edge jle = edgeChanis[keyj].Last();

                            BRepBuilderAPI_MakeWire mWireLF = new BRepBuilderAPI_MakeWire();
                            mWireLF.Add(ile);
                            mWireLF.Add(jfe);

                            BRepBuilderAPI_MakeWire mWireFL = new BRepBuilderAPI_MakeWire();
                            mWireFL.Add(jle);
                            mWireFL.Add(ife);

                            if (mWireLF.Error() != BRepBuilderAPI_WireError.DisconnectedWire)
                            {
                                List<TopoDS_Edge> tempEdges = new List<TopoDS_Edge>();
                                tempEdges.InsertRange(0,edgeChanis[keyj]);
                                int numj = tempEdges.Count;
                                for (int k = 0; k < numj; k++)
                                {
                                    edgeChanis[keyi].Add(tempEdges[k]);
                                   
                                }
                                edgeChanis[keyj].Clear(); ;
                                found = true;
                                continue;

                            }
                            else if (mWireFL.Error() != BRepBuilderAPI_WireError.DisconnectedWire)
                            {
                                List<TopoDS_Edge> tempEdges = new List<TopoDS_Edge>();
                                tempEdges.InsertRange(0, edgeChanis[keyi]);
                                int numi = edgeChanis[keyi].Count;
                                for (int k = 0; k < numi; k++)
                                {
                                    edgeChanis[keyj].Add(tempEdges[k]);
                                }
                                edgeChanis[keyi].Clear(); ;
                                found = true;
                                i = j;
                                continue;
                            }
                        }
                    }
                }

                foreach(List<TopoDS_Edge> es in edgeChanis.Values)
                {
                    if(es.Count==0)
                    {
                        continue;
                    }
                  
                    vtkLine line = new vtkLine();
                    int m = 0;
                    foreach (TopoDS_Edge e in es)
                    {
                        double first = 0;
                        double last = 0;
                        Geom_Curve curve = BRep_Tool.Curve(e, ref first, ref last);

                        GProp_GProps props = new GProp_GProps();
                        BRepGProp.LinearProperties(e, props);
                        double len = props.Mass();

                        double step1 = (last - first) / 2;
                        double numLen = len / 0.1;
                        double step = (last - first) / numLen;
                        for (double i = first; i <= last; i += step)
                        {
                            Pnt p1 = new Pnt();
                            curve.D0(i, ref p1);
                            int id= (int)points.InsertNextPoint(p1.X, p1.Y, p1.Z);

                            line.GetPointIds().InsertId(m,id);
                            m++;
                        }
                     
                    }
                    // 这段代码可以不要 封闭/开放
                    int fisrtId = (int)line.GetPointId(0);
                    double[] firstPos = points.GetPoint(fisrtId);
                    int lastid = (int)points.InsertNextPoint(firstPos[0], firstPos[1], firstPos[2]);
                    line.GetPointIds().InsertId(m, lastid);
                    // 

                    cellArray.InsertNextCell(line);
                }
            }

            vtkPolyData polyData = new vtkPolyData();
            polyData.SetPoints(points);
            polyData.SetLines(cellArray);
            return polyData;
        }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值