Beautifl - Flash Gallery

Thumbnail : Image Mesh Generator
Image Mesh Generator
narutohyper 2010-08-17 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

package
{
    /**
     * 画像をメッシュ化するTOOLです。
     * とある目的の為に作成しましたw
     *
     * アウトライン作成 ->メッシュ作成の為のアウトラインを作成します。
     * ・頂点作成;画像上クリック。
     * ・アウトライン作成の終了(アウトラインを閉じる):始点を再度クリック。
     * ・頂点を追加:アウトライン上をクリック
     * ・頂点を削除:SHIFTキーを押しながら、頂点をクリック
     * ・頂点の移動:閉じたアウトラインの頂点をドラッグ
     *
     * ・線を交差させると、正しくMeshが作成できません
     *
     *
     * メッシュ化 -> アウトラインをメッシュ化します。
     * ・アウトラインの周りの矩形上の8つの点をクリックする事で、
     *  メッシュ化の為の基準点を変更できます。(メッシュ化の前に選択)
     * ・基準点によって、メッシュの区切り方が変化します。
     * ・キーボードダウン(何でも可)でメッシュが確認できます。
     * ・メッシュ化した画像はドラッグで動かせます。(頂点移動も可)
     *
     * メッシュ解除 -> 作成したメッシュをアウトラインに戻します。
     *
     *
     * 書き出し -> 頂点情報をXMLに書き出します。
     *
     * 画像の変更 -> 画像が変更できます。HTTP経由での指定もできますが、crossdomainエラーが出るので、アップロードでw
     * 需要があれば直します。
     
     
     * @author narutohyper
     */
    
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;

    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.geom.Point;
    import flash.display.BitmapData;
    import flash.display.LineScaleMode;
    
    import flash.display.Loader;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    import flash.system.ApplicationDomain;
    import flash.system.System;
    import flash.system.Security;   
    
    public class Main extends Sprite {
    
        private var _canvas:Sprite
        private var _imgArea:Bitmap
        private var _buttonSet:Sprite;
        private var _urlPanel:ImageLoadPanel;
        private var _alert:AlertPanel;
        private var _outputPanel:OutputPanel
        
        private var _imgChangeButton:myButton;
        private var _makeButton:myButton;
        private var _addButton:myButton;
        private var _meshMakeButton:myButton;
        private var _meshClearButton:myButton;
        private var _clearButton:myButton;
        private var _outputButton:myButton;
        
        private var _meshs:Array;
        private var _bmd:BitmapData;

        
        private var imgLoader:Loader;
        
        public function Main() {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            //Sample画像の読み込み

            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.quality = StageQuality.HIGH;

            
            _canvas = new Sprite();
            addChild(_canvas)
            _bmd = new BitmapData(100,100, true, 0x00000000);
            _imgArea=new Bitmap(_bmd)
            _canvas.addChild(_imgArea)

            _buttonSet = new Sprite();
            _buttonSet.visible = false;
            addChild(_buttonSet);
            
            _imgChangeButton = new myButton('画像の変更',0,0)
            _imgChangeButton.addEventListener(myButton.CLICK, imgChange);
            _buttonSet.addChild(_imgChangeButton);
            
            _makeButton = new myButton('アウトラインの作成',100,0)
            _makeButton.addEventListener(myButton.CLICK, add);
            _buttonSet.addChild(_makeButton);

            _addButton = new myButton('アウトラインの追加',100,0)
            _addButton.addEventListener(myButton.CLICK, add);
            _buttonSet.addChild(_addButton);
            _addButton.visible = false
            
            _clearButton = new myButton('クリア', 220, 0)
            _clearButton.addEventListener(myButton.CLICK, clear);
            _buttonSet.addChild(_clearButton);
            _clearButton.visible=false
            
            _meshMakeButton = new myButton('メッシュ化', 280, 0)
            _meshMakeButton.addEventListener(myButton.CLICK, makeMesh);
            _buttonSet.addChild(_meshMakeButton);
            _meshMakeButton.visible = false
            
            _meshClearButton = new myButton('メッシュ解除', 280, 0)
            _meshClearButton.addEventListener(myButton.CLICK, clearMesh);
            _buttonSet.addChild(_meshClearButton);
            _meshClearButton.visible=false

            _outputButton = new myButton('書き出し', 380, 0);
            _outputButton.addEventListener(myButton.CLICK, output);
            _buttonSet.addChild(_outputButton);
            _outputButton.visible = false
            
            _outputPanel = new OutputPanel();
            addChild(_outputPanel);
            
            _urlPanel = new ImageLoadPanel();
            addChild(_urlPanel);

            _alert = new AlertPanel('エラー')
            addChild(_alert);
            
            _meshs = [];
            
            onStageResize();
            this.stage.addEventListener(Event.RESIZE, onStageResize);
            
            //---------------------------------
            //Sample画像の読み込み
            //---------------------------------
            imgLoad('http://marubayashi.net/archive/sample/imagemesh/dolphin.jpg');
            
        }

        
        private function add(e:MouseEvent):void {
            _meshs[_meshs.length] = new ImgMesh2d()
            _meshs[_meshs.length - 1].bitmapData = _bmd;
            _meshs[_meshs.length - 1].addEventListener(ImgMesh2d.CLOSED, closed);
            _meshs[_meshs.length - 1].x = _imgArea.x;

            _imgChangeButton.visible = false;
            
            _makeButton.visible = false;
            _addButton.visible = false;
            _clearButton.visible = false;
            _meshMakeButton.visible = false;
            _meshClearButton.visible = false;
            _outputButton.visible = false;

            _canvas.addChild(_meshs[_meshs.length-1])
        }
        
        private function clear(e:MouseEvent):void {
            for (var i:int = 0; i < _meshs.length; i++) {
                _meshs[i].destroy();
                _meshs[i].removeEventListener(ImgMesh2d.CLOSED, closed);
                _canvas.removeChild(_meshs[i])
                _meshs[i] = null;
            }
            _meshs = [];
            _clearButton.visible = false;
            _meshMakeButton.visible = false;
            _meshClearButton.visible = false;
            _imgChangeButton.visible = true;
        }

        //-----------------------------------------
        //パスが閉じたら呼ばれる
        //-----------------------------------------
        private function closed(e:Event):void {
            _meshs[_meshs.length-1].removeEventListener(ImgMesh2d.CLOSED, closed);
            _meshMakeButton.visible = true
            _addButton.visible=true
            _outputButton.visible = true
            _clearButton.visible = true;
        }

    
        private function makeMesh(e:MouseEvent):void {
            _meshMakeButton.visible = false;
            _meshClearButton.visible = true;
            for (var i:int = 0; i < _meshs.length; i++) {
                _meshs[i].makeMesh();
            }
        }
        
        private function clearMesh(e:MouseEvent):void {
            _meshMakeButton.visible = true;
            _meshClearButton.visible = false;
            for (var i:int = 0; i < _meshs.length; i++) {
                _meshs[i].clearMesh();
            }
        }
        


        private function set buttonsEnable(value:Boolean):void {
            _imgChangeButton.enabled = value;
            _makeButton.enabled = value;
            _addButton.enabled = value;
            _meshMakeButton.enabled = value;
            _meshClearButton.enabled = value;
            _clearButton.enabled = value;
            _outputButton.enabled = value;
            
        }



        //------------------------------------------------------
        //画像の入れ替え
        //------------------------------------------------------
        private function imgChange(e:MouseEvent):void {
            buttonsEnable=false

            _urlPanel.visible = true;
            _urlPanel.addEventListener(ImageLoadPanel.LOAD,load)
            _urlPanel.addEventListener(ImageLoadPanel.CANCEL,cancel)
            _urlPanel.addEventListener(ImageLoadPanel.UPLOAD,upload)

            function load():void {
                if (_urlPanel.url) {
                    imgLoad(_urlPanel.url)
                } else {
                    buttonsEnable = true
                }
                remove()
            }

            function upload():void {
                if (imgLoader) {
                    imgLoader.unload();
                }
                imgLoader = new Loader();
                imgLoader.loadBytes(_urlPanel.data);
                imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded)
                
                remove()
            }

            function cancel():void {
                buttonsEnable = true
                remove()
            }
            
            function remove():void {
                _urlPanel.removeEventListener(ImageLoadPanel.LOAD,load)
                _urlPanel.removeEventListener(ImageLoadPanel.CANCEL,cancel)
                _urlPanel.removeEventListener(ImageLoadPanel.UPLOAD,upload)
            }

            
            
        }

        
        //------------------------------------------------
        //画像の読み込み
        //------------------------------------------------
        private function imgLoad(url:String):void {

            if (imgLoader) {
                imgLoader.unload();
            }
            imgLoader = new Loader();

            Security.loadPolicyFile("http://marubayashi.net/crossdomain.xml");
            var urlReq:URLRequest=new URLRequest(url);
            var context :LoaderContext = new LoaderContext();
            context.applicationDomain = ApplicationDomain.currentDomain;
            //imgLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,progressHandler);

            imgLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onImageIoerror);
            imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,onImageLoaded)
            imgLoader.load(urlReq, context);
            
        }

        private function onImageLoaded(e:Event):void {
            _bmd = new BitmapData(imgLoader.width,imgLoader.height, true, 0x00000000);
            _bmd.draw(imgLoader, null, null, null, null, true);
            _imgArea.bitmapData = _bmd;
            _buttonSet.visible = true;
            _makeButton.visible = true;
            onStageResize();
            buttonsEnable = true
        }
        
        private function onImageIoerror(e:IOErrorEvent):void {
            _alert.setText(e.text);
            _alert.addEventListener(myWindow.CLOSE, alertClose);
            function alertClose(e:Event):void {
                _alert.removeEventListener(myWindow.CLOSE, alertClose);
                buttonsEnable = true
            }
        }
        

        //------------------------------------------------
        //XMLデータへのPointの書き出し
        //------------------------------------------------
        private function output(e:MouseEvent):void {
            
            var result:XML=<date>
            </date>;

            var tempXML:XML
            for (var i:int = 0; i < _meshs.length; i++) {
                tempXML = _meshs[i].outputVertices();
                tempXML.@id = i
                result.mesh[i]=tempXML
            }
            
            _outputPanel.visible = true;
            _outputPanel.setText(result);
            
            buttonsEnable = false;
            _outputPanel.addEventListener(myWindow.CLOSE, outputPanelClose);
            _outputPanel.addEventListener(OutputPanel.COPY, outputPanelCopy);


            function outputPanelCopy(e:Event):void {
                System.setClipboard(result);
            }

            function outputPanelClose(e:Event):void {
                _outputPanel.removeEventListener(OutputPanel.COPY, outputPanelCopy);
                _outputPanel.removeEventListener(myWindow.CLOSE, outputPanelClose);
                buttonsEnable = true
            }
            
        }



        private function onStageResize(e:Event=null):void {
            _buttonSet.x = int((this.stage.stageWidth - _buttonSet.width) / 2);
            _buttonSet.y = 10;
            _canvas.x = int((this.stage.stageWidth - _imgArea.width) / 2);
            _canvas.y = 40;
        }
        
        

    }

}




