Example #1
0
        public void Decaler(Face2 face, Double decal, Boolean inverser)
        {
            Loop2 bord = null;

            foreach (Loop2 loop in face.GetLoops())
            {
                if (loop.IsOuter())
                {
                    bord = loop;
                    break;
                }
            }

            var listeFace = new List <Face2>();

            foreach (Edge e in bord.GetEdges())
            {
                listeFace.Add(e.eAutreFace(face));
            }

            MdlBase.eEffacerSelection();

            foreach (var f in listeFace)
            {
                f.eSelectEntite(MdlBase, 1, true);
            }

            var feat = MdlBase.FeatureManager.InsertMoveFace3((int)swMoveFaceType_e.swMoveFaceTypeOffset, inverser, 0, decal, null, null, 0, 0);

            WindowLog.Ecrire("Décalage : " + feat.IsRef());
        }
Example #2
0
        protected override void Command()
        {
            Feature Fonction = MdlBase.eSelect_RecupererObjet <Feature>(1, -1);

            MdlBase.eEffacerSelection();

            Esquisse = Fonction.GetSpecificFeature2();
            xForm    = Esquisse.ModelToSketchTransform.Inverse();
            Mu       = App.Sw.GetMathUtility();

            String fact = "0.8";

            if (Interaction.InputBox("Facteur de décalage", "F :", ref fact) == DialogResult.OK)
            {
                if (!String.IsNullOrWhiteSpace(fact))
                {
                    Double r = fact.eToDouble();
                    if (r != 0)
                    {
                        FacteurDecal = r;
                    }
                }
            }

            var polygon = new Polygon();

            if (Esquisse.GetSketchRegionCount() == 0)
            {
                return;
            }

            // On ajoute les contours
            SketchRegion region = Esquisse.GetSketchRegions()[0];
            Loop2        loop   = region.GetFirstLoop();

            int i = 0;

            while (loop != null)
            {
                var ListPt = new List <TriangleNet.Geometry.Vertex>();
                foreach (SolidWorks.Interop.sldworks.Vertex v in loop.GetVertices())
                {
                    double[] pt = (double[])v.GetPoint();
                    ListPt.Add(new TriangleNet.Geometry.Vertex(pt[0], pt[1]));
                }

                polygon.Add(new Contour(ListPt, i++), !loop.IsOuter());

                loop = loop.GetNext();
            }


            foreach (SketchPoint pt in Esquisse.GetSketchPoints2())
            {
                polygon.Add(new TriangleNet.Geometry.Vertex(pt.X, pt.Y));
            }

            var contraintes = new ConstraintOptions();

            contraintes.ConformingDelaunay = true;
            contraintes.SegmentSplitting   = 0;

            //var Qualite = new QualityOptions();
            //Qualite.SteinerPoints = 0;
            Mesh mesh = (Mesh)polygon.Triangulate(contraintes);

            var voronoi = new BoundedVoronoi(mesh);

            var SM = MdlBase.SketchManager;

            SelectionnerSupportEsquisse();
            SM.InsertSketch(false);
            SM.AddToDB          = true;
            SM.DisplayWhenAdded = false;

            List <TriangleNet.Geometry.Vertex> lstVertex = new List <TriangleNet.Geometry.Vertex>();

            foreach (var v in mesh.Vertices)
            {
                lstVertex.Add(v);
            }

            foreach (var edge in mesh.Edges)
            {
                try
                {
                    TriangleNet.Geometry.Point p1 = TransformPt(lstVertex[edge.P0]);
                    TriangleNet.Geometry.Point p2 = TransformPt(lstVertex[edge.P1]);
                    SM.CreateLine(p1.X, p1.Y, 0, p2.X, p2.Y, 0);
                }
                catch (Exception errDesc)
                { this.LogMethode(new Object[] { errDesc }); }
            }

            SM.DisplayWhenAdded = true;
            SM.AddToDB          = false;
            SM.InsertSketch(true);
            MdlBase.eEffacerSelection();

            SelectionnerSupportEsquisse();
            SM.InsertSketch(false);
            SM.AddToDB          = true;
            SM.DisplayWhenAdded = false;

            foreach (var t in mesh.Triangles)
            {
                try
                {
                    TriangleNet.Geometry.Point p1 = TransformPt(lstVertex[t.GetVertexID(0)]);
                    TriangleNet.Geometry.Point p2 = TransformPt(lstVertex[t.GetVertexID(1)]);
                    TriangleNet.Geometry.Point p3 = TransformPt(lstVertex[t.GetVertexID(2)]);

                    TriangleNet.Geometry.Point centre = new TriangleNet.Geometry.Point();
                    centre.X = (p1.X + p2.X + p3.X) / 3.0;
                    centre.Y = (p1.Y + p2.Y + p3.Y) / 3.0;

                    TriangleNet.Geometry.Point pt1;
                    TriangleNet.Geometry.Point pt2;

                    pt1 = TransformPt(Echelle(centre, t.GetVertex(0), FacteurDecal));
                    pt2 = TransformPt(Echelle(centre, t.GetVertex(1), FacteurDecal));
                    SM.CreateLine(pt1.X, pt1.Y, 0, pt2.X, pt2.Y, 0);

                    pt1 = TransformPt(Echelle(centre, t.GetVertex(1), FacteurDecal));
                    pt2 = TransformPt(Echelle(centre, t.GetVertex(2), FacteurDecal));
                    SM.CreateLine(pt1.X, pt1.Y, 0, pt2.X, pt2.Y, 0);

                    pt1 = TransformPt(Echelle(centre, t.GetVertex(2), FacteurDecal));
                    pt2 = TransformPt(Echelle(centre, t.GetVertex(0), FacteurDecal));
                    SM.CreateLine(pt1.X, pt1.Y, 0, pt2.X, pt2.Y, 0);
                }
                catch (Exception errDesc)
                { this.LogMethode(new Object[] { errDesc }); }
            }

            SM.DisplayWhenAdded = true;
            SM.AddToDB          = false;
            SM.InsertSketch(true);
            MdlBase.eEffacerSelection();

            SelectionnerSupportEsquisse();
            SM.InsertSketch(false);
            SM.AddToDB          = true;
            SM.DisplayWhenAdded = false;

            foreach (var f in voronoi.Faces)
            {
                try
                {
                    TriangleNet.Geometry.Point centre = f.generator;

                    foreach (var e in f.EnumerateEdges())
                    {
                        var pt1 = TransformPt(Echelle(centre, e.Origin, FacteurDecal));
                        var pt2 = TransformPt(Echelle(centre, e.Twin.Origin, FacteurDecal));
                        SM.CreateLine(pt1.X, pt1.Y, 0, pt2.X, pt2.Y, 0);
                    }
                }
                catch (Exception errDesc)
                { this.LogMethode(new Object[] { errDesc }); }
            }

            SM.DisplayWhenAdded = true;
            SM.AddToDB          = false;
            SM.InsertSketch(true);
        }
