Exemple #1
0
        public override GeoVector DirectionAt(double pos)
        {
            GeoPoint2D  p   = curve2D.PointAt(pos);
            GeoVector2D dir = curve2D.DirectionAt(pos);

            surface.DerivationAt(p, out GeoPoint location, out GeoVector diru, out GeoVector dirv);
            return(dir.x * diru + dir.y * dirv);
        }
Exemple #2
0
        /// <summary>
        /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.PointAt (GeoPoint2D)"/>
        /// </summary>
        /// <param name="uv"></param>
        /// <returns></returns>
        public override GeoPoint PointAt(GeoPoint2D uv)
        {
            double     pos       = GetPos(uv.y);
            GeoPoint2D p2d       = basisCurve2D.PointAt(pos);
            ModOp      rot       = ModOp.Rotate(1, (SweepAngle)uv.x);
            ModOp      movePitch = ModOp.Translate(0, pitch * uv.x / (Math.PI * 2.0), 0);

            return(toSurface * movePitch * rot * p2d);
        }
        /// <summary>
        /// Liefert die 3D Kurve zu diesem Objekt, wenn die Surface stimmt. Bestimmt bei geklippten Objekten
        /// die Start- und Endpunkte im 3D. Ansonsten ist es identisch mit der 3D Kurve
        /// </summary>
        /// <param name="onThisSurface"></param>
        /// <returns></returns>
        public ICurve Get3DCurve(ISurface onThisSurface)
        {
            if (onThisSurface != theSurface)
            {
                return(null);
            }
            if (!clipped)
            {
                return(dualSurfaceCurve.Curve3D);
            }
            // bei interpolatedDualSurfaceCurve ist schon geklippt, und hier wird nochmal
            // mit position of parameter gesucht und nochmal geklippt, das ist schlecht!!
            double startParam = dualSurfaceCurve.Curve3D.PositionOf(startPoint);
            double endParam   = dualSurfaceCurve.Curve3D.PositionOf(endPoint);

            if (endParam < startParam)
            {
                double tmp = endParam;
                endParam   = startParam;
                startParam = tmp;
            }
            if (dualSurfaceCurve.Curve3D.IsClosed)
            {
                ICurve[] splitted = dualSurfaceCurve.Curve3D.Split(startParam, endParam);
                if (splitted.Length == 2) // müsste wohl immer so eine
                {
                    double pos1 = splitted[0].PositionOf(theSurface.PointAt(clippedCurve.PointAt(0.5)));
                    double pos2 = splitted[1].PositionOf(theSurface.PointAt(clippedCurve.PointAt(0.5)));
                    if (Math.Abs(pos1 - 0.5) < Math.Abs(pos2 - 0.5))
                    {
                        return(splitted[0]);
                    }
                    else
                    {
                        return(splitted[1]);
                    }
                }
                else if (splitted.Length > 0)
                {   // sollte nicht vorkommen
                    return(splitted[0]);
                }
                else
                {   // sollte nicht vorkommen
                    return(null);
                }
            }
            else
            {
                ICurve res = dualSurfaceCurve.Curve3D.Clone();
                res.Trim(startParam, endParam);
                return(res);
            }
        }
Exemple #4
0
            GeoPoint2D ICurveTransformation2D.TransformPoint(ICurve2D curve, double par)
            {   // gesucht: Punkt der Kurve im nichtperiodischen System
                GeoPoint2D uv = curve.PointAt(par);
                double     r  = uv.y - vmin;

                return(new GeoPoint2D(r * Math.Cos(uv.x), r * Math.Sin(uv.x)));
            }
