Reposition the text position of a sketch dimension using the API
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
My application is driven by user parameters, and I'm using constraints to determine the actual dimensions rather than calculating it in code. This allows a user to change user parameters, and see the effect of it on the design almost immediately.
There's a lot of constraints, specially dimensions. As a result, I've been trying to generate a sketch that can be understood by a user. When I do this manually, I usually center the text in the line.
The final soltuion I came up with, did not work as it crashes Fusion 360, and it's unclear why.
At first, I wrote a function to add a dimension between two sketch points, and center the text on the line.
def add_distance_dimension(sketch, point1, point2, orientation, distance=0.5, parameter=None):
# Normalize the values
x1 = min(point1.geometry.x, point2.geometry.x)
y1 = min(point1.geometry.y, point2.geometry.y)
x2 = max(point1.geometry.x, point2.geometry.x)
y2 = max(point1.geometry.y, point2.geometry.y)
# Get the sketch boundaries
max_x = sketch.boundingBox.maxPoint.x
min_x = sketch.boundingBox.minPoint.x
max_y = sketch.boundingBox.maxPoint.y
min_y = sketch.boundingBox.minPoint.y
width = max_x - min_x
depth = max_y - min_y
cx = width / 2
cy = depth / 2
if orientation == vertical_dimension_orientation:
y = (y2 - y1) / 2
if x1 < cx:
x = min_x - distance
else:
x = max_x + distance
else:
x = (x2 - x1) / 2
if y1 < cy:
y = min_y - distance
else:
y = max_y + distance
app.log(f'text position = ({x}, {y})')
text_position = adsk.core.Point3D.create(x, y, 0)
dim = sketch.sketchDimensions.addDistanceDimension(point1, point2, orientation, text_position)
if parameter:
dim.parameter.expression = parameter.name
The sketch looks something like this afterwards, when it's applied to the rectangle.
The code has a defect. The parameter evaluates to be 0.5. Any dimenion not set against the bottom and left sides, and misaligned.
It's evident from the code that this happens because of how the middle was calculated, and it was done BEFORE the point was constrained. I probably have to do it AFTER applying the constraint. So I updated the code to look as follows, and add some logging:
def add_distance_dimension(sketch, point1, point2, orientation, distance=0.5, parameter=None):
# Normalize the values
x1 = min(point1.geometry.x, point2.geometry.x)
y1 = min(point1.geometry.y, point2.geometry.y)
x2 = max(point1.geometry.x, point2.geometry.x)
y2 = max(point1.geometry.y, point2.geometry.y)
app.log(f'Before: ({x1}, {y1}) <-> ({x2}, {y2})')
text_position = adsk.core.Point3D.create(1, 1, 0)
dim = sketch.sketchDimensions.addDistanceDimension(point1, point2, orientation, text_position)
if parameter:
dim.parameter.expression = parameter.name
x1 = min(point1.geometry.x, point2.geometry.x)
y1 = min(point1.geometry.y, point2.geometry.y)
x2 = max(point1.geometry.x, point2.geometry.x)
y2 = max(point1.geometry.y, point2.geometry.y)
app.log(f'After: ({x1}, {y1}) <-> ({x2}, {y2})')
# Get the sketch boundaries
max_x = sketch.boundingBox.maxPoint.x
min_x = sketch.boundingBox.minPoint.x
max_y = sketch.boundingBox.maxPoint.y
min_y = sketch.boundingBox.minPoint.y
width = max_x - min_x
depth = max_y - min_y
cx = width / 2
cy = depth / 2
if orientation == vertical_dimension_orientation:
y = (y2 - y1) / 2
if x1 < cx:
x = min_x - distance
else:
x = max_x + distance
else:
x = (x2 - x1) / 2
if y1 < cy:
y = min_y - distance
else:
y = max_y + distance
text_position = adsk.core.Point3D.create(x, y, 0)
app.log(f'text position = ({x}, {y})')
app.log(f'isValid = {dim.isValid}')
dim.textPosition = text_position
The last line causes Fusion 360 to crash, and generate an error report.
dim.textPosition = text_position
When I comment out the line, nothing seems out of the ordinary for the logs:
0 = (0.0,0.0)x(6.267,0.0)
1 = (6.267,0.0)x(6.267,8.948)
2 = (6.267,8.948)x(0.0,8.948)
3 = (0.0,8.948)x(0.0,0.0)
Before: (0.0, 0.0) <-> (6.267, 0.0)
After: (0.0, 0.0) <-> (6.267, 0.0)
text position = (3.1335, -1.001)
isValid = True
Before: (0.0, 0.0) <-> (0.0, 8.948)
After: (0.0, 0.0) <-> (0.0, 8.948)
text position = (-1.001, 4.474)
isValid = True
Before: (0.0, 0.0) <-> (0.5, 0.5)
After: (0.0, 0.0) <-> (0.5, 0.5)
text position = (0.25, -0.501)
isValid = True
Before: (0.0, 0.0) <-> (0.5, 0.5)
After: (0.0, 0.0) <-> (0.5, 0.5)
text position = (-0.501, 0.25)
isValid = True
Before: (0.0, 6.448) <-> (0.5, 8.948)
After: (0.0, 8.448) <-> (0.5, 8.948)
text position = (-0.501, 0.25)
isValid = True
Before: (0.0, 8.448) <-> (0.5, 8.948)
After: (0.0, 8.448) <-> (0.5, 8.948)
text position = (0.25, 9.449)
isValid = True
Before: (3.7670000000000003, 0.0) <-> (6.267, 0.5)
After: (3.7670000000000003, 0.0) <-> (6.267, 0.5)
text position = (6.768000198364258, 0.25)
isValid = True
Before: (3.7670000000000003, 0.0) <-> (6.267, 0.5)
After: (5.767, 0.0) <-> (6.267, 0.5)
text position = (0.25, -0.501)
isValid = True
Before: (3.7670000000000003, 6.448) <-> (6.267, 8.948)
After: (3.7670000000000003, 8.448) <-> (6.267, 8.948)
text position = (6.768000198364258, 0.25)
isValid = True
Before: (3.7670000000000003, 8.448) <-> (6.267, 8.948)
After: (5.767, 8.448) <-> (6.267, 8.948)
text position = (0.25, 9.449)
isValid = True
And the documentation doesn't say much either.
The code that uses this function looks something like this
document = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
design = document.products[0]
units_mgr = design.unitsManager
units_mgr.distanceDisplayUnits = adsk.fusion.DistanceUnits.MillimeterDistanceUnits
root = design.rootComponent
component = root.occurrences.addNewComponent(adsk.core.Matrix3D.create()).component
margin_p = design.userParameters.add('Margin',
create_real_value(0.5),
'mm',
'A margin of some sorts')
width = 6.534
depth = 11.896
sketch = component.sketches.add(component.xYConstructionPlane)
sketch.name = "Sketch1"
lines = sketch.sketchCurves.sketchLines
p1 = adsk.core.Point3D.create(0, 0, 0)
p2 = adsk.core.Point3D.create(width + 2, depth + 2, 0)
rectangle = lines.addTwoPointRectangle(p1, p2)
bottom = rectangle.item(0)
top = rectangle.item(2)
right = rectangle.item(1)
left = rectangle.item(3)
for n in range(0, 4):
g = rectangle.item(n).startSketchPoint.geometry
h = rectangle.item(n).endSketchPoint.geometry
app.log(f'{n} = ({g.x},{g.y})x({h.x},{h.y}) ')
margin = margin_p.value
points = adsk.core.ObjectCollection.create()
hlb = sketch.sketchPoints.add(adsk.core.Point3D.create(margin, margin, 0))
htl = sketch.sketchPoints.add(adsk.core.Point3D.create(margin, depth - margin, 0))
hrb = sketch.sketchPoints.add(adsk.core.Point3D.create(width - margin, margin, 0))
hrt = sketch.sketchPoints.add(adsk.core.Point3D.create(width - margin, depth - margin, 0))
points.add(hlb)
points.add(htl)
points.add(hrb)
points.add(hrt)
# bottom = 0.0, 0.0
# right = 8.534, 0.0
# top = 8.534, 13.896
# left = 0.0, 13.896
# Rectangle
constraints = sketch.geometricConstraints
constraints.addHorizontal(top)
constraints.addHorizontal(bottom)
constraints.addVertical(right)
constraints.addVertical(left)
# Make sure rectangle is anchored at the origin.
constraints.addCoincident(bottom.startSketchPoint, sketch.originPoint)
add_distance_dimension(sketch, bottom.startSketchPoint, bottom.endSketchPoint, horizontal_dimension_orientation, 1)
add_distance_dimension(sketch, left.startSketchPoint, left.endSketchPoint, vertical_dimension_orientation, 1)
add_distance_dimension(sketch, bottom.startSketchPoint, hlb, horizontal_dimension_orientation, 0.5, margin_p)
add_distance_dimension(sketch, left.endSketchPoint, hlb, vertical_dimension_orientation, 0.5, margin_p)
add_distance_dimension(sketch, left.startSketchPoint, htl, vertical_dimension_orientation, 0.5, margin_p)
add_distance_dimension(sketch, top.endSketchPoint, htl, horizontal_dimension_orientation, 0.5, margin_p)
add_distance_dimension(sketch, right.startSketchPoint, hrb, vertical_dimension_orientation, 0.5, margin_p)
add_distance_dimension(sketch, bottom.endSketchPoint, hrb, horizontal_dimension_orientation, 0.5, margin_p)
add_distance_dimension(sketch, right.endSketchPoint, hrt, vertical_dimension_orientation, 0.5, margin_p)
add_distance_dimension(sketch, top.startSketchPoint, hrt, horizontal_dimension_orientation, 0.5, margin_p)
https://wernerstrydom.com