public static SurfaceEvaluation ProjectPointToShell(this Body body, Point point, out Face face) { Debug.Assert(body != null); face = null; double leastDistSquared = double.MaxValue; SurfaceEvaluation leastEval = null; SurfaceEvaluation eval = null; foreach (Face testFace in body.Faces) { eval = testFace.ProjectPoint(point); double distSquared = (eval.Point - point).MagnitudeSquared(); if (distSquared == Math.Min(leastDistSquared, distSquared)) { face = testFace; leastEval = eval; leastDistSquared = distSquared; } } Debug.Assert(face != null); Debug.Assert(leastEval != null); return(leastEval); }
public static Plane GetPlaneCenteredOnFace(DesignFace face) { PointUV centerUV = face.Shape.BoxUV.Center; SurfaceEvaluation evaluation = face.Shape.Geometry.Evaluate(centerUV); Point point = evaluation.Point; Direction dirU = (face.Shape.Geometry.Evaluate(PointUV.Create(centerUV.U + 0.001, centerUV.V)).Point.Vector - face.Shape.Geometry.Evaluate(PointUV.Create(centerUV.U - 0.001, centerUV.V)).Point.Vector).Direction; Direction dirVTemp = Direction.Cross(evaluation.Normal, dirU); if (face.Shape.Geometry as Plane != null) { if (!Accuracy.Equals(Vector.Dot(dirU.UnitVector, Direction.DirZ.UnitVector), 0.0)) // if our U direction has a Z component, the text might be slanted { if (Accuracy.Equals(Vector.Dot(dirVTemp.UnitVector, Direction.DirZ.UnitVector), 0.0)) // if our V direction has no Z component, use it { dirU = dirVTemp; } } } if (face.Shape.Geometry as Cylinder != null) { dirU = dirVTemp; } dirVTemp = Direction.Cross(evaluation.Normal, dirU); if (Vector.Dot(dirVTemp.UnitVector, Direction.DirZ.UnitVector) < 0.0) // Prevent upside-down notes { dirU = -dirU; } return(Plane.Create(Frame.Create(point, dirU, Direction.Cross(evaluation.Normal, dirU)))); }
protected override bool OnClickStart(ScreenPoint cursorPos, Line cursorRay) { var iDesignFace = InteractionContext.Preselection as IDesignFace; if (iDesignFace == null) { return(false); } SurfaceEvaluation eval = iDesignFace.Shape.GetSingleRayIntersection(cursorRay); if (eval == null) { return(false); } double defaultHeight = 0.02; WriteBlock.ExecuteTask("Create Oscillator", () => { OscillatorPart.Create(HandleTypeEnum.Shaft, iDesignFace, eval.Param, defaultHeight, 0); OscillatorPart.Create(HandleTypeEnum.Base, iDesignFace, eval.Param, defaultHeight, 0); OscillatorPart.Create(HandleTypeEnum.Start, iDesignFace, eval.Param, defaultHeight, 0); OscillatorPart.Create(HandleTypeEnum.End, iDesignFace, eval.Param, defaultHeight, 0); }); return(false); }
private static ToolEvaluation Evaluate(PointUV pointUV, FaceToolPath toolPath) { SurfaceEvaluation eval = toolPath.Surface.Evaluate(pointUV); Point surfacePoint = eval.Point; Direction surfaceNormal = toolPath.IsNormalFlipped ? -eval.Normal : eval.Normal; return(new ToolEvaluation(surfacePoint + toolPath.CuttingTool.Radius * surfaceNormal, surfacePoint, surfaceNormal)); }
public SpiralStrategy(Plane plane, ICollection <ITrimmedCurve> curves, double initialOffset, ToolPath toolPath) { this.plane = plane; this.curves = curves; this.toolPath = toolPath; this.tool = toolPath.CuttingTool; this.parameters = toolPath.CuttingParameters; this.initialOffset = initialOffset; SurfaceEvaluation eval = plane.Evaluate(PointUV.Origin); centerOffset = eval.Normal * tool.Radius; tip = -toolPath.Csys.DirZ * tool.Radius; closeClearanceVector = toolPath.Csys.DirZ * tool.Radius; }
protected override bool OnDragStart(ScreenPoint cursorPos, Line cursorRay) { //SelectionTypes = new Type[0]; // disable preselection while dragging OscillatorPart oscillatorPart = OscillatorPart.GetWrapper(InteractionContext.Preselection as CustomObject); if (oscillatorPart == null) { return(false); } Point?pointOnCustom = InteractionContext.PreselectionPoint; if (pointOnCustom == null) { oscillatorPart = null; return(false); } switch (oscillatorPart.HandleType) { case HandleTypeEnum.Base: var iDesignFace = InteractionContext.Preselection as IDesignFace; if (iDesignFace == null) { return(false); } SurfaceEvaluation eval = iDesignFace.Shape.GetSingleRayIntersection(cursorRay); if (eval == null) { return(false); } oscillatorIDesignFace = iDesignFace; oscillatorPointUV = eval.Param; StatusText = "Drag to move the oscillator."; break; case HandleTypeEnum.Start: case HandleTypeEnum.End: break; } return(false); }
static Frame?GetFrameFromPoint(IDesignFace designFace, Point startPoint) { SurfaceEvaluation evaluation = designFace.Shape.Geometry.ProjectPoint(startPoint); Point point = evaluation.Point; PointUV pointUV = evaluation.Param; Direction dirU = (designFace.Shape.Geometry.Evaluate(PointUV.Create(pointUV.U + 0.0001, pointUV.V)).Point.Vector - designFace.Shape.Geometry.Evaluate(PointUV.Create(pointUV.U - 0.0001, pointUV.V)).Point.Vector).Direction; Direction dirV = Direction.Cross(evaluation.Normal, dirU); Frame frame = Frame.Create(point, dirU, dirV); if (designFace.Shape.IsReversed) { return(Frame.Create(frame.Origin, -frame.DirX, frame.DirY)); } return(frame); }
static void FaceCenter_Executing(object sender, EventArgs e) { Window activeWindow = Window.ActiveWindow; ICollection <IDesignFace> iDesignFaces = activeWindow.GetAllSelectedIDesignFaces(); if (iDesignFaces.Count == 0) { return; } Part parent = activeWindow.ActiveContext.Context as Part; if (parent == null) { return; } Part part = Part.Create(parent.Document, "Face Centers"); Component component = Component.Create(parent, part); foreach (IDesignFace iDesignFace in iDesignFaces) { List <Point> points = new List <Point>(); foreach (IDesignEdge iDesignEdge in iDesignFace.Edges) { points.Add(iDesignEdge.Shape.StartPoint); points.Add(iDesignEdge.Shape.EndPoint); } Point center = points.Average(); SurfaceEvaluation surfaceEvaluation = iDesignFace.Shape.ProjectPoint(center); center = surfaceEvaluation.Point; if (isCreatingSpheres) { ShapeHelper.CreateSphere(center, cylinderDiameter, part); } if (isCreatingCylinders) { ShapeHelper.CreateCylinder(center + surfaceEvaluation.Normal * cylinderDiameter, center - surfaceEvaluation.Normal * cylinderDiameter, cylinderDiameter, part); } } }
protected override bool OnMouseMove(ScreenPoint cursorPos, Line cursorRay, MouseButtons button) { if (button != MouseButtons.None) { return(false); } IDocObject preselection = InteractionContext.Preselection; IDesignFace iDesignFace = null; OscillatorPart existingOscillatorHandle = OscillatorPart.GetWrapper(preselection as CustomObject); if (existingOscillatorHandle != null) { iDesignFace = existingOscillatorHandle.IDesignFace; } if (iDesignFace == null) { iDesignFace = preselection as DesignFace; } if (iDesignFace == null) // selection filtering is not applied if you (pre)select in the tree { return(false); } SurfaceEvaluation eval = iDesignFace.Shape.GetSingleRayIntersection(cursorRay); if (eval == null) { return(false); } Rendering = Graphic.Create(null, null, OscillatorPart.GetGraphics(iDesignFace, eval.Param, 0.05, 0, HandleTypeEnum.All)); return(false); // if we return true, the preselection won't update }
public static ICollection <Graphic> GetGraphics(IDesignFace iDesignFace, PointUV pointUV, double span, double position, HandleTypeEnum handleType) { Debug.Assert(iDesignFace != null); Window activeWindow = Window.ActiveWindow; var graphics = new List <Graphic>(); var primitives = new List <Primitive>(); SurfaceEvaluation eval = iDesignFace.Shape.Geometry.Evaluate(pointUV); Point point = eval.Point; Direction normal = eval.Normal; double pixelSize = activeWindow.ActiveContext.GetPixelSize(point); double shaftDiameter = 4 * pixelSize; double handleDiameter = 8 * pixelSize; double handleHeight = 4 * pixelSize; Point startPoint = point - (normal * (span * (position + 1) / 2 - handleHeight)); Point endPoint = startPoint + normal * (span + 2 * handleHeight); Vector handleHalfThickness = normal * handleHeight / 2; bool isDrawingAll = handleType == HandleTypeEnum.All; var mesh = new List <Primitive>(); var style = new GraphicStyle { EnableDepthBuffer = true, LineColor = Color.DimGray, LineWidth = 1, FillColor = Color.DimGray }; switch (handleType) { case HandleTypeEnum.All: case HandleTypeEnum.Shaft: mesh.AddRange(ShapeHelper.CreateCylinderMesh(startPoint, endPoint, shaftDiameter, 8)); graphics.Add(Graphic.Create(style, mesh)); if (isDrawingAll) { goto case HandleTypeEnum.Base; } else { break; } case HandleTypeEnum.Base: mesh.AddRange(ShapeHelper.CreateCylinderMesh(point - handleHalfThickness, point + handleHalfThickness, handleDiameter, 12)); style.LineColor = Color.DodgerBlue; style.FillColor = Color.DodgerBlue; graphics.Add(Graphic.Create(style, mesh)); if (isDrawingAll) { goto case HandleTypeEnum.Start; } else { break; } case HandleTypeEnum.Start: mesh.AddRange(ShapeHelper.CreateCylinderMesh(startPoint - handleHalfThickness, startPoint + handleHalfThickness, handleDiameter, 12)); style.LineColor = Color.DarkViolet; style.FillColor = Color.DarkViolet; graphics.Add(Graphic.Create(style, mesh)); if (isDrawingAll) { goto case HandleTypeEnum.End; } else { break; } case HandleTypeEnum.End: mesh.AddRange(ShapeHelper.CreateCylinderMesh(endPoint - handleHalfThickness, endPoint + handleHalfThickness, handleDiameter, 12)); style.LineColor = Color.DarkViolet; style.FillColor = Color.DarkViolet; graphics.Add(Graphic.Create(style, mesh)); break; } return(graphics); }
protected override void OnExecute(Command command, ExecutionContext context, System.Drawing.Rectangle buttonRect) { base.OnExecute(command, context, buttonRect); Window activeWindow = Window.ActiveWindow; Part activePart = (activeWindow.Scene as Part); Layer tabLayer = NoteHelper.CreateOrGetLayer(activeWindow.ActiveContext.Context.Document, "Tabs", System.Drawing.Color.Fuchsia); IDesignEdge iDesignEdge = activeWindow.ActiveContext.SingleSelection as IDesignEdge; if (iDesignEdge == null) { return; } if (iDesignEdge.Faces.Count != 1) { return; } IDesignFace iDesignFace = null; foreach (IDesignFace testFace in iDesignEdge.Faces) { iDesignFace = testFace; } Debug.Assert(iDesignFace != null); Point startPoint = iDesignEdge.Shape.StartPoint; Point endPoint = iDesignEdge.Shape.EndPoint; if (areTabsFlipped) { Point tempPoint = startPoint; startPoint = endPoint; endPoint = tempPoint; } SurfaceEvaluation surfEval = iDesignFace.Shape.ProjectPoint(startPoint); Direction faceNormal = surfEval.Normal; Point midpoint = startPoint + (endPoint - startPoint) / 2; Double edgeLength = iDesignEdge.Shape.Length; Direction xDir = (endPoint - startPoint).Direction; List <Window> tabWindows = null; string tabFile = string.Empty; if (!isTabStartSlot) { tabFile = @"C:\Users\bcr.SPACECLAIM\Documents\Models\Dodecahedron Foldcrease\Tab-Circle-Male.scdoc"; } else { tabFile = @"C:\Users\bcr.SPACECLAIM\Documents\Models\Dodecahedron Foldcrease\Tab-Circle-Female.scdoc"; } try { tabWindows = new List <Window>(Document.Open(tabFile, ImportOptions.Create())); } catch (Exception exception) { System.Windows.Forms.MessageBox.Show(SpaceClaim.Api.V10.Application.MainWindow, exception.Message); } DesignBody tabDesignBody = null; foreach (DesignBody testBody in (tabWindows[0].Scene as Part).Bodies) { tabDesignBody = testBody; } Debug.Assert(tabDesignBody != null); tabDesignBody = DesignBody.Create(activePart, "tab", tabDesignBody.Shape.Body.Copy()); foreach (Window window in tabWindows) { window.Delete(); } Matrix scale = Matrix.CreateScale(edgeLength / 0.02, Point.Origin); Matrix trans = Matrix.CreateMapping(Frame.Create(midpoint, xDir, Direction.Cross(faceNormal, xDir))); tabDesignBody.Transform(trans * scale); tabDesignBody.Layer = tabLayer; }
// hardwired to place on about inch-spaced points // Edge-only for now -- See EO comments static void MakeTabs_Executing(object sender, EventArgs e) { Window activeWindow = Window.ActiveWindow; Layer tabLayer = NoteHelper.CreateOrGetLayer(activeWindow.ActiveContext.Context.Document, "Tabs", System.Drawing.Color.Fuchsia); ICollection <ITrimmedCurve> trimmedCurves = AddInHelper.GetITrimmedCurvesOfSelectedTopology(activeWindow); // quantize with lines to points separated by approx targetDistance; TrimmedCurveChain curveChain = new TrimmedCurveChain(trimmedCurves); Point lastPoint = curveChain.Curves[0].StartPoint; double tolerance = 0.2 * inches; double targetDistance = 1 * inches; trimmedCurves = new List <ITrimmedCurve>(); Dictionary <ITrimmedCurve, Direction> OriginalNormals = new Dictionary <ITrimmedCurve, Direction>(); double extraLength = 0; foreach (OrientedTrimmedCurve curve in curveChain.Curves) { Point point = curve.EndPoint; if (Math.Abs((lastPoint - point).Magnitude - targetDistance) > tolerance) { extraLength += (lastPoint - point).Magnitude; continue; } CurveSegment curveSegment = null; // if (extraLength == 0) curveSegment = CurveSegment.Create(lastPoint, point); // else // curveSegment = CurveSegment.Create(point - (lastPoint - point).Direction * ((lastPoint - point).Magnitude + extraLength), point); trimmedCurves.Add(curveSegment); Edge edge = curve.TrimmedCurve as Edge; if (edge != null) { Face face = null; foreach (Face testFace in edge.Faces) { face = testFace; break; } SurfaceEvaluation surfEval = face.ProjectPoint(curve.StartPoint); OriginalNormals[curveSegment] = surfEval.Normal; } lastPoint = point; // extraLength = 0; } curveChain = new TrimmedCurveChain(trimmedCurves); if (AreTabsFlipped) { curveChain.Reverse(); } List <Window> curveWindows = new List <Window>(Document.Open(@"C:\Users\bcr.SPACECLAIM\Documents\Models\Pod Tent\TabCurve.scdoc", false)); bool adjustEnds = true; #if false List <Window> curveWindows = new List <Window>(Document.Open(@"C:\Users\bcr.SPACECLAIM\Documents\Models\Pod Tent\TabStrapEdgeCurve.scdoc", false)); bool adjustEnds = true; #endif NurbsCurve middle = GetFirstNurbsCurveFromPart(curveWindows[0].Scene as Part); Debug.Assert(middle != null); NurbsCurve endTab = null; NurbsCurve endSlot = null; foreach (Component component in (curveWindows[0].Scene as Part).Components) { if (component.Template.Name == "EndTab") { endTab = GetFirstNurbsCurveFromPart(component.Template); } if (component.Template.Name == "EndSlot") { endSlot = GetFirstNurbsCurveFromPart(component.Template); } } Debug.Assert(endTab != null); Debug.Assert(endSlot != null); Point startPoint = curveChain.Curves[0].StartPoint; Point endPoint = curveChain.Curves[0].EndPoint; Point startTail = startPoint + (endPoint - startPoint); bool mirror = false; if (IsTabStartSlot) { NurbsCurve tmp = endTab; endTab = endSlot; endSlot = tmp; mirror = !mirror; } for (int i = 0; i < curveChain.Curves.Count; i++) { Point endTail; if (i == curveChain.Curves.Count - 1) { endTail = curveChain.Curves[i].EndPoint + (curveChain.Curves[i].EndPoint - curveChain.Curves[i].StartPoint); } else { endTail = curveChain.Curves[i + 1].EndPoint; } Point mid = Point.Origin + (startPoint.Vector + endPoint.Vector) / 2; Direction startDirection = (startPoint - startTail).Direction; Direction lineDirection = (endPoint - startPoint).Direction; Direction endDirection = (endTail - endPoint).Direction; Direction upDirection = Direction.DirZ; //if (upDirection.IsParallelTo(lineDirection)) // upDirection = Direction.DirY; if (OriginalNormals.ContainsKey(curveChain.Curves[i].TrimmedCurve)) { upDirection = OriginalNormals[curveChain.Curves[i].TrimmedCurve]; } Direction normalDirection = Direction.Cross(lineDirection, upDirection); Line startMidLine; if (startDirection.UnitVector == lineDirection.UnitVector) { startMidLine = Line.Create(startPoint, Direction.Cross(lineDirection, upDirection)); } else { startMidLine = Line.Create(startPoint, (startDirection.UnitVector - lineDirection.UnitVector).Direction); } Line endMidLine; if (lineDirection.UnitVector == endDirection.UnitVector) { endMidLine = Line.Create(endPoint, Direction.Cross(lineDirection, upDirection)); } else { endMidLine = Line.Create(endPoint, (lineDirection.UnitVector - endDirection.UnitVector).Direction); } NurbsCurve template = middle; if (mirror) { lineDirection = -lineDirection; Line tmp = startMidLine; startMidLine = endMidLine; endMidLine = tmp; } if (i == 0) { template = endSlot; } if (i == curveChain.Curves.Count - 1) { if (mirror ^ IsTabStartSlot) { template = endSlot; } else { template = endTab; } } Frame frame = Frame.Create(mid, lineDirection, normalDirection); Matrix transform = Matrix.CreateMapping(frame); ControlPoint[] controlPoints = new ControlPoint[template.ControlPoints.Length]; int j = 0; foreach (ControlPoint controlPoint in template.ControlPoints) { controlPoints[j] = new ControlPoint(transform * controlPoint.Position, controlPoint.Weight); j++; } //CurveEvaluation curveEval = null; //curveEval = startMidLine.Evaluate(1); //DesignCurve.Create(activeWindow.SubjectMatter as Part, CurveSegment.Create(startPoint, curveEval.Point)); //curveEval = endMidLine.Evaluate(1); //DesignCurve.Create(activeWindow.SubjectMatter as Part, CurveSegment.Create(endPoint, curveEval.Point)); MakeNurbsEndTangent(endMidLine, controlPoints, 0, 1); if (adjustEnds) { MakeNurbsEndTangent(startMidLine, controlPoints, controlPoints.Length - 1, controlPoints.Length - 2); } Curve curve = NurbsCurve.Create(template.Data, controlPoints); CurveSegment curveSegment = CurveSegment.Create(curve, template.Parameterization.Range.Value); DesignCurve tab = DesignCurve.Create(activeWindow.ActiveContext.Context as Part, curveSegment); tab.Layer = tabLayer; startTail = startPoint; startPoint = endPoint; endPoint = endTail; mirror = !mirror; } foreach (Window window in curveWindows) { window.Close(); } }