public static double[] Cross(this IMathUtility math, double[] a, double[] b) { var v0 = (IMathVector)math.CreateVector(a); var v1 = (IMathVector)math.CreateVector(b); return((double[])((IMathVector)v0.Cross(v1)).ArrayData); }
public double[] TransformVector(double[] dir, IMathTransform transform) { IMathVector vec = m_MathUtils.CreateVector(dir) as IMathVector; vec = vec.MultiplyTransform(transform) as IMathVector; return(vec.ArrayData as double[]); }
/// <summary> /// Sets the direction of the macro feature dimension. /// </summary> /// <param name="dim">Pointer to dimension. Usually retrieved from <see cref="DimensionData.Dimension"/></param> /// <param name="originPt">Dimension starting attach point</param> /// <param name="dir">Direction of the dimension</param> /// <param name="length">Length of the dimension (usually equal to its value)</param> /// <param name="extDir">Optional direction of extension line</param> /// <remarks>Call this method within the <see cref="CodeStack.SwEx.MacroFeature.MacroFeatureEx{TParams}.OnSetDimensions(ISldWorks, IModelDoc2, IFeature, DimensionDataCollection, TParams)"/></remarks> public static void SetDirection(this IDimension dim, Point originPt, Vector dir, double length, Vector extDir = null) { var dimDirVec = m_MathUtils.CreateVector(dir.ToArray()) as MathVector; var startPt = m_MathUtils.CreatePoint(originPt.ToArray()) as IMathPoint; var endPt = m_MathUtils.CreatePoint(originPt.Move(dir, length).ToArray()) as IMathPoint; var refPts = new IMathPoint[] { startPt, endPt, m_MathUtils.CreatePoint(new double[3]) as IMathPoint }; if (extDir == null) { var yVec = new Vector(0, 1, 0); if (dir.IsSame(yVec)) { extDir = new Vector(1, 0, 0); } else { extDir = yVec.Cross(dir); } } var extDirVec = m_MathUtils.CreateVector(extDir.ToArray()) as MathVector; dim.DimensionLineDirection = dimDirVec; dim.ExtensionLineDirection = extDirVec; dim.ReferencePoints = refPts; }
public static MathTransform CreateTranslationTransform (this ITriadManipulator m, swTriadManipulatorControlPoints_e h, IMathUtility math, double value) { MathVector translVector = null; switch (h) { case swTriadManipulatorControlPoints_e.swTriadManipulatorOrigin: break; case swTriadManipulatorControlPoints_e.swTriadManipulatorXAxis: translVector = (MathVector)math.CreateVector(new[] {value, 0, 0}); break; case swTriadManipulatorControlPoints_e.swTriadManipulatorYAxis: translVector = (MathVector)math.CreateVector(new[] {0, value, 0}); break; case swTriadManipulatorControlPoints_e.swTriadManipulatorZAxis: translVector = (MathVector)math.CreateVector(new[] {0, 0, value}); break; case swTriadManipulatorControlPoints_e.swTriadManipulatorXYPlane: break; case swTriadManipulatorControlPoints_e.swTriadManipulatorYZPlane: break; case swTriadManipulatorControlPoints_e.swTriadManipulatorZXPlane: break; default: throw new ArgumentOutOfRangeException(nameof(h), h, null); } if (translVector == null) return null; return math.ComposeTransform(m.XAxis, m.YAxis, m.ZAxis, translVector, 1.0); }
private bool IsHole(IFace2 face) { ISurface surf = face.IGetSurface(); if (surf.IsCylinder()) { double[] uvBounds = face.GetUVBounds() as double[]; double[] evalData = surf.Evaluate((uvBounds[1] - uvBounds[0]) / 2, (uvBounds[3] - uvBounds[2]) / 2, 1, 1) as double[]; double[] pt = new double[] { evalData[0], evalData[1], evalData[2] }; int sense = face.FaceInSurfaceSense() ? 1 : -1; double[] norm = new double[] { evalData[evalData.Length - 3] * sense, evalData[evalData.Length - 2] * sense, evalData[evalData.Length - 1] * sense }; double[] cylParams = surf.CylinderParams as double[]; double[] orig = new double[] { cylParams[0], cylParams[1], cylParams[2] }; double[] dir = new double[] { pt[0] - orig[0], pt[1] - orig[1], pt[2] - orig[2] }; IMathUtility mathUtils = swApp.IGetMathUtility(); IMathVector dirVec = mathUtils.CreateVector(dir) as IMathVector; IMathVector normVec = mathUtils.CreateVector(norm) as IMathVector; return(GetAngle(dirVec, normVec) < Math.PI / 2); } else { throw new NotSupportedException("Only cylindrical face is supported"); } }
public Vector TransformVector(Vector vector, TransformationMaxtrix transform) { IMathVector vec = m_MathUtils.CreateVector(vector.ToArray()) as IMathVector; var swTransform = m_MathUtils.CreateTransFormTransformationMaxtrix(transform); vec = vec.MultiplyTransform(swTransform) as IMathVector; return(new Vector(vec.ArrayData as double[])); }
private IBody2 CreateBodyFromSketchContour(IModeler modeler, IMathUtility mathUtils, ISketchContour skCont, double height, bool midPlane) { var sketch = skCont.Sketch; if (sketch.Is3D()) { throw new UserErrorException("Only 2D sketches are supported"); } var transform = sketch.ModelToSketchTransform.IInverse(); var boundary = (skCont.GetEdges() as object[]) .Cast <IEdge>() .Select(e => { var curve = e.IGetCurve().ICopy(); //must copy curve otherwise CreateTrimmedSheet4 is failing return(curve); }).ToArray(); var centerPt = mathUtils.CreatePoint(new double[] { 0, 0, 0 }) as IMathPoint; var dirVec = mathUtils.CreateVector(new double[] { 0, 0, 1 }) as IMathVector; var refVec = mathUtils.CreateVector(new double[] { 1, 0, 0 }) as IMathVector; centerPt = centerPt.IMultiplyTransform(transform); dirVec = dirVec.IMultiplyTransform(transform); refVec = refVec.IMultiplyTransform(transform); if (midPlane) { var dirRevVec = new Vector(dirVec.ArrayData as double[]); dirRevVec.Scale(-1); var origPt = new Point(centerPt.ArrayData as double[]); MoveCurves(origPt, dirRevVec, height / 2, boundary, mathUtils); centerPt = mathUtils.CreatePoint(origPt.Move(dirRevVec, height / 2).ToArray()) as IMathPoint; } var surf = modeler.CreatePlanarSurface2(centerPt.ArrayData, dirVec.ArrayData, refVec.ArrayData) as ISurface; var sheetBody = surf.CreateTrimmedSheet4(boundary, true) as Body2; if (sheetBody == null) { throw new NullReferenceException("Failed to create trimmed sheet from surface region"); } var solidBody = modeler.CreateExtrudedBody(sheetBody, dirVec as MathVector, height) as IBody2; var faces = (solidBody.GetFaces() as object[]).Cast <IFace2>().ToArray(); return(modeler.CreateSheetFromFaces(faces)); }
private double[] GetDirection(IModelDoc2 model, object inputObj) { if (inputObj is IFace2) { ISurface surf = (inputObj as IFace2).GetSurface() as ISurface; if (surf.IsCylinder()) { double[] cylParams = surf.CylinderParams as double[]; return(new double[] { cylParams[3], cylParams[4], cylParams[5] }); } } else if (inputObj is IFeature) { IRefPlane refPlane = (inputObj as IFeature).GetSpecificFeature2() as IRefPlane; if (refPlane != null) { IMathUtility mathUtils = swApp.GetMathUtility() as IMathUtility; IMathVector vec = mathUtils.CreateVector(new double[] { 0, 0, 1 }) as IMathVector; vec = vec.MultiplyTransform(refPlane.Transform) as IMathVector; return(vec.ArrayData as double[]); } } throw new NullReferenceException("Failed to find the direction. Please select cylindrical face or plane"); }
/// <summary> /// 获取基准面的法向量 /// </summary> /// <param name="plane"></param> /// <param name="math"></param> /// <returns></returns> public static double[] Normal(this IRefPlane plane, IMathUtility math) { var transform = plane.Transform; var normalWorld = math.CreateVector(new[] { 0.0, 0, 1 }) as MathVector; return(((MathTransform)normalWorld.MultiplyTransform(transform)).ArrayData as double[]); }
//TODO: calculate height based on bounding box private IBody2 CreateBodyFromSketchContour(IModeler modeler, IMathUtility mathUtils, ISketchContour skCont, double height = 1000) { var sketch = skCont.Sketch; if (sketch.Is3D()) { throw new UserErrorException("Only 2D sketches are supported"); } var transform = sketch.ModelToSketchTransform.IInverse(); var boundary = (skCont.GetEdges() as object[]) .Cast <IEdge>() .Select(e => { var curve = e.IGetCurve().ICopy(); //must copy curve otherwise CreateTrimmedSheet4 is failing return(curve); }).ToArray(); var centerPt = mathUtils.CreatePoint(new double[] { 0, 0, 0 }) as IMathPoint; var dirVec = mathUtils.CreateVector(new double[] { 0, 0, 1 }) as IMathVector; var refVec = mathUtils.CreateVector(new double[] { 1, 0, 0 }) as IMathVector; centerPt = centerPt.IMultiplyTransform(transform); dirVec = dirVec.IMultiplyTransform(transform); refVec = refVec.IMultiplyTransform(transform); var surf = modeler.CreatePlanarSurface2(centerPt.ArrayData, dirVec.ArrayData, refVec.ArrayData) as ISurface; var sheetBody = surf.CreateTrimmedSheet4(boundary, true) as Body2; if (sheetBody == null) { throw new NullReferenceException("Failed to create trimmed sheet from surface region"); } var firstBody = modeler.CreateExtrudedBody(sheetBody, dirVec as MathVector, height * 0.9 / 2) as IBody2; var secondBody = modeler.CreateExtrudedBody(sheetBody, dirVec.IScale(-1), height * 0.9 / 2) as IBody2; int err; var res = firstBody.Operations2((int)swBodyOperationType_e.SWBODYADD, secondBody, out err) as object[]; return(res.First() as IBody2); }
private void ExportToStl(string filePath, float[] tessTriangs, float[] tessNorms, double[] transformMatrix) { IMathUtility mathUtils = swApp.IGetMathUtility(); IMathTransform transform = (mathUtils.CreateTransform(transformMatrix) as IMathTransform).IInverse(); using (FileStream fileStream = File.Create(filePath)) { using (BinaryWriter writer = new BinaryWriter(fileStream)) { byte[] header = new byte[80]; writer.Write(header); uint triangsCount = (uint)tessTriangs.Length / 9; writer.Write(triangsCount); for (uint i = 0; i < triangsCount; i++) { float normalX = tessNorms[i * 9]; float normalY = tessNorms[i * 9 + 1]; float normalZ = tessNorms[i * 9 + 2]; IMathVector mathVec = mathUtils.CreateVector( new double[] { normalX, normalY, normalZ }) as IMathVector; mathVec = mathVec.MultiplyTransform(transform) as IMathVector; double[] vec = mathVec.ArrayData as double[]; writer.Write((float)vec[0]); writer.Write((float)vec[1]); writer.Write((float)vec[2]); for (uint j = 0; j < 3; j++) { float vertX = tessTriangs[i * 9 + j * 3]; float vertY = tessTriangs[i * 9 + j * 3 + 1]; float vertZ = tessTriangs[i * 9 + j * 3 + 2]; IMathPoint mathPt = mathUtils.CreatePoint( new double[] { vertX, vertY, vertZ }) as IMathPoint; mathPt = mathPt.MultiplyTransform(transform) as IMathPoint; double[] pt = mathPt.ArrayData as double[]; writer.Write((float)pt[0]); writer.Write((float)pt[1]); writer.Write((float)pt[2]); } ushort atts = 0; writer.Write(atts); } } } }
/// <param name="refDir">Input or output direction of ref axis which corresponds to X. Specify null to auto calculate</param> private IBody2 CreateBoxBody(Point center, Vector dir, Vector refDir, double width, double length, double height) { IMathVector refVec; var surf = CreatePlanarSurface(center, dir, refDir, out refVec); var xVec = new Vector(refVec.ArrayData as double[]); var yVec = xVec.Cross(dir); var getPointFunc = new Func <double, double, Point>( (x, y) => { var pt = center.Move(xVec, x); pt = pt.Move(yVec, y); return(pt); }); var corners = new Point[] { getPointFunc.Invoke(-width / 2, -length / 2), getPointFunc.Invoke(-width / 2, length / 2), getPointFunc.Invoke(width / 2, length / 2), getPointFunc.Invoke(width / 2, -length / 2) }; var createCurveFunc = new Func <Point, Point, ICurve>((Point p1, Point p2) => { var curve = m_Modeler.CreateLine(p1.ToArray(), (p1 - p2).ToArray()) as ICurve; curve = curve.CreateTrimmedCurve2(p1.X, p1.Y, p1.Z, p2.X, p2.Y, p2.Z); return(curve); }); var curves = new ICurve[] { createCurveFunc.Invoke(corners[0], corners[1]), createCurveFunc.Invoke(corners[1], corners[2]), createCurveFunc.Invoke(corners[2], corners[3]), createCurveFunc.Invoke(corners[3], corners[0]) }; var zVec = m_MathUtils.CreateVector(dir.ToArray()) as MathVector; return(Extrude(surf, curves, zVec, height)); }
/// <summary> /// Find the vector in model space from the point to the viewers eye. /// </summary> /// <param name="modelView"></param> /// <param name="mathUtility"></param> /// <param name="p"></param> /// <returns></returns> private static MathVector ViewVector(IModelView modelView, IMathUtility mathUtility, IMathPoint p) { var world2screen = modelView.Transform; var pScreen = (MathPoint) p.MultiplyTransform(world2screen); var vv = (IMathVector) mathUtility.CreateVector(new[] {0.0, 0, 1}); var pScreenUp = (MathPoint) pScreen.AddVector(vv); var pWorldDelta = (MathPoint) pScreenUp.MultiplyTransform((MathTransform) world2screen.Inverse()); var viewVector = (MathVector) p.Subtract(pWorldDelta); return viewVector; }
/// <summary> /// 创建变换矩阵 /// </summary> /// <param name="m"></param> /// <param name="h"></param> /// <param name="math"></param> /// <param name="value"></param> /// <returns></returns> public static MathTransform CreateTranslationTransform (this ITriadManipulator m, swTriadManipulatorControlPoints_e h, IMathUtility math, double value) { MathVector translVector = null; switch (h) { case swTriadManipulatorControlPoints_e.swTriadManipulatorOrigin: break; case swTriadManipulatorControlPoints_e.swTriadManipulatorXAxis: translVector = (MathVector)math.CreateVector(new[] { value, 0, 0 }); break; case swTriadManipulatorControlPoints_e.swTriadManipulatorYAxis: translVector = (MathVector)math.CreateVector(new[] { 0, value, 0 }); break; case swTriadManipulatorControlPoints_e.swTriadManipulatorZAxis: translVector = (MathVector)math.CreateVector(new[] { 0, 0, value }); break; case swTriadManipulatorControlPoints_e.swTriadManipulatorXYPlane: break; case swTriadManipulatorControlPoints_e.swTriadManipulatorYZPlane: break; case swTriadManipulatorControlPoints_e.swTriadManipulatorZXPlane: break; default: throw new ArgumentOutOfRangeException(nameof(h), h, null); } if (translVector == null) { return(null); } return(math.ComposeTransform(m.XAxis, m.YAxis, m.ZAxis, translVector, 1.0)); }
/// <summary> /// Find the vector in model space from the point to the viewers eye. /// </summary> /// <param name="modelView"></param> /// <param name="mathUtility"></param> /// <param name="p"></param> /// <returns></returns> private static MathVector ViewVector(IModelView modelView, IMathUtility mathUtility, IMathPoint p) { var world2screen = modelView.Transform; var pScreen = (MathPoint)p.MultiplyTransform(world2screen); var vv = (IMathVector)mathUtility.CreateVector(new[] { 0.0, 0, 1 }); var pScreenUp = (MathPoint)pScreen.AddVector(vv); var pWorldDelta = (MathPoint)pScreenUp.MultiplyTransform((MathTransform)world2screen.Inverse()); var viewVector = (MathVector)p.Subtract(pWorldDelta); return(viewVector); }
public bool TryProjectPoint(Point point, Vector direction, out Point projectedPoint) { var dirVec = (MathVector)m_MathUtils.CreateVector(direction.ToArray()); var startPt = (MathPoint)m_MathUtils.CreatePoint(point.ToArray()); var resPt = Surface.GetProjectedPointOn(startPt, dirVec); if (resPt != null) { projectedPoint = new Point((double[])resPt.ArrayData); return(true); } else { projectedPoint = null; return(false); } }
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); }
public static MathVector Vector(this IMathUtility m, double[] v) { return((MathVector)m.CreateVector(v)); }