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()); }
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); }
public UserControl SetPayload(Loop2 item) { txtSteps.Value = item.Step; return(this); }
public static void Next(IEnumLoops2Object IEnumLoops2instance, Int32 Celt, Loop2&Object Rgelt, Int32& PceltFetched)
/// <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); }