Exemple #5
0
            GeoVector2D ICurveTransformation2D.TransformDeriv1(ICurve2D curve, double par)
            {   // gesucht: Richtung im nicht periodischen System
                GeoPoint2D  uv  = curve.PointAt(par);
                GeoVector2D dir = curve.DirectionAt(par);

                return(new GeoVector2D(Math.Cos(uv.x) * (dir.y) - Math.Sin(uv.x) * (dir.x) * (uv.y - vmin),
                                       Math.Cos(uv.x) * (dir.x) * (uv.y - vmin) + Math.Sin(uv.x) * (dir.y)));
            }
        ModOp IMovement.GetPosition(double u)
        {
            GeoVector du, dv;
            GeoPoint  loc;

            surface.DerivationAt(c2d.PointAt(u), out loc, out du, out dv);
            GeoVector2D dir2d = c2d.DirectionAt(u);
            GeoVector   ux    = dir2d.x * du + dir2d.y * dv;
            GeoVector   uz    = du ^ dv;
            GeoVector   uy    = ux ^ uz;
            ModOp       res   = ModOp.Translate(loc - GeoPoint.Origin) * ModOp.Fit(new GeoVector[] { startX.Normalized, startY.Normalized, startZ.Normalized }, new GeoVector[] { ux.Normalized, uy.Normalized, uz.Normalized }) * ModOp.Translate(GeoPoint.Origin - startPos);

            return(res);
            //return new ModOp(toUnit * ux, toUnit * uy, toUnit * uz, toUnit * loc);
        }
        private bool showLine()
        {
            ArrayList usableCurves = new ArrayList(); // lokales Array, das die gültigen Kurven sammelt
            double    mindist      = double.MaxValue;

            for (int i = 0; i < perpCurves.Length; ++i)
            {
                Plane pl;
                if (Curves.GetCommonPlane(startPoint, perpCurves[i], out pl))
                {
                    ICurve2D l2D = perpCurves[i].GetProjectedCurve(pl);
                    if (l2D is Path2D)
                    {
                        (l2D as Path2D).Flatten();
                    }
                    GeoPoint2D[] perpPoints = l2D.PerpendicularFoot(pl.Project(startPoint));
                    if (perpPoints.Length > 0)
                    {   // eine gültige Kurve ist gefunden
                        usableCurves.Add(perpCurves[i]);
                        for (int j = 0; j < perpPoints.Length; ++j)
                        {
                            //							double dist = Geometry.Dist(perpPoints[j],pl.Project(startPoint));
                            double dist = Geometry.Dist(perpPoints[j], pl.Project(objectPoint));
                            if (dist < mindist)
                            {
                                mindist  = dist;
                                selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist
                                endPoint = perpPoints[j];
                            }
                        }
                    }
                    else
                    {   // beim Kreis oder Bogen vom Mittelpunkt aus gilt jeder Punkt
                        if (l2D is Circle2D)
                        {
                            if (Precision.IsEqual((l2D as Circle2D).Center, pl.Project(startPoint)))
                            {
                                GeoPoint2D pp   = l2D.PointAt(l2D.PositionOf(pl.Project(objectPoint)));
                                double     dist = Geometry.Dist(pp, pl.Project(objectPoint));
                                if (dist < mindist)
                                {
                                    mindist  = dist;
                                    selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist
                                    endPoint = pp;
                                }
                            }
                        }
                    }
                }
                if (mindist < double.MaxValue)
                {
                    line.SetTwoPoints(startPoint, pl.ToGlobal(endPoint));
                    perpCurves            = (ICurve[])usableCurves.ToArray(typeof(ICurve)); // perpCurves wird mit den gültigen überschrieben und unten zur Anzeige zurückgegeben an den Sender
                    base.ShowActiveObject = true;
                    return(true);
                }
            }
            line.SetTwoPoints(startPoint, objectPoint);
            base.ShowActiveObject = true;
            return(false);
        }
