sketch.offset behaving weird
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I'm trying to create a sketch using the API and stumble upon 2 problems when using the sketch.offset function.
First: no matter which dirPoint I use (or whether I use positive or negative offset value), the created lines always go to the outside of the rectangle lines I pass in.
Second: my first tests revealed an order of the returned lines, but sometimes the wrong line is chosen to place the circle at the end (running script 5 to 7 times shows this).
Here's the commented script code (extracted from my add-on, but shows same behavior here):
How can I create an offset to the inside of the baseRect?
How can I ensure to pick the leftmost edge of the (inner, i.e. offset) rectangle (best without having to loop through lines and check coordinates min/max).
#Author-
#Description-
import adsk.core, adsk.fusion, adsk.cam, traceback
BORDER = 0.05
HOLE_DIAMETER = 0.15
DIM_DISTANCE = 0.2
def run(context):
ui = None
try:
app = adsk.core.Application.get()
design = app.activeProduct
targetComponent = design.rootComponent
constructionPlane = targetComponent.xYConstructionPlane
sketches: adsk.fusion.Sketches = targetComponent.sketches
sketch: adsk.fusion.Sketch = sketches.add(constructionPlane)
baseOrigin = sketch.modelToSketchSpace(adsk.core.Point3D.create(0, 0, 0))
length = 3.5
depth = 1.1
lines = sketch.sketchCurves.sketchLines
baseRect: adsk.fusion.SketchLineList = lines.addTwoPointRectangle(
baseOrigin,
adsk.core.Point3D.create(baseOrigin.x + length, baseOrigin.y + depth, 0)
)
sketch.geometricConstraints.addHorizontal(baseRect.item(0))
sketch.geometricConstraints.addHorizontal(baseRect.item(2))
sketch.geometricConstraints.addVertical(baseRect.item(1))
sketch.geometricConstraints.addVertical(baseRect.item(3))
sketch.geometricConstraints.addCoincident(baseRect.item(0).startSketchPoint, sketch.originPoint)
sketch.sketchDimensions.addDistanceDimension(
baseRect.item(0).startSketchPoint,
baseRect.item(0).endSketchPoint,
adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
adsk.core.Point3D.create(length/2, -DIM_DISTANCE, 0)
)
sketch.sketchDimensions.addDistanceDimension(
baseRect.item(1).startSketchPoint,
baseRect.item(1).endSketchPoint,
adsk.fusion.DimensionOrientations.VerticalDimensionOrientation,
adsk.core.Point3D.create(length + DIM_DISTANCE, depth/2, 0)
)
# create mirror axis to get midpoint and for later use
mirrorLine = lines.addByTwoPoints(
adsk.core.Point3D.create(length / 2, 0, 0),
adsk.core.Point3D.create(length / 2, depth, 0),
)
mirrorLine.isConstruction = True
sketch.geometricConstraints.addMidPoint(mirrorLine.startSketchPoint, baseRect.item(0))
sketch.geometricConstraints.addMidPoint(mirrorLine.endSketchPoint, baseRect.item(2))
mirrorLineMidPoint = createMidPoint(sketch, mirrorLine)
# This works so far
# create offset for base rect
objs = adsk.core.ObjectCollection.create()
[objs.add(l) for l in baseRect]
# PROBLEM 1: no matter which dirPoint I use, no matter whether I use BORDER or -BORDER,
# the offset is always created to the outside, but I want inside.
dirPoint = mirrorLineMidPoint.geometry # my most obvious value
# dirPoint = adsk.core.Point3D.create( 1, 0.5, 0)
# dirPoint = adsk.core.Point3D.create(-1, 0.5, 0)
offsetLines = sketch.offset(objs, dirPoint, BORDER)
# first tests reveal:
# item(0) = bottom, 1 = top, 2 = left, 3 = right
leftOffsetLine = offsetLines.item(2)
leftOffsetMidPoint = createMidPoint(sketch, leftOffsetLine)
# create circle
# PROBLEM 2: sometimes the circle is created with center on top rectangle line,
# most of the times correctly on the left line.
# Why does offsetLines.item(2) not always refer to the same line?
circles = sketch.sketchCurves.sketchCircles
leftCircle = circles.addByCenterRadius(leftOffsetMidPoint.geometry, HOLE_DIAMETER / 2)
sketch.sketchDimensions.addDiameterDimension(leftCircle,
adsk.core.Point3D.create(leftOffsetMidPoint.geometry.x + HOLE_DIAMETER / 2,
leftOffsetMidPoint.geometry.y + HOLE_DIAMETER / 2,
0))
sketch.geometricConstraints.addCoincident(leftCircle.centerSketchPoint, leftOffsetLine)
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def createMidPoint(sketch: adsk.fusion.Sketch, curve: adsk.fusion.SketchCurve, point: adsk.core.Point3D = None) -> adsk.fusion.SketchPoint:
if point is None:
if type(curve) is adsk.fusion.SketchLine:
point = adsk.core.Point3D.create(
(curve.startSketchPoint.geometry.x + curve.endSketchPoint.geometry.x) / 2,
(curve.startSketchPoint.geometry.y + curve.endSketchPoint.geometry.y) / 2,
(curve.startSketchPoint.geometry.z + curve.endSketchPoint.geometry.z) / 2
)
else:
raise TypeError("curve must be a SketchLine if point is not given")
midPoint = sketch.sketchPoints.add(point)
sketch.geometricConstraints.addMidPoint(midPoint, curve)
return midPoint