import flash.display.Sprite;
import flash.display.LineScaleMode;
import flash.display.SimpleButton;
import flash.text.*
import flash.utils.ByteArray;

import flash.events.MouseEvent;
import flash.events.Event;

//-----------------------------------------------------------
//簡易コンポーネント
//-----------------------------------------------------------

//---------------------------------------
//簡単ボタンクラス
//---------------------------------------
class myButton extends SimpleButton {
    
    public static const CLICK:String = 'click2';
    
    public function myButton($str:String,$x:Number=0,$y:Number=0,$w:Number=0,$h:Number=0) {
        this.upState = state($str, $w, $h);
        this.overState = state($str, $w, $h,0xFFDDDD);
        this.downState = state($str, $w, $h, 0xDDDDFF);
        this.hitTestState = state($str, $w, $h, 0xDDDDFF);
        this.x = $x;
        this.y = $y;
        
        this.addEventListener(MouseEvent.CLICK,inClick)
    }
    
    private function state($str:String,$w:Number,$h:Number,$color:uint=0xFFFFFF):Sprite {
        var result:Sprite = new Sprite();
        var label:TextField=new TextField()
        label.autoSize=TextFieldAutoSize.LEFT
        label.selectable=false;
        label.mouseEnabled=false;
        var format:TextFormat=new TextFormat();
        format.color=0x666666
        format.size=12;
        format.font='_ゴシック';
        label.defaultTextFormat = format;
        label.htmlText = $str;
        if (!$w) {
            $w = label.width + 20;
        }
        if (!$h) {
            $h = label.height + 4;
        }
        label.x = int(($w - label.width) / 2);
        label.y = int(($h - label.height) / 2);
        result.addChild(label)
        result.graphics.lineStyle(0,0x666666,0.5,true,LineScaleMode.NONE)
        result.graphics.beginFill($color,1)
        result.graphics.drawRect(0,0,$w,$h)
        return result;
        

    }
    
