예제 #1
0
        public static IBody2 CreateCirclularSheet(this IModeler modeler, Vector3 center, Vector3 vNormal, float radius)
        {
            var surf       = (Surface)modeler.CreatePlanarSurface(center.ToDoubles(), vNormal.ToDoubles());
            var startPoint = center + vNormal.Orthogonal().Unit() * radius;
            var endPoint   = startPoint;
            var arc        =
                (Curve)
                modeler.CreateArc
                    (center.ToDoubles(), vNormal.ToDoubles(), (float)radius, startPoint.ToDoubles(), endPoint.ToDoubles());

            return((IBody2)surf.CreateTrimmedSheet(new[] { arc }));
        }
        public static ICurve CreateTrimmedArc
            (this IModeler modeler, Vector3 center, Vector3 axis, Vector3 startPoint, Vector3 endPoint)
        {
            var radius = (startPoint - center).Length();
            var arc    =
                (Curve)
                modeler.CreateArc
                    (center.ToDoubles(), axis.ToDoubles(), (double)radius, startPoint.ToDoubles(), endPoint.ToDoubles());

            var pp0 = arc.GetClosestPointOn(startPoint.X, startPoint.Y, startPoint.Z).CastArray <double>();
            var pp1 = arc.GetClosestPointOn(endPoint.X, endPoint.Y, endPoint.Z).CastArray <double>();

            return(arc.CreateTrimmedCurve(pp0[3], pp1[3]));
        }
