70002170 In a 2D drawing I want to know the visible and invisible area of a polyline

Article 70002170
Type HowTo
Product Engine
Version 8
Date Added 2/24/2022 12:00:00 AM
Fixed 10.1001.0.1 (2/24/2022 12:00:00 AM)
Submitted by Peter Chanios

Summary

In a 2D drawing I want to know the visible and invisible area of a polyline

Solution

In the sample code below we calculate the visible and invisible area represented in polyhatch objects.
Check the image below , using the code and clicking to the yellow rect the result are the two blue polyhatches.




                gPoint pt1;
                doc.Prompt("Select a SoidFill Polyline or Rect");
                doc.ActionUtility.getUserEntity(out fig, out pt1);
                doc.Prompt(null);
                #endregion


                IvdHatchFigure hpropfig = fig as IvdHatchFigure;
                if (hpropfig == null) return;
                if (hpropfig.HatchProperties == null || hpropfig.HatchProperties.FillMode != VectorDraw.Professional.Constants.VdConstFill.VdFillModeSolid) return;
                if (!(fig is vdPolyline) && !(fig is vdRect)) return;

                //get the points of the region of selected polyline or vdrect in current view coordinate system
                vdCurve curve = (vdCurve)fig;
                gPoints pts = curve.GetSamplePoints(0, 0);
                curve.ECSMatrix.Transform(pts);
                doc.World2ViewMatrix.Transform(pts);

                //create a selection for all figures that cross the selected figure
                //note the items in the selection are added in the same order as the are in the model entities collection with is the same as they are drawn
                vdSelection set = new vdSelection();
                set.SetUnRegisterDocument(doc);
                set.Select(RenderSelect.SelectingMode.CrossingWindowPolygon, pts);


                //array to hold the region of each selected polyline
                vdArray mregions = new vdArray();
                vdArray clipopers = new vdArray();
                //select all filled polylines and rect that are in front of seleted fig
                bool findselectedfigure = false;
                foreach (vdFigure item in set)
                {
                    //get the regions of all solid filled  polylines, including the selected one, that are drawn after the selected figure
                    if (item == fig)
                    {
                        findselectedfigure = true;
                    }
                    if (!findselectedfigure) continue;
                    hpropfig = item as IvdHatchFigure;
                    if (hpropfig == null) continue;
                    if (hpropfig.HatchProperties == null || hpropfig.HatchProperties.FillMode != VectorDraw.Professional.Constants.VdConstFill.VdFillModeSolid) continue;
                    if (!(item is vdPolyline) && !(item is vdRect)) continue;

                    curve = (vdCurve)item;
                    gPoints pts2 = curve.GetSamplePoints(0, 0);
                    curve.ECSMatrix.Transform(pts2);
                    mregions.AddItem(pts2);
                    clipopers.AddItem(VectorDraw.Geometry.GpcWrapper.ClippingOperation.Difference);

                }
                //we calculate the final regions that produced if we subtruct all selected polylines from the basic selected figure


                //test if the selected regions of objects that are in front of selected fig complete hide the selected fig
                vdArray visible_regions = PolygonClipper.getClipCountours(mregions, clipopers);

                //we calculate the area of the cliping region.So if it is near to zero we assume that the selected polyline is completed overlapped  from the other polylines so it is not visible
                double area = 0.0;
                if (visible_regions != null && visible_regions.Count > 0)
                {
                    foreach (gPoints points in visible_regions)
                    {
                        area += Math.Abs(points.Area());
                    }
                }
                if (Globals.AreEqual(area, 0.0, Globals.DefaultAreaEquality)) MessageBox.Show("Selected polyline is completed hidden");

                //create a polyhatch for the visible portion of selected figure and add it to entities for testing purpose

                vdPolyCurves polycurves = new vdPolyCurves();
                foreach (gPoints points in visible_regions)
                {
                    vdCurves curves = new vdCurves();
                    curves.AddItem(new vdPolyline(doc, points));
                    polycurves.AddItem(curves);
                }
                vdPolyhatch ph = new vdPolyhatch(doc, polycurves, new vdColor(Color.Red, 196), true);
                doc.Model.Entities.AddItem(ph);
                doc.Redraw(true);

                //Since we calculated the visible areas now we create a new polyhatch where we add the whole figure as one polycurve and then with XOR
                //We add the visible areas as different polycurves
                //This way the result polyhatch will show the hidden areas
                vdPolyhatch ph2 = new vdPolyhatch(doc);
                ph2.PenColor = new vdColor(Color.Yellow, 196);
                vdPolyCurves polycurves2 = new vdPolyCurves();
                vdCurves curves2 = new vdCurves();
                curves2.AddItem(new vdPolyline(doc, pts));
                ph2.PolyCurves.AddItem(curves2);
                foreach (gPoints points in visible_regions)
                {
                    vdCurves curves = new vdCurves();
                    curves.AddItem(new vdPolyline(doc, points));
                    ph2.PolyCurves.AddItem(curves);
                }
                ph2.HatchProperties = new vdHatchProperties(VdConstFill.VdFillModeSolid);
                doc.Model.Entities.AddItem(ph2);

                //If you want you can explode this polyhatch and then you can get only the filled polylines
                //which will be the invisible ones.
                doc.Redraw(true);

Send comments on this topic.