    private function inClick(e:MouseEvent):void {
        if (enabled) {
            dispatchEvent(new MouseEvent(CLICK));
        }
    }
    
    
    override public function set enabled(value:Boolean):void {
        super.enabled = value;
        
        if (value) {
            this.alpha = 1
        } else {
            this.alpha = 0.2
        }
    }
    
}

//---------------------------------------
//簡単インプットクラス
//---------------------------------------
class myInput extends Sprite {
    private var _label:TextField;
    
    public function myInput($str:String='', $x:Number=0, $y:Number=0, $w:Number = 100, $h:Number = 18) {
        this.x = $x;
        this.y = $y;
        graphics.lineStyle(0,0x666666,0.5,true,LineScaleMode.NONE)
        graphics.beginFill(0xFFFFFF,1)
        graphics.drawRect(0,0,$w,$h)
        _label = new TextField();
        _label.autoSize =TextFieldAutoSize.LEFT
        _label.selectable=true;
        _label.mouseEnabled = true;
        _label.mouseWheelEnabled = false;
        _label.border = false;
        _label.type = TextFieldType.INPUT;
        _label.width = $w-4;
        _label.height = $h - 2;
        _label.x=2
        _label.y=1
        var format:TextFormat=new TextFormat();
        format.color=0x666666
        format.size=12;
        format.font='_ゴシック';
        _label.defaultTextFormat = format
        _label.text = $str;
        addChild(_label);
    }
    
    public function get text():String {
        return _label.text;
    }
    
}


//---------------------------------------
//簡単ウインドクラス
//---------------------------------------
class myWindow extends Sprite {
    public static const CLOSE:String = 'close';
    
    public function myWindow($str:String = '', $x:Number = 0, $y:Number = 0, $w:Number = 100, $h:Number = 100) {
        //---------------------------------------------
        //title
        //---------------------------------------------
        var _label:TextField = new TextField();
        _label.autoSize =TextFieldAutoSize.LEFT
        _label.selectable=false;
        _label.mouseEnabled = false;
        _label.x=4
        _label.y=3
        var format:TextFormat=new TextFormat();
        format.color = 0xFFFFFF
        format.size=12;
        format.font='_ゴシック';
        _label.defaultTextFormat = format
        _label.text = $str;
        addChild(_label);
        
        this.x = $x;
        this.y = $y;

        resize($w, $h);
        
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }
    
    private function init(e:Event = null):void {
        removeEventListener(Event.ADDED_TO_STAGE, init);

        onStageResize();
        stage.addEventListener(Event.RESIZE, onStageResize);
    }
    
    public function onStageResize(e:Event=null):void {
        x = int((this.stage.stageWidth - width) / 2);
        y = int((this.stage.stageHeight - height) / 2);
    }
    
    public function resize($w:Number, $h:Number):void {
        graphics.clear()
        graphics.lineStyle(0, 0x666666, 1, true, LineScaleMode.NONE);
        graphics.beginFill(0xFFFFFF, 1);
        graphics.drawRect(0, 0, $w, $h);
        graphics.beginFill(0xCCCCCC, 1);
        graphics.drawRect(0, 0, $w, 20);
    }
    
    public function close(e:MouseEvent):void {
        visible = false;
        dispatchEvent(new Event(CLOSE));
    }
    
}

import flash.net.FileReference;
import flash.net.FileReferenceList;
import flash.utils.ByteArray;



//------------------------------------------------------
//アラートパネル
//------------------------------------------------------
class AlertPanel extends myWindow {
    private var _label:TextField;
    private var _closeBt:myButton;
    
    public function AlertPanel($str:String = 'エラーが発生しました') {
        
        super('エラー!', 0, 0, 300, 100);
        
        _label = new TextField();
        _label.autoSize =TextFieldAutoSize.LEFT
        _label.selectable=false;
        _label.mouseEnabled = false;
        _label.multiline = true;
        _label.wordWrap = true;
        _label.x=20
        _label.y = 40
        _label.width = 260;
        var format:TextFormat=new TextFormat();
        format.color = 0x666666
        format.size=12;
        format.font='_ゴシック';
        _label.defaultTextFormat = format
        _label.text = $str;
        addChild(_label);
        visible = false;
        
        _closeBt = new myButton('閉じる',0, 70);
        _closeBt.x = (300 - _closeBt.width)/2;
        _closeBt.addEventListener(MouseEvent.CLICK, close);
        addChild(_closeBt);
    }
    
    public function setText($str:String):void {
        _label.text = $str;
        visible = true;
        _closeBt.y = _label.y + _label.height + 20;
        resize(300,_label.y + _label.height + _closeBt.height+30);
        onStageResize();
    }
    

    
    
}