예제 #3
0
        /// <summary>
        /// Creates the cylindrical body
        /// </summary>
        /// <param name="modeler">Pointer to modeler</param>
        /// <param name="center">Center coordinate of cylinder in meters</param>
        /// <param name="axis">Cylinder axis</param>
        /// <param name="radius">Cylinder radius in meters</param>
        /// <param name="height">Cylinder height</param>
        /// <returns>Cylindrical temp body</returns>
        /// <remarks>Use this method instead of built-in <see href="http://help.solidworks.com/2016/english/api/sldworksapi/SolidWorks.Interop.sldworks~SolidWorks.Interop.sldworks.IModeler~CreateBodyFromCyl.html">IModeler::CreateBodyFromCyl</see>
        /// If you need to preserve entity ids as the body generated using the built-in method won't allow to set user id,
        /// which means any reference geometry generated in relation to cylinder entities will become dangling upon rebuild</remarks>
        private IBody2 CreateCylinderBody(Point center, Vector axis, Vector refDir, double radius, double height)
        {
            IMathVector refVec;

            var surf = CreatePlanarSurface(center, axis, refDir, out refVec);

            var radDir = new Vector(refVec.ArrayData as double[]);
            var refPt  = center.Move(radDir, radius);

            var arc = m_Modeler.CreateArc(center.ToArray(), axis.ToArray(), radius, refPt.ToArray(), refPt.ToArray()) as ICurve;

            arc = arc.CreateTrimmedCurve2(refPt.X, refPt.Y, refPt.Z, refPt.X, refPt.Y, refPt.Z);

            var dir = m_MathUtils.CreateVector(axis.ToArray()) as MathVector;

            return(Extrude(surf, new ICurve[] { arc }, dir, height));
        }
        public static IBody2 CreateSemiCirclularSheet
            (this IModeler modeler
            , Vector3 center
            , Vector3 vNormal
            , Vector3 vRef // Horizontal
            , double radius)
        {
            // Should be orthogonal
            Debug.Assert(vRef.Dot(vNormal) < 1e-9);

            var math          = SwAddinBase.Active.Math;
            var centerSw      = center.ToSwMathPoint();
            var vNormalSw     = vNormal.ToSwMathPoint();
            var vNormalOrthSw = vRef.ToSWVector(math).Normalise();

            var centerDbls      = centerSw.ArrayData;
            var vNormalDbls     = vNormalSw.ArrayData;
            var vNormalOrthDbls = vNormalOrthSw.ArrayData;

            var surf = (Surface)modeler.CreatePlanarSurface2(centerDbls, vNormalDbls, vNormalOrthDbls);


            var startPoint = center + radius * vRef.Unit();
            var endPoint   = center - radius * vRef.Unit();

            var startPointDbls = startPoint.ToDoubles();
            var endPointDbls   = endPoint.ToDoubles();


            var arco = modeler.CreateArc
                           (centerDbls, vNormalDbls, radius, startPointDbls, endPointDbls);

            var arc           = (Curve)arco;
            var arcStartPoint = startPoint;
            var arcEndPoint   = endPoint;

            var trimmedArc = arc.CreateTrimmedCurve2(arcStartPoint.X, arcStartPoint.Y, arcStartPoint.Z, arcEndPoint.X, arcEndPoint.Y, arcEndPoint.Z);
            var line       = modeler.CreateTrimmedLine(arcEndPoint, arcStartPoint);

            return((IBody2)surf.CreateTrimmedSheet(new[] { trimmedArc, line }));
        }
        public static IBody2 CreateCirclularSheet
            (this IModeler modeler
            , Vector3 center
            , Vector3 vNormal
            , Vector3 vRef
            , double radius)
        {
            // Should be orthogonal
            Debug.Assert(vRef.Dot(vNormal) < 1e-9);

            var math          = SwAddinBase.Active.Math;
            var centerSw      = center.ToSwMathPoint();
            var vNormalSw     = vNormal.ToSwMathPoint();
            var vNormalOrthSw = vRef.ToSWVector(math).Normalise();

            var centerDbls      = centerSw.ArrayData;
            var vNormalDbls     = vNormalSw.ArrayData;
            var vNormalOrthDbls = vNormalOrthSw.ArrayData;

            var surf = (Surface)modeler.CreatePlanarSurface2(centerDbls, vNormalDbls, vNormalOrthDbls);


            var startPoint = centerSw.AddTs(vNormalOrthSw.ScaleTs(radius));

            var startPointDbls = startPoint.ArrayData;


            var arco = modeler.CreateArc
                           (centerDbls, vNormalDbls, radius, startPointDbls, startPointDbls);

            var arc           = (Curve)arco;
            var arcStartPoint = arc.StartPoint();
            var arcEndPoint   = arc.EndPoint();

            var trimmedArc = arc.CreateTrimmedCurve2(arcStartPoint.X, arcStartPoint.Y, arcStartPoint.Z, arcEndPoint.X, arcEndPoint.Y, arcEndPoint.Z);

            return((IBody2)surf.CreateTrimmedSheet(new[] { trimmedArc }));
        }
        public Body2 CreateOffset(IEnumerable <ISketchSegment> segs, double offset,
                                  double innerRadius, double outerRadius, bool reverse)
        {
            if (!segs.Any())
            {
                throw new UserException("No segments provided");
            }

            var curves = new List <ICurve>();

            var transform = segs.First().GetSketch().ModelToSketchTransform.IInverse();

            foreach (var skSeg in segs)
            {
                if (!skSeg.ConstructionGeometry)
                {
                    var curve = skSeg.GetTrimmedCurve();
                    curve.ApplyTransform(transform);
                    curves.Add(curve);
                }
            }

            var wireBody = m_Modeler.CreateWireBody(curves.ToArray(),
                                                    (int)swCreateWireBodyOptions_e.swCreateWireBodyByDefault);

            if (wireBody == null)
            {
                throw new UserException("Segments must be connected and form chain");
            }

            var offsetNormal = m_MathUtils.CreateVector(new double[] { 0, 0, reverse ? -1 : 1 }) as MathVector;

            offsetNormal = offsetNormal.MultiplyTransform(transform) as MathVector;

            var offsetBody = wireBody.OffsetPlanarWireBody(offset, offsetNormal,
                                                           (int)swOffsetPlanarWireBodyOptions_e.swOffsetPlanarWireBodyOptions_GapFillRound);

            if (offsetBody == null)
            {
                throw new UserException("Failed to offset the body. Try change the parameters");
            }

            var offsetCurves = new List <ICurve>();

            var linearEdges = (offsetBody.GetEdges() as object[]).Cast <IEdge>()
                              .Where(e => e.IGetCurve().IsLine()).ToArray();

            var findFarMostPointFunc = new Func <IEdge, double[], double[]>(
                (edge, startPt) =>
            {
                var startVert = edge.IGetStartVertex().GetPoint() as double[];
                var endVert   = edge.IGetEndVertex().GetPoint() as double[];

                var startDist = MathUtils.GetDistanceBetweenPoints(startVert, startPt);
                var endDist   = MathUtils.GetDistanceBetweenPoints(endVert, startPt);

                if (startDist > endDist)
                {
                    return(startVert);
                }
                else
                {
                    return(endVert);
                }
            });

            double[] prevEndPt = null;

            for (int i = 0; i < linearEdges.Length - 1; i++)
            {
                var firstEdge  = linearEdges[i];
                var secondEdge = linearEdges[i + 1];

                var interPt = firstEdge.IGetCurve().GetIntersectionWithLinearCurve(secondEdge.IGetCurve());

                //TODO: check parallel curves

                var firstStartPt  = findFarMostPointFunc.Invoke(firstEdge, interPt);
                var secondStartPt = findFarMostPointFunc.Invoke(secondEdge, interPt);

                var firstDir = new double[]
                {
                    firstStartPt[0] - interPt[0],
                    firstStartPt[1] - interPt[1],
                    firstStartPt[2] - interPt[2]
                };

                var secondDir = new double[]
                {
                    secondStartPt[0] - interPt[0],
                    secondStartPt[1] - interPt[1],
                    secondStartPt[2] - interPt[2]
                };

                var radius = outerRadius;

                if (i % 2 == 0)
                {
                    radius = innerRadius;
                }

                var firstVec  = m_MathUtils.CreateVector(firstDir) as IMathVector;
                var secondVec = m_MathUtils.CreateVector(secondDir) as IMathVector;

                var ang = firstVec.GetAngle(secondVec);

                var dist = radius / Math.Sin(ang / 2);

                var bisecVec = firstVec.Normalise().Add(secondVec.Normalise()) as IMathVector;

                var centerPt = m_MathUtils.CreatePoint(interPt) as IMathPoint;
                centerPt = centerPt.MoveAlongVector(bisecVec, dist);

                var centrPtCoord = centerPt.ArrayData as double[];

                var createLineFunc = new Func <double[], double[], Curve>(
                    (s, e) =>
                {
                    var line = m_Modeler.CreateLine(s,
                                                    new double[] { e[0] - s[0], e[1] - s[1], e[2] - s[2] }) as Curve;
                    line = line.CreateTrimmedCurve2(s[0], s[1], s[2], e[0], e[1], e[2]);
                    return(line);
                });

                var firstCurve = firstEdge.IGetCurve().GetBaseCurve();

                var firstEndPt = firstCurve.GetClosestPointOn(
                    centrPtCoord[0], centrPtCoord[1], centrPtCoord[2]) as double[];

                firstEndPt = new double[] { firstEndPt[0], firstEndPt[1], firstEndPt[2] };

                if (prevEndPt != null)
                {
                    firstStartPt = prevEndPt;
                }

                firstCurve = createLineFunc.Invoke(firstStartPt, firstEndPt);

                offsetCurves.Add(firstCurve);

                var secondCurve = secondEdge.IGetCurve().GetBaseCurve();
                var secondEndPt = secondCurve.GetClosestPointOn(centrPtCoord[0], centrPtCoord[1], centrPtCoord[2]) as double[];
                secondEndPt = new double[] { secondEndPt[0], secondEndPt[1], secondEndPt[2] };

                var isLast = i == linearEdges.Length - 2;

                if (isLast)
                {
                    secondCurve = createLineFunc.Invoke(secondStartPt, secondEndPt);

                    offsetCurves.Add(secondCurve);
                }

                ICurve filletCurve = null;

                var arcDir = (secondVec.Cross(firstVec) as IMathVector).ArrayData as double[];

                filletCurve = m_Modeler.CreateArc(centrPtCoord, arcDir,
                                                  radius, firstEndPt, secondEndPt) as ICurve;

                filletCurve = filletCurve.CreateTrimmedCurve2(firstEndPt[0], firstEndPt[1], firstEndPt[2],
                                                              secondEndPt[0], secondEndPt[1], secondEndPt[2]);

                prevEndPt = secondEndPt;

                offsetCurves.Add(filletCurve);
            }

            var offsetFilletBody = m_Modeler.CreateWireBody(offsetCurves.ToArray(),
                                                            (int)swCreateWireBodyOptions_e.swCreateWireBodyByDefault);

            if (offsetFilletBody == null)
            {
                throw new UserException("Failed to generate the chain from offset result");
            }

            offsetBody = null;
            GC.Collect();

            return(offsetFilletBody);
        }