             }
         }
     }
+    public var transform : SDTransform {
+        get {
+            return baseTransform * SDTransform.Scale(scale) as SDTransform * SDTransform.Rotate(rotate)
+        }
+        set {
+            baseTransform = newValue * SDTransform.Rotate(rotate).inverse * SDTransform.Scale(scale).inverse
+        }
+    }
     
     public init() {
         self.commands = []


extension Shape {
    
    @_transparent
    fileprivate var _identity : Shape {
        if rotate == 0 && scale == 1 && baseTransform == SDTransform.Identity() {
            return self
        }
        let transform = self.transform
        if transform == SDTransform.Identity() {
            return Shape(self.commands)
        }
        var _path = Shape()
        _path.reserveCapacity(self.commands.count)
        for command in self.commands {
            switch command {
            case let .move(point): _path.commands.append(.move(point * transform))
            case let .line(point): _path.commands.append(.line(point * transform))
            case let .quad(p1, p2): _path.commands.append(.quad(p1 * transform, p2 * transform))
            case let .cubic(p1, p2, p3): _path.commands.append(.cubic(p1 * transform, p2 * transform, p3 * transform))
            case .close: _path.commands.append(.close)
            }
        }
        return _path
    }
    
    public var identity : Shape {
        if cache.identity == nil {
            cache.identity = _identity
        }
        return cache.identity!
    }

        }
        return cache.originalBoundary!
    }
    
    public var frame : [Point] {
        let _transform = self.transform
        return originalBoundary.points.map { $0 * _transform }
    }
}