class OutputPanel extends myWindow {
    public static const COPY:String = 'copy';

    private var _label:TextField;
    private var _closeBt:myButton;
    private var _copyBt:myButton;

    public function OutputPanel() {
        super('XMLへの書き出し', 0, 0, 400, 400);
        _label = new TextField();
        _label.autoSize =TextFieldAutoSize.NONE
        _label.selectable=true;
        _label.mouseEnabled = true;
        _label.multiline = true;
        _label.wordWrap = true;
        _label.x=20
        _label.y = 30
        _label.width = 360;
        _label.height = 360;
        _label.border = true;
        var format:TextFormat=new TextFormat();
        format.color = 0x666666
        format.size=12;
        format.font='_ゴシック';
        _label.defaultTextFormat = format
        _label.text = '';
        addChild(_label);
        visible = false;
        
        _closeBt = new myButton('閉じる',0, 70);
        _closeBt.x = (400 - _closeBt.width - 20);
        _closeBt.addEventListener(MouseEvent.CLICK, close);
        addChild(_closeBt);

        _copyBt = new myButton('クリップボードにコピー',0, 70);
        _copyBt.x = 20;
        _copyBt.addEventListener(MouseEvent.CLICK, copy);
        addChild(_copyBt);

    }

    public function copy(e:MouseEvent):void {
        dispatchEvent(new Event(COPY));
    }

    
    public function setText($str:String):void {
        _label.text = $str;
        visible = true;
        _closeBt.y = _label.y + _label.height + 20;
        _copyBt.y = _label.y + _label.height + 20;
        resize(400, _label.y + _label.height + _closeBt.height + 30);
        onStageResize();
    }
    
}

//------------------------------------------------------
//画像loadパネル
//------------------------------------------------------
class ImageLoadPanel extends myWindow {
    public static const CANCEL:String = 'cancel';
    public static const LOAD:String = 'load';
    public static const UPLOAD:String = 'upload';
    
    private var _file:FileReference;
    private var _urlInput:myInput
    private const _firstMessage:String='画像をHTTP経由で読み込む場合はURLを入力し、読み込むボタンを押してください'

    public function ImageLoadPanel() {
        
        super('新規画像の読み込み',0,0,440,100);

        _urlInput = new myInput(_firstMessage,20,36,400);
        addChild(_urlInput);
        
        var _changeBt:myButton = new myButton('読み込む', 300, 70);
        _changeBt.x = (400 - _changeBt.width + 20);
        _changeBt.addEventListener(MouseEvent.CLICK, load);
        addChild(_changeBt);
        
        var _uploadBt:myButton = new myButton('画像のアップロード', 300, 70);
        _uploadBt.x = int((440 - _uploadBt.width) / 2);
        _uploadBt.addEventListener(MouseEvent.CLICK,upload)
        addChild(_uploadBt);

        var _cancelBt:myButton = new myButton('キャンセル', 20, 70);
        _cancelBt.addEventListener(MouseEvent.CLICK,cancel)
        addChild(_cancelBt);

        visible = false;
    }

    
    private function cancel(e:MouseEvent):void {
        visible = false;
        dispatchEvent(new Event(CANCEL));
    }

    private function load(e:MouseEvent):void {
        visible = false;
        dispatchEvent(new Event(LOAD));
    }


    //------------------------------------------
    //ファイルのアップロード
    //------------------------------------------
    private function upload(e:MouseEvent):void {
        visible = false;

        _file = new FileReference();
        _file.addEventListener(Event.SELECT, loadFileSelected)
        _file.addEventListener(Event.CANCEL, loadFileCancel)
        _file.browse();
        
    }

    private function loadFileSelected(e:Event):void {
        _file.removeEventListener(Event.SELECT, loadFileSelected)
        _file.removeEventListener(Event.CANCEL, loadFileCancel)

        _file.addEventListener(Event.COMPLETE,fileLoaded)
        _file.load();

    }

    private function loadFileCancel(e:Event):void {
        _file.removeEventListener(Event.SELECT, loadFileSelected)
        _file.removeEventListener(Event.CANCEL, loadFileCancel)
        dispatchEvent(new Event(CANCEL));
    }

    private function fileLoaded(e:Event):void {
        _file.removeEventListener(Event.COMPLETE,fileLoaded)
        
        dispatchEvent(new Event(UPLOAD));
    }

    public function get data():ByteArray {
        return _file.data;
    }
    
    public function get url():String {
        var result:String;
        if (_firstMessage != _urlInput.text) {
            result=_urlInput.text
        }
        return result;
    }

    
    
}




