Rotating sketch

Rotating sketch

Anonymous
Not applicable
2,681 Views
3 Replies
Message 1 of 4

Rotating sketch

Anonymous
Not applicable

Simple question - how to rotate a sketch (or profile in sketch) via API ?

 

Tried sketch.move(sketchEntities, matrix), transform etc., but all failed.

Accepted solutions (1)
2,682 Views
3 Replies
Replies (3)
Message 2 of 4

KrisKaplan
Autodesk
Autodesk
Accepted solution

For a parametric design (a design that is capturing history, the default type), you would need to rotate the desired set of sketch entities using the Sketch.move API.  This would be equivalent to how you would perform a sketch rotation in the UI (using the 'Move/Copy' command with a selection of 'Sketch Objects' for the 'Move Object' type).  You just have to be aware that the transformation matrix used must be in the sketch's coordinate system.  The Sketch.transform property returns the transformation from the world coordinate system to the sketch coordinate system.  For example, the following script will rotate all sketch curves and points by an angle of pi/8 around the origin of the sketch along an axis that is normal to the sketch's reference plane.

 

sketch = root.sketches.item(0)
all = ObjectCollection.create()
for c in sketch.sketchCurves:
    all.add(c)
for p in sketch.sketchPoints:
    all.add(p)
normal = sketch.xDirection.crossProduct(sketch.yDirection)
normal.transformBy(sketch.transform)
origin = sketch.origin
origin.transformBy(sketch.transform)
mat = Matrix3D.create()
mat.setToRotation(math.pi / 8, normal, origin)
sketch.move(all, mat)

(The Sketch.x/yDirection and origin are returned in the model coordinate system, so they need to be transformed into the sketch coordinate system before being used to construct a sketch coordinate system transformation matrix.)  Keep in mind that just as with the UI command, this only produce the desired results if there are no geometric constraints or fixed (projected) geometry that would prevent this rotation.  If for example, the sketch contains projected fixed geometry, or there are geometric constraints (such as horizontal or vertical, or constraints to fixed geometry) that would be violated by this transformation, the operation would fail and you would need to reconcile or remove these relationships first.

 

If you are using a direct modeling design (not capturing design history), then you can use the Sketch.transform property directly, and you could rotate an entire sketch by simply assigning a matrix of rotation to the sketch.

 

Kris



Kris Kaplan
Message 3 of 4

Anonymous
Not applicable

Thank you for detailed explanation. It works now, the problem was with parametric design set by default in the script.

0 Likes
Message 4 of 4

marcinszydlowski.1984
Enthusiast
Enthusiast

For those who still have problem with this, especially in cases when sketches lays on planes created by angles, three points, cones' surfaces, etc. theres slightly simple solution. In all those cases you don't need to construct or get normal from planes/sketches. The only thing you need to do is to proper create of matrix based on origin and angle, no mather what direction of plane's normal is. I realized it after some samples. Here are my script for testing rotation of sketches on three different planes. It prepares plane, sketch on it (line) and later, rotate those sketches. The main function is sampleSketchRotation() and rotates are done in rotateSketch(sketch, angle, origin) function.

 

def handleErrorMessage(traceinfo, displayRawException: bool = False):
    if ui:
        if displayRawException:
            ui.messageBox('Error(s) occured:\n\n{}'.format(traceinfo.format_exc()))
        else:
            formattedLines = traceinfo.format_exc().splitlines()
            ui.messageBox('Error(s) occured\n\nReason:\n{}\n\nLine:\n{}\n\nPlace:\n{}'.format(formattedLines[3],formattedLines[2],formattedLines[1]))
            
def prepareSketch(sketches, plane):
    try:
        sketch = sketches.add(plane)
        lines = sketch.sketchCurves.sketchLines
        p_1 = adsk.core.Point3D.create(0, 0, 0)
        p_2 = adsk.core.Point3D.create(20, 0, 0)
         
        lines.addByTwoPoints(p_1, p_2)
        
        return sketch
    except:
        handleErrorMessage(traceback)

def displayMatrixCells(matrix):
    lines = ''
    
    for r in range(0, 4):
        line = ''
        for c in range(0, 4):
            value = matrix.getCell(r, c)
            
            if abs(value) < 0.000000001:
                value = 0

            line += format(value, ">-8.2f")
            
        lines += line + '\n'
            
    ui.messageBox(lines)

def getRotationMatrix(angle, origin):
    try:
        matrix = adsk.core.Matrix3D.create()
        normal = adsk.core.Vector3D.create(0, 0, 1)
        matrix.setToRotation(angle, normal, origin)
        
        return matrix
    except:
        handleErrorMessage(traceback)
    
def rotateSketch(sketch, angle, origin):
    try:        
        all = adsk.core.ObjectCollection.create()
        for c in sketch.sketchCurves:
            all.add(c)
            
        for p in sketch.sketchPoints:
            all.add(p)
            
        matrix = getRotationMatrix(angle, origin)
        #displayMatrixCells(matrix)
        sketch.move(all, matrix)
     
        return sketch
    except:
        handleErrorMessage(traceback)

def sampleSketchRotation():
    try:
        # get document and prepare other properties     
        app = adsk.core.Application.get()
        ui = app.userInterface
        design = app.activeProduct
        rootComp = design.rootComponent
        sketches = rootComp.sketches
        xyPlane = rootComp.xYConstructionPlane
        planes = rootComp.constructionPlanes
        rotationAngle = math.pi / 2
        #origin = adsk.core.Point3D.create(0, 0, 0)
        origin = adsk.core.Point3D.create(1, 1, 0)
        
        # xyPlane       
        firstSketch = prepareSketch(sketches, xyPlane)
        firstSketch.name = 'xyPlane sketch'
        firstSketch = rotateSketch(firstSketch, rotationAngle, origin)
        
        # plane rotated around x-axis
        p_1 = adsk.core.Point3D.create(-2, 0, 0)
        p_2 = adsk.core.Point3D.create(2, 0, 0)
        rotationAxis = firstSketch.sketchCurves.sketchLines.addByTwoPoints(p_1, p_2)
        planeInput = planes.createInput()
        planeAngleInput = adsk.core.ValueInput.createByString('30.0 deg')
        planeInput.setByAngle(rotationAxis, planeAngleInput, xyPlane)
        rotatedPlane = planes.add(planeInput)
        rotatedPlane.name = 'Rotated plane'
        secondSketch = prepareSketch(sketches, rotatedPlane)
        secondSketch.name = 'Rotated plane sketch'
        secondSketch = rotateSketch(secondSketch, rotationAngle, origin)
        
        # plane created based on three points
        pos_3 = adsk.core.Point3D.create(0, 0, 1)
        pos_4 = adsk.core.Point3D.create(2, 0, 0)
        pos_5 = adsk.core.Point3D.create(0, -3, 0)
        p_3 = firstSketch.sketchPoints.add(pos_3)
        p_4 = firstSketch.sketchPoints.add(pos_4)
        p_5 = firstSketch.sketchPoints.add(pos_5)
        planeInput.setByThreePoints(p_3, p_4, p_5)
        threePointsPlane = planes.add(planeInput)
        threePointsPlane.name = 'Three-points plane'
        thirdSketch = prepareSketch(sketches, threePointsPlane)
        thirdSketch.name = 'Three-points plane sketch'
        thirdSketch = rotateSketch(thirdSketch, rotationAngle, origin)

    except:
        handleErrorMessage(traceback)