Example #3
0
 public UserControl SetPayload(Loop2 item)
 {
     txtSteps.Value = item.Step;
     return(this);
 }
Example #4
0
 public static void Next(IEnumLoops2Object IEnumLoops2instance, Int32 Celt, Loop2&Object Rgelt, Int32& PceltFetched)
Example #5
0
        /// <summary>
        ///     Updates the with.
        /// </summary>
        /// <param name="face">The face.</param>
        public bool BuildIfCylinderIsHole(bool isPositive)
        {
            if (isPositive)
            {
                throw new Exception("BuildIfCylinderIsHole assumes that the faces have already been collected, " +
                                    "such that the cylinder is negative");
            }
            IsPositive = false;

            //To truly be a hole, there should be two loops of vertices that form circles on either ends of the faces.
            //These are easy to capture because all the edges between them should be shared by two of the faces
            //Start by collecting the edges at either end. Each edge belongs to only two faces, so any edge that only
            //comes up once, must be at the edge of the cylinder (assuming it is a cylinder).
            var edges = new HashSet <Edge>();

            foreach (var face in Faces)
            {
                foreach (var edge in face.Edges)
                {
                    if (edges.Contains(edge))
                    {
                        edges.Remove(edge);
                    }
                    else
                    {
                        edges.Add(edge);
                    }
                }
            }
            //Now we can loop through the edges to form two loops
            if (edges.Count < 5)
            {
                return(false);                 //5 is the minimum number of vertices to look remotely circular (8 is more likely)
            }
            var(allLoopsClosed, edgeLoops, loops) = GetLoops(edges, true);
            if (loops.Count != 2)
            {
                return(false);                  //There must be two and only two loops.
            }
            Loop1     = loops[0];
            Loop2     = loops[1];
            EdgeLoop1 = edgeLoops[0];
            EdgeLoop2 = edgeLoops[1];

            //Next, we need to get the central axis.
            //The ends of the cylinder could be any shape (flat, curved, angled) and the shapes
            //on each end do not need to match. This rules out using the vertex loops to form
            //a plane (most accurate) and creating a plane from edge midpoints (next most accurate).
            //The next most accurate thing is to use the edge vectors to set the axis.
            //This is more precise than taking a bunch of cross products with the faces.
            //And it is more universal than creating a plane from the loops, since it works
            //for holes that enter and exit at an angle.
            var throughEdgeVectors = new Dictionary <Vertex, double[]>();
            var dotFromSharpestEdgesConnectedToVertex = new Dictionary <Vertex, double>();

            foreach (var edge in InnerEdges)
            {
                //Skip those edges that are on "flat" surfaces
                var dot = edge.OwnedFace.Normal.dotProduct(edge.OtherFace.Normal);
                if (dot.IsPracticallySame(1.0, Constants.ErrorForFaceInSurface))
                {
                    continue;
                }
                //This uses a for loop to remove duplicate code, to decide which vertex to check with which loop
                for (var i = 0; i < 2; i++)
                {
                    var A = i == 0 ? edge.To : edge.From;
                    var B = i == 0 ? edge.From : edge.To;
                    if (Loop1.Contains(A))
                    {
                        bool reachedEnd = Loop2.Contains(B);
                        if (!reachedEnd)
                        {
                            //Check if this edge needs to "extended" to reach the end of the cylinder
                            var previousEdge   = edge;
                            var previousVertex = B;
                            while (!reachedEnd)
                            {
                                var  maxDot        = 0.0;
                                Edge extensionEdge = null;
                                foreach (var otherEdge in previousVertex.Edges.Where(e => e != previousEdge))
                                {
                                    //This other edge must be contained in the InnerEdges and along the same direction
                                    if (!InnerEdges.Contains(otherEdge))
                                    {
                                        continue;
                                    }
                                    var edgeDot = Math.Abs(otherEdge.Vector.normalize().dotProduct(previousEdge.Vector.normalize()));
                                    if (!edgeDot.IsPracticallySame(1.0, Constants.ErrorForFaceInSurface))
                                    {
                                        continue;
                                    }
                                    //Choose the edge that is most along the previous edge
                                    if (edgeDot > maxDot)
                                    {
                                        maxDot        = edgeDot;
                                        extensionEdge = otherEdge;
                                    }
                                }
                                if (extensionEdge == null)
                                {
                                    break;                        //go to the next edge
                                }
                                if (Loop2.Contains(extensionEdge.OtherVertex(previousVertex)))
                                {
                                    reachedEnd = true;
                                    B          = extensionEdge.OtherVertex(previousVertex);
                                }
                                else
                                {
                                    previousVertex = extensionEdge.OtherVertex(previousVertex);
                                    previousEdge   = extensionEdge;
                                }
                            }
                        }
                        //If there was a vertex from the edge or edges in the second loop.
                        if (reachedEnd)
                        {
                            if (!dotFromSharpestEdgesConnectedToVertex.ContainsKey(A))
                            {
                                throughEdgeVectors.Add(A, B.Position.subtract(A.Position));
                                dotFromSharpestEdgesConnectedToVertex.Add(A, edge.InternalAngle);
                            }
                            else if (dot < dotFromSharpestEdgesConnectedToVertex[A])
                            {
                                throughEdgeVectors[A] = B.Position.subtract(A.Position);
                                dotFromSharpestEdgesConnectedToVertex[A] = dot;
                            }
                            break; //Go to the next edge
                        }
                    }
                }
            }
            if (throughEdgeVectors.Count < 3)
            {
                return(false);
            }

            //Estimate the axis from the sum of the through edge vectors
            //The axis points from loop 1 to loop 2, since we always start the edge vector from Loop1
            var edgeVectors = new List <double[]>(throughEdgeVectors.Values);
            var numEdges    = edgeVectors.Count;
            var axis        = new double[] { 0.0, 0.0, 0.0 };

            foreach (var edgeVector in edgeVectors)
            {
                axis = axis.add(edgeVector);
            }
            Axis = axis.normalize();

            /* to adjust the Axis, we will average the cross products of the new face with all the old faces */
            //Since we will be taking cross products, we need to be sure not to have faces along the same normal
            var faces = MiscFunctions.FacesWithDistinctNormals(Faces.ToList());
            var n     = faces.Count;

            //Check if the loops are circular along the axis
            var path1 = MiscFunctions.Get2DProjectionPointsAsLight(Loop1, Axis, out var backTransform);
            var poly  = new PolygonLight(path1);

            if (!PolygonOperations.IsCircular(new Polygon(poly), out var centerCircle, Constants.MediumConfidence))
            {
                return(false);
            }
            var path2 = MiscFunctions.Get2DProjectionPointsAsLight(Loop2, Axis, out var backTransform2);
            var poly2 = new PolygonLight(path2);

            if (!PolygonOperations.IsCircular(new Polygon(poly2), out var centerCircle2, Constants.MediumConfidence))
            {
                return(false);
            }
            Radius = (centerCircle.Radius + centerCircle2.Radius) / 2; //Average
            return(true);
        }