//====================================================================================================================
//画像をメッシュ化するClass
//====================================================================================================================

    import flash.display.BitmapData;
    import flash.display.LineScaleMode;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.geom.Point;
    import flash.geom.Rectangle;

    class ImgMesh2d extends Sprite {
        public static const CLOSED:String = "closed";
        public static const TOP_LEFT:uint = 0;
        public static const TOP_CENTER:uint = 1;
        public static const TOP_RIGHT:uint = 2;
        public static const MIDDLE_LEFT:uint = 3;
        public static const MIDDLE_CENTER:uint = 4;
        public static const MIDDLE_RIGHT:uint = 5;
        public static const BOTTOM_LEFT:uint = 6;
        public static const BOTTOM_CENTER:uint = 7;
        public static const BOTTOM_RIGHT:uint = 8;


        private var _polygons:Vector.<Polygon2d>;
        private var _vertices:Vector.<Vertex2d>;
        private var _lines:Vector.<Line2d>;
        
        private var _imageLayer:Sprite
        private var _vertexLayer:Sprite
        private var _lineLayer:Sprite
        private var _polygonLayer:Sprite
        private var _frameLayer:Sprite
        
        private var _closed:Boolean = false;
        private var _meshed:Boolean = false;

        private var _bitmapData:BitmapData;
        private var _uvtData:Vector.<Number>
        private var _verticesData:Vector.<Number>;
        
        private var _lineLock:Boolean = false;
        private var _lineOverId:int = -1;
        
        private var _dragPoint:Point;
        
        //自動Mesh生成での基準点
        private var _meshBaseMarker:Sprite;
        private var _meshBasePoint:uint = TOP_CENTER;
        private var _clickArea:Array
        
        public function ImgMesh2d() {
            
            //クリックしたところにPointを置いていく
            _imageLayer = new Sprite();
            _vertexLayer = new Sprite();
            _lineLayer = new Sprite();
            _polygonLayer = new Sprite();
            _frameLayer = new Sprite();
            this.addChild(_imageLayer);
            this.addChild(_polygonLayer);
            this.addChild(_lineLayer);
            this.addChild(_vertexLayer);
            this.addChild(_frameLayer);

            _polygonLayer.visible = false;
            
            _vertices = new Vector.<Vertex2d>();
            _lines = new Vector.<Line2d>();
            _polygons = new Vector.<Polygon2d>();
            this.addEventListener(Event.ADDED_TO_STAGE, onAdded);
            
            makeBaseFrame();
        }
        

    //===========================================================================================
    //MouseEvent
    //===========================================================================================
        private function onAdded(e:Event):void {
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown)
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove)
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown)
            stage.addEventListener(KeyboardEvent.KEY_UP,onKeyUp)
        }
        
        
        private function onKeyDown(e:KeyboardEvent):void {
            _polygonLayer.visible = true;
        }
        
        private function onKeyUp(e:KeyboardEvent):void {
            _polygonLayer.visible = false;
        }
        
        private function onMouseMove(e:MouseEvent):void {
            if (_meshed) {
                x=stage.mouseX-parent.x-_dragPoint.x
                y=stage.mouseY-parent.y-_dragPoint.y
            } else if (_closed) {
            } else {
                drawLine(mouseX, mouseY)
            }
        }

        
        private function onMouseUp(e:MouseEvent):void {
            if (_meshed) {
                stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
                stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
                _imageLayer.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            }
        }
        
        
        private function onMouseDown(e:MouseEvent):void {
            var no:uint;
            var i:uint;
            if (_meshed) {
                _imageLayer.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
                stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
                stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
                _dragPoint = new Point(mouseX, mouseY);
            } else if (_closed) {
                //line上の場合は、Pointの追加
                if (_lineOverId>=0) {
                    _vertices.splice(_lineOverId + 1, 0, new Vertex2d(_lineOverId + 1, mouseX, mouseY));
                    _vertexLayer.addChild(_vertices[_lineOverId + 1])
                    //追加した、以降のIDふりなおし、
                    no = _lines.length;
                    _lines[no] = new Line2d();
                    _lineLayer.addChild(_lines[no]);
                    for (i = 0; i < _vertices.length; i++) {
                        _vertices[i].id = i;
                        if (i == _vertices.length - 1) {
                            _lines[i].setVertices(i, _vertices[i], _vertices[0]);
                        } else {
                            _lines[i].setVertices(i, _vertices[i], _vertices[i + 1]);
                        }
                    }
                } else if (e.shiftKey) {
                    //シフトキーが押されていたら削除
                    if (e.target.hasOwnProperty('id')) {
                        no = e.target.id;
                        _vertices[no].destroy();
                        _vertexLayer.removeChild(_vertices[no]);
                        _vertices[no] = null;
                        _vertices.splice(no, 1);

                        //追加した、以降のIDふりなおし、
                        no = _lines.length - 1;
                        _lines[no].destroy();
                        _lineLayer.removeChild(_lines[no]);
                        _lines[no] = null;
                        _lines.splice(no, 1);

                        for (i = 0; i < _vertices.length; i++) {
                            _vertices[i].id = i;
                            if (i == _vertices.length - 1) {
                                _lines[i].setVertices(i, _vertices[i], _vertices[0]);
                            } else {
                                _lines[i].setVertices(i, _vertices[i], _vertices[i + 1]);
                            }
                        }
                    }    
                    
                }
            } else {
                if (_vertices.length && _vertices[0].overFlag) {
                    //閉じる
                    stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove)

                    no = _lines.length;
                    _lines[no] = new Line2d();
                    _lines[no].setVertices(no, _vertices[no], _vertices[0]);
                    _lineLayer.addChild(_lines[no]);
                    graphics.clear();
                    _closed = true;
                    
                    setBaseFrame()

                    dispatchEvent(new Event(CLOSED));
                } else {
                    no = _vertices.length;
                
                    _vertices[no] = new Vertex2d(no, mouseX, mouseY);
                    _vertexLayer.addChild(_vertices[no]);
                    if (_vertices.length > 1) {
                        no = _lines.length;
                        _lines[no] = new Line2d();
                        _lines[no].setVertices(no, _vertices[no], _vertices[no + 1]);
                        _lineLayer.addChild(_lines[no]);
                    }
                }
            }
        }



    //===========================================================================================
    //public
    //===========================================================================================
        //-----------------------------------------------
        //書き出し
        //-----------------------------------------------
        public function outputVertices():XML {
            var result:XML=<mesh>
            </mesh>
            result.@meshBasePoint=_meshBasePoint
            
            var tempXML:XML
            for (var i:uint = 0; i < _vertices.length; i++) {
                tempXML=<vertex>
                </vertex>
                tempXML.@id=_vertices[i].id
                tempXML.@x=_vertices[i].x
                tempXML.@y=_vertices[i].y
                result.data[i]=tempXML
            }

            return result;
        }
        
        
        
    
        //-----------------------------------------------
        //削除
        //-----------------------------------------------
        public function destroy():void {
            _imageLayer.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
            stage.removeEventListener(KeyboardEvent.KEY_UP,onKeyUp)
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            stage.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown)
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove)
            
            var i:uint
            for (i = 0; i < _polygons.length; i++) {
                _polygons[i].destroy()
                _polygonLayer.removeChild(_polygons[i]);
                _polygons[i] = null;
            }
            _polygons = null;
            for (i = 0; i < _lines.length; i++) {
                _lines[i].destroy()
                _lineLayer.removeChild(_lines[i]);
                _lines[i] = null;
            }
            _lines = null;

            for (i = 0; i < _vertices.length; i++) {
                _vertices[i].destroy()
                _vertexLayer.removeChild(_vertices[i]);
                _vertices[i] = null;
            }
            _vertices=null;

            for (i = 0; i < 9; i++) {
                _frameLayer.removeChild(_clickArea[i]);
                _clickArea[i].removeEventListener(MouseEvent.CLICK,baseChange)
                _clickArea[i] = null;
            }
            _clickArea = null;
            
            _imageLayer.graphics.clear();
            _frameLayer.graphics.clear();
            
        }

        //-----------------------------------------------
        //Mesh削除
        //-----------------------------------------------
        public function clearMesh():void {
            var i:uint
            for (i = 0; i < _polygons.length; i++) {
                _polygons[i].destroy()
                _polygonLayer.removeChild(_polygons[i]);
                _polygons[i] = null;
            }
            _polygons = new Vector.<Polygon2d>();
            _imageLayer.graphics.clear();
            _meshed = false;
            
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            _imageLayer.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            _frameLayer.visible = true;
        }
        
        
        //-----------------------------------------------
        //Mesh作成
        //-----------------------------------------------
        public function makeMesh():void {
        
            //頂点情報のclone
            var tempVerties:Vector.<Vertex2d> = _vertices.slice(0);
            var maxLength:Number = 0;
            var tempLength:Number = 0;
            var maxVertex:Vertex2d;
            var maxId:int = -1;
            
            var sA:Vertex2d;
            var sB:Vertex2d;
            var sC:Vertex2d;
            var sP:Vertex2d;
            var oldCross:int=-2;
            var newCross:int=-2;

            //基準点
            var basePoint:Point
            basePoint=new Point(_meshBaseMarker.x,_meshBaseMarker.y);

            while (tempVerties.length > 2) {
                maxLength = 0;
                tempLength = 0;
                maxVertex=null;
                maxId = -1;
            
                sA=null;
                sB=null;
                sC=null;
                sP=null;
                oldCross=-2;
                newCross=0;
                var i:int

                for (i = 0; i < tempVerties.length; i++) {
                    //中心点,0から各頂点への長さを求める
                    tempLength = Point.distance(basePoint, tempVerties[i].point);
                    if (maxLength < tempLength) {
                        maxLength = tempLength;
                        maxVertex = _vertices[i]
                        maxId = i;
                    }
                }
                var counter:uint=0
                while (counter<tempVerties.length) {
                    if (maxId>-1) {
                        if (maxId == 0) {
                            //三角形用の頂点
                            sA = tempVerties[tempVerties.length - 1]
                            sB = tempVerties[maxId];
                            sC = tempVerties[maxId + 1]
                        } else if (maxId == tempVerties.length - 1) {
                            sA = tempVerties[maxId - 1];
                            sB = tempVerties[maxId];
                            sC = tempVerties[0];
                        } else {
                            sA = tempVerties[maxId - 1];
                            sB = tempVerties[maxId];
                            sC = tempVerties[maxId + 1];
                        }
                    
                        //内包する頂点が無いかのチェック
                        var inDelta:Boolean=false;
                        for (i = 0; i < tempVerties.length; i++) {
                            if (tempVerties[i] != sA && tempVerties[i] != sB && tempVerties[i] != sC) {
                                if (InDeltaCheck(sA.point, sB.point, sC.point, tempVerties[i].point)) {
                                    inDelta = true;
                                    break
                                }
                            }
                        }
                        newCross = crossCheck(sB.point.subtract(sA.point), sB.point.subtract(sC.point));
                        if (!inDelta && (oldCross==-2 || oldCross==newCross)) {
                            //内包する点は無い
                            //三角を形成して、頂点を削除
                            _polygons[_polygons.length] = new Polygon2d(sA, sB, sC);
                            _polygonLayer.addChild(_polygons[_polygons.length-1])
                            tempVerties.splice(maxId, 1);

                            break;
                        } else {
                            //sBからsAへのベクトルとsBからsCへのベクトルの外積を取って保管
                            if (oldCross==-2) {
                                oldCross = crossCheck(sB.point.subtract(sA.point), sB.point.subtract(sC.point))
                            }
                            if (maxId==0) {
                                maxId=tempVerties.length-1
                            } else {
                                maxId--;
                            }
                            counter++;
                        }
                    }
                }
            }
        
            //------------------------------------
            //uvtDataの作成
            //------------------------------------
            if (_bitmapData) {
                _uvtData = new Vector.<Number>();
                for (i = 0; i < _vertices.length; i++) {
                    _uvtData[_uvtData.length] = _vertices[i].x / _bitmapData.width
                    _uvtData[_uvtData.length] = _vertices[i].y / _bitmapData.height
                }
            }
            _meshed = true;
            draw();

            stage.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            _imageLayer.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            _frameLayer.visible=false
        }
        

        //-----------------------------------------------
        //vertexが動いた時にvertexから呼ばれる命令
        //-----------------------------------------------
        public function vertexMove($id:uint):void {
            if ($id == 0) {
                _lines[_lines.length-1].draw()
                _lines[$id].draw()
            } else {
                _lines[$id-1].draw()
                _lines[$id].draw()
            }
            draw();
        }


    //===========================================================================================
    //private
    //===========================================================================================
        private function drawLine($x:Number, $y:Number):void {
            if (_vertices.length) {
                graphics.clear();
                graphics.lineStyle(0, 0xCC0000);
                graphics.moveTo(_vertices[_vertices.length - 1].x, _vertices[_vertices.length - 1].y)
                graphics.lineTo($x, $y)
            }
        }
        
        
        private function crossCheck($p1:Point, $p2:Point):int {
            var result:int = 0;
            var cross:Number=(($p1.x * $p2.y) - ($p1.y * $p2.x))
            if (cross < 0) {
                result = -1;
            } else if (cross > 0) {
                result = 1;
            }
            return result;
        }

        private function distance($p1:Point,$p2:Point,$p3:Point):Number {
            var vX:Number=$p1.x -$p2.x;
            var vY:Number=$p1.y -$p2.y;
            return (vY*$p3.x-vX*$p3.y+vX*$p1.y-vY*$p1.x)/Math.sqrt(Math.pow(vX,2)+Math.pow(vY,2));
        }


        private function isSide($p1:Point,$p2:Point,$p3:Point,$p4:Point):Boolean {
            return ((distance($p1,$p2,$p3)*distance($p1,$p2,$p4)) >= 0);
        }

        private function InDeltaCheck($p1:Point,$p2:Point,$p3:Point,$p4:Point):Boolean {
            return isSide($p1,$p2,$p3,$p4) && isSide($p2,$p3,$p1,$p4) && isSide($p3,$p1,$p2,$p4)
        }
        
        
        //---------------------------------------------------
        //関連付けられたBitmapDataをdrawTrianglesで描写する。
        //---------------------------------------------------
        private function draw():void {

            if (_meshed) {
                _verticesData = new Vector.<Number>();
                var i:uint;
                for (i = 0; i < _vertices.length; i++) {
                    _verticesData[_verticesData.length] = _vertices[i].x
                    _verticesData[_verticesData.length] = _vertices[i].y

                }
                var _indicesData:Vector.<int> = new Vector.<int>();
                for (i = 0; i < _polygons.length; i++) {
                    _indicesData[_indicesData.length] = _polygons[i].p1.id;
                    _indicesData[_indicesData.length] = _polygons[i].p2.id;
                    _indicesData[_indicesData.length] = _polygons[i].p3.id;
                }
                _imageLayer.graphics.clear();
                _imageLayer.graphics.beginBitmapFill(_bitmapData,null,false,true);
                _imageLayer.graphics.drawTriangles(_verticesData, _indicesData, _uvtData);
                _imageLayer.graphics.endFill()
            }
        }
        
        
        //---------------------------------------------------
        //メッシュ化基準点UI
        //9つの基準点を選択できるようにする
        //---------------------------------------------------
        private function makeBaseFrame():void {
            _clickArea = [];
            for (var i:int=0;i<9;i++) {
                _clickArea[i] = new Sprite();
                _clickArea[i].graphics.beginFill(0x0,0.1)
                _clickArea[i].graphics.drawCircle(0,0,4)
                _frameLayer.addChild(_clickArea[i]);
                _clickArea[i].addEventListener(MouseEvent.CLICK,baseChange)

            }
            _meshBaseMarker  = new Sprite();
            _meshBaseMarker.graphics.beginFill(0xFF8800, 1);
            _meshBaseMarker.graphics.drawCircle(0, 0, 4);
            _frameLayer.addChild(_meshBaseMarker);
            _frameLayer.visible=false
        }

        private function setBaseFrame():void {
            var basePoint:Point
            
            var rect:Rectangle = _vertexLayer.getBounds(this)
            rect.x -= 10
            rect.y -= 10
            rect.width += 20
            rect.height += 20

            _frameLayer.graphics.clear();
            _frameLayer.graphics.lineStyle(0,0x000000,0.1,true,LineScaleMode.NONE)
            _frameLayer.graphics.drawRect(rect.x,rect.y,rect.width,rect.height)
            
            for (var i:int=0;i<9;i++) {
                switch (i) {
                    case 0:
                        basePoint=new Point(rect.x,rect.y);
                        break;
                    case 1:
                        basePoint=new Point(rect.x+rect.width/2,rect.y);
                        break;
                    case 2:
                        basePoint=new Point(rect.x+rect.width,rect.y);
                        break;
                    case 3:
                        basePoint=new Point(rect.x,rect.y+rect.height/2);
                        break;
                    case 4:
                        basePoint=new Point(rect.x+rect.width/2,rect.y+rect.height/2);
                        break;
                    case 5:
                        basePoint=new Point(rect.x+rect.width,rect.y+rect.height/2);
                        break;
                    case 6:
                        basePoint=new Point(rect.x,rect.y+rect.height);
                        break;
                    case 7:
                        basePoint=new Point(rect.x+rect.width/2,rect.y+rect.height);
                        break;
                    case 8:
                        basePoint=new Point(rect.x+rect.width,rect.y+rect.height);
                        break;
                }
                _clickArea[i].x=basePoint.x
                _clickArea[i].y=basePoint.y
            }
            _frameLayer.visible = true
            setBasePoint()
        }
        
        private function baseChange(e:MouseEvent):void {
            for (var i:int=0;i<9;i++) {
                if (e.target == _clickArea[i]) {
                    _meshBasePoint=i
                    break;
                }
            }
            setBasePoint()
        }
        
        private function setBasePoint():void {
            _meshBaseMarker.x=_clickArea[_meshBasePoint].x
            _meshBaseMarker.y=_clickArea[_meshBasePoint].y;
        }



    //===========================================================================================
    //Setter&Getter
    //===========================================================================================
        public function get bitmapData():BitmapData {
            return _bitmapData;
        }
        
        public function set bitmapData(value:BitmapData):void {
            _bitmapData = value;
        }
        
        public function get lineLock():Boolean { return _lineLock; }
        
        public function set lineLock(value:Boolean):void
        {
            _lineLock = value;
        }
        
        public function get lineOverId():int { return _lineOverId; }
        
        public function set lineOverId(value:int):void
        {
            _lineOverId = value;
        }

    }

    
    
//====================================================================================================================
//2D用の頂点Class
//====================================================================================================================
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.geom.Point;
    
    class Vertex2d extends Sprite {
        public static const MOVE:String = "move";
        public var overFlag:Boolean = false

        private var _id:uint;
        private var _defColor:uint;
        private var _pmc:ImgMesh2d;
        private var _size:Number;
        

        
        public function Vertex2d($id:uint, $x:Number, $y:Number,$size:Number=4, $color:uint=0x000066) {
            id = $id;
            this.x = $x;
            this.y = $y;
            _defColor=$color
            _size=$size;

            draw()
            this.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown)
            this.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver)
            this.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut)
            this.addEventListener(Event.ADDED_TO_STAGE,onAdded)
        }

        private function onAdded(e:Event):void {
            this.removeEventListener(Event.ADDED_TO_STAGE,onAdded)
            _pmc = this.parent.parent as ImgMesh2d;
        }
        
        private function onMouseOver(e:MouseEvent):void {
            draw(0xFF0000)
            overFlag=true
        }
        
        private function onMouseOut(e:MouseEvent):void {
            draw()
            overFlag=false
        }

        
        private function onMouseDown(e:MouseEvent):void {
            stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove)
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp)
            _pmc.lineLock = true;
        }

        private function onMouseMove(e:MouseEvent):void {
            x = _pmc.mouseX
            y = _pmc.mouseY

            _pmc.vertexMove(id)
            dispatchEvent(new Event(MOVE));
        }

        private function onMouseUp(e:MouseEvent):void {
            stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMouseMove)
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp)
            _pmc.lineLock = false;
        }

        public function draw($color:uint = 0):void {
            if (!$color) {
                $color=_defColor
            }
            graphics.clear();
            graphics.beginFill($color)
            graphics.drawCircle(0,0,_size);
        }

        public function destroy():void {
            this.removeEventListener(MouseEvent.MOUSE_DOWN,onMouseDown)
            this.removeEventListener(MouseEvent.MOUSE_OVER, onMouseOver)
            this.removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut)
            stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMouseMove)
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp)
        }
        
        
        public function get point():Point {
            return new Point(x,y)
        }
        
        public function get id():uint { return _id; }
        
        public function set id(value:uint):void
        {
            _id = value;
        }

    }