Exemple #8
0
        //		private Border FindNextBorder()
        //		{
        //			// Alle Cluster enthalten zwei Punkte. Suche einen Joint, dessen angeschlossener
        //			// ICurve2D länger als maxGap ist (warum eigentlich?)
        //			// Gehe solange durch die Cluster, bis wieder der erste Punkt erreicht ist
        //			Joint StartWith = null;
        //			foreach (Cluster cl in clusterSet)
        //			{
        //				foreach (Joint lp in cl.Points)
        //				{
        //					if (lp.curve.Length>maxGap)
        //					{
        //						StartWith = lp;
        //						RemoveJoint(lp,cl);
        //						break;
        //					}
        //				}
        //				if (StartWith!=null) break;
        //			}
        //			if (StartWith==null) return null; // keinen Anfang gefunden
        //			Joint LastPoint = StartWith;
        //			Cluster goon = null;
        //			BorderBuilder makeBorder = new BorderBuilder();
        //			makeBorder.Precision = clusterSize;
        //			while ((goon = ExtractCurve(LastPoint.curve,!LastPoint.isStartPoint))!=null)
        //			{
        //				makeBorder.AddSegment(LastPoint.curve.CloneReverse(!LastPoint.isStartPoint));
        //				if (goon.Points.Count==0) break; // auf den letzten und ersten Punkt gestoßen
        //				LastPoint = (Joint)goon.Points[0]; // es sollte ja nur diesen einen geben
        //				RemoveJoint(LastPoint,goon); // damit müsste dieser Cluster verschwinden
        //			}
        //			return makeBorder.BuildBorder();
        //		}
        //		private bool FindSimpleBorder(Set clusterSet, ArrayList AllBorders, Set UsedJoints, ICurve2D startWith, bool forward)
        //		{
        //			Set tmpUsedJoints = new Set();
        //			tmpUsedJoints.Add(new UsedJoint(startWith,forward));
        //			// Anfangskante gefunden, wie gehts weiter
        //			BorderBuilder bb = new BorderBuilder();
        //			bb.Precision = clusterSize;
        //			if (forward) bb.AddSegment(startWith.Clone());
        //			else bb.AddSegment(startWith.CloneReverse(true));
        //
        //			while (!bb.IsClosed)
        //			{
        //				Cluster cl = FindCluster(startWith, bb.EndPoint, false);
        //				if (cl==null) return false; // eine angefangene Border geht nicht weiter, sollte nicht passieren, da keine Sackgassen
        //				int ind = -1;
        //				double sa = -1.0;
        //				for (int i=0; i<cl.Points.Count; ++i)
        //				{
        //					Joint j = cl.Points[i] as Joint;
        //					if (j.curve==startWith) continue; // nicht auf der Stelle rückwärts weiter
        //					UsedJoint uj = new UsedJoint(j.curve,j.isStartPoint);
        //					if (!UsedJoints.Contains(uj) && !tmpUsedJoints.Contains(uj))
        //					{
        //						SweepAngle d;
        //						if (j.isStartPoint) d = new SweepAngle(bb.EndDirection,j.curve.StartDirection);
        //						else d = new SweepAngle(bb.EndDirection,j.curve.EndDirection.Opposite());
        //						// d zwischen -PI und +PI
        //						if (d+Math.PI > sa)
        //						{	// je mehr nach links umso größer is d
        //							sa = d+Math.PI;
        //							ind = i;
        //						}
        //					}
        //				}
        //				if (ind>=0)
        //				{
        //					Joint j = cl.Points[ind] as Joint;
        //					if (j.isStartPoint) bb.AddSegment(j.curve.Clone());
        //					else bb.AddSegment(j.curve.CloneReverse(true));
        //					tmpUsedJoints.Add(new UsedJoint(j.curve,j.isStartPoint));
        //					startWith = j.curve;
        //				}
        //				else
        //				{
        //					return false; // kein weitergehen möglich
        //				}
        //			}
        //			if (bb.IsOriented)
        //			{
        //				Border bdr = bb.BuildBorder();
        //				AllBorders.Add(bdr);
        //				foreach (UsedJoint uj in tmpUsedJoints)
        //				{
        //					if (!UsedJoints.Contains(uj))
        //					{
        //						UsedJoints.Add(uj);
        //					}
        //					else
        //					{
        //						int dbg = 0;
        //					}
        //				}
        //				return true;
        //			}
        //			return false;
        //		}
        //		private bool FindSimpleBorder(Set clusterSet, ArrayList AllBorders, Set UsedJoints)
        //		{
        //			// es wird eine minimale Border gesucht: von irgend einem Cluster ausgehend immer
        //			// linksrum bis man wieder am Anfang ist.
        //			// UsedJoints enthält UsedJoint objekte, damit man feststellen kann, ob eine Kante bereits
        //			// benutzt ist oder nicht
        //			ICurve2D startWith = null;
        //			bool forward = false;
        //			foreach (Cluster cl in clusterSet)
        //			{
        //				for (int i=0; i<cl.Points.Count; ++i)
        //				{
        //					UsedJoint uj = new UsedJoint();
        //					Joint j = cl.Points[i] as Joint;
        //					uj.curve = j.curve;
        //					uj.forward = true;
        //					if (!UsedJoints.Contains(uj))
        //					{
        //						forward = j.isStartPoint;
        //						startWith = j.curve;
        //						if (FindSimpleBorder(clusterSet,AllBorders,UsedJoints,startWith,forward))
        //							return true;
        //					}
        //					uj.forward = false;
        //					if (!UsedJoints.Contains(uj))
        //					{
        //						forward = !j.isStartPoint;
        //						startWith = j.curve;
        //						if (FindSimpleBorder(clusterSet,AllBorders,UsedJoints,startWith,forward))
        //							return true;
        //					}
        //				}
        //			}
        //			return false;
        //		}
        private Joint[] SortCluster()
        {   // sortiert die Kanten (Joints) in einem Cluster im Gegenuhrzeigersinn
            // liefert alle Kanten

            // Verwerfen von identischen Kanten:
            // Zwei Kanten in einem Cluster, die das selbe "Gegencluster" haben
            // stehen im Verdacht identisch zu sein. Ihre Mittelpunkte werden auf
            // identität überprüft und die Kanten werden ggf. entfernt.
            foreach (Cluster cl in clusterSet)
            {
                for (int i = 0; i < cl.Joints.Count - 1; ++i)
                {
                    int duplicate = -1;
                    for (int j = i + 1; j < cl.Joints.Count; ++j)
                    {
                        Cluster cl1;
                        Cluster cl2;
                        Joint   j1 = cl.Joints[i] as Joint;
                        Joint   j2 = cl.Joints[j] as Joint;
                        if (j1.StartCluster == cl)
                        {
                            cl1 = j1.EndCluster;
                        }
                        else
                        {
                            cl1 = j1.StartCluster;
                        }
                        if (j2.StartCluster == cl)
                        {
                            cl2 = j2.EndCluster;
                        }
                        else
                        {
                            cl2 = j2.StartCluster;
                        }
                        if (cl1 == cl2)
                        {   // zwei Kanten verbinden dieselben Cluster. Sie könnten identisch sein
                            ICurve2D curve1 = j1.curve.CloneReverse(j1.StartCluster != cl);
                            ICurve2D curve2 = j2.curve.CloneReverse(j2.StartCluster != cl);
                            // curve1 und curve2 haben jetzt die selbe Richtung
                            GeoPoint2D p1 = curve1.PointAt(0.5);
                            GeoPoint2D p2 = curve2.PointAt(0.5);
                            if (Geometry.Dist(p1, p2) < clusterSize)
                            {
                                duplicate = j;
                                break;
                            }
                        }
                    }
                    if (duplicate > 0)
                    {
                        cl.Joints.RemoveAt(duplicate);
                    }
                }
            }
            // zu kurze Joints werden entfern
            foreach (Cluster cl in clusterSet)
            {
                for (int i = cl.Joints.Count - 1; i >= 0; --i)
                {
                    Joint j1 = cl.Joints[i] as Joint;
                    if (j1.curve.Length < this.clusterSize)
                    {
                        cl.Joints.RemoveAt(i);
                    }
                }
            }

            UntypedSet allJoints = new UntypedSet();

            foreach (Cluster cl in clusterSet)
            {
                if (cl.Joints.Count < 3)
                {
                    foreach (Joint j in cl.Joints)
                    {
                        if (!allJoints.Contains(j))
                        {
                            allJoints.Add(j);
                        }
                    }
                    continue;
                }
                // zwei Punkte im cluster muss man nicht sortieren
                double minDist = double.MaxValue;
                foreach (Joint j in cl.Joints)
                {
                    if (!allJoints.Contains(j))
                    {
                        allJoints.Add(j);
                    }
                    GeoPoint2D p;
                    if (j.StartCluster == cl)
                    {
                        p = j.EndCluster.center;
                    }
                    else
                    {
                        if (j.EndCluster != cl)
                        {
                            throw new CurveGraphException("SortCluster");
                        }
                        p = j.StartCluster.center;
                    }
                    double d = Geometry.Dist(cl.center, p);
                    if (d == 0.0)
                    {
                        if (j.StartCluster == j.EndCluster)
                        {
                            continue;
                        }
                        throw new CurveGraphException("SortCluster");
                    }
                    if (d < minDist)
                    {
                        minDist = d;
                    }
                }
                // Kreis um cl mit halber Entfernung zum nächsten Knoten als Radius
                Circle2D c2d = new Circle2D(cl.center, minDist / 2.0);
                foreach (Joint j in cl.Joints)
                {
                    GeoPoint2DWithParameter[] ip = c2d.Intersect(j.curve);
                    if (ip.Length > 0)
                    {
                        for (int i = 0; i < ip.Length; ++i)
                        {
                            if (j.curve.IsParameterOnCurve(ip[i].par2))
                            {
                                Angle a = new Angle(ip[i].p, cl.center);
                                j.tmpAngle = a.Radian;
                                break;
                            }
                        }
                    }
                    else
                    {
                        // darf nicht vorkommen, eine Kante schneidet nicht den Kreis um
                        // den Knoten mit halbem Radius zum nächsten knoten
                        // der Sortierwert bleibt halt 0.0, aber man sollte solche Kanten
                        // entfernen ...
                        // kommt vor, das Problem liegt bei regle4!!!
                        if (j.StartCluster == cl)
                        {   // curve startet hier
                            j.tmpAngle = j.curve.StartDirection.Angle;
                        }
                        else
                        {
                            j.tmpAngle = j.curve.EndDirection.Opposite().Angle;
                        }
                    }
                }
                cl.Joints.Sort(); // es wird nach tmpAngle sortiert
            }
            Joint[] res = new Joint[allJoints.Count];
            int     ii  = 0;

            foreach (Joint j in allJoints)
            {   // die Kurve exakt ausrichten
                try
                {
                    j.curve.StartPoint = j.StartCluster.center;
                    j.curve.EndPoint   = j.EndCluster.center;
                }
                catch (Curve2DException) { } // z.B. Kreise endpunkt setzen
                res[ii] = j;
                ++ii;
            }
            return(res);
        }
