/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.FixedU (double, double, double)"/> /// </summary> /// <param name="u"></param> /// <param name="vmin"></param> /// <param name="vmax"></param> /// <returns></returns> public override ICurve FixedU(double u, double vmin, double vmax) { ICurve2D btr = basisCurve2D.Trim(GetPos(vmin), GetPos(vmax)); ICurve b3d = btr.MakeGeoObject(Plane.XYPlane) as ICurve; ModOp rot = ModOp.Rotate(1, (SweepAngle)u); ModOp movePitch = ModOp.Translate(0, pitch * u / (Math.PI * 2.0), 0); return(b3d.CloneModified(toSurface * movePitch * rot)); }
static public CurveGraph CrackCurves(GeoObjectList l, Plane plane, double maxGap) { // alle Kurven in l werden in die Ebene plane projiziert. Das ist mal ein erster Ansatz // Man könnte auch gemeinsame Ebenen finden u.s.w. ArrayList curves = new ArrayList(); BoundingRect ext = BoundingRect.EmptyBoundingRect; foreach (IGeoObject go in l) { ICurve cv = go as ICurve; if (cv != null) { ICurve2D cv2 = cv.GetProjectedCurve(plane); if (cv2 != null) { // "3d" wird nur verwendet um hinterher aus den Originalkurven die Ebene zu bestimmen // in die alles zurücktranformiert wird. Besser würde man vermutlich mit "plane" arbeiten // so wie es hier reinkommt. if (cv2 is Path2D && (cv2 as Path2D).GetSelfIntersections().Length > 0) { // ein sich selbst überschneidender Pfad muss aufgelöst werden ICurve2D[] sub = (cv2 as Path2D).SubCurves; curves.AddRange(sub); for (int i = 0; i < sub.Length; ++i) { sub[i].UserData.Add("3d", cv); } ext.MinMax(cv2.GetExtent()); } else { cv2.UserData.Add("3d", cv); curves.Add(cv2); ext.MinMax(cv2.GetExtent()); } } } } if (curves.Count == 0) { return(null); } QuadTree qt = new QuadTree(ext); qt.MaxDeepth = 8; qt.MaxListLen = 3; for (int i = 0; i < curves.Count; ++i) { qt.AddObject(curves[i] as ICurve2D); } // jetzt alle mit allen schneiden und die Schnipsel in eine weitere Liste stecken ArrayList snippet = new ArrayList(); for (int i = 0; i < curves.Count; ++i) { ICurve2D cv1 = curves[i] as ICurve2D; ArrayList intersectionPoints = new ArrayList(); // double ICollection closecurves = qt.GetObjectsCloseTo(cv1); foreach (ICurve2D cv2 in closecurves) { if (cv2 != cv1) { //if ((cv1 is Line2D && (cv1 as Line2D).Length > 10 && (cv1 as Line2D).Length < 15) || // (cv2 is Line2D && (cv2 as Line2D).Length > 10 && (cv2 as Line2D).Length < 15)) //{ //} GeoPoint2DWithParameter[] isp = cv1.Intersect(cv2); for (int k = 0; k < isp.Length; ++k) { if (cv2.IsParameterOnCurve(isp[k].par2) && 0.0 < isp[k].par1 && isp[k].par1 < 1.0) { intersectionPoints.Add(isp[k].par1); } } } } if (intersectionPoints.Count == 0) { snippet.Add(cv1); } else { intersectionPoints.Add(0.0); intersectionPoints.Add(1.0); // damit sinds mindesten 3 double[] pps = (double[])intersectionPoints.ToArray(typeof(double)); Array.Sort(pps); for (int ii = 1; ii < pps.Length; ++ii) { if (pps[ii - 1] < pps[ii]) { ICurve2D cv3 = cv1.Trim(pps[ii - 1], pps[ii]); if (cv3 != null) { #if DEBUG GeoPoint2D dbg1 = cv1.PointAt(pps[ii - 1]); GeoPoint2D dbg2 = cv1.PointAt(pps[ii]); GeoPoint2D dbg3 = cv3.StartPoint; GeoPoint2D dbg4 = cv3.EndPoint; double d1 = dbg1 | dbg3; double d2 = dbg2 | dbg4; #endif cv3.UserData.Add("3d", cv1.UserData.GetData("3d")); snippet.Add(cv3); } } } } } // snippet ist jetzt die Liste aller Schnipsel return(new CurveGraph((ICurve2D[])snippet.ToArray(typeof(ICurve2D)), maxGap)); }
private void InsertCurve(int ind) { ICurve toInsert = closedBorder.Curve(ind); Face fromFace = vertexToFace[ind]; int ind1 = ind + 1; if (ind1 >= vertexToFace.Length) { ind1 = 0; } Face toFace = vertexToFace[ind1]; ICurve2D c2d = fromFace.Surface.GetProjectedCurve(toInsert, precision); double[] clp = fromFace.Area.Clip(c2d, true); if (clp == null || clp.Length < 2) { throw new SplitShellWithCurvesException("curve outside of face"); } if (clp.Length == 2 && clp[0] == 0.0 && clp[1] == 1.0) { if (fromFace == toFace) { List <ICurve2D> lc2d; if (!all2DCurves.TryGetValue(fromFace, out lc2d)) { lc2d = new List <ICurve2D>(); all2DCurves[fromFace] = lc2d; } lc2d.Add(c2d); } else { throw new SplitShellWithCurvesException("endpoint on wrong face"); } } else { // die Kurve geht in ein anderes Face Face face1 = fromFace; ICurve2D curveOnFace1 = c2d; double startOnFace1 = clp[0]; // sollte immer 0.0 sein, oder? double endOnFace1 = clp[1]; Face face2 = null; ICurve2D curveOnFace2 = null; double startOnFace2 = 0.0, endOnFace2 = 0.0; bool success; do { success = false; GeoPoint onEdge = face1.Surface.PointAt(curveOnFace1.PointAt(endOnFace1)); Edge[] close = FindCloseEdges(face1, onEdge); if (close.Length == 0) { throw new SplitShellWithCurvesException("no connecting edge found"); } for (int i = 0; i < close.Length; i++) { face2 = close[i].OtherFace(face1); success = SplitAndInsertCurve(toInsert, face1, face2, curveOnFace1, startOnFace1, out curveOnFace2, out startOnFace2, out endOnFace2); if (success) { face1 = face2; startOnFace1 = startOnFace2; endOnFace1 = endOnFace2; curveOnFace1 = curveOnFace2; break; } } if (success && face1 == toFace && endOnFace2 == 1.0) { ICurve2D clipped2 = curveOnFace2.Trim(startOnFace2, endOnFace2); List <ICurve2D> lc2d; if (!all2DCurves.TryGetValue(face2, out lc2d)) { lc2d = new List <ICurve2D>(); all2DCurves[face2] = lc2d; } lc2d.Add(clipped2); break; } } while (success); } }
private bool SplitAndInsertCurve(ICurve toInsert, Face face1, Face face2, ICurve2D curveOnFace1, double startOnFace1, out ICurve2D curveOnFace2, out double startOnFace2, out double endOnFace2) { curveOnFace2 = null; startOnFace2 = -1.0; endOnFace2 = -1.0; double[] clp1 = face1.Area.Clip(curveOnFace1, true); double endOnFace1 = 0.0; for (int i = 0; i < clp1.Length; i += 2) { if (clp1[i] == startOnFace1) { endOnFace1 = clp1[i + 1]; } } if (endOnFace1 == 0.0) { return(false); // sollte nicht vorkommen } GeoPoint leaveFace1 = face1.Surface.PointAt(curveOnFace1.PointAt(endOnFace1)); Edge[] close = FindCloseEdges(face1, leaveFace1); Edge commonEdge = null; for (int i = 0; i < close.Length; i++) { if (close[i].OtherFace(face1) == face2) { commonEdge = close[i]; break; } } if (commonEdge == null) { return(false); } curveOnFace2 = face2.Surface.GetProjectedCurve(toInsert, precision); AdjustPeriodic(face2, curveOnFace2, leaveFace1); double[] clp2 = face2.Area.Clip(curveOnFace2, true); for (int i = 0; i < clp2.Length; i += 2) { GeoPoint enterFace2 = face2.Surface.PointAt(curveOnFace2.PointAt(clp2[i])); if (commonEdge.Curve3D.DistanceTo(enterFace2) < precision) { // a good common edge which both 2d curves connect double pos = (commonEdge.Curve3D.PositionOf(enterFace2) + commonEdge.Curve3D.PositionOf(leaveFace1)) / 2.0; List <double> edgePositions; if (!splitedEdges.TryGetValue(commonEdge, out edgePositions)) { splitedEdges[commonEdge] = new List <double>(); edgePositions = splitedEdges[commonEdge]; } edgePositions.Add(pos); ICurve2D clipped1 = curveOnFace1.Trim(startOnFace1, endOnFace1); GeoPoint2D uv1 = face1.Surface.PositionOf(commonEdge.Curve3D.PointAt(pos)); clipped1.EndPoint = uv1; List <ICurve2D> lc2d; if (!all2DCurves.TryGetValue(face1, out lc2d)) { lc2d = new List <ICurve2D>(); all2DCurves[face1] = lc2d; } lc2d.Add(clipped1); startOnFace2 = clp2[i]; endOnFace2 = clp2[i + 1]; return(true); } } return(false); }
private void AddSplittedFace(Face face) { List <ICurve> edgeCurves = new List <ICurve>(); List <ICurve2D> curves2d = new List <ICurve2D>(); #if DEBUG Vertex[] vtx = face.Vertices; bool[] outside = new bool[vtx.Length]; Polyline pln = Polyline.Construct(); for (int i = 0; i < vtx.Length; i++) { outside[i] = outsideVertices.Contains(vtx[i]); pln.AddPoint(vtx[i].Position); } DebuggerContainer dc = new DebuggerContainer(); #endif Edge[] edges = face.AllEdges; // sollte keine Löcher haben for (int i = 0; i < edges.Length; i++) { List <double> positions; if (splitedEdges.TryGetValue(edges[i], out positions)) { List <double> pos = new List <double>(positions); pos.Add(0.0); pos.Add(1.0); pos.Sort(); int startj; Vertex startVertex; ICurve2D c2d = edges[i].Curve2D(face); #if DEBUG dc.Add(c2d, System.Drawing.Color.Red, i); #endif if ((face.Surface.PointAt(c2d.StartPoint) | edges[i].Vertex1.Position) < (face.Surface.PointAt(c2d.StartPoint) | edges[i].Vertex2.Position)) { startVertex = edges[i].Vertex1; } else { startVertex = edges[i].Vertex2; // die Kurve geht andersrum als die Kante, also Kantenschnittpunkte umdrehen pos.Reverse(); } if (outsideVertices.Contains(startVertex)) { startj = 1; } else { startj = 0; } for (int j = startj; j < pos.Count - 1; j += 2) { double pos1 = c2d.PositionOf(face.Surface.PositionOf(edges[i].Curve3D.PointAt(pos[j]))); double pos2 = c2d.PositionOf(face.Surface.PositionOf(edges[i].Curve3D.PointAt(pos[j + 1]))); if (pos2 < pos1) { double tmp = pos1; pos1 = pos2; pos2 = tmp; } ICurve2D trimmed = c2d.Trim(pos1, pos2); curves2d.Add(trimmed); #if DEBUG dc.Add(trimmed, System.Drawing.Color.Blue, i); #endif } } else { if (!outsideVertices.Contains(edges[i].Vertex1)) { #if DEBUG dc.Add(edges[i].Curve2D(face), System.Drawing.Color.Green, i); #endif curves2d.Add(edges[i].Curve2D(face)); } } } List <ICurve2D> lc2d; if (all2DCurves.TryGetValue(face, out lc2d)) { for (int i = 0; i < lc2d.Count; i++) { #if DEBUG dc.Add(lc2d[i], System.Drawing.Color.HotPink, i); #endif // die folgende Kurve mit Start- und Endpunkt anpassen, denn sie ist evtl ungenau... curves2d.Add(lc2d[i]); } } // alle zuletzt hinzugefügten Kurven magnetisch einschnappen lassen for (int i = all2DCurves.Count - lc2d.Count; i < all2DCurves.Count; i++) { AddAndAdjust2DCurve(curves2d, i); } // eigentlich wäre mehr Information vorhanden, als dass man diese Kurven völlig neu sortieren müsste // aber so ist es nun mal einfacher ICurve2D[] acsd = new ICurve2D[curves2d.Count]; for (int i = 0; i < acsd.Length; i++) { acsd[i] = curves2d[i].Clone(); } Reduce2D r2d = new Reduce2D(); r2d.Add(acsd); r2d.OutputMode = Reduce2D.Mode.Paths; ICurve2D[] red = r2d.Reduced; if (red.Length == 1) { Border bdr = new Border(red[0]); SimpleShape ss = new SimpleShape(bdr); Face splitted = Face.MakeFace(face.Surface, ss); resultingFaces.Add(splitted); } //CompoundShape cs = CompoundShape.CreateFromList(acsd, Precision.eps); //if (cs != null && cs.SimpleShapes.Length == 1) //{ // SimpleShape ss = cs.SimpleShapes[0]; // Face splitted = Face.MakeFace(face.Surface, ss); // resultingFaces.Add(splitted); //} //else //{ //} }
public override void Trim(double StartPos, double EndPos) { curve2D = curve2D.Clone(); curve2D.Trim(StartPos, EndPos); }