//====================================================================================================================
//2D用のラインClass
//====================================================================================================================
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.geom.Point;
    
    class Line2d extends Sprite {
        public var overFlag:Boolean = false
        private var _id:uint;
        private var _v1:Vertex2d;
        private var _v2:Vertex2d;
        private var _pmc:ImgMesh2d;
        private var _defColor:uint=0x009900;


        public function Line2d() {
            this.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver)
            this.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut)
            this.addEventListener(Event.ADDED_TO_STAGE,onAdded)
        }

        public function destroy():void {
            this.removeEventListener(MouseEvent.MOUSE_OVER, onMouseOver)
            this.removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut)
        }
        
        private function onAdded(e:Event):void {
            this.removeEventListener(Event.ADDED_TO_STAGE,onAdded)
            _pmc = this.parent.parent as ImgMesh2d;
        }
        
        public function setVertices($id:uint, $v1:Vertex2d, $v2:Vertex2d):void {
            _id = $id;
            _v1 = $v1;
            _v2 = $v2;
            draw();
        }
        
        public function draw($color:uint = 0):void {
            if (!$color) {
                $color=_defColor
            }
            graphics.clear()
            graphics.lineStyle(5, 0xFF0000,0);
            graphics.moveTo(_v1.x, _v1.y);
            graphics.lineTo(_v2.x, _v2.y);
            graphics.lineStyle(0, $color);
            graphics.moveTo(_v1.x, _v1.y);
            graphics.lineTo(_v2.x, _v2.y);
        }
        
        private function onMouseOver(e:MouseEvent):void {
            if (!_pmc.lineLock) {
                draw(0xFF0000)
                overFlag = true
                _pmc.lineOverId = _id;
            }
        }
        
        private function onMouseOut(e:MouseEvent):void {
            if (!_pmc.lineLock) {
                draw()
                overFlag = false
                _pmc.lineOverId = -1;
            }
        }
        
    }


//====================================================================================================================
//2D用のポリゴンClass
//====================================================================================================================

    import flash.display.Sprite;
    import flash.events.Event;

    class Polygon2d extends Sprite {
        private var _p1:Vertex2d
        private var _p2:Vertex2d
        private var _p3:Vertex2d


        public function Polygon2d($p1:Vertex2d,$p2:Vertex2d,$p3:Vertex2d) {
            _p1=$p1
            _p2=$p2
            _p3=$p3

            _p1.addEventListener(Vertex2d.MOVE, draw);
            _p2.addEventListener(Vertex2d.MOVE, draw);
            _p3.addEventListener(Vertex2d.MOVE, draw);
            
            draw()
        }

        //-------------------------------------
        //テスト用三角の描画
        //-------------------------------------
        public function draw(e:Event=null):void {
            graphics.clear()
            graphics.lineStyle(0, 0x000000);
            graphics.beginFill(0x00FF00,0.1)
            graphics.moveTo(_p1.x, _p1.y);
            graphics.lineTo(_p2.x, _p2.y);
            graphics.lineTo(_p3.x, _p3.y);
            graphics.lineTo(_p1.x, _p1.y);
        }
        
        public function destroy():void {
            _p1.removeEventListener(Vertex2d.MOVE, draw);
            _p2.removeEventListener(Vertex2d.MOVE, draw);
            _p3.removeEventListener(Vertex2d.MOVE, draw);
            
        }
        
        public function get p1():Vertex2d { return _p1; }
        
        public function set p1(value:Vertex2d):void
        {
            _p1 = value;
        }
        
        public function get p2():Vertex2d { return _p2; }
        
        public function set p2(value:Vertex2d):void
        {
            _p2 = value;
        }
        
        public function get p3():Vertex2d { return _p3; }
        
        public function set p3(value:Vertex2d):void
        {
            _p3 = value;
        }
        

    }