Exemple #9
0
        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);
        }
Exemple #12
0
        private bool showObject()
        {
            base.FeedBack.ClearSelected();
            base.ActiveObject = null;
            double[]   cutPlace;
            ICurve2D   c2d  = iCurve.GetProjectedCurve(CurrentMouseView.Projection.ProjectionPlane);
            GeoPoint2D op2d = CurrentMouseView.Projection.ProjectUnscaled(objectPoint);

            lowerEnd = (c2d.PositionOf(op2d) < 0.5); // im 2D überprüfen, in 3D ist objectPoint möglicherweise weit von iCurve entfernt
            // bool lowerEnd = (iCurve.PositionOf(objectPoint)< 0.5);
            ProjectedModel.IntersectionMode cutMode;
            bool realCut;

            if (lowerEnd)
            {
                cutMode = ProjectedModel.IntersectionMode.StartExtension;
            }
            else
            {
                cutMode = ProjectedModel.IntersectionMode.EndExtension;
            }
            //			if (expandSourceObject.Fixed)
            ICurve[] targetCurves = null;
            if (sourceCurve != null)
            {
                cutPlace = Curves.Intersect(iCurve, sourceCurve, false);
            }
            else
            {
                cutPlace = base.Frame.ActiveView.ProjectedModel.GetIntersectionParameters(iCurve, cutMode, out targetCurves);
            }
            if (cutPlace.Length > 0)
            {
                realCut = false;
                for (int i = 0; i < cutPlace.Length; ++i)
                {
                    if (distToCurve.Length == 0)
                    {
                        if (cutPlace[i] < -1e-8 || cutPlace[i] > 1 + 1e-8) // Endpunkte nicht mit berücksichtigen
                        //if (!((Math.Abs(cutPlace[i]) < 1e-8) || (Math.Abs(cutPlace[i] - 1) < 1e-8)))
                        {
                            realCut = true;
                            break;
                        }
                    }
                    else
                    {
                        //if (cutPlace[i] < 1e-8 || cutPlace[i] > 1 - 1e-8) // Endpunkte mit berücksichtigen
                        {
                            realCut = true;
                            break;
                        }
                    }
                }
                if (realCut)
                {
                    int k = -1;
                    if (lowerEnd)
                    {
                        param = double.MinValue;
                    }
                    else
                    {
                        param = double.MaxValue;
                    }
                    double eps; // wenn distToCurve gesetzt ist, dann bleibt ein exakt getrimmtes am Ende gültig, ansonsten wird die nächste Querkurve verwendet
                    if (distToCurve.Length == 0)
                    {
                        eps = 1e-8;
                    }
                    else
                    {
                        if (sourceCurve != null && sourceCurve.Length > 0) // eine Zielkurve wurde angewählt. Schnitte dürfen jetzt vor dem Ende von iCurve sein
                        //eps = -Math.Abs(distToCurve.Length) / sourceCurve.Length;
                        {
                            eps = -1.0; // egal, Hauptsache auf der Kurve
                        }
                        else
                        {
                            eps = -1e-8;
                        }
                    }
                    for (int i = 0; i < cutPlace.Length; ++i)
                    {
                        if (lowerEnd)
                        { // verlängern nach hinten, der größte Wert, der kleiner Null und ungleich quasi Null
                            if ((cutPlace[i] > param) && (cutPlace[i] < 0.0 - eps))
                            {
                                param = cutPlace[i];
                                k     = i;
                            }
                        }
                        else
                        { // verlängern nach vorne, der kleinste Wert, der größer 1.0 und ungleich quasi 1.0
                            if ((cutPlace[i] < param) && (cutPlace[i] > 1.0 + eps))
                            {
                                param = cutPlace[i];
                                k     = i;
                            }
                        }
                    }
                    if (k >= 0)  // was gefunden
                    {
                        newCurve = iCurve.Clone();
                        if (distToCurve.Length != 0.0)
                        {   // zusätzlich länger oder kürzer machen
                            ICurve targetCurve = sourceCurve;
                            if (targetCurves != null)
                            {
                                targetCurve = targetCurves[k];
                            }
                            Plane pl;
                            if (Curves.GetCommonPlane(iCurve, targetCurve, out pl))
                            {   // muss der Fall sein
                                ICurve2D targetCurve2d = targetCurve.GetProjectedCurve(pl);
                                ICurve2D parl1         = targetCurve2d.Parallel(-distToCurve.Length, true, Precision.eps, 0.0);
                                ICurve2D parl2         = targetCurve2d.Parallel(distToCurve.Length, true, Precision.eps, 0.0);
                                ICurve2D newCurve2d    = newCurve.GetProjectedCurve(pl);
                                // im 2d verlängern
                                if (lowerEnd)
                                {
                                    newCurve2d.StartPoint = newCurve2d.PointAt(param);
                                }
                                else
                                {
                                    newCurve2d.EndPoint = newCurve2d.PointAt(param);
                                }
                                if (lowerEnd)
                                {   // jetzt nur den Vorwärtsfall betrachten
                                    newCurve2d.Reverse();
                                }
                                // betrachte beide Parallelen, wir kennen die Richtungen nicht
                                GeoPoint2DWithParameter[] gp1 = newCurve2d.Intersect(parl1);
                                GeoPoint2DWithParameter[] gp2 = newCurve2d.Intersect(parl2);
                                double bestPar;
                                if (distToCurve.Length > 0)
                                {   // Kurve muss kürzer werden
                                    bestPar = 0.0;
                                    for (int i = 0; i < gp1.Length; i++)
                                    {
                                        if (gp1[i].par2 >= 0 && gp1[i].par2 <= 1 && gp1[i].par1 <1 && gp1[i].par1> bestPar)
                                        {
                                            bestPar = gp1[i].par1;
                                        }
                                    }
                                    for (int i = 0; i < gp2.Length; i++)
                                    {
                                        if (gp2[i].par2 >= 0 && gp2[i].par2 <= 1 && gp2[i].par1 <1 && gp2[i].par1> bestPar)
                                        {
                                            bestPar = gp2[i].par1;
                                        }
                                    }
                                }
                                else
                                {
                                    bestPar = double.MaxValue;
                                    for (int i = 0; i < gp1.Length; i++)
                                    {
                                        if (gp1[i].par2 >= 0 && gp1[i].par2 <= 1 && gp1[i].par1 > 1 && gp1[i].par1 < bestPar)
                                        {
                                            bestPar = gp1[i].par1;
                                        }
                                    }
                                    for (int i = 0; i < gp2.Length; i++)
                                    {
                                        if (gp2[i].par2 >= 0 && gp2[i].par2 <= 1 && gp2[i].par1 > 1 && gp2[i].par1 < bestPar)
                                        {
                                            bestPar = gp2[i].par1;
                                        }
                                    }
                                }
                                // den gefundenen Punkt auf die Kurve setzen
                                if (bestPar > 0 && bestPar < double.MaxValue)
                                {
                                    GeoPoint pp = pl.ToGlobal(newCurve2d.PointAt(bestPar));
                                    param = iCurve.PositionOf(pp); // param ist das eigentliche Ergebnis, welches bei onDone verwendet wird
                                    if (lowerEnd)
                                    {
                                        newCurve.StartPoint = pp;
                                    }
                                    else
                                    {
                                        newCurve.EndPoint = pp;
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (lowerEnd)
                            {
                                newCurve.StartPoint = iCurve.PointAt(param);
                            }
                            else
                            {
                                newCurve.EndPoint = iCurve.PointAt(param);
                            }
                        }
                        (newCurve as IGeoObject).CopyAttributes(iCurve as IGeoObject);
                        //Color backColor = base.Frame.GetColorSetting("Colors.Feedback", Color.DarkGray);
                        //if (newCurve is IColorDef)
                        //    (newCurve as IColorDef).ColorDef = new ColorDef("", backColor);
                        base.ActiveObject = (newCurve as IGeoObject);
                        base.FeedBack.AddSelected(newCurve as IGeoObject);// letzte Linie einfügen
                        return(true);
                    }
                }
            }
            param = 0.0;
            return(false);
        }