diff options
Diffstat (limited to 'source/blender/src')
88 files changed, 106542 insertions, 0 deletions
diff --git a/source/blender/src/.BCkey b/source/blender/src/.BCkey new file mode 100644 index 00000000000..a0fd5e817d4 --- /dev/null +++ b/source/blender/src/.BCkey @@ -0,0 +1 @@ +0xffffffff 0xfffffff0 fffffffe diff --git a/source/blender/src/B.blend.c b/source/blender/src/B.blend.c new file mode 100644 index 00000000000..f15ebb05ae7 --- /dev/null +++ b/source/blender/src/B.blend.c @@ -0,0 +1,1051 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +/* DataToC output of file <B_blend> */ + +int datatoc_B_blend_size= 32472; +char datatoc_B_blend[]= { + 66, 76, 69, 78, 68, 69, 82, 95,118, 50, 49, 50, 82, 69, 78, 68, 32, 0, 0, 0,136,237,255,191, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 8, 83, 82, 0, 0,100, 0, 0, 0, 80,237, 89, 8, 70, 0, 0, 0, 1, 0, 0, 0,192,148, 95, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82,115, 99,114,101,101,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,168,107, 93, 8,240,152, 92, 8, 56,153, 92, 8, 96, 89, 94, 8,168, 89, 94, 8, +104, 95, 94, 8, 24,190, 95, 8, 0, 0,255, 4, 0, 0,255, 3, 0, 5, 0, 4, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 9, 0, + 68, 65, 84, 65, 20, 0, 0, 0,168,107, 93, 8, 71, 0, 0, 0, 1, 0, 0, 0,168,106, 93, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,168,106, 93, 8, 71, 0, 0, 0, 1, 0, 0, 0, 80, 22, 93, 8, +168,107, 93, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 80, 22, 93, 8, 71, 0, 0, 0, + 1, 0, 0, 0, 16, 23, 93, 8,168,106, 93, 8, 0, 0, 0, 0, 0, 5, 0, 4, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, + 16, 23, 93, 8, 71, 0, 0, 0, 1, 0, 0, 0,232,105, 93, 8, 80, 22, 93, 8, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 20, 0, 0, 0,232,105, 93, 8, 71, 0, 0, 0, 1, 0, 0, 0, 48,106, 93, 8, 16, 23, 93, 8, 0, 0, 0, 0, + 0, 0,252, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 48,106, 93, 8, 71, 0, 0, 0, 1, 0, 0, 0,216, 98, 93, 8, +232,105, 93, 8, 0, 0, 0, 0, 0, 5,252, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,216, 98, 93, 8, 71, 0, 0, 0, + 1, 0, 0, 0, 32, 99, 93, 8, 48,106, 93, 8, 0, 0, 0, 0, 0, 0,228, 3, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, + 32, 99, 93, 8, 71, 0, 0, 0, 1, 0, 0, 0,104, 99, 93, 8,216, 98, 93, 8, 0, 0, 0, 0, 0, 5,228, 3, 0, 0, 0, 0, + 68, 65, 84, 65, 20, 0, 0, 0,104, 99, 93, 8, 71, 0, 0, 0, 1, 0, 0, 0,240,152, 92, 8, 32, 99, 93, 8, 0, 0, 0, 0, + 20, 3,252, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,240,152, 92, 8, 71, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +104, 99, 93, 8, 0, 0, 0, 0, 20, 3,228, 3, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 56,153, 92, 8, 72, 0, 0, 0, + 1, 0, 0, 0,128,153, 92, 8, 0, 0, 0, 0, 80, 22, 93, 8,168,106, 93, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0,128,153, 92, 8, 72, 0, 0, 0, 1, 0, 0, 0, 96,159, 92, 8, 56,153, 92, 8, 16, 23, 93, 8,168,107, 93, 8, + 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 96,159, 92, 8, 72, 0, 0, 0, 1, 0, 0, 0,168,159, 92, 8, +128,153, 92, 8,232,105, 93, 8,168,107, 93, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,168,159, 92, 8, + 72, 0, 0, 0, 1, 0, 0, 0,240,159, 92, 8, 96,159, 92, 8, 16, 23, 93, 8, 48,106, 93, 8, 1, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 24, 0, 0, 0,240,159, 92, 8, 72, 0, 0, 0, 1, 0, 0, 0,184, 71, 93, 8,168,159, 92, 8,232,105, 93, 8, + 48,106, 93, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,184, 71, 93, 8, 72, 0, 0, 0, 1, 0, 0, 0, + 0, 72, 93, 8,240,159, 92, 8,216, 98, 93, 8,168,106, 93, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, + 0, 72, 93, 8, 72, 0, 0, 0, 1, 0, 0, 0, 72, 72, 93, 8,184, 71, 93, 8, 80, 22, 93, 8, 32, 99, 93, 8, 1, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 72, 72, 93, 8, 72, 0, 0, 0, 1, 0, 0, 0,144, 72, 93, 8, 0, 72, 93, 8, +216, 98, 93, 8, 32, 99, 93, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,144, 72, 93, 8, 72, 0, 0, 0, + 1, 0, 0, 0,168,103, 93, 8, 72, 72, 93, 8,104, 99, 93, 8,232,105, 93, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0,168,103, 93, 8, 72, 0, 0, 0, 1, 0, 0, 0,240,103, 93, 8,144, 72, 93, 8,104, 99, 93, 8, 48,106, 93, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,240,103, 93, 8, 72, 0, 0, 0, 1, 0, 0, 0, 56,104, 93, 8, +168,103, 93, 8,240,152, 92, 8,216, 98, 93, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 56,104, 93, 8, + 72, 0, 0, 0, 1, 0, 0, 0,128,104, 93, 8,240,103, 93, 8,240,152, 92, 8, 32, 99, 93, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 24, 0, 0, 0,128,104, 93, 8, 72, 0, 0, 0, 1, 0, 0, 0,200,104, 93, 8, 56,104, 93, 8,240,152, 92, 8, +104, 99, 93, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,200,104, 93, 8, 72, 0, 0, 0, 1, 0, 0, 0, + 96, 89, 94, 8,128,104, 93, 8, 32, 99, 93, 8, 48,106, 93, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, + 96, 89, 94, 8, 72, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,200,104, 93, 8,216, 98, 93, 8,232,105, 93, 8, 1, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0,168, 89, 94, 8, 73, 0, 0, 0, 1, 0, 0, 0,136, 91, 94, 8, 0, 0, 0, 0, +168,107, 93, 8,232,105, 93, 8, 48,106, 93, 8, 16, 23, 93, 8, 0, 0, 0, 0,120, 81,101, 8,120, 81,101, 8,240, 67, 95, 8, +240, 67, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0,249, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,229, 0, 0, 0, +249, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 1, 5,229, 0, + 1, 0, 3, 0,253, 2, 0, 0,100, 0, 0, 0, 0, 0, 0, 0,208,226, 20, 8, 16, 56, 20, 8,108,217, 23, 8, 36,197, 20, 8, + 36,197, 20, 8,184, 90, 94, 8, 40,151,101, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0,184, 90, 94, 8, + 63, 0, 0, 0, 1, 0, 0, 0, 40,151,101, 8, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,159, 68, + 0, 0, 0, 0, 0, 0,100, 67, 73,194,122,193,133,213,161, 68, 60,222, 71,192,122, 31,103, 67, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 67, 0, 0, 40, 66, 0, 0,200, 68, 0, 0,225, 67, 0, 0, 0, 63,225,122,180, 63, + 0, 0, 1, 0, 1, 0, 1, 0, 4, 0,255,255, 0, 0, 4, 0, 0,197, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,150, 1, 68, 65, 84, 65, 60, 1, 0, 0, 40,151,101, 8, 65, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +184, 90, 94, 8, 5, 0, 0, 0, 0, 0, 0, 0, 72,215,100, 8, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 57, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0, +136, 91, 94, 8, 73, 0, 0, 0, 1, 0, 0, 0,152, 92, 94, 8,168, 89, 94, 8,216, 98, 93, 8,168,106, 93, 8, 80, 22, 93, 8, + 32, 99, 93, 8, 0, 0, 0, 0, 32, 70, 95, 8, 32, 70, 95, 8,152,244, 95, 8,152,244, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, +231, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,231, 3, 0, 0,251, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, +252, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 0, 7, 7, 1, 5, 5, 0, 3, 0, 3, 1,145, 2, 0, 0,100, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 16, 56, 20, 8,196,189, 20, 8, 0, 0, 0, 0,188,234, 20, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0,152, 92, 94, 8, 73, 0, 0, 0, 1, 0, 0, 0,104, 95, 94, 8, +136, 91, 94, 8,232,105, 93, 8,216, 98, 93, 8,240,152, 92, 8,104, 99, 93, 8, 0, 0, 0, 0,200,246, 95, 8,200,246, 95, 8, +200,249, 95, 8,200,249, 95, 8,124, 9,109, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61,190,129, 61, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 18, 3,187, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0,128, + 0, 0, 0,128, 0, 0,128, 63, 0, 0, 0, 0, 17, 3, 0, 0,255, 0, 0, 0,225, 3, 0, 0, 0, 0, 0, 0, 17, 3, 0, 0, +255, 0, 0, 0, 19, 1, 0, 0, 0, 0, 0, 0, 17, 3, 0, 0, 20, 1, 0, 0,225, 3, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, + 18, 3,206, 2, 1, 0, 1, 0,151, 2, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 32,227, 20, 8, 16, 56, 20, 8, 88,146, 11, 8, +132,166, 20, 8,132,166, 20, 8,168, 93, 94, 8,160,140,101, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,140, 1, 0, 0, +168, 93, 94, 8, 60, 0, 0, 0, 1, 0, 0, 0,160,140,101, 8, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,124, 9,109, 61, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61,190,129, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +111, 18, 3,187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,112, 61,138, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,132,143,124, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255,255,249,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,112, 61,138, 65, 0, 0, 7, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 10,215, 35, 60, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,194, 95, 8,137, 1,103, 1,137, 1,103, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 20, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 60, 1, 0, 0, +160,140,101, 8, 65, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,168, 93, 94, 8, 5, 0, 0, 0, 0, 0, 0, 0,168,130, 94, 8, + 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 57, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,255,255, 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0,104, 95, 94, 8, 73, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +152, 92, 94, 8,104, 99, 93, 8,240,152, 92, 8, 32, 99, 93, 8, 48,106, 93, 8, 0, 0, 0, 0,200,252, 95, 8,200,252, 95, 8, +200,255, 95, 8,200,255, 95, 8, 1,184,157, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, +225,215,163,188, 0, 0, 0, 0, 23, 3, 0, 0, 0, 5, 0, 0,255, 0, 0, 0,225, 3, 0, 0, 23, 3, 0, 0, 0, 5, 0, 0, +255, 0, 0, 0, 19, 1, 0, 0, 23, 3, 0, 0, 0, 5, 0, 0, 20, 1, 0, 0,225, 3, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, +234, 1,206, 2, 3, 0, 3, 0,189, 1, 0, 0,100, 0, 0, 0, 0, 0, 0, 0,252,226, 20, 8, 16, 56, 20, 8,152,252, 24, 8, +104,184, 20, 8,104,184, 20, 8,120, 96, 94, 8,200, 95, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,180, 0, 0, 0, +120, 96, 94, 8, 62, 0, 0, 0, 1, 0, 0, 0, 96, 97, 94, 8, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,122, 67,205,204,204,189,205,204,140, 63, 0, 0, 0, 0, 0, 0,122, 67, 0, 0,160,192, 0, 0,160, 64, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0,206, 2, 0, 0, 17, 0, 0, 0,169, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, +169, 1, 0, 0, 17, 0, 0, 0,206, 2, 0, 0, 10,215, 35, 60, 10,215, 35, 60, 0, 96,106, 70, 0, 0,122, 68, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 64,107,101, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,197, 95, 8, + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 67,205,204,204,189,205,204,140, 63, + 68, 65, 84, 65,140, 1, 0, 0, 96, 97, 94, 8, 60, 0, 0, 0, 1, 0, 0, 0,200, 95, 95, 8,120, 96, 94, 8, 1, 0, 0, 0, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,193, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0,128, 63, + 1,184,157, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65, + 33,195, 79, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 29,254,249,195,125,254, 71,194, 0, 0, 0, 0, 0, 0, 0, 0,173,128,249, 67,138, 0, 72, 66, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 1, 0, 7, 0, 2, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 10,215, 35, 60, 0, 0,250, 67, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,194, 95, 8, 64, 1,104, 1, 64, 1,104, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 60, 1, 0, 0,200, 95, 95, 8, 65, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 96, 97, 94, 8, 5, 0, 0, 0, + 0, 0, 0, 0,240,109,101, 8, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 57, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 83, 82, 0, 0,100, 0, 0, 0,192,148, 95, 8, 70, 0, 0, 0, + 1, 0, 0, 0, 8,163, 95, 8, 80,237, 89, 8, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82,115, 99,114,101,101,110, 46, 48, 48, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 99, 94, 8, 8,151, 95, 8, 80,151, 95, 8, +216,153, 95, 8, 32,154, 95, 8, 16,157, 95, 8, 24,190, 95, 8, 0, 0,255, 4, 0, 0,255, 3, 0, 5, 0, 4, 1, 0, 2, 0, + 0, 0, 0, 0, 1, 0, 8, 0, 68, 65, 84, 65, 20, 0, 0, 0, 32, 99, 94, 8, 71, 0, 0, 0, 1, 0, 0, 0, 88,149, 95, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 88,149, 95, 8, 71, 0, 0, 0, + 1, 0, 0, 0,160,149, 95, 8, 32, 99, 94, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, +160,149, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0,232,149, 95, 8, 88,149, 95, 8, 0, 0, 0, 0, 0, 5, 0, 4, 0, 0, 0, 0, + 68, 65, 84, 65, 20, 0, 0, 0,232,149, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0, 48,150, 95, 8,160,149, 95, 8, 0, 0, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 48,150, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0,120,150, 95, 8, +232,149, 95, 8, 0, 0, 0, 0, 0, 0,252, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,120,150, 95, 8, 71, 0, 0, 0, + 1, 0, 0, 0,192,150, 95, 8, 48,150, 95, 8, 0, 0, 0, 0, 0, 5,252, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, +192,150, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0, 8,151, 95, 8,120,150, 95, 8, 0, 0, 0, 0, 0, 0,232, 3, 0, 0, 0, 0, + 68, 65, 84, 65, 20, 0, 0, 0, 8,151, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,192,150, 95, 8, 0, 0, 0, 0, + 0, 5,232, 3, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 80,151, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0,152,151, 95, 8, + 0, 0, 0, 0, 88,149, 95, 8,160,149, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,152,151, 95, 8, + 72, 0, 0, 0, 1, 0, 0, 0,224,151, 95, 8, 80,151, 95, 8, 32, 99, 94, 8,232,149, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 24, 0, 0, 0,224,151, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0, 40,152, 95, 8,152,151, 95, 8, 32, 99, 94, 8, + 48,150, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 40,152, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0, +112,152, 95, 8,224,151, 95, 8,232,149, 95, 8,120,150, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, +112,152, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0,184,152, 95, 8, 40,152, 95, 8, 48,150, 95, 8,120,150, 95, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,184,152, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0, 0,153, 95, 8,112,152, 95, 8, + 88,149, 95, 8,192,150, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 0,153, 95, 8, 72, 0, 0, 0, + 1, 0, 0, 0, 72,153, 95, 8,184,152, 95, 8,160,149, 95, 8, 8,151, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0, 72,153, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0,144,153, 95, 8, 0,153, 95, 8,192,150, 95, 8, 8,151, 95, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,144,153, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0,216,153, 95, 8, + 72,153, 95, 8, 48,150, 95, 8,192,150, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,216,153, 95, 8, + 72, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,144,153, 95, 8,120,150, 95, 8, 8,151, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65,220, 0, 0, 0, 32,154, 95, 8, 73, 0, 0, 0, 1, 0, 0, 0, 0,156, 95, 8, 0, 0, 0, 0, 32, 99, 94, 8, + 48,150, 95, 8,120,150, 95, 8,232,149, 95, 8, 0, 0, 0, 0,192, 53, 95, 8,192, 53, 95, 8,192, 56, 95, 8,192, 56, 95, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0,249, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,229, 0, 0, 0,249, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0,228, 0, 0, 0, 4, 0, 5, 0, 2, 0, 4, 4, 1, 5,229, 0, 3, 1, 3, 0, + 37, 3, 0, 0,100, 0, 0, 0, 0, 0, 0, 0,208,226, 20, 8, 16, 56, 20, 8,108,217, 23, 8, 36,197, 20, 8, 36,197, 20, 8, + 48,155, 95, 8,176,142,101, 8,232,124, 94, 8, 8,211,100, 8, 68, 65, 84, 65,160, 0, 0, 0, 48,155, 95, 8, 63, 0, 0, 0, + 1, 0, 0, 0,176,142,101, 8, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,159, 68, 0, 0, 0, 0, + 0, 0,100, 67,165,194,122,193,133,213,161, 68,112,222, 71,192,122, 31,103, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 67, 0, 0, 40, 66, 0, 0,200, 68, 0, 0,225, 67, 0, 0, 0, 63,225,122,180, 63, 0, 0, 1, 0, + 1, 0, 1, 0, 6, 0,255,255, 0, 0, 6, 0, 24,190, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, + 0, 0,150, 1, 68, 65, 84, 65, 60, 1, 0, 0,176,142,101, 8, 65, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 48,155, 95, 8, + 5, 0, 0, 0, 0, 0, 0, 0, 96, 97, 95, 8, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 57, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0, 0,156, 95, 8, + 73, 0, 0, 0, 1, 0, 0, 0, 16,157, 95, 8, 32,154, 95, 8,192,150, 95, 8, 88,149, 95, 8,160,149, 95, 8, 8,151, 95, 8, + 0, 0, 0, 0,192, 59, 95, 8,192, 59, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,235, 3, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,235, 3, 0, 0,255, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, + 0, 4, 0, 0, 6, 0, 0, 0, 1, 0, 7, 7, 1, 5, 1, 0, 1, 1, 3, 1,145, 2, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 56, 20, 8, 0, 0, 0, 0, 0, 0, 0, 0,188,234, 20, 8, 0, 0, 0, 0, 0, 0, 0, 0,184,236,101, 8, +184,236,101, 8, 68, 65, 84, 65,220, 0, 0, 0, 16,157, 95, 8, 73, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,156, 95, 8, + 48,150, 95, 8,192,150, 95, 8, 8,151, 95, 8,120,150, 95, 8, 0, 0, 0, 0,192, 62, 95, 8,192, 62, 95, 8,192, 65, 95, 8, +204, 65, 95, 8,232,135, 69, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 59,175, 61, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 18, 3,187, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, + 0, 0,128, 63, 0, 0, 0, 0, 0, 5, 0, 0,255, 0, 0, 0,229, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,255, 0, 0, 0, + 19, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 20, 1, 0, 0,229, 3, 0, 0, 7, 0, 8, 0, 1, 0, 1, 1, 1, 5,210, 2, + 1, 1, 1, 0,151, 2, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 32,227, 20, 8, 16, 56, 20, 8, 88,146, 11, 8,132,166, 20, 8, +132,166, 20, 8, 32,158, 95, 8, 56,162, 95, 8,184, 15, 96, 8,184, 15, 96, 8, 68, 65, 84, 65,140, 1, 0, 0, 32,158, 95, 8, + 60, 0, 0, 0, 1, 0, 0, 0,224,159, 95, 8, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0,120,208,132,190,180,208, 4, 61, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0,120,208,132, 62,180,208, 4,189, 0, 0, 0, 0, 0, 0,128, 63,232,135, 69, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,193, 59,175, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 18, 3,187, + 0, 0, 0, 0,221,245, 76,188, 87,211, 53, 59, 0, 0, 0, 0, 0, 0,128, 63, 83,227,165, 65, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 14,255, 58, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,255,255,249,195, + 0, 0, 0, 0,120,208,132, 62,181,208, 4,189, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83,227,165, 65, 0, 0, 7, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 12, 66, 0, 0,128, 63,205,204,204, 61, 0, 0,250, 67,120,208,132,190,180,208, 4, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,104,194, 95, 8,120, 2,106, 1,120, 2,106, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 60, 1, 0, 0,224,159, 95, 8, + 65, 0, 0, 0, 1, 0, 0, 0, 80,161, 95, 8, 32,158, 95, 8, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, + 0, 79, 65, 68, 32, 70, 73, 76, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 57, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255, + 0, 0, 0, 0, 68, 65, 84, 65,180, 0, 0, 0, 80,161, 95, 8, 62, 0, 0, 0, 1, 0, 0, 0, 56,162, 95, 8,224,159, 95, 8, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 32,193, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0,122, 67, + 0, 0, 32,193, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,215, 35, 60, 10,215, 35, 60, + 0, 96,106, 70, 0, 0,122, 68, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 56,162, 95, 8, 63, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 80,161, 95, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,159, 68, 0, 0, 0, 0, 0, 0,100, 67, + 0, 0, 0, 0, 0,224,159, 68, 0,128,118,195, 0, 64,237, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 67, 0, 0, 40, 66, 0, 0,200, 68, 0, 0,225, 67, 0, 0, 0, 63,225,122,180, 63, 0, 0, 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,150, 1, + 83, 82, 0, 0,100, 0, 0, 0, 8,163, 95, 8, 70, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,192,148, 95, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 82,115, 99,114,101,101,110, 46, 48, 48, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0,160,163, 95, 8,184,166, 95, 8, 0,167, 95, 8,200,171, 95, 8, 16,172, 95, 8,240,184, 95, 8, 24,190, 95, 8, + 0, 0,255, 4, 0, 0,255, 3, 0, 5, 0, 4, 1, 0, 3, 0, 0, 0, 0, 0, 1, 0, 9, 0, 68, 65, 84, 65, 20, 0, 0, 0, +160,163, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0,232,163, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 20, 0, 0, 0,232,163, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0, 48,164, 95, 8,160,163, 95, 8, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 48,164, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0,120,164, 95, 8, +232,163, 95, 8, 0, 0, 0, 0, 0, 5, 0, 4, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,120,164, 95, 8, 71, 0, 0, 0, + 1, 0, 0, 0,192,164, 95, 8, 48,164, 95, 8, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, +192,164, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0, 8,165, 95, 8,120,164, 95, 8, 0, 0, 0, 0, 0, 0,252, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 20, 0, 0, 0, 8,165, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0, 80,165, 95, 8,192,164, 95, 8, 0, 0, 0, 0, + 0, 5,252, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 80,165, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0,152,165, 95, 8, + 8,165, 95, 8, 0, 0, 0, 0, 0, 0,228, 3, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,152,165, 95, 8, 71, 0, 0, 0, + 1, 0, 0, 0,224,165, 95, 8, 80,165, 95, 8, 0, 0, 0, 0, 0, 5,228, 3, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, +224,165, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0, 40,166, 95, 8,152,165, 95, 8, 0, 0, 0, 0, 0, 0,120, 2, 0, 0, 0, 0, + 68, 65, 84, 65, 20, 0, 0, 0, 40,166, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0,112,166, 95, 8,224,165, 95, 8, 0, 0, 0, 0, + 0, 5,120, 2, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,112,166, 95, 8, 71, 0, 0, 0, 1, 0, 0, 0,184,166, 95, 8, + 40,166, 95, 8, 0, 0, 0, 0,248, 2,120, 2, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,184,166, 95, 8, 71, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0,112,166, 95, 8, 0, 0, 0, 0,248, 2,228, 3, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, + 0,167, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0, 72,167, 95, 8, 0, 0, 0, 0,232,163, 95, 8, 48,164, 95, 8, 1, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 72,167, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0,144,167, 95, 8, 0,167, 95, 8, +160,163, 95, 8,120,164, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,144,167, 95, 8, 72, 0, 0, 0, + 1, 0, 0, 0,216,167, 95, 8, 72,167, 95, 8,160,163, 95, 8,192,164, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0,216,167, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0, 32,168, 95, 8,144,167, 95, 8,120,164, 95, 8, 8,165, 95, 8, + 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 32,168, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0,104,168, 95, 8, +216,167, 95, 8,192,164, 95, 8, 8,165, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,104,168, 95, 8, + 72, 0, 0, 0, 1, 0, 0, 0,176,168, 95, 8, 32,168, 95, 8,232,163, 95, 8, 80,165, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 24, 0, 0, 0,176,168, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0,248,168, 95, 8,104,168, 95, 8, 48,164, 95, 8, +152,165, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,248,168, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0, + 64,169, 95, 8,176,168, 95, 8, 80,165, 95, 8,152,165, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, + 64,169, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0,136,169, 95, 8,248,168, 95, 8,192,164, 95, 8,224,165, 95, 8, 1, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,136,169, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0,208,169, 95, 8, 64,169, 95, 8, + 80,165, 95, 8,224,165, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,208,169, 95, 8, 72, 0, 0, 0, + 1, 0, 0, 0, 24,170, 95, 8,136,169, 95, 8,152,165, 95, 8, 40,166, 95, 8, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0, 24,170, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0, 96,170, 95, 8,208,169, 95, 8, 8,165, 95, 8, 40,166, 95, 8, + 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 96,170, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0,168,170, 95, 8, + 24,170, 95, 8,224,165, 95, 8, 40,166, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,168,170, 95, 8, + 72, 0, 0, 0, 1, 0, 0, 0,240,170, 95, 8, 96,170, 95, 8,224,165, 95, 8,112,166, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 24, 0, 0, 0,240,170, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0, 56,171, 95, 8,168,170, 95, 8, 40,166, 95, 8, +112,166, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 56,171, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0, +128,171, 95, 8,240,170, 95, 8, 80,165, 95, 8,184,166, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, +128,171, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0,200,171, 95, 8, 56,171, 95, 8,152,165, 95, 8,184,166, 95, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,200,171, 95, 8, 72, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,128,171, 95, 8, +112,166, 95, 8,184,166, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0, 16,172, 95, 8, 73, 0, 0, 0, + 1, 0, 0, 0,240,173, 95, 8, 0, 0, 0, 0,160,163, 95, 8,192,164, 95, 8, 8,165, 95, 8,120,164, 95, 8, 0, 0, 0, 0, + 64,195, 94, 8, 64,195, 94, 8,112,197, 94, 8,112,197, 94, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0,249, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 0,229, 0, 0, 0,249, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0,228, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 4, 4, 1, 5,229, 0, 3, 0, 3, 1, 37, 3, 0, 0,100, 0, 0, 0, 0, 0, 0, 0,208,226, 20, 8, + 16, 56, 20, 8,108,217, 23, 8, 36,197, 20, 8, 36,197, 20, 8, 32,173, 95, 8, 48, 79, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65,160, 0, 0, 0, 32,173, 95, 8, 63, 0, 0, 0, 1, 0, 0, 0, 48, 79, 95, 8, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,224,159, 68, 0, 0, 0, 0, 0, 0,100, 67, 73,194,122,193,133,213,161, 68, 60,222, 71,192, +122, 31,103, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 67, 0, 0, 40, 66, 0, 0,200, 68, + 0, 0,225, 67, 0, 0, 0, 63,225,122,180, 63, 0, 0, 1, 0, 1, 0, 1, 0, 6, 0,255,255, 0, 0, 6, 0, 24,190, 95, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,150, 1, 68, 65, 84, 65, 60, 1, 0, 0, 48, 79, 95, 8, + 65, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32,173, 95, 8, 5, 0, 0, 0, 0, 0, 0, 0,160,230,100, 8, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 57, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255, + 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0,240,173, 95, 8, 73, 0, 0, 0, 1, 0, 0, 0, 0,175, 95, 8, 16,172, 95, 8, + 80,165, 95, 8,232,163, 95, 8, 48,164, 95, 8,152,165, 95, 8, 0, 0, 0, 0,152, 81, 95, 8,152, 81, 95, 8,200, 83, 95, 8, +200, 83, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,231, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,231, 3, 0, 0, +251, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,252, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 0, 7, 7, 1, 5, 5, 0, + 3, 0, 3, 1,145, 2, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 56, 20, 8,196,189, 20, 8, 0, 0, 0, 0, +188,234, 20, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0, 0,175, 95, 8, + 73, 0, 0, 0, 1, 0, 0, 0,248,179, 95, 8,240,173, 95, 8,192,164, 95, 8,224,165, 95, 8, 40,166, 95, 8, 8,165, 95, 8, + 0, 0, 0, 0,208, 74, 95, 8,208, 74, 95, 8, 0, 77, 95, 8, 0, 77, 95, 8,228, 56,142, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,185,206,105, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 18, 3,187, + 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0,128, 63, 0, 0, 0, 0, 0, 5, 0, 0,255, 0, 0, 0, +117, 2, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,255, 0, 0, 0, 19, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 20, 1, 0, 0, +117, 2, 0, 0, 0, 0, 0, 0, 1, 0, 8, 8, 1, 5, 98, 1, 1, 0, 3, 1, 9, 1, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, +252,226, 20, 8, 16, 56, 20, 8,156, 57, 25, 8, 0, 0, 0, 0, 44,199, 20, 8, 16,176, 95, 8,136,178, 95, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,136, 0, 0, 0, 16,176, 95, 8, 64, 0, 0, 0, 1, 0, 0, 0,200,176, 95, 8, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0,122, 67, + 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 98, 1, 0, 0, 17, 0, 0, 0, 1, 5, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 1, 5, 0, 0, 17, 0, 0, 0, 98, 1, 0, 0, 0, 0, 32, 65, 0, 0,128, 64, + 0, 0,250, 70, 0, 0, 0, 66,205,204,204, 61, 0, 0, 32, 65, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 68, 65, 84, 65,140, 1, 0, 0,200,176, 95, 8, 60, 0, 0, 0, 1, 0, 0, 0,136,178, 95, 8, 16,176, 95, 8, 1, 0, 0, 0, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, +228, 56,142, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,185,206,105, 62, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,111, 18, 3,187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, +102,102,102, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 38,140, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,255,255,249,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102,102,102, 65, 0, 0, 7, 0, 2, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 10,215, 35, 60, 0, 0,250, 67, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,194, 95, 8,127, 2,194, 0,127, 2,194, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 60, 1, 0, 0,136,178, 95, 8, 65, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,200,176, 95, 8, 5, 0, 0, 0, + 0, 0, 0, 0,168, 67,105, 8, 20, 0, 0, 0, 0, 65, 86, 69, 32, 84, 65, 82, 71, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,116, 49, 46, 98,108,101,110,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 57, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0,248,179, 95, 8, 73, 0, 0, 0, + 1, 0, 0, 0,240,184, 95, 8, 0,175, 95, 8,112,166, 95, 8,184,166, 95, 8,152,165, 95, 8, 40,166, 95, 8, 0, 0, 0, 0, + 48, 87, 95, 8, 48, 87, 95, 8, 48, 90, 95, 8, 48, 90, 95, 8,228, 56,142, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,191, 72, 20, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 18, 3,187, 0, 0, 0, 0, + 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0,128, 63,251, 2, 0, 0, 0, 5, 0, 0,123, 2, 0, 0,225, 3, 0, 0, +251, 2, 0, 0, 0, 5, 0, 0,123, 2, 0, 0,143, 2, 0, 0,251, 2, 0, 0, 0, 5, 0, 0,144, 2, 0, 0,225, 3, 0, 0, + 0, 0, 0, 0, 1, 0, 8, 8, 6, 2, 82, 1, 3, 0, 3, 1, 9, 1, 0, 0,100, 0, 0, 0, 0, 0, 0, 0,252,226, 20, 8, + 16, 56, 20, 8,156, 57, 25, 8, 0, 0, 0, 0, 44,199, 20, 8, 8,181, 95, 8,128,183, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65,136, 0, 0, 0, 8,181, 95, 8, 64, 0, 0, 0, 1, 0, 0, 0,192,181, 95, 8, 0, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0,122, 67, 0, 0, 0, 0, + 0, 0, 0, 65, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 49, 1, 0, 0, 17, 0, 0, 0,124, 2, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 17, 0, 0, 0,124, 2, 0, 0, 17, 0, 0, 0, 49, 1, 0, 0, 0, 0, 32, 65, 0, 0,128, 64, 0, 0,250, 70, + 0, 0, 0, 66,205,204,204, 61, 0, 0, 32, 65, 9, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 68, 65, 84, 65, +140, 1, 0, 0,192,181, 95, 8, 60, 0, 0, 0, 1, 0, 0, 0,128,183, 95, 8, 8,181, 95, 8, 1, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,228, 56,142, 61, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 72, 20, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,111, 18, 3,187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,102,102,102, 65, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42,251,220, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,255,255,249,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102,102,102, 65, 0, 0, 7, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 10,215, 35, 60, 0, 0,250, 67, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,194, 95, 8, 62, 1,152, 0, 62, 1,152, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 60, 1, 0, 0,128,183, 95, 8, 65, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,192,181, 95, 8, 5, 0, 0, 0, 0, 0, 0, 0, + 80, 52,105, 8, 20, 0, 0, 0, 0, 65, 86, 69, 32, 84, 65, 82, 71, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,116, 49, 46, 98,108,101,110,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 57, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0,240,184, 95, 8, 73, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0,248,179, 95, 8,224,165, 95, 8, 80,165, 95, 8,184,166, 95, 8,112,166, 95, 8, 0, 0, 0, 0, 48, 93, 95, 8, + 48, 93, 95, 8,152,154, 94, 8,152,154, 94, 8,228, 56,142, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +205,220, 29, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 18, 3,187, 0, 0, 0, 0, 0, 0, 0,128, + 0, 0, 0,128, 0, 0, 0,128, 0, 0,128, 63, 0, 0, 0, 0,245, 2, 0, 0,123, 2, 0, 0,225, 3, 0, 0, 0, 0, 0, 0, +245, 2, 0, 0,123, 2, 0, 0,143, 2, 0, 0, 0, 0, 0, 0,245, 2, 0, 0,144, 2, 0, 0,225, 3, 0, 0, 0, 0, 0, 0, + 1, 0, 2, 2,246, 2, 82, 1, 1, 0, 3, 0,189, 1, 0, 0,100, 0, 0, 0, 0, 0, 0, 0,252,226, 20, 8, 16, 56, 20, 8, +152,252, 24, 8,104,184, 20, 8,104,184, 20, 8, 0,186, 95, 8,168,188, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +180, 0, 0, 0, 0,186, 95, 8, 62, 0, 0, 0, 1, 0, 0, 0,232,186, 95, 8, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, + 0, 0,160,192, 0, 0,210, 66,205,204,204,189,205,204,140, 63, 0, 0,160,192, 0, 0,210, 66,205,204,204,189,205,204,140, 63, + 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 17, 0, 0, 0,181, 2, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, + 17, 0, 0, 0,181, 2, 0, 0, 17, 0, 0, 0, 82, 1, 0, 0, 10,215, 35, 60, 10,215, 35, 60, 0, 96,106, 70, 0, 0,122, 68, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 24,194, 94, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 81, 0, 0, 0, 0, 0, 0,160,192, 0, 0,210, 66,205,204,204,189, +205,204,140, 63, 68, 65, 84, 65,140, 1, 0, 0,232,186, 95, 8, 60, 0, 0, 0, 1, 0, 0, 0,168,188, 95, 8, 0,186, 95, 8, + 1, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63,228, 56,142, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,220, 29, 62, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 18, 3,187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63,102,102,102, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179,146,207, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,249,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102,102,102, 65, 0, 0, 7, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 10,215, 35, 60, 0, 0,250, 67, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,194, 95, 8,122, 1,170, 0, +122, 1,170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 60, 1, 0, 0,168,188, 95, 8, 65, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,232,186, 95, 8, + 5, 0, 0, 0, 0, 0, 0, 0, 72, 68,102, 8, 20, 0, 0, 0, 0, 79, 65, 68, 32, 70, 73, 76, 69, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 57, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 83, 67, 0, 0,128, 3, 0, 0, 24,190, 95, 8, + 58, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 49, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,104,194, 95, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,200,193, 95, 8, 24,194, 95, 8,200,193, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,250, 0,100, 0, +100, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0,141, 0, + 64, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0,255,255,255,127,153,153,185, 63,154,153,153,153,204,204,236, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 95, 0, 0, 0, 4, 0, 0, 0, 0, 0, 8, 0, + 25, 0, 0, 0, 0, 0, 0, 64, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47,114,101,110,100,101,114, + 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 35, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 28, 0, 0, 0,200,193, 95, 8, 56, 0, 0, 0, 1, 0, 0, 0, 24,194, 95, 8, + 0, 0, 0, 0, 1, 0, 0, 0, 23, 7, 7, 0, 1, 0, 0, 0,120, 2,106, 1, 0,197, 95, 8, 68, 65, 84, 65, 28, 0, 0, 0, + 24,194, 95, 8, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,200,193, 95, 8, 1, 0, 0, 0, 39, 7, 7, 0, 0, 0, 0, 0, +120, 2,111, 0,104,194, 95, 8, 79, 66, 0, 0,100, 2, 0, 0,104,194, 95, 8, 53, 0, 0, 0, 1, 0, 0, 0, 0,197, 95, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 67, 97,109,101,114, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,201, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,198, 15, 2,193, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,221, 15,201, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166,119,151,180, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,191,166,119,151,180, 0, 0, 0, 0, 0, 0, 0, 0,198, 15, 2,193, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,192,185,171, 40, + 0, 0, 0, 0, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0,100, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 6, 41,100, 63, 0, 0,128, 63, 6, 41,100, 63, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, + 79, 66, 0, 0,100, 2, 0, 0, 0,197, 95, 8, 53, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,104,194, 95, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 79, 66, 80,108, 97,110,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,152,199, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166,119,151,180, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0,128, 0, 0,128,191,166,119,151,180, 0, 0, 0, 0, 0, 0, 0,128,198, 15, 2,193, 0, 0, 0,128, 0, 0,128, 63, + 1, 0, 0, 0, 0, 4, 0, 0, 0, 68, 1, 2, 79, 66, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,100, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 0,128, 63, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 61, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,128, 63, 0, 64, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 77, 69, 0, 0,184, 0, 0, 0, +152,199, 95, 8, 50, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 80,108, + 97,110,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 96, 52, 95, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,201, 95, 8, + 0, 0, 0, 0, 0, 0, 0, 0,128,200, 95, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,128,179, 0, 0, 64, 52, 0, 0, 0, 0, 0, 0,128, 63, + 2, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 80, 0, 0, 0,128,200, 95, 8, 47, 0, 0, 0, 4, 0, 0, 0, 0, 0,128, 63,255,255,127, 63, + 0, 0, 0, 0, 0, 0, 0, 0,255,127, 2,255, 0, 0,128, 63, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,255,127, 2,255, + 1, 0,128,191,253,255,127,191, 0, 0, 0, 0, 0, 0, 0, 0,255,127, 2,255,250,255,127,191, 3, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0,255,127, 2,255, 68, 65, 84, 65, 12, 0, 0, 0, 0,201, 95, 8, 44, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, + 2, 0, 1, 0, 16, 0, 15, 0, 67, 65, 0, 0,108, 0, 0, 0, 64,201, 95, 8, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 65, 67, 97,109,101,114, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,204,204, 61, 0, 0,200, 66, 0, 0,128, 63, + 0, 0,160, 65, 0, 0, 12, 66, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 71, 76, 79, 66, 12, 0, 0, 0,188,239,255,191, 74, 0, 0, 0, 1, 0, 0, 0,192,148, 95, 8, + 1, 0,128, 0, 0, 0, 0, 0, 85, 83, 69, 82,204, 1, 0, 0, 64,229, 85, 8, 69, 0, 0, 0, 1, 0, 0, 0,225, 24, 63, 0, + 4, 0, 0, 0, 47, 0, 0, 0, 0, 0,109,112, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 47, 0,115,114, 47,112,101,111,112,108,101, 47,116,114, 97, 99,101, 47,102,111,110,116, 47, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 47, 0,101,110,100,101,114, 47, 0,108,101, 47, 98,108,101,110,100, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 47, 0,105, 99,115, 47,116,101,120,116,117,114,101,115, 47, 0,100, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 47, 0,115,114, 47,112,101,111,112,108,101, 47,116,111,110, 47,112,108,117,103,105,110,115, 47, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 68, 78, 65, 49, 28, 61, 0, 0, 44, 3, 64, 8, 0, 0, 0, 0, 1, 0, 0, 0, 83, 68, 78, 65, + 78, 65, 77, 69,169, 3, 0, 0, 42,110,101,120,116, 0, 42,112,114,101,118, 0, 42,102,105,114,115,116, 0, 42,108, 97,115,116, + 0,116, 97,103, 49, 0,108,101,110, 0, 42,110, 97,109,101, 0, 42,110,101,120,116,110, 97,109,101, 0,108,101,118,101,108, 0, +116, 97,103, 50, 0,116, 97,103, 51, 0,112, 97,100, 0,120, 0,121, 0,122, 0,119, 0,120,109,105,110, 0,120,109, 97,120, 0, +121,109,105,110, 0,121,109, 97,120, 0, 42,110,101,119,105,100, 0, 42,108,105, 98, 0,110, 97,109,101, 91, 50, 52, 93, 0,117, +115, 0,102,108, 97,103, 0,105,100, 0, 42,105,100, 98,108,111, 99,107, 0, 42,102,105,108,101,100, 97,116, 97, 0,110, 97,109, +101, 91, 49, 54, 48, 93, 0,116,111,116, 0, 99,117,114,118,101, 0, 99,117,114, 0, 98,108,111, 99,107,116,121,112,101, 0,115, +104,111,119,107,101,121, 0,112,111,115, 0,116,111,116,101,108,101,109, 0,116,121,112,101, 0,114,116, 0, 42,100, 97,116, 97, + 0, 42,114,101,102,107,101,121, 0,101,108,101,109,115,116,114, 91, 51, 50, 93, 0,101,108,101,109,115,105,122,101, 0, 99,117, +114,118, 97,108, 0, 98,108,111, 99,107, 0, 42,105,112,111, 0, 42,102,114,111,109, 0,116,111,116,107,101,121, 0,115,108,117, +114,112,104, 0, 97, 99,116,107,101,121, 0, 42, 42,115, 99,114,105,112,116,115, 0, 42,102,108, 97,103, 0, 97, 99,116,115, 99, +114,105,112,116, 0,116,111,116,115, 99,114,105,112,116, 0, 42,108,105,110,101, 0, 98,108,101,110, 0,102,108, 97,103,115, 0, +110,108,105,110,101,115, 0,108,105,110,101,115, 0, 42, 99,117,114,108, 0, 42,115,101,108,108, 0, 99,117,114, 99, 0,115,101, +108, 99, 0, 42,117,110,100,111, 95, 98,117,102, 0,117,110,100,111, 95,112,111,115, 0,117,110,100,111, 95,108,101,110, 0, 42, + 99,111,109,112,105,108,101,100, 0,115,105,122,101, 0,115,101,101,107, 0,100,114, 97,119,122,111,111,109, 0,104,111,108,100, + 0, 99,108,105,112,115,116, 97, 0, 99,108,105,112,101,110,100, 0,110,101,116,115,116, 97, 0,110,101,116,101,110,100, 0,108, +101,110,115, 0,100,114, 97,119,115,105,122,101, 0,104,111,108,111,108,101,110, 0,104,111,108,111,108,101,110, 49, 0,115, 99, +114,105,112,116,108,105,110,107, 0, 42, 97,110,105,109, 0, 42,105, 98,117,102, 0, 42,109,105,112,109, 97,112, 91, 49, 48, 93, + 0,111,107, 0,108, 97,115,116,102,114, 97,109,101, 0,108, 97,115,116,113,117, 97,108,105,116,121, 0,116,112, 97,103,101,102, +108, 97,103, 0,116,111,116, 98,105,110,100, 0,120,114,101,112, 0,121,114,101,112, 0,116,119,115,116, 97, 0,116,119,101,110, +100, 0, 98,105,110,100, 99,111,100,101, 0, 42,114,101,112, 98,105,110,100, 0, 42,112, 97, 99,107,101,100,102,105,108,101, 0, +116,101,120, 99,111, 0,109, 97,112,116,111, 0,109, 97,112,116,111,110,101,103, 0, 98,108,101,110,100,116,121,112,101, 0, 42, +111, 98,106,101, 99,116, 0, 42,116,101,120, 0,112,114,111,106,120, 0,112,114,111,106,121, 0,112,114,111,106,122, 0,109, 97, +112,112,105,110,103, 0,111,102,115, 91, 51, 93, 0,115,105,122,101, 91, 51, 93, 0,116,101,120,102,108, 97,103, 0, 99,111,108, +111,114,109,111,100,101,108, 0,114, 0,103, 0, 98, 0,107, 0,100,101,102, 95,118, 97,114, 0, 99,111,108,102, 97, 99, 0,110, +111,114,102, 97, 99, 0,118, 97,114,102, 97, 99, 0, 42,104, 97,110,100,108,101, 0, 42,112,110, 97,109,101, 0, 42,115,116,110, + 97,109,101,115, 0,115,116,121,112,101,115, 0,118, 97,114,115, 0, 42,118, 97,114,115,116,114, 0, 42,114,101,115,117,108,116, + 0, 42, 99,102,114, 97, 0,100, 97,116, 97, 91, 51, 50, 93, 0, 40, 42,100,111,105,116, 41, 40, 41, 0, 40, 42, 99, 97,108,108, + 98, 97, 99,107, 41, 40, 41, 0,118,101,114,115,105,111,110, 0, 97, 0,105,112,111,116,121,112,101, 0,100, 97,116, 97, 91, 49, + 54, 93, 0, 42,105,109, 97, 0, 42, 99,117, 98,101, 91, 54, 93, 0,105,109, 97,116, 91, 52, 93, 91, 52, 93, 0,115,116,121,112, +101, 0,110,111,116,108, 97,121, 0, 99,117, 98,101,114,101,115, 0,110,111,105,115,101,115,105,122,101, 0,116,117,114, 98,117, +108, 0, 98,114,105,103,104,116, 0, 99,111,110,116,114, 97,115,116, 0,114,102, 97, 99, 0,103,102, 97, 99, 0, 98,102, 97, 99, + 0,102,105,108,116,101,114,115,105,122,101, 0,110,111,105,115,101,100,101,112,116,104, 0,110,111,105,115,101,116,121,112,101, + 0,105,109, 97,102,108, 97,103, 0, 99,114,111,112,120,109,105,110, 0, 99,114,111,112,121,109,105,110, 0, 99,114,111,112,120, +109, 97,120, 0, 99,114,111,112,121,109, 97,120, 0,120,114,101,112,101, 97,116, 0,121,114,101,112,101, 97,116, 0,101,120,116, +101,110,100, 0,102,114, 97,109,101,115, 0,111,102,102,115,101,116, 0,115,102,114, 97, 0,102,105,101, 95,105,109, 97, 0, 42, +110,111,114, 0, 42,112,108,117,103,105,110, 0, 42, 99,111, 98, 97, 0, 42,101,110,118, 0,102,114, 97,100,117,114, 91, 52, 93, + 91, 50, 93, 0,109,111,100,101, 0,116,111,116,101,120, 0,101,110,101,114,103,121, 0,100,105,115,116, 0,115,112,111,116,115, +105,122,101, 0,115,112,111,116, 98,108,101,110,100, 0,104, 97,105,110,116, 0, 97,116,116, 49, 0, 97,116,116, 50, 0, 98,117, +102,115,105,122,101, 0,115, 97,109,112, 0,115,104, 97,100,115,112,111,116,115,105,122,101, 0, 98,105, 97,115, 0,115,111,102, +116, 0,116,101,120, 97, 99,116, 0,115,104, 97,100,104, 97,108,111,115,116,101,112, 0, 42,109,116,101,120, 91, 56, 93, 0,108, + 97,121, 0,115,112,101, 99,114, 0,115,112,101, 99,103, 0,115,112,101, 99, 98, 0,109,105,114,114, 0,109,105,114,103, 0,109, +105,114, 98, 0, 97,109, 98,114, 0, 97,109, 98, 98, 0, 97,109, 98,103, 0, 97,109, 98, 0,101,109,105,116, 0, 97,110,103, 0, +115,112,101, 99,116,114, 97, 0, 97,108,112,104, 97, 0,114,101,102, 0,115,112,101, 99, 0,122,111,102,102,115, 0, 97,100,100, + 0,107,102, 97, 99, 0,104, 97,114, 0,115,101,101,100, 49, 0,115,101,101,100, 50, 0,109,111,100,101, 50, 0,102,108, 97,114, +101, 99, 0,115,116, 97,114, 99, 0,108,105,110,101, 99, 0,114,105,110,103, 99, 0,104, 97,115,105,122,101, 0,102,108, 97,114, +101,115,105,122,101, 0,115,117, 98,115,105,122,101, 0,102,108, 97,114,101, 98,111,111,115,116, 0,114,103, 98,115,101,108, 0, +112,114, 95,116,121,112,101, 0,115,101,112,116,101,120, 0,112,114, 95, 98, 97, 99,107, 0,112,114, 95,108, 97,109,112, 0,112, + 97,100, 49, 0, 42,114,101,110, 0,102,114,105, 99,116,105,111,110, 0,102,104, 0,114,101,102,108,101, 99,116, 0,102,104,100, +105,115,116, 0,120,121,102,114,105, 99,116, 0,100,121,110, 97,109,111,100,101, 0,110, 97,109,101, 91, 50, 53, 53, 93, 0,110, + 97,109,101,110,117,108,108, 0,115, 99, 97,108,101, 0,115,101,108, 99,111,108, 0,101,120,112,120, 0,101,120,112,121, 0,101, +120,112,122, 0,114, 97,100, 0,114, 97,100, 50, 0,115, 0,109, 97,120,114, 97,100, 50, 0, 42,109, 97,116, 0, 42,105,109, 97, +116, 0, 42, 98, 98, 0,101,108,101,109,115, 0,100,105,115,112, 0, 42, 42,109, 97,116, 0,116,111,116, 99,111,108, 0,108,111, + 99, 91, 51, 93, 0,114,111,116, 91, 51, 93, 0,119,105,114,101,115,105,122,101, 0,114,101,110,100,101,114,115,105,122,101, 0, +116,104,114,101,115,104, 0,118,101, 99, 91, 51, 93, 91, 51, 93, 0, 97,108,102, 97, 0,115, 91, 51, 93, 91, 50, 93, 0,104, 49, + 0,104, 50, 0,102, 49, 0,102, 50, 0,102, 51, 0,104,105,100,101, 0,118,101, 99, 91, 52, 93, 0,115, 91, 50, 93, 0,109, 97, +116, 95,110,114, 0,112,110,116,115,117, 0,112,110,116,115,118, 0,114,101,115,111,108,117, 0,114,101,115,111,108,118, 0,111, +114,100,101,114,117, 0,111,114,100,101,114,118, 0,102,108, 97,103,117, 0,102,108, 97,103,118, 0, 42,107,110,111,116,115,117, + 0, 42,107,110,111,116,115,118, 0, 42, 98,112, 0, 42, 98,101,122,116, 0,110,117,114, 98, 0, 42, 98,101,118,111, 98,106, 0, + 42,116,101,120,116,111,110, 99,117,114,118,101, 0, 42,112, 97,116,104, 0, 42,107,101,121, 0, 98,101,118, 0, 42,111,114, 99, +111, 0,112, 97,116,104,108,101,110, 0, 98,101,118,114,101,115,111,108, 0,119,105,100,116,104, 0,101,120,116, 49, 0,101,120, +116, 50, 0,115,112, 97, 99,101,109,111,100,101, 0,115,112, 97, 99,105,110,103, 0,108,105,110,101,100,105,115,116, 0,115,104, +101, 97,114, 0,102,115,105,122,101, 0,120,111,102, 0,121,111,102, 0, 42,115,116,114, 0,102, 97,109,105,108,121, 91, 50, 52, + 93, 0, 42,118,102,111,110,116, 0,109, 97,120,114, 99,116, 0,116,111,116,114, 99,116, 0, 97,100,114, 99,111,100,101, 0,118, + 97,114,116,121,112,101, 0,116,111,116,118,101,114,116, 0,105,112,111, 0,101,120,116,114, 97,112, 0, 98,105,116,109, 97,115, +107, 0,118, 49, 0,118, 50, 0,118, 51, 0,118, 52, 0,112,117,110,111, 0,101,100, 99,111,100,101, 0,117,118, 91, 52, 93, 91, + 50, 93, 0, 99,111,108, 91, 52, 93, 0,110,111, 91, 51, 93, 0,116,114, 97,110,115,112, 0,116,105,108,101, 0, 42,116,112, 97, +103,101, 0, 42, 99,108,117,116, 0, 99,111, 91, 51, 93, 0, 99,111, 91, 50, 93, 0,101,102,102,101, 99,116, 0, 42,109,102, 97, + 99,101, 0, 42,100,102, 97, 99,101, 0, 42,116,102, 97, 99,101, 0, 42,109,118,101,114,116, 0, 42,109, 99,111,108, 0, 42,109, +115,116,105, 99,107,121, 0, 42,116,101,120, 99,111,109,101,115,104, 0, 42,111, 99, 0, 42,115,117,109,111,104, 97,110,100,108, +101, 0,116,111,116,102, 97, 99,101, 0,115,109,111,111,116,104,114,101,115,104, 0,115,117, 98,100,105,118, 0, 99,117, 98,101, +109, 97,112,115,105,122,101, 0,114,116,102, 0,112,110,116,115,119, 0,116,121,112,101,117, 0,116,121,112,101,118, 0,116,121, +112,101,119, 0, 42,100,101,102, 0,109, 97,120, 0, 42, 42,111, 98, 0,112, 97,114,116,121,112,101, 0,112, 97,114, 49, 0,112, + 97,114, 50, 0,112, 97,114, 51, 0, 42,112, 97,114,101,110,116, 0, 42,116,114, 97, 99,107, 0,110,101,116,119,111,114,107, 0, + 42,108,105,102,101, 0,100,108,111, 99, 91, 51, 93, 0,111,114,105,103, 91, 51, 93, 0,100,115,105,122,101, 91, 51, 93, 0,100, +114,111,116, 91, 51, 93, 0,113,117, 97,116, 91, 52, 93, 0,100,113,117, 97,116, 91, 52, 93, 0,111, 98,109, 97,116, 91, 52, 93, + 91, 52, 93, 0,112, 97,114,101,110,116,105,110,118, 91, 52, 93, 91, 52, 93, 0, 99,111,108, 98,105,116,115, 0,116,114, 97,110, +115,102,108, 97,103, 0,105,112,111,102,108, 97,103, 0,116,114, 97, 99,107,102,108, 97,103, 0,117,112,102,108, 97,103, 0,105, +112,111,119,105,110, 0,115, 99, 97,102,108, 97,103, 0,115, 99, 97,118,105,115,102,108, 97,103, 0, 98,111,117,110,100,116,121, +112,101, 0,100,117,112,111,110, 0,100,117,112,111,102,102, 0,100,117,112,115,116, 97, 0,100,117,112,101,110,100, 0,115,102, + 0, 99,116,105,109,101, 0,109, 97,115,115, 0,100, 97,109,112,105,110,103, 0,105,110,101,114,116,105, 97, 0,114,100, 97,109, +112,105,110,103, 0,115,105,122,101,102, 97, 99, 0,100,116, 0,100,116,120, 0, 97, 99,116, 99,111,108, 0,112,114,111,112, 0, +115,101,110,115,111,114,115, 0, 99,111,110,116,114,111,108,108,101,114,115, 0, 97, 99,116,117, 97,116,111,114,115, 0,108, 98, +117,102, 0,112,111,114,116, 0, 98, 98,115,105,122,101, 91, 51, 93, 0,100,102,114, 97,115, 0,103, 97,109,101,102,108, 97,103, + 0, 97,110,105,115,111,116,114,111,112,105, 99, 70,114,105, 99,116,105,111,110, 91, 51, 93, 0,109,105,115,116,121,112,101, 0, +104,111,114,114, 0,104,111,114,103, 0,104,111,114, 98, 0,104,111,114,107, 0,122,101,110,114, 0,122,101,110,103, 0,122,101, +110, 98, 0,122,101,110,107, 0, 97,109, 98,107, 0,102, 97,115,116, 99,111,108, 0,101,120,112,111,115,117,114,101, 0,103,114, + 97,118,105,116,121, 0,115,107,121,116,121,112,101, 0,109,105,115,105, 0,109,105,115,116,115,116, 97, 0,109,105,115,116,100, +105,115,116, 0,109,105,115,116,104,105, 0,115,116, 97,114,114, 0,115,116, 97,114,103, 0,115,116, 97,114, 98, 0,115,116, 97, +114,107, 0,115,116, 97,114,115,105,122,101, 0,115,116, 97,114,109,105,110,100,105,115,116, 0,115,116, 97,114,100,105,115,116, + 0,115,116, 97,114, 99,111,108,110,111,105,115,101, 0,100,111,102,115,116, 97, 0,100,111,102,101,110,100, 0,100,111,102,109, +105,110, 0,100,111,102,109, 97,120, 0,104,101,109,105,114,101,115, 0,109, 97,120,105,116,101,114, 0,100,114, 97,119,116,121, +112,101, 0,115,117, 98,115,104,111,111,116,112, 0,115,117, 98,115,104,111,111,116,101, 0,110,111,100,101,108,105,109, 0,109, + 97,120,115,117, 98,108, 97,109,112, 0,112, 97,109, 97, 0,112, 97,109,105, 0,101,108,109, 97, 0,101,108,109,105, 0,109, 97, +120,110,111,100,101, 0, 99,111,110,118,101,114,103,101,110, 99,101, 0,114, 97,100,102, 97, 99, 0,103, 97,109,109, 97, 0,115, +120, 0,115,121, 0, 99,102,114, 97, 0,101,102,114, 97, 0,105,109, 97,103,101,115, 0,102,114, 97,109, 97,112,116,111, 0,102, +114, 97,109,101,108,101,110, 0, 98,108,117,114,102, 97, 99, 0,101,100,103,101, 82, 0,101,100,103,101, 71, 0,101,100,103,101, + 66, 0,109, 97,120,105,109,115,105,122,101, 0,120,115, 99,104, 0,121,115, 99,104, 0,120, 97,115,112, 0,121, 97,115,112, 0, +120,112, 97,114,116,115, 0,121,112, 97,114,116,115, 0,115, 97,102,101,116,121, 0, 98,111,114,100,101,114, 0,119,105,110,112, +111,115, 0,112,108, 97,110,101,115, 0,105,109,116,121,112,101, 0, 98,117,102,102,108, 97,103, 0,113,117, 97,108,105,116,121, + 0,115, 99,101,109,111,100,101, 0, 97,108,112,104, 97,109,111,100,101, 0,100,111,103, 97,109,109, 97, 0,111,115, 97, 0,102, +114,115, 95,115,101, 99, 0,101,100,103,101,105,110,116, 0,112,111,115,116,109,117,108, 0,112,111,115,116,103, 97,109,109, 97, + 0,112,111,115,116, 97,100,100, 0,112,111,115,116,105,103, 97,109,109, 97, 0, 98, 97, 99,107, 98,117,102, 91, 49, 54, 48, 93, + 0,112,105, 99, 91, 49, 54, 48, 93, 0,102,116,121,112,101, 91, 49, 54, 48, 93, 0,109,111,118,105,101, 91, 49, 54, 48, 93, 0, + 42, 99, 97,109,101,114, 97, 0, 42,119,111,114,108,100, 0, 42,115,101,116, 0, 98, 97,115,101, 0, 42, 98, 97,115, 97, 99,116, + 0, 42,103,114,111,117,112, 0, 99,117,114,115,111,114, 91, 51, 93, 0, 42,102, 99, 97,109, 0, 42,101,100, 0, 42,114, 97,100, +105,111, 0,122,111,111,109, 0, 98,108,101,110,100, 0,120,105,109, 0,121,105,109, 0, 42,114,101, 99,116, 0,115,112, 97, 99, +101,116,121,112,101, 0,118,105,101,119,109, 97,116, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,105,110,118, 91, 52, 93, 91, 52, + 93, 0,112,101,114,115,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,101,114,115,105,110,118, 91, 52, 93, 91, 52, 93, 0,118,105, +101,119,113,117, 97,116, 91, 52, 93, 0,112,101,114,115,112, 0,118,105,101,119, 0,108,111, 99, 97,108,118,105,101,119, 0,108, + 97,121, 97, 99,116, 0,115, 99,101,110,101,108,111, 99,107, 0, 97,114,111,117,110,100, 0, 99, 97,109,122,111,111,109, 0,103, +114,105,100, 0,110,101, 97,114, 0,102, 97,114, 0,109,120, 0,109,121, 0,109,120,111, 0,109,121,111, 0,112,114, 95,120,109, +105,110, 0,112,114, 95,120,109, 97,120, 0,112,114, 95,121,109,105,110, 0,112,114, 95,121,109, 97,120, 0,112,114, 95,115,105, +122,101,120, 0,112,114, 95,115,105,122,101,121, 0,103,114,105,100,108,105,110,101,115, 0,118,105,101,119, 98,117,116, 0,112, +114, 95,102, 97, 99,120, 0,112,114, 95,102, 97, 99,121, 0, 42, 98,103,112,105, 99, 0, 42,108,111, 99, 97,108,118,100, 0,118, +101,114,116, 0,104,111,114, 0,109, 97,115,107, 0,109,105,110, 91, 50, 93, 0,109, 97,120, 91, 50, 93, 0,109,105,110,122,111, +111,109, 0,109, 97,120,122,111,111,109, 0,115, 99,114,111,108,108, 0,107,101,101,112,116,111,116, 0,107,101,101,112, 97,115, +112,101, 99,116, 0,107,101,101,112,122,111,111,109, 0,114,111,119, 98,117,116, 0,118, 50,100, 0, 42,101,100,105,116,105,112, +111, 0,105,112,111,107,101,121, 0,116,111,116,105,112,111, 0,108,111, 99,107, 0, 98,117,116,111,102,115, 0, 99,104, 97,110, +110,101,108, 0,109,101,110,117,110,114, 0, 99,117,114,115,101,110,115, 0, 99,117,114, 97, 99,116, 0,109, 97,105,110, 98, 0, +109, 97,105,110, 98,111, 0, 42,108,111, 99,107,112,111,105,110, 0,116,101,120,110,114, 0,116,101,120,102,114,111,109, 0,115, +104,111,119,103,114,111,117,112, 0,114,101, 99,116,120, 0,114,101, 99,116,121, 0, 99,117,114,121, 0,109,111,100,101,108,116, +121,112,101, 0,115, 99,114,105,112,116, 98,108,111, 99,107, 0,112, 97,100, 50, 0, 42,102,105,108,101,108,105,115,116, 0,116, +111,116,102,105,108,101, 0,116,105,116,108,101, 91, 50, 52, 93, 0,100,105,114, 91, 49, 54, 48, 93, 0,102,105,108,101, 91, 56, + 48, 93, 0,111,102,115, 0,115,111,114,116, 0,109, 97,120,110, 97,109,101,108,101,110, 0, 99,111,108,108,117,109,115, 0, 42, +108,105, 98,102,105,108,101,100, 97,116, 97, 0,114,101,116,118, 97,108, 0,109,101,110,117, 0, 97, 99,116, 0, 40, 42,114,101, +116,117,114,110,102,117,110, 99, 41, 40, 41, 0,111,111,112,115, 0,118,105,115,105,102,108, 97,103, 0, 42,105,109, 97,103,101, + 0,112, 97,100, 51, 0,105,109, 97,110,114, 0, 99,117,114,116,105,108,101, 0,108,101,102,116, 0, 42,116,101,120,116, 0,116, +111,112, 0,118,105,101,119,108,105,110,101,115, 0,102,111,110,116, 95,105,100, 0,108,104,101,105,103,104,116, 0,112,105,120, + 95,112,101,114, 95,108,105,110,101, 0,116,120,116,115, 99,114,111,108,108, 0,116,120,116, 98, 97,114, 0, 42,112,121, 95,100, +114, 97,119, 0, 42,112,121, 95,101,118,101,110,116, 0, 42,112,121, 95, 98,117,116,116,111,110, 0,100,117,112,102,108, 97,103, + 0,115, 97,118,101,116,105,109,101, 0,116,101,109,112,100,105,114, 91, 54, 52, 93, 0,102,111,110,116,100,105,114, 91, 54, 52, + 93, 0,114,101,110,100,101,114,100,105,114, 91, 54, 52, 93, 0,116,101,120,116,117,100,105,114, 91, 54, 52, 93, 0,112,108,117, +103,116,101,120,100,105,114, 91, 54, 52, 93, 0,112,108,117,103,115,101,113,100,105,114, 91, 54, 52, 93, 0,115,111,117,110,100, +100,105,114, 91, 54, 52, 93, 0,118,101,114,115,105,111,110,115, 0,118,101,114,116, 98, 97,115,101, 0,101,100,103,101, 98, 97, +115,101, 0, 97,114,101, 97, 98, 97,115,101, 0, 42,115, 99,101,110,101, 0,115,116, 97,114,116,120, 0,101,110,100,120, 0,115, +116, 97,114,116,121, 0,101,110,100,121, 0,115,105,122,101,120, 0,115,105,122,101,121, 0,115, 99,101,110,101,110,114, 0,115, + 99,114,101,101,110,110,114, 0,102,117,108,108, 0,109, 97,105,110,119,105,110, 0,119,105,110, 97,107,116, 0, 42,110,101,119, +118, 0,118,101, 99, 0, 42,118, 49, 0, 42,118, 50, 0, 42,118, 51, 0, 42,118, 52, 0, 42,102,117,108,108, 0, 42,104,101, 97, +100,113,117,101,117,101, 0, 42,104,113, 0, 42,119,105,110,113,117,101,117,101, 0, 42,119,113, 0,119,105,110,109, 97,116, 91, + 52, 93, 91, 52, 93, 0,104,101, 97,100,114, 99,116, 0,119,105,110,114, 99,116, 0,104,101, 97,100,119,105,110, 0,119,105,110, + 0,104,101, 97,100,101,114,116,121,112,101, 0, 98,117,116,115,112, 97, 99,101,116,121,112,101, 0,119,105,110,120, 0,119,105, +110,121, 0,104,101, 97,100, 95,115,119, 97,112, 0,104,101, 97,100, 95,101,113,117, 97,108, 0,119,105,110, 95,115,119, 97,112, + 0,119,105,110, 95,101,113,117, 97,108, 0,104,101, 97,100, 98,117,116,108,101,110, 0,104,101, 97,100, 98,117,116,111,102,115, + 0, 99,117,114,115,111,114, 0, 40, 42,104,101, 97,100, 99,104, 97,110,103,101, 41, 40, 41, 0, 40, 42,119,105,110, 99,104, 97, +110,103,101, 41, 40, 41, 0, 40, 42,104,101, 97,100,100,114, 97,119, 41, 40,118,111,105,100, 41, 0, 40, 42,119,105,110,100,114, + 97,119, 41, 40,118,111,105,100, 41, 0, 40, 42,104,101, 97,100,113,114,101, 97,100, 41, 40, 41, 0, 40, 42,119,105,110,113,114, +101, 97,100, 41, 40, 41, 0,115,112, 97, 99,101,100, 97,116, 97, 0,117,105, 98,108,111, 99,107,115, 0, 42, 99,117,114,115, 99, +114,101,101,110, 0,100,105,115,112,108, 97,121,109,111,100,101, 0,102,105,108,101,102,108, 97,103,115, 0,110, 97,109,101, 91, + 52, 48, 93, 0, 42,115,101, 49, 0, 42,115,101, 50, 0, 42,115,101, 51, 0,110,114, 0,100,111,110,101, 0, 42,115,116,114,105, +112,100, 97,116, 97, 0,100,105,114, 91, 56, 48, 93, 0,111,114,120, 0,111,114,121, 0,110, 97,109,101, 91, 56, 48, 93, 0, 42, +110,101,119,115,101,113, 0,115,116, 97,114,116, 0,115,116, 97,114,116,111,102,115, 0,101,110,100,111,102,115, 0,115,116, 97, +114,116,115,116,105,108,108, 0,101,110,100,115,116,105,108,108, 0,109, 97, 99,104,105,110,101, 0,100,101,112,116,104, 0,115, +116, 97,114,116,100,105,115,112, 0,101,110,100,100,105,115,112, 0,109,117,108, 0,104, 97,110,100,115,105,122,101, 0, 42,115, +116,114,105,112, 0, 42, 99,117,114,101,108,101,109, 0,102, 97, 99,102, 48, 0,102, 97, 99,102, 49, 0, 42,115,101,113, 49, 0, + 42,115,101,113, 50, 0, 42,115,101,113, 51, 0,115,101,113, 98, 97,115,101, 0, 42,115,101,113, 98, 97,115,101,112, 0,109,101, +116, 97,115,116, 97, 99,107, 0, 98,117,116,116,121,112,101, 0,115,116, 97, 0,101,110,100, 0,108,105,102,101,116,105,109,101, + 0,116,111,116,112, 97,114,116, 0,115,101,101,100, 0,110,111,114,109,102, 97, 99, 0,111, 98,102, 97, 99, 0,114, 97,110,100, +102, 97, 99, 0,116,101,120,102, 97, 99, 0,114, 97,110,100,108,105,102,101, 0,102,111,114, 99,101, 91, 51, 93, 0,100, 97,109, +112, 0,110, 97, 98,108, 97, 0,118,101, 99,116,115,105,122,101, 0,100,101,102,118,101, 99, 91, 51, 93, 0,109,117,108,116, 91, + 52, 93, 0,108,105,102,101, 91, 52, 93, 0, 99,104,105,108,100, 91, 52, 93, 0,109, 97,116, 91, 52, 93, 0,116,101,120,109, 97, +112, 0, 99,117,114,109,117,108,116, 0,115,116, 97,116,105, 99,115,116,101,112, 0, 42,107,101,121,115, 0,104,101,105,103,104, +116, 0,110, 97,114,114,111,119, 0,115,112,101,101,100, 0,109,105,110,102, 97, 99, 0,116,105,109,101,111,102,102,115, 0, 42, +111, 98, 0,112,114,101,109, 97,116, 91, 52, 93, 91, 52, 93, 0,112,111,115,116,109, 97,116, 91, 52, 93, 91, 52, 93, 0,118,101, + 99, 91, 51, 93, 0,102, 97, 99, 0,108,101,110,111, 0, 97,108,112,104, 97,111, 0,101,102,102, 91, 50, 93, 0,105,116,101,114, + 0,108, 97,115,116,102,114, 97, 0,108,105,109, 98, 98, 97,115,101, 0,101,102,102, 91, 51, 93, 0,101,102,102,103, 91, 51, 93, + 0,101,102,102,110, 91, 51, 93, 0,109,101,109, 0,115,108,111,119, 0,116,111,116,121, 0,116,111,116,120, 0,120,121, 99,111, +110,115,116,114, 97,105,110,116, 0,116,111,116,100,101,102, 0,100,101,102, 95,115, 99,114,111,108,108, 0,108,105,109, 98, 95, +115, 99,114,111,108,108, 0,100,120, 0,100,121, 0, 42,105,100, 0,108,105,110,107, 0,102, 97,115,101, 0,115,117, 98,102, 97, +115,101, 0,109,111,117,115,101, 95,109,111,118,101, 95,114,101,100,114, 97,119, 0,105,109, 97,102, 97,115,101, 0,100,105,114, +115,108,105, 0,100,105,114,115,108,105, 95,108,105,110,101,115, 0,100,105,114,115,108,105, 95,115,120, 0,100,105,114,115,108, +105, 95,101,121, 0,100,105,114,115,108,105, 95,101,120, 0,100,105,114,115,108,105, 95,104, 0,105,109, 97,115,108,105, 0,102, +105,108,101,115,101,108,109,101,110,117,105,116,101,109, 0,105,109, 97,115,108,105, 95,115,120, 0,105,109, 97,115,108,105, 95, +101,121, 0,105,109, 97,115,108,105, 95,101,120, 0,105,109, 97,115,108,105, 95,104, 0,100,115,115,120, 0,100,115,115,121, 0, +100,115,101,120, 0,100,115,101,121, 0,100,101,115,120, 0,100,101,115,121, 0,100,101,101,120, 0,100,101,101,121, 0,102,115, +115,120, 0,102,115,115,121, 0,102,115,101,120, 0,102,115,101,121, 0,100,115,100,104, 0,102,115,100,104, 0,102,101,115,120, + 0,102,101,115,121, 0,102,101,101,120, 0,102,101,101,121, 0,105,110,102,115,120, 0,105,110,102,115,121, 0,105,110,102,101, +120, 0,105,110,102,101,121, 0,100,110,115,120, 0,100,110,115,121, 0,100,110,119, 0,100,110,104, 0,102,110,115,120, 0,102, +110,115,121, 0,102,110,119, 0,102,110,104, 0,102,111,108,101, 91, 49, 50, 56, 93, 0,100,111,114, 91, 49, 50, 56, 93, 0,102, +105,108,101, 91, 49, 50, 56, 93, 0,100,105,114, 91, 49, 50, 56, 93, 0, 42,102,105,114,115,116,100,105,114, 0, 42,102,105,114, +115,116,102,105,108,101, 0,116,111,112,100,105,114, 0,116,111,116, 97,108,100,105,114,115, 0,104,105,108,105,116,101, 0,116, +111,112,102,105,108,101, 0,116,111,116, 97,108,102,105,108,101,115, 0,105,109, 97,103,101, 95,115,108,105,100,101,114, 0,115, +108,105,100,101,114, 95,104,101,105,103,104,116, 0,115,108,105,100,101,114, 95,115,112, 97, 99,101, 0,116,111,112,105,109, 97, + 0,116,111,116, 97,108,105,109, 97, 0, 99,117,114,105,109, 97,120, 0, 99,117,114,105,109, 97,121, 0, 42,102,105,114,115,116, + 95,115,101,108, 95,105,109, 97, 0, 42,104,105,108,105,116,101, 95,105,109, 97, 0,116,111,116, 97,108, 95,115,101,108,101, 99, +116,101,100, 0,105,109, 97, 95,114,101,100,114, 97,119, 0, 42, 99,109, 97,112, 0,110, 97,109,101, 91, 51, 50, 93, 0,111,116, +121,112,101, 0,100, 97,116, 97, 0,111,108,100, 0, 42,112,111,105,110, 0, 42,111,108,100,112,111,105,110, 0,114,101,115,101, +116,100,105,115,116, 0,108, 97,115,116,118, 97,108, 0, 42,109, 97, 0,107,101,121, 0,113,117, 97,108, 0,113,117, 97,108, 50, + 0,118, 97,108,117,101, 91, 51, 50, 93, 0,109, 97,120,118, 97,108,117,101, 91, 51, 50, 93, 0,109, 97,116,101,114,105, 97,108, + 78, 97,109,101, 91, 51, 50, 93, 0,100, 97,109,112,116,105,109,101,114, 0, 97,110,103,108,101, 0,114, 97,110,103,101, 0, 97, +120,105,115, 0,100,101,108, 97,121, 0,112,114,111,112,110, 97,109,101, 91, 51, 50, 93, 0,109, 97,116,110, 97,109,101, 91, 51, + 50, 93, 0, 97,120,105,115,102,108, 97,103, 0, 42,115,101,110,100,111, 98, 0,112,114,111,112,116,121,112,101, 0,109,101,115, +115, 97,103,101, 91, 51, 50, 93, 0,112,117,108,115,101, 0,102,114,101,113, 0,116,111,116,108,105,110,107,115, 0, 42, 42,108, +105,110,107,115, 0,105,110,118,101,114,116, 0,102,114,101,113, 50, 0,115,116,114, 91, 49, 50, 56, 93, 0, 42,109,121,110,101, +119, 0,105,110,112,117,116,115, 0,116,111,116,115,108,105,110,107,115, 0, 42, 42,115,108,105,110,107,115, 0,118, 97,108, 0, +118, 97,108,111, 0,112, 97,100, 53, 0,116,105,109,101, 0,115,110,100,110,114, 0, 42,115,111,117,110,100, 0,112, 97,100, 91, + 51, 93, 0, 42,109,101, 0,108,105,110, 86,101,108,111, 99,105,116,121, 91, 51, 93, 0,108,111, 99, 97,108,102,108, 97,103, 0, +102,111,114, 99,101,108,111, 99, 91, 51, 93, 0,102,111,114, 99,101,114,111,116, 91, 51, 93, 0,108,105,110,101, 97,114,118,101, +108,111, 99,105,116,121, 91, 51, 93, 0, 97,110,103,117,108, 97,114,118,101,108,111, 99,105,116,121, 91, 51, 93, 0, 98,117,116, +115,116, 97, 0, 98,117,116,101,110,100, 0,109,105,110, 0,118,105,115,105,102, 97, 99, 0,109,105,110,108,111, 99, 91, 51, 93, + 0,109, 97,120,108,111, 99, 91, 51, 93, 0,109,105,110,114,111,116, 91, 51, 93, 0,109, 97,120,114,111,116, 91, 51, 93, 0,100, +105,115,116,114,105, 98,117,116,105,111,110, 0,105,110,116, 95, 97,114,103, 95, 49, 0,105,110,116, 95, 97,114,103, 95, 50, 0, +102,108,111, 97,116, 95, 97,114,103, 95, 49, 0,102,108,111, 97,116, 95, 97,114,103, 95, 50, 0, 42,100,101,115,116,111, 98, 0, +103,111, 0, 97, 99, 99,101,108,108,101,114, 97,116,105,111,110, 0,109, 97,120,115,112,101,101,100, 0,109, 97,120,114,111,116, +115,112,101,101,100, 0,109, 97,120,116,105,108,116,115,112,101,101,100, 0,114,111,116,100, 97,109,112, 0,116,105,108,116,100, + 97,109,112, 0,115,112,101,101,100,100, 97,109,112, 0,116,111,116,112,111,114,116, 0, 97, 99,116,112,111,114,116, 0, 42,112, +111,114,116, 97,108,115, 0, 42, 99, 97,109,112,111,115, 0, 42, 99, 97,109,102,114, 97,109,101, 0, 42,100,121,110, 97,109,101, +115,104, 0, 42,116,101,120,109,101,115,104, 0,116,111,116, 99, 97,109, 0,116,111,116,102,114, 97, 0, 42,115,101, 99,116,111, +114, 0,111,108,100,108,111, 99, 91, 51, 93, 0,115,112,101,101,100, 91, 51, 93, 0,111,108,100,108,111, 99, 49, 91, 51, 93, 0, +108,111, 99, 49, 91, 51, 93, 0,115,112,101,101,100, 49, 91, 51, 93, 0,115,116, 97,114,116,108,111, 99, 91, 51, 93, 0,115,116, + 97,114,116,114,111,116, 91, 51, 93, 0,114,111,116,115,112,101,101,100, 91, 51, 93, 0,111,108,100,105,109, 97,116, 91, 52, 93, + 91, 52, 93, 0,102,114,105, 99,116, 0,114,111,116,102,114,105, 99,116, 0, 97,120,115,105,122,101, 0,102,114,105, 99,116,102, + 97, 99, 0, 97,101,114,111, 0,112, 97,100,102, 0, 42,115,101,110,115,111,114,115, 0, 42, 99,111,110,116, 97, 99,116, 0, 42, + 99,111,108,108,105,115,105,111,110, 0, 42,102,108,111,111,114, 0, 42,111,108,100,109,101,115,104, 0,116,111,116,115,101,110, +115, 0, 97, 99,116,115,101,110,115, 0,116,105,109,101,114, 0,100,102,108, 97,103, 0,115,116, 97,116,101, 91, 52, 93, 0, 99, +111,108,108,111, 99, 91, 51, 93, 0,102,108,111,111,114,108,111, 99, 91, 51, 93, 0,108,105,110,107,115, 0, 42,115, 97,109,112, +108,101, 0, 42,115,110,100, 95,115,111,117,110,100, 0,118,111,108,117,109,101, 0,112, 97,110,110,105,110,103, 0, 97,116,116, +101,110,117, 97,116,105,111,110, 0,112,105,116, 99,104, 0, 99,104, 97,110,110,101,108,115, 0, 42,103,107,101,121, 0,111,107, +101,121, 0,103,111, 98,106,101, 99,116, 0,103,107,101,121, 0, 42, 97, 99,116,105,118,101, 0,114,101,115,116,109, 97,116, 91, + 52, 93, 91, 52, 93, 0,111,102,102,115,101,116, 91, 51, 93, 0,108,101,110,103,116,104, 0,100,117,109,109,121, 0, 98,111,110, +101, 98, 97,115,101, 0,114,101,115, 49, 0,114,101,115, 50, 0,114,101,115, 51, 0, 0, 0, 0, 84, 89, 80, 69,149, 0, 0, 0, + 99,104, 97,114, 0,117, 99,104, 97,114, 0,115,104,111,114,116, 0,117,115,104,111,114,116, 0,105,110,116, 0,108,111,110,103, + 0,117,108,111,110,103, 0,102,108,111, 97,116, 0,100,111,117, 98,108,101, 0,118,111,105,100, 0, 76,105,110,107, 0, 76,105, +115,116, 66, 97,115,101, 0, 77,101,109, 72,101, 97,100, 0, 77,101,109, 84, 97,105,108, 0,118,101, 99, 50,115, 0,118,101, 99, + 50,105, 0,118,101, 99, 50,102, 0,118,101, 99, 50,100, 0,118,101, 99, 51,105, 0,118,101, 99, 51,102, 0,118,101, 99, 51,100, + 0,118,101, 99, 52,105, 0,118,101, 99, 52,102, 0,118,101, 99, 52,100, 0,114, 99,116,105, 0,114, 99,116,102, 0, 73, 68, 0, + 76,105, 98,114, 97,114,121, 0, 73,112,111, 0, 75,101,121, 66,108,111, 99,107, 0, 75,101,121, 0, 83, 99,114,105,112,116, 76, +105,110,107, 0, 84,101,120,116, 76,105,110,101, 0, 84,101,120,116, 0, 80, 97, 99,107,101,100, 70,105,108,101, 0, 67, 97,109, +101,114, 97, 0, 73,109, 97,103,101, 0, 97,110,105,109, 0, 73,109, 66,117,102, 0, 77, 84,101,120, 0, 79, 98,106,101, 99,116, + 0, 84,101,120, 0, 80,108,117,103,105,110, 84,101,120, 0, 67, 66, 68, 97,116, 97, 0, 67,111,108,111,114, 66, 97,110,100, 0, + 69,110,118, 77, 97,112, 0, 76, 97,109,112, 0, 87, 97,118,101, 0, 77, 97,116,101,114,105, 97,108, 0, 86, 70,111,110,116, 0, + 86, 70,111,110,116, 68, 97,116, 97, 0, 77,101,116, 97, 69,108,101,109, 0, 77,101,116, 97, 66, 97,108,108, 0, 66,111,117,110, +100, 66,111,120, 0, 66,101,122, 84,114,105,112,108,101, 0, 66, 80,111,105,110,116, 0, 78,117,114, 98, 0, 67,117,114,118,101, + 0, 80, 97,116,104, 0, 73,112,111, 67,117,114,118,101, 0, 77, 70, 97, 99,101, 0, 77, 70, 97, 99,101, 73,110,116, 0, 84, 70, + 97, 99,101, 0, 77, 86,101,114,116, 0, 77, 67,111,108, 0, 77, 83,116,105, 99,107,121, 0, 77,101,115,104, 0, 79, 99, 73,110, +102,111, 0, 76, 97,116,116,105, 99,101, 0, 76, 66,117,102, 0, 76,105,102,101, 0, 87,111,114,108,100, 0, 82, 97,100,105,111, + 0, 66, 97,115,101, 0, 82,101,110,100,101,114, 68, 97,116, 97, 0, 83, 99,101,110,101, 0, 71,114,111,117,112, 0, 70,114,101, +101, 67, 97,109,101,114, 97, 0, 66, 71,112,105, 99, 0, 86,105,101,119, 51, 68, 0, 86,105,101,119, 50, 68, 0, 83,112, 97, 99, +101, 73,112,111, 0, 83,112, 97, 99,101, 66,117,116,115, 0, 83,112, 97, 99,101, 83,101,113, 0, 83,112, 97, 99,101, 70,105,108, +101, 0,100,105,114,101,110,116,114,121, 0, 83,112, 97, 99,101, 79,111,112,115, 0, 83,112, 97, 99,101, 73,109, 97,103,101, 0, + 83,112, 97, 99,101, 84,101,120,116, 0, 85,115,101,114, 68,101,102, 0, 98, 83, 99,114,101,101,110, 0, 83, 99,114, 86,101,114, +116, 0, 83, 99,114, 69,100,103,101, 0, 83, 99,114, 65,114,101, 97, 0, 70,105,108,101, 71,108,111, 98, 97,108, 0, 83,116,114, +105,112, 69,108,101,109, 0, 83,116,114,105,112, 0, 80,108,117,103,105,110, 83,101,113, 0, 83,101,113,117,101,110, 99,101, 0, + 69,100,105,116,105,110,103, 0, 69,102,102,101, 99,116, 0, 66,117,105,108,100, 69,102,102, 0, 80, 97,114,116, 69,102,102, 0, + 80, 97,114,116,105, 99,108,101, 0, 87, 97,118,101, 69,102,102, 0, 68,101,102,111,114,109, 0, 76,105,109, 98, 0, 73,107, 97, + 0, 79,111,112,115, 0, 83,112, 97, 99,101, 73,109, 97, 83,101,108, 0, 73,109, 97, 68,105,114, 0, 79,110,101, 83,101,108,101, + 99,116, 97, 98,108,101, 73,109, 97, 0, 98, 80,114,111,112,101,114,116,121, 0, 98, 78,101, 97,114, 83,101,110,115,111,114, 0, + 98, 77,111,117,115,101, 83,101,110,115,111,114, 0, 98, 84,111,117, 99,104, 83,101,110,115,111,114, 0, 98, 75,101,121, 98,111, + 97,114,100, 83,101,110,115,111,114, 0, 98, 80,114,111,112,101,114,116,121, 83,101,110,115,111,114, 0, 98, 67,111,108,108,105, +115,105,111,110, 83,101,110,115,111,114, 0, 98, 82, 97,100, 97,114, 83,101,110,115,111,114, 0, 98, 82, 97,110,100,111,109, 83, +101,110,115,111,114, 0, 98, 82, 97,121, 83,101,110,115,111,114, 0, 98, 77,101,115,115, 97,103,101, 83,101,110,115,111,114, 0, + 98, 83,101,110,115,111,114, 0, 98, 67,111,110,116,114,111,108,108,101,114, 0, 98, 69,120,112,114,101,115,115,105,111,110, 67, +111,110,116, 0, 98, 80,121,116,104,111,110, 67,111,110,116, 0, 98, 65, 99,116,117, 97,116,111,114, 0, 98, 65,100,100, 79, 98, +106,101, 99,116, 65, 99,116,117, 97,116,111,114, 0, 98, 83,111,117,110,100, 65, 99,116,117, 97,116,111,114, 0, 98, 83,111,117, +110,100, 0, 98, 69,100,105,116, 79, 98,106,101, 99,116, 65, 99,116,117, 97,116,111,114, 0, 98, 83, 99,101,110,101, 65, 99,116, +117, 97,116,111,114, 0, 98, 80,114,111,112,101,114,116,121, 65, 99,116,117, 97,116,111,114, 0, 98, 79, 98,106,101, 99,116, 65, + 99,116,117, 97,116,111,114, 0, 98, 73,112,111, 65, 99,116,117, 97,116,111,114, 0, 98, 67, 97,109,101,114, 97, 65, 99,116,117, + 97,116,111,114, 0, 98, 67,111,110,115,116,114, 97,105,110,116, 65, 99,116,117, 97,116,111,114, 0, 98, 71,114,111,117,112, 65, + 99,116,117, 97,116,111,114, 0, 98, 82, 97,110,100,111,109, 65, 99,116,117, 97,116,111,114, 0, 98, 77,101,115,115, 97,103,101, + 65, 99,116,117, 97,116,111,114, 0, 83,101, 99,116,111,114, 0, 98, 83, 97,109,112,108,101, 0, 83,112, 97, 99,101, 83,111,117, +110,100, 0, 71,114,111,117,112, 75,101,121, 0, 79, 98,106,101, 99,116, 75,101,121, 0, 71,114,111,117,112, 79, 98,106,101, 99, +116, 0, 66,111,110,101, 0, 98, 65,114,109, 97,116,117,114,101, 0, 0, 0, 0, 84, 76, 69, 78, 1, 0, 1, 0, 2, 0, 2, 0, + 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 0, 0, 8, 0, 8, 0, 32, 0, 8, 0, 4, 0, 8, 0, 8, 0, 16, 0, 12, 0, 12, 0, + 24, 0, 16, 0, 16, 0, 32, 0, 16, 0, 16, 0, 48, 0,224, 0, 80, 0, 28, 0,116, 0, 16, 0, 20, 0,100, 0, 20, 0,108, 0, + 32, 1, 0, 0, 0, 0, 80, 0,100, 2,168, 0, 80, 1, 24, 0,136, 1,120, 0,180, 0, 52, 0, 16, 1, 64, 1, 0, 0, 72, 0, +132, 0, 0, 0, 60, 0, 28, 0, 48, 0,232, 0, 0, 0, 80, 0, 12, 0, 20, 0, 72, 0, 20, 0, 4, 0, 8, 0,184, 0, 0, 0, + 76, 0, 12, 0,120, 1,228, 0, 40, 0, 28, 0, 0, 3,128, 3, 68, 0, 40, 0, 36, 0,140, 1,112, 0,180, 0,160, 0,136, 0, + 60, 1, 0, 0,148, 0,156, 0, 88, 0,204, 1,100, 0, 20, 0, 24, 0,220, 0, 12, 0, 64, 0,108, 0,240, 0,148, 0, 28, 0, + 16, 0, 24, 0,156, 0, 0, 0, 56, 0,236, 0, 40, 0,156, 0, 44, 0,208, 2, 0, 0, 0, 0, 64, 0, 48, 0, 8, 0, 44, 0, + 8, 0,104, 0, 72, 0, 44, 0, 40, 0,108, 0,140, 0, 76, 0, 80, 0,128, 0, 4, 0, 60, 0, 12, 0, 20, 0,248, 0, 64, 0, + 16, 0, 76, 0,104, 0, 48, 0, 28, 0, 56, 0, 52, 0, 56, 0, 76, 0,148, 0, 0, 0,148, 0, 48, 0,112, 1, 20, 0, 96, 0, + 72, 0, 0, 0, 83, 84, 82, 67,128, 0, 0, 0, 10, 0, 2, 0, 10, 0, 0, 0, 10, 0, 1, 0, 11, 0, 2, 0, 9, 0, 2, 0, + 9, 0, 3, 0, 12, 0, 8, 0, 4, 0, 4, 0, 4, 0, 5, 0, 12, 0, 0, 0, 12, 0, 1, 0, 0, 0, 6, 0, 0, 0, 7, 0, + 4, 0, 8, 0, 4, 0, 9, 0, 13, 0, 2, 0, 4, 0, 10, 0, 4, 0, 11, 0, 14, 0, 2, 0, 2, 0, 12, 0, 2, 0, 13, 0, + 15, 0, 2, 0, 4, 0, 12, 0, 4, 0, 13, 0, 16, 0, 2, 0, 7, 0, 12, 0, 7, 0, 13, 0, 17, 0, 2, 0, 8, 0, 12, 0, + 8, 0, 13, 0, 18, 0, 3, 0, 4, 0, 12, 0, 4, 0, 13, 0, 4, 0, 14, 0, 19, 0, 3, 0, 7, 0, 12, 0, 7, 0, 13, 0, + 7, 0, 14, 0, 20, 0, 3, 0, 8, 0, 12, 0, 8, 0, 13, 0, 8, 0, 14, 0, 21, 0, 4, 0, 4, 0, 12, 0, 4, 0, 13, 0, + 4, 0, 14, 0, 4, 0, 15, 0, 22, 0, 4, 0, 7, 0, 12, 0, 7, 0, 13, 0, 7, 0, 14, 0, 7, 0, 15, 0, 23, 0, 4, 0, + 8, 0, 12, 0, 8, 0, 13, 0, 8, 0, 14, 0, 8, 0, 15, 0, 24, 0, 4, 0, 4, 0, 16, 0, 4, 0, 17, 0, 4, 0, 18, 0, + 4, 0, 19, 0, 25, 0, 4, 0, 7, 0, 16, 0, 7, 0, 17, 0, 7, 0, 18, 0, 7, 0, 19, 0, 26, 0, 8, 0, 9, 0, 0, 0, + 9, 0, 1, 0, 26, 0, 20, 0, 27, 0, 21, 0, 0, 0, 22, 0, 2, 0, 23, 0, 2, 0, 24, 0, 4, 0, 11, 0, 27, 0, 6, 0, + 26, 0, 25, 0, 26, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 4, 0, 29, 0, 4, 0, 11, 0, 28, 0, 6, 0, 26, 0, 25, 0, + 11, 0, 30, 0, 25, 0, 31, 0, 2, 0, 32, 0, 2, 0, 33, 0, 4, 0, 11, 0, 29, 0, 9, 0, 29, 0, 0, 0, 29, 0, 1, 0, + 7, 0, 34, 0, 2, 0, 24, 0, 2, 0, 35, 0, 2, 0, 36, 0, 2, 0, 37, 0, 4, 0, 11, 0, 9, 0, 38, 0, 30, 0, 12, 0, + 26, 0, 25, 0, 29, 0, 39, 0, 0, 0, 40, 0, 4, 0, 41, 0, 7, 0, 42, 0, 11, 0, 43, 0, 28, 0, 44, 0, 26, 0, 45, 0, + 2, 0, 36, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 48, 0, 31, 0, 5, 0, 26, 0, 49, 0, 2, 0, 50, 0, 2, 0, 51, 0, + 2, 0, 52, 0, 4, 0, 11, 0, 32, 0, 5, 0, 32, 0, 0, 0, 32, 0, 1, 0, 0, 0, 53, 0, 4, 0, 5, 0, 4, 0, 54, 0, + 33, 0, 13, 0, 26, 0, 25, 0, 0, 0, 6, 0, 4, 0, 55, 0, 4, 0, 56, 0, 11, 0, 57, 0, 32, 0, 58, 0, 32, 0, 59, 0, + 4, 0, 60, 0, 4, 0, 61, 0, 0, 0, 62, 0, 4, 0, 63, 0, 4, 0, 64, 0, 9, 0, 65, 0, 34, 0, 5, 0, 4, 0, 66, 0, + 4, 0, 67, 0, 4, 0, 55, 0, 4, 0, 11, 0, 9, 0, 38, 0, 35, 0, 15, 0, 26, 0, 25, 0, 2, 0, 36, 0, 2, 0, 24, 0, + 2, 0, 68, 0, 2, 0, 69, 0, 7, 0, 70, 0, 7, 0, 71, 0, 7, 0, 72, 0, 7, 0, 73, 0, 7, 0, 74, 0, 7, 0, 75, 0, + 7, 0, 76, 0, 7, 0, 77, 0, 28, 0, 44, 0, 31, 0, 78, 0, 36, 0, 18, 0, 26, 0, 25, 0, 0, 0, 28, 0, 37, 0, 79, 0, + 38, 0, 80, 0, 38, 0, 81, 0, 2, 0, 82, 0, 2, 0, 24, 0, 2, 0, 83, 0, 2, 0, 84, 0, 2, 0, 85, 0, 2, 0, 86, 0, + 2, 0, 87, 0, 2, 0, 88, 0, 2, 0, 89, 0, 2, 0, 90, 0, 4, 0, 91, 0, 4, 0, 92, 0, 34, 0, 93, 0, 39, 0, 22, 0, + 2, 0, 94, 0, 2, 0, 95, 0, 2, 0, 96, 0, 2, 0, 97, 0, 40, 0, 98, 0, 41, 0, 99, 0, 0, 0,100, 0, 0, 0,101, 0, + 0, 0,102, 0, 0, 0,103, 0, 7, 0,104, 0, 7, 0,105, 0, 2, 0,106, 0, 2, 0,107, 0, 7, 0,108, 0, 7, 0,109, 0, + 7, 0,110, 0, 7, 0,111, 0, 7, 0,112, 0, 7, 0,113, 0, 7, 0,114, 0, 7, 0,115, 0, 42, 0, 14, 0, 0, 0, 28, 0, + 9, 0,116, 0, 0, 0,117, 0, 0, 0,118, 0, 4, 0,119, 0, 4, 0,120, 0, 9, 0,121, 0, 7, 0,122, 0, 7, 0,123, 0, + 7, 0,124, 0, 4, 0,125, 0, 9, 0,126, 0, 4, 0,127, 0, 4, 0, 11, 0, 43, 0, 6, 0, 7, 0,108, 0, 7, 0,109, 0, + 7, 0,110, 0, 7, 0,128, 0, 7, 0, 34, 0, 4, 0, 31, 0, 44, 0, 5, 0, 2, 0, 24, 0, 2, 0, 29, 0, 2, 0, 31, 0, + 2, 0,129, 0, 43, 0,130, 0, 45, 0, 12, 0, 40, 0, 98, 0, 36, 0,131, 0, 36, 0,132, 0, 7, 0,133, 0, 2, 0, 36, 0, + 2, 0,134, 0, 7, 0, 70, 0, 7, 0, 71, 0, 4, 0,135, 0, 4, 0,136, 0, 2, 0, 82, 0, 2, 0, 83, 0, 41, 0, 35, 0, + 26, 0, 25, 0, 7, 0,137, 0, 7, 0,138, 0, 7, 0,139, 0, 7, 0,140, 0, 7, 0,141, 0, 7, 0,142, 0, 7, 0,143, 0, + 7, 0,144, 0, 2, 0,145, 0, 2, 0,146, 0, 2, 0,147, 0, 2, 0, 24, 0, 2, 0, 36, 0, 2, 0,134, 0, 7, 0,148, 0, + 7, 0,149, 0, 7, 0,150, 0, 7, 0,151, 0, 2, 0,152, 0, 2, 0,153, 0, 2, 0,154, 0, 2, 0, 5, 0, 2, 0,155, 0, + 2, 0,156, 0, 2, 0,157, 0, 2, 0,158, 0, 7, 0,114, 0, 7, 0,159, 0, 28, 0, 44, 0, 36, 0,131, 0, 42, 0,160, 0, + 44, 0,161, 0, 45, 0,162, 0, 2, 0,163, 0, 46, 0, 28, 0, 26, 0, 25, 0, 2, 0, 36, 0, 2, 0,164, 0, 2, 0,107, 0, + 2, 0,165, 0, 7, 0,108, 0, 7, 0,109, 0, 7, 0,110, 0, 7, 0,111, 0, 7, 0,166, 0, 7, 0,167, 0, 7, 0,168, 0, + 7, 0,169, 0, 7, 0,170, 0, 7, 0,171, 0, 7, 0,172, 0, 2, 0,173, 0, 2, 0,174, 0, 7, 0, 70, 0, 7, 0, 71, 0, + 7, 0,175, 0, 7, 0,176, 0, 7, 0,177, 0, 2, 0,178, 0, 2, 0,179, 0, 39, 0,180, 0, 28, 0, 44, 0, 31, 0, 78, 0, + 47, 0, 2, 0, 26, 0, 25, 0, 28, 0, 44, 0, 48, 0, 58, 0, 26, 0, 25, 0, 2, 0,107, 0, 2, 0,181, 0, 7, 0,108, 0, + 7, 0,109, 0, 7, 0,110, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, + 7, 0,188, 0, 7, 0,189, 0, 7, 0,190, 0, 7, 0,191, 0, 7, 0,192, 0, 7, 0,193, 0, 7, 0,194, 0, 7, 0,195, 0, + 7, 0,196, 0, 7, 0,197, 0, 7, 0,198, 0, 7, 0,199, 0, 7, 0,200, 0, 2, 0,201, 0, 0, 0,202, 0, 0, 0,203, 0, + 4, 0,164, 0, 4, 0,204, 0, 2, 0,205, 0, 2, 0,206, 0, 2, 0,207, 0, 2, 0,208, 0, 7, 0,209, 0, 7, 0,210, 0, + 7, 0,211, 0, 7, 0,212, 0, 0, 0,213, 0, 0, 0,178, 0, 0, 0,214, 0, 0, 0,215, 0, 2, 0,216, 0, 2, 0,217, 0, + 4, 0,218, 0, 2, 0, 94, 0, 2, 0, 95, 0, 39, 0,180, 0, 28, 0, 44, 0, 48, 0,219, 0, 7, 0,220, 0, 7, 0,221, 0, + 7, 0,222, 0, 7, 0,223, 0, 7, 0,224, 0, 2, 0,225, 0, 2, 0, 11, 0, 31, 0, 78, 0, 49, 0, 8, 0, 26, 0, 25, 0, + 0, 0,226, 0, 0, 0,227, 0, 7, 0,228, 0, 2, 0, 24, 0, 2, 0, 37, 0, 50, 0, 38, 0, 34, 0, 93, 0, 51, 0, 20, 0, + 51, 0, 0, 0, 51, 0, 1, 0, 2, 0, 36, 0, 2, 0,181, 0, 2, 0, 24, 0, 2, 0,229, 0, 7, 0, 12, 0, 7, 0, 13, 0, + 7, 0, 14, 0, 7, 0,230, 0, 7, 0,231, 0, 7, 0,232, 0, 7, 0,233, 0, 7, 0,234, 0, 7, 0,235, 0, 7, 0, 5, 0, + 7, 0,236, 0, 4, 0, 11, 0, 7, 0,237, 0, 7, 0,238, 0, 52, 0, 15, 0, 26, 0, 25, 0, 53, 0,239, 0, 11, 0,240, 0, + 11, 0,241, 0, 28, 0, 44, 0, 48, 0,242, 0, 2, 0, 24, 0, 2, 0,243, 0, 4, 0,106, 0, 7, 0,244, 0, 7, 0,105, 0, + 7, 0,245, 0, 7, 0,246, 0, 7, 0,247, 0, 7, 0,248, 0, 54, 0, 9, 0, 7, 0,249, 0, 7, 0,250, 0, 2, 0,251, 0, + 2, 0,252, 0, 2, 0,253, 0, 0, 0,254, 0, 0, 0,255, 0, 0, 0, 0, 1, 0, 0, 1, 1, 55, 0, 5, 0, 7, 0, 2, 1, + 7, 0,250, 0, 2, 0, 3, 1, 2, 0,254, 0, 2, 0, 1, 1, 56, 0, 18, 0, 56, 0, 0, 0, 56, 0, 1, 0, 2, 0, 36, 0, + 2, 0, 4, 1, 2, 0, 1, 1, 2, 0, 24, 0, 2, 0, 5, 1, 2, 0, 6, 1, 2, 0, 7, 1, 2, 0, 8, 1, 2, 0, 9, 1, + 2, 0, 10, 1, 2, 0, 11, 1, 2, 0, 12, 1, 7, 0, 13, 1, 7, 0, 14, 1, 55, 0, 15, 1, 54, 0, 16, 1, 57, 0, 38, 0, + 26, 0, 25, 0, 53, 0,239, 0, 11, 0, 17, 1, 11, 0,241, 0, 40, 0, 18, 1, 40, 0, 19, 1, 28, 0, 44, 0, 58, 0, 20, 1, + 30, 0, 21, 1, 48, 0,242, 0, 11, 0, 22, 1, 7, 0, 23, 1, 7, 0,244, 0, 7, 0,105, 0, 7, 0,245, 0, 4, 0,106, 0, + 2, 0, 24, 1, 2, 0,243, 0, 2, 0, 24, 0, 2, 0, 25, 1, 7, 0, 26, 1, 7, 0, 27, 1, 7, 0, 28, 1, 2, 0, 7, 1, + 2, 0, 8, 1, 2, 0, 5, 0, 2, 0, 57, 0, 2, 0, 34, 0, 2, 0, 29, 1, 7, 0, 30, 1, 7, 0, 31, 1, 7, 0, 32, 1, + 7, 0, 33, 1, 7, 0, 34, 1, 7, 0, 35, 1, 0, 0, 36, 1, 0, 0, 37, 1, 49, 0, 38, 1, 59, 0, 18, 0, 59, 0, 0, 0, + 59, 0, 1, 0, 55, 0, 15, 1, 54, 0, 16, 1, 25, 0, 39, 1, 25, 0, 40, 1, 2, 0, 32, 0, 2, 0, 41, 1, 2, 0, 42, 1, + 2, 0, 43, 1, 2, 0, 44, 1, 2, 0, 45, 1, 2, 0, 24, 0, 2, 0, 37, 0, 7, 0, 18, 0, 7, 0, 19, 0, 4, 0, 46, 1, + 7, 0, 42, 0, 60, 0, 8, 0, 3, 0, 47, 1, 3, 0, 48, 1, 3, 0, 49, 1, 3, 0, 50, 1, 0, 0, 51, 1, 0, 0, 4, 1, + 0, 0, 52, 1, 0, 0, 24, 0, 61, 0, 8, 0, 4, 0, 47, 1, 4, 0, 48, 1, 4, 0, 49, 1, 4, 0, 50, 1, 0, 0, 51, 1, + 0, 0, 4, 1, 0, 0, 52, 1, 0, 0, 24, 0, 62, 0, 10, 0, 7, 0, 53, 1, 4, 0, 54, 1, 2, 0, 55, 1, 0, 0, 24, 0, + 0, 0, 56, 1, 2, 0,164, 0, 2, 0, 57, 1, 4, 0, 11, 0, 9, 0, 58, 1, 9, 0, 59, 1, 63, 0, 4, 0, 7, 0, 60, 1, + 2, 0, 55, 1, 0, 0, 24, 0, 0, 0, 4, 1, 64, 0, 4, 0, 0, 0,128, 0, 0, 0,108, 0, 0, 0,109, 0, 0, 0,110, 0, + 65, 0, 1, 0, 7, 0, 61, 1, 66, 0, 29, 0, 26, 0, 25, 0, 53, 0,239, 0, 11, 0, 62, 1, 11, 0,241, 0, 28, 0, 44, 0, + 30, 0, 21, 1, 48, 0,242, 0, 9, 0, 63, 1, 9, 0, 64, 1, 9, 0, 65, 1, 63, 0, 66, 1, 64, 0, 67, 1, 65, 0, 68, 1, + 66, 0, 69, 1, 7, 0, 23, 1, 67, 0, 70, 1, 9, 0, 71, 1, 4, 0, 43, 1, 4, 0, 72, 1, 4, 0,106, 0, 7, 0,244, 0, + 7, 0,105, 0, 7, 0,245, 0, 2, 0, 73, 1, 2, 0, 24, 0, 2, 0, 74, 1, 2, 0,243, 0, 7, 0, 75, 1, 7, 0, 76, 1, + 68, 0, 13, 0, 26, 0, 25, 0, 2, 0, 5, 1, 2, 0, 6, 1, 2, 0, 77, 1, 2, 0, 24, 0, 0, 0, 78, 1, 0, 0, 79, 1, + 0, 0, 80, 1, 0, 0, 36, 0, 4, 0, 11, 0, 55, 0, 81, 1, 28, 0, 44, 0, 30, 0, 21, 1, 69, 0, 4, 0, 2, 0, 29, 0, + 2, 0, 82, 1, 4, 0, 11, 0, 40, 0, 83, 1, 40, 0, 69, 0, 26, 0, 25, 0, 2, 0, 36, 0, 2, 0, 84, 1, 4, 0, 85, 1, + 4, 0, 86, 1, 4, 0, 87, 1, 40, 0, 88, 1, 40, 0, 89, 1, 28, 0, 44, 0, 58, 0, 20, 1, 53, 0,239, 0, 9, 0, 38, 0, + 11, 0, 62, 1, 11, 0, 90, 1, 11, 0,241, 0, 48, 0,242, 0, 70, 0, 91, 1, 7, 0,244, 0, 7, 0, 92, 1, 7, 0, 93, 1, + 7, 0,105, 0, 7, 0, 94, 1, 7, 0,245, 0, 7, 0, 95, 1, 7, 0, 96, 1, 7, 0, 97, 1, 7, 0, 98, 1, 7, 0, 99, 1, + 7, 0,133, 0, 4, 0,181, 0, 2, 0, 24, 0, 2, 0,100, 1, 0, 0,101, 1, 0, 0,102, 1, 0, 0,103, 1, 0, 0,104, 1, + 2, 0,105, 1, 2, 0,106, 1, 2, 0,107, 1, 2, 0,108, 1, 2, 0,109, 1, 2, 0,110, 1, 2, 0,111, 1, 2, 0,112, 1, + 7, 0,113, 1, 7, 0,114, 1, 7, 0,115, 1, 7, 0,116, 1, 7, 0,117, 1, 7, 0,118, 1, 7, 0,119, 1, 0, 0,120, 1, + 0, 0,121, 1, 0, 0,243, 0, 0, 0,122, 1, 31, 0, 78, 0, 11, 0,123, 1, 11, 0,124, 1, 11, 0,125, 1, 11, 0,126, 1, + 9, 0, 71, 1, 69, 0,127, 1, 69, 0,128, 1, 7, 0,129, 1, 2, 0,130, 1, 2, 0,218, 0, 7, 0, 54, 1, 4, 0,131, 1, + 7, 0,132, 1, 71, 0, 41, 0, 26, 0, 25, 0, 2, 0,107, 0, 2, 0,165, 0, 2, 0,178, 0, 2, 0,133, 1, 7, 0,134, 1, + 7, 0,135, 1, 7, 0,136, 1, 7, 0,137, 1, 7, 0,138, 1, 7, 0,139, 1, 7, 0,140, 1, 7, 0,141, 1, 7, 0,188, 0, + 7, 0,190, 0, 7, 0,189, 0, 7, 0,142, 1, 4, 0,143, 1, 7, 0,144, 1, 7, 0,145, 1, 2, 0,146, 1, 2, 0,164, 0, + 7, 0,147, 1, 7, 0,148, 1, 7, 0,149, 1, 7, 0,150, 1, 7, 0,151, 1, 7, 0,152, 1, 7, 0,153, 1, 7, 0,154, 1, + 7, 0,155, 1, 7, 0,156, 1, 7, 0,157, 1, 7, 0,158, 1, 2, 0,159, 1, 2, 0,160, 1, 2, 0,161, 1, 2, 0,162, 1, + 28, 0, 44, 0, 39, 0,180, 0, 31, 0, 78, 0, 72, 0, 16, 0, 2, 0,163, 1, 2, 0,164, 1, 2, 0,165, 1, 2, 0, 24, 0, + 2, 0,166, 1, 2, 0,167, 1, 2, 0,168, 1, 2, 0,169, 1, 2, 0,170, 1, 2, 0,171, 1, 2, 0,172, 1, 2, 0,173, 1, + 4, 0,174, 1, 7, 0,175, 1, 7, 0,176, 1, 7, 0,177, 1, 73, 0, 8, 0, 73, 0, 0, 0, 73, 0, 1, 0, 4, 0,181, 0, + 4, 0,229, 0, 4, 0, 24, 0, 2, 0,178, 1, 2, 0,179, 1, 40, 0, 98, 0, 74, 0, 43, 0, 2, 0,180, 1, 2, 0,157, 0, + 2, 0,181, 1, 2, 0,182, 1, 2, 0,183, 1, 2, 0, 24, 0, 7, 0,114, 1, 7, 0,184, 1, 7, 0,185, 1, 7, 0,186, 1, + 7, 0,187, 1, 7, 0,188, 1, 2, 0, 66, 0, 2, 0,189, 1, 2, 0,190, 1, 2, 0,191, 1, 2, 0,192, 1, 2, 0,193, 1, + 2, 0,194, 1, 2, 0,195, 1, 25, 0,196, 1, 25, 0,197, 1, 2, 0,198, 1, 2, 0,199, 1, 2, 0,200, 1, 2, 0,201, 1, + 2, 0,202, 1, 2, 0,203, 1, 2, 0,164, 0, 2, 0,204, 1, 2, 0,205, 1, 2, 0,206, 1, 2, 0,207, 1, 2, 0,208, 1, + 7, 0,177, 1, 7, 0,209, 1, 7, 0,210, 1, 7, 0,211, 1, 7, 0,212, 1, 0, 0,213, 1, 0, 0,214, 1, 0, 0,215, 1, + 0, 0,216, 1, 75, 0, 16, 0, 26, 0, 25, 0, 40, 0,217, 1, 71, 0,218, 1, 75, 0,219, 1, 36, 0,131, 0, 11, 0,220, 1, + 73, 0,221, 1, 76, 0,222, 1, 7, 0,223, 1, 4, 0,181, 0, 77, 0,224, 1, 9, 0,225, 1, 72, 0,226, 1, 9, 0, 71, 1, + 74, 0,108, 0, 31, 0, 78, 0, 78, 0, 10, 0, 36, 0,131, 0, 41, 0, 99, 0, 7, 0, 34, 1, 7, 0, 35, 1, 7, 0, 66, 0, + 7, 0,227, 1, 7, 0,228, 1, 2, 0,229, 1, 2, 0,230, 1, 4, 0,231, 1, 79, 0, 42, 0, 79, 0, 0, 0, 79, 0, 1, 0, + 4, 0,232, 1, 7, 0,233, 1, 7, 0,234, 1, 7, 0,235, 1, 7, 0,236, 1, 7, 0,237, 1, 7, 0,167, 0, 2, 0,238, 1, + 2, 0,239, 1, 2, 0,165, 1, 2, 0,240, 1, 4, 0,181, 0, 4, 0,241, 1, 2, 0,242, 1, 2, 0,243, 1, 2, 0,244, 1, + 2, 0, 24, 0, 7, 0, 74, 0, 7, 0,245, 1, 7, 0,246, 1, 7, 0,247, 1, 7, 0,104, 0, 7, 0,223, 1, 40, 0,217, 1, + 2, 0,248, 1, 2, 0,249, 1, 2, 0,250, 1, 2, 0,251, 1, 2, 0,252, 1, 2, 0,253, 1, 2, 0,254, 1, 2, 0,255, 1, + 2, 0, 0, 2, 2, 0, 1, 2, 2, 0, 2, 2, 2, 0, 3, 2, 7, 0, 4, 2, 7, 0, 5, 2, 78, 0, 6, 2, 79, 0, 7, 2, + 80, 0, 13, 0, 25, 0, 29, 0, 25, 0, 31, 0, 24, 0, 8, 2, 24, 0, 9, 2, 24, 0, 10, 2, 7, 0, 11, 2, 7, 0, 12, 2, + 7, 0, 13, 2, 7, 0, 14, 2, 2, 0, 15, 2, 2, 0, 16, 2, 2, 0, 17, 2, 2, 0, 18, 2, 81, 0, 18, 0, 81, 0, 0, 0, + 81, 0, 1, 0, 4, 0,232, 1, 4, 0, 19, 2, 80, 0, 20, 2, 9, 0, 21, 2, 11, 0, 22, 2, 28, 0, 44, 0, 26, 0, 45, 0, + 2, 0, 23, 2, 2, 0, 24, 2, 2, 0, 25, 2, 2, 0, 26, 2, 2, 0, 33, 0, 2, 0, 32, 0, 2, 0, 27, 2, 2, 0, 37, 0, + 25, 0, 29, 0, 82, 0, 21, 0, 82, 0, 0, 0, 82, 0, 1, 0, 4, 0,232, 1, 2, 0, 28, 2, 2, 0, 29, 2, 80, 0, 20, 2, + 2, 0, 30, 2, 2, 0, 27, 2, 2, 0, 24, 2, 2, 0, 31, 2, 9, 0, 32, 2, 2, 0, 33, 2, 0, 0, 34, 2, 0, 0, 35, 2, + 2, 0, 36, 2, 2, 0, 37, 2, 4, 0,231, 1, 2, 0, 38, 2, 2, 0, 39, 2, 2, 0, 40, 2, 2, 0,106, 1, 83, 0, 8, 0, + 83, 0, 0, 0, 83, 0, 1, 0, 4, 0,232, 1, 4, 0,218, 0, 80, 0, 20, 2, 2, 0, 30, 2, 2, 0,227, 1, 4, 0, 41, 2, + 84, 0, 21, 0, 84, 0, 0, 0, 84, 0, 1, 0, 4, 0,232, 1, 4, 0, 11, 0, 85, 0, 42, 2, 4, 0, 43, 2, 0, 0, 44, 2, + 0, 0, 45, 2, 0, 0, 46, 2, 2, 0, 36, 0, 2, 0, 47, 2, 2, 0, 24, 0, 2, 0, 48, 2, 2, 0, 49, 2, 2, 0, 50, 2, + 0, 0, 51, 2, 2, 0, 52, 2, 2, 0,129, 0, 2, 0, 53, 2, 2, 0, 54, 2, 9, 0, 55, 2, 86, 0, 11, 0, 86, 0, 0, 0, + 86, 0, 1, 0, 4, 0,232, 1, 4, 0, 11, 0, 80, 0, 20, 2, 11, 0, 56, 2, 2, 0, 24, 2, 2, 0, 57, 2, 2, 0, 24, 0, + 2, 0, 37, 0, 9, 0, 32, 2, 87, 0, 16, 0, 87, 0, 0, 0, 87, 0, 1, 0, 4, 0,232, 1, 4, 0, 11, 0, 80, 0, 20, 2, + 36, 0, 58, 2, 7, 0,227, 1, 7, 0, 41, 2, 2, 0,164, 0, 2, 0, 59, 2, 2, 0, 60, 2, 2, 0, 61, 2, 2, 0, 34, 1, + 2, 0, 35, 1, 2, 0, 24, 0, 2, 0, 24, 2, 88, 0, 17, 0, 88, 0, 0, 0, 88, 0, 1, 0, 4, 0,232, 1, 4, 0, 62, 2, + 33, 0, 63, 2, 4, 0, 64, 2, 4, 0, 65, 2, 2, 0, 55, 0, 2, 0, 27, 2, 4, 0, 66, 2, 4, 0, 67, 2, 7, 0, 68, 2, + 24, 0, 69, 2, 24, 0, 70, 2, 9, 0, 71, 2, 9, 0, 72, 2, 9, 0, 73, 2, 89, 0, 12, 0, 2, 0, 24, 0, 2, 0, 74, 2, + 4, 0, 75, 2, 0, 0, 76, 2, 0, 0, 77, 2, 0, 0, 78, 2, 0, 0, 79, 2, 0, 0, 80, 2, 0, 0, 81, 2, 0, 0, 82, 2, + 2, 0, 83, 2, 2, 0, 37, 0, 90, 0, 17, 0, 26, 0, 25, 0, 11, 0, 84, 2, 11, 0, 85, 2, 11, 0, 86, 2, 75, 0, 87, 2, + 2, 0, 88, 2, 2, 0, 89, 2, 2, 0, 90, 2, 2, 0, 91, 2, 2, 0, 92, 2, 2, 0, 93, 2, 2, 0, 94, 2, 2, 0, 95, 2, + 2, 0, 96, 2, 2, 0, 37, 0, 2, 0, 97, 2, 2, 0, 98, 2, 91, 0, 5, 0, 91, 0, 0, 0, 91, 0, 1, 0, 91, 0, 99, 2, + 14, 0,100, 2, 4, 0, 24, 0, 92, 0, 7, 0, 92, 0, 0, 0, 92, 0, 1, 0, 91, 0,101, 2, 91, 0,102, 2, 2, 0,197, 1, + 2, 0, 24, 0, 4, 0, 11, 0, 93, 0, 38, 0, 93, 0, 0, 0, 93, 0, 1, 0, 91, 0,101, 2, 91, 0,102, 2, 91, 0,103, 2, + 91, 0,104, 2, 90, 0,105, 2, 2, 0,106, 2, 2, 0,107, 2, 2, 0,108, 2, 2, 0,109, 2, 7, 0,110, 2, 24, 0, 40, 1, + 24, 0,111, 2, 24, 0,112, 2, 2, 0,113, 2, 2, 0,114, 2, 2, 0,115, 2, 0, 0,232, 1, 0, 0,116, 2, 2, 0,117, 2, + 2, 0,118, 2, 0, 0,119, 2, 0, 0,120, 2, 0, 0,121, 2, 0, 0,122, 2, 2, 0,123, 2, 2, 0,124, 2, 2, 0,125, 2, + 2, 0, 37, 0, 9, 0,126, 2, 9, 0,127, 2, 9, 0,128, 2, 9, 0,129, 2, 9, 0,130, 2, 9, 0,131, 2, 11, 0,132, 2, + 11, 0,133, 2, 94, 0, 4, 0, 9, 0,134, 2, 2, 0,135, 2, 2, 0,198, 1, 4, 0,136, 2, 95, 0, 8, 0, 0, 0,137, 2, + 38, 0, 80, 0, 95, 0,138, 2, 95, 0,139, 2, 95, 0,140, 2, 2, 0, 82, 0, 2, 0,141, 2, 4, 0, 11, 0, 96, 0, 11, 0, + 96, 0, 0, 0, 96, 0, 1, 0, 2, 0, 37, 0, 2, 0, 5, 0, 2, 0, 23, 0, 2, 0,142, 2, 95, 0,143, 2, 0, 0,144, 2, + 2, 0,145, 2, 2, 0,146, 2, 4, 0, 11, 0, 97, 0, 10, 0, 0, 0,147, 2, 9, 0,116, 0, 0, 0,117, 0, 4, 0,120, 0, + 4, 0,127, 0, 9, 0,121, 0, 7, 0,123, 0, 7, 0,124, 0, 9, 0,125, 0, 9, 0,126, 0, 98, 0, 32, 0, 98, 0, 0, 0, + 98, 0, 1, 0, 98, 0,148, 2, 9, 0, 21, 0, 0, 0, 22, 0, 2, 0, 24, 0, 2, 0, 36, 0, 4, 0, 5, 0, 4, 0,149, 2, + 4, 0,150, 2, 4, 0,151, 2, 4, 0,152, 2, 4, 0,153, 2, 4, 0,154, 2, 4, 0,155, 2, 4, 0,156, 2, 4, 0,157, 2, + 7, 0,158, 2, 7, 0,159, 2, 4, 0,157, 0, 96, 0,160, 2, 95, 0,161, 2, 28, 0, 44, 0, 75, 0, 87, 2, 37, 0, 79, 0, + 7, 0,162, 2, 7, 0,163, 2, 97, 0,160, 0, 98, 0,164, 2, 98, 0,165, 2, 98, 0,166, 2, 11, 0,167, 2, 99, 0, 6, 0, + 11, 0,168, 2, 11, 0,167, 2, 11, 0,169, 2, 2, 0, 24, 0, 2, 0, 37, 0, 4, 0, 11, 0,100, 0, 6, 0,100, 0, 0, 0, +100, 0, 1, 0, 2, 0, 36, 0, 2, 0, 24, 0, 2, 0,170, 2, 2, 0, 37, 0,101, 0, 8, 0,101, 0, 0, 0,101, 0, 1, 0, + 2, 0, 36, 0, 2, 0, 24, 0, 2, 0,170, 2, 2, 0, 37, 0, 7, 0, 5, 0, 7, 0,157, 0,102, 0, 31, 0,102, 0, 0, 0, +102, 0, 1, 0, 2, 0, 36, 0, 2, 0, 24, 0, 2, 0,170, 2, 2, 0,134, 0, 7, 0,171, 2, 7, 0,172, 2, 7, 0,173, 2, + 4, 0,174, 2, 4, 0, 46, 0, 4, 0,175, 2, 7, 0,176, 2, 7, 0,177, 2, 7, 0,178, 2, 7, 0,179, 2, 7, 0,180, 2, + 7, 0,181, 2, 7, 0,182, 2, 7, 0,183, 2, 7, 0,184, 2, 7, 0,185, 2, 7, 0,186, 2, 7, 0,187, 2, 2, 0,188, 2, + 2, 0,189, 2, 2, 0,190, 2, 2, 0,191, 2, 2, 0,192, 2, 2, 0, 11, 0,103, 0,193, 2,104, 0, 16, 0,104, 0, 0, 0, +104, 0, 1, 0, 2, 0, 36, 0, 2, 0, 24, 0, 2, 0,170, 2, 2, 0,134, 0, 7, 0, 88, 2, 7, 0, 90, 2, 7, 0,194, 2, + 7, 0, 26, 1, 7, 0,195, 2, 7, 0,196, 2, 7, 0,197, 2, 7, 0,182, 2, 7, 0,198, 2, 7, 0,173, 2,105, 0, 13, 0, + 40, 0,199, 2, 2, 0, 24, 0, 2, 0, 84, 1, 4, 0, 85, 1, 4, 0, 86, 1, 4, 0, 87, 1, 7, 0,133, 0, 7, 0,200, 2, + 7, 0,201, 2, 7, 0,202, 2, 7, 0,203, 2, 7, 0,167, 0, 7, 0, 11, 0,106, 0, 9, 0,106, 0, 0, 0,106, 0, 1, 0, + 7, 0, 5, 0, 7, 0,204, 2, 7, 0,203, 2, 7, 0,195, 0, 7, 0,205, 2, 7, 0, 11, 0, 7, 0,206, 2,107, 0, 23, 0, + 26, 0, 25, 0, 2, 0, 84, 1, 2, 0, 24, 0, 2, 0,207, 2, 2, 0,208, 2, 11, 0,209, 2, 7, 0,210, 2, 7, 0,211, 2, + 7, 0,212, 2, 7, 0,213, 2, 7, 0,214, 2, 7, 0,215, 2, 7, 0,216, 2, 7, 0,217, 2, 28, 0, 44, 0, 40, 0, 88, 1, + 4, 0, 85, 1, 4, 0, 86, 1, 4, 0, 87, 1, 4, 0,218, 2,105, 0, 81, 1, 4, 0,219, 2, 4, 0,220, 2,108, 0, 12, 0, +108, 0, 0, 0,108, 0, 1, 0, 2, 0, 36, 0, 2, 0, 24, 0, 2, 0,120, 1, 2, 0, 1, 1, 7, 0, 12, 0, 7, 0, 13, 0, + 7, 0,221, 2, 7, 0,222, 2, 26, 0,223, 2, 11, 0,224, 2,109, 0, 78, 0,109, 0, 0, 0,109, 0, 1, 0, 4, 0,232, 1, + 0, 0, 44, 2, 4, 0,225, 2, 2, 0,164, 0, 2, 0,226, 2, 2, 0,227, 2, 2, 0,228, 2, 2, 0,248, 1, 2, 0,249, 1, + 2, 0,229, 2, 2, 0,230, 2, 2, 0,231, 2, 2, 0,232, 2, 2, 0,233, 2, 2, 0,234, 2, 2, 0,235, 2, 2, 0,236, 2, + 2, 0,237, 2, 2, 0,238, 2, 2, 0,239, 2, 2, 0,240, 2, 2, 0,241, 2, 2, 0,242, 2, 2, 0,243, 2, 2, 0,244, 2, + 2, 0,245, 2, 2, 0,246, 2, 2, 0,247, 2, 2, 0,248, 2, 2, 0,249, 2, 2, 0,250, 2, 2, 0,251, 2, 2, 0,252, 2, + 2, 0,253, 2, 2, 0,254, 2, 2, 0,255, 2, 2, 0, 0, 3, 2, 0, 1, 3, 2, 0, 2, 3, 2, 0, 3, 3, 2, 0, 4, 3, + 2, 0, 5, 3, 2, 0, 6, 3, 2, 0, 7, 3, 2, 0, 8, 3, 2, 0, 9, 3, 2, 0, 10, 3, 2, 0, 11, 3, 2, 0, 12, 3, + 2, 0, 13, 3, 2, 0, 14, 3, 0, 0, 15, 3, 0, 0, 16, 3, 0, 0, 17, 3, 0, 0, 18, 3,110, 0, 19, 3,110, 0, 20, 3, + 4, 0, 21, 3, 4, 0, 22, 3, 4, 0, 23, 3, 4, 0, 24, 3, 4, 0, 25, 3, 7, 0, 26, 3, 7, 0, 27, 3, 7, 0, 28, 3, + 2, 0, 29, 3, 2, 0, 30, 3, 2, 0, 31, 3, 2, 0, 32, 3,111, 0, 33, 3,111, 0, 34, 3, 2, 0, 35, 3, 2, 0, 36, 3, + 4, 0, 11, 0, 38, 0, 37, 3, 9, 0, 55, 2,112, 0, 11, 0,112, 0, 0, 0,112, 0, 1, 0, 0, 0, 38, 3, 2, 0, 36, 0, + 2, 0, 39, 3, 4, 0, 40, 3, 4, 0, 41, 3, 2, 0, 24, 0, 2, 0, 11, 0, 9, 0, 42, 3, 9, 0, 43, 3,113, 0, 5, 0, + 0, 0, 38, 3, 7, 0,167, 0, 7, 0, 44, 3, 4, 0, 45, 3, 4, 0, 11, 0,114, 0, 3, 0, 2, 0, 36, 0, 2, 0, 24, 0, + 4, 0, 11, 0,115, 0, 4, 0, 0, 0, 38, 3, 48, 0, 46, 3, 7, 0,167, 0, 7, 0, 11, 0,116, 0, 4, 0, 2, 0, 47, 3, + 2, 0, 48, 3, 2, 0, 36, 0, 2, 0, 49, 3,117, 0, 5, 0, 4, 0, 36, 0, 4, 0, 11, 0, 0, 0, 38, 3, 0, 0, 50, 3, + 0, 0, 51, 3,118, 0, 6, 0, 0, 0, 38, 3, 0, 0, 52, 3, 2, 0, 53, 3, 2, 0,182, 2, 2, 0,164, 0, 2, 0, 41, 2, +119, 0, 5, 0, 0, 0, 38, 3, 7, 0, 54, 3, 7, 0, 55, 3, 2, 0, 24, 0, 2, 0, 56, 3,120, 0, 3, 0, 0, 0, 38, 3, + 4, 0,175, 2, 4, 0, 57, 3,121, 0, 7, 0, 0, 0, 38, 3, 7, 0, 55, 3, 0, 0, 58, 3, 0, 0, 59, 3, 2, 0,164, 0, + 2, 0,218, 0, 4, 0, 60, 3,122, 0, 8, 0, 40, 0, 61, 3, 2, 0, 36, 0, 2, 0, 62, 3, 4, 0, 11, 0, 0, 0, 63, 3, + 0, 0, 58, 3, 0, 0, 50, 3, 0, 0, 51, 3,123, 0, 17, 0,123, 0, 0, 0,123, 0, 1, 0, 2, 0, 36, 0, 2, 0, 39, 3, + 2, 0, 24, 0, 2, 0, 64, 3, 2, 0, 65, 3, 2, 0, 66, 3, 2, 0,218, 0, 2, 0, 41, 2, 0, 0, 38, 3, 9, 0, 38, 0, +124, 0, 67, 3, 40, 0,199, 2, 2, 0, 68, 3, 2, 0, 69, 3, 4, 0, 11, 0,125, 0, 1, 0, 0, 0, 70, 3,126, 0, 1, 0, + 33, 0, 63, 2,124, 0, 18, 0,124, 0, 0, 0,124, 0, 1, 0,124, 0, 71, 3, 2, 0, 36, 0, 2, 0, 24, 0, 2, 0, 72, 3, + 2, 0, 66, 3, 2, 0, 39, 3, 2, 0, 73, 3, 2, 0, 41, 2, 2, 0, 59, 2, 0, 0, 38, 3, 9, 0, 38, 0,127, 0, 67, 3, +123, 0, 74, 3, 2, 0, 75, 3, 2, 0, 76, 3, 4, 0, 77, 3,128, 0, 3, 0, 4, 0, 78, 3, 4, 0, 11, 0, 40, 0,199, 2, +129, 0, 7, 0, 2, 0, 24, 0, 2, 0, 79, 3, 2, 0,171, 2, 2, 0,172, 2,130, 0, 80, 3, 2, 0, 36, 0, 2, 0, 81, 3, +131, 0, 9, 0, 4, 0, 78, 3, 2, 0, 36, 0, 2, 0, 24, 0, 40, 0,199, 2, 66, 0, 82, 3, 0, 0, 38, 3, 7, 0, 83, 3, + 2, 0, 84, 3, 2, 0, 11, 0,132, 0, 5, 0, 2, 0, 36, 0, 2, 0, 24, 0, 4, 0, 11, 0, 75, 0, 87, 2, 40, 0,217, 1, +133, 0, 5, 0, 4, 0, 24, 0, 4, 0, 36, 0, 0, 0, 38, 3, 0, 0, 50, 3, 40, 0,199, 2,134, 0, 10, 0, 4, 0, 24, 0, + 4, 0, 11, 0, 7, 0, 85, 3, 7, 0, 86, 3, 7, 0,244, 0, 7, 0,245, 0, 7, 0, 92, 1, 7, 0, 95, 1, 7, 0, 87, 3, + 7, 0, 88, 3,135, 0, 9, 0, 2, 0, 24, 0, 2, 0, 36, 0, 2, 0,171, 2, 2, 0,172, 2, 0, 0, 38, 3, 2, 0,218, 0, + 2, 0, 31, 0, 2, 0, 89, 3, 2, 0, 90, 3,136, 0, 8, 0, 40, 0,199, 2, 7, 0,194, 2, 7, 0, 91, 3, 7, 0, 82, 1, + 7, 0,203, 2, 2, 0, 24, 0, 2, 0, 56, 3, 7, 0, 92, 3,137, 0, 7, 0, 2, 0, 24, 0, 2, 0,182, 2, 7, 0,214, 2, + 7, 0, 93, 3, 7, 0, 94, 3, 7, 0, 95, 3, 7, 0, 96, 3,138, 0, 10, 0, 2, 0, 24, 0, 2, 0, 36, 0, 2, 0,171, 2, + 2, 0,172, 2, 0, 0, 38, 3, 2, 0,218, 0, 2, 0, 31, 0, 2, 0, 89, 3, 2, 0, 90, 3, 76, 0,222, 1,139, 0, 7, 0, + 4, 0,175, 2, 4, 0, 97, 3, 4, 0, 98, 3, 4, 0, 99, 3, 7, 0,100, 3, 7, 0,101, 3, 0, 0, 58, 3,140, 0, 5, 0, + 40, 0,102, 3, 4, 0, 36, 0, 4, 0, 11, 0, 0, 0, 63, 3, 0, 0, 58, 3,127, 0, 10, 0,127, 0, 0, 0,127, 0, 1, 0, +127, 0, 71, 3, 2, 0, 36, 0, 2, 0, 24, 0, 2, 0, 39, 3, 2, 0,103, 3, 0, 0, 38, 3, 9, 0, 38, 0, 40, 0,199, 2, + 77, 0, 10, 0, 7, 0,115, 1, 7, 0,104, 3, 7, 0,105, 3, 7, 0,106, 3, 7, 0,107, 3, 4, 0, 24, 0, 7, 0,108, 3, + 7, 0,109, 3, 7, 0,110, 3, 7, 0, 11, 0,141, 0, 24, 0, 26, 0, 25, 0, 40, 0,199, 2, 2, 0, 36, 0, 2, 0, 24, 0, + 2, 0,111, 3, 2, 0,112, 3, 9, 0,113, 3, 69, 0,127, 1, 9, 0,114, 3, 9, 0,115, 3, 11, 0, 44, 1, 66, 0,116, 3, + 66, 0,117, 3, 2, 0,118, 3, 2, 0,180, 1, 2, 0,119, 3, 2, 0,157, 0, 2, 0,155, 2, 2, 0, 37, 0, 7, 0,105, 0, + 7, 0,129, 1, 7, 0,108, 0, 7, 0,109, 0, 7, 0,110, 0, 70, 0, 45, 0, 26, 0, 25, 0, 9, 0,120, 3, 7, 0,121, 3, + 7, 0,244, 0, 7, 0,122, 3, 7, 0,123, 3, 7, 0,124, 3, 7, 0,125, 3, 7, 0,126, 3, 7, 0,127, 3, 7, 0,245, 0, + 7, 0,128, 3, 7, 0,129, 3, 7, 0,115, 1, 7, 0,130, 3, 7, 0,131, 3, 7, 0,132, 3, 7, 0,133, 3, 7, 0,108, 0, + 7, 0,109, 0, 7, 0,110, 0, 7, 0,134, 3, 7, 0,135, 3, 9, 0,136, 3, 48, 0,137, 3, 40, 0,138, 3, 40, 0, 45, 0, + 9, 0,139, 3, 66, 0,116, 3, 66, 0,117, 3, 66, 0,140, 3, 2, 0,141, 3, 2, 0,142, 3, 0, 0, 36, 0, 0, 0,181, 0, + 2, 0, 24, 0, 2, 0,143, 3, 2, 0,157, 0, 2, 0,180, 1, 2, 0,144, 3, 2, 0,145, 3, 7, 0,146, 3, 7, 0,147, 3, + 69, 0,148, 3, 11, 0, 44, 1,130, 0, 13, 0, 26, 0, 25, 0, 0, 0, 28, 0,142, 0,149, 3, 34, 0, 93, 0, 9, 0,150, 3, + 28, 0, 44, 0, 7, 0,151, 3, 7, 0,152, 3, 7, 0,153, 3, 7, 0,154, 3, 4, 0, 55, 0, 0, 0,155, 3, 0, 0, 81, 3, +143, 0, 13, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 0,232, 1, 4, 0, 11, 0, 80, 0, 20, 2,130, 0, 80, 3, 2, 0,164, 0, + 2, 0, 79, 3, 2, 0, 34, 1, 2, 0, 35, 1, 2, 0, 24, 0, 2, 0, 24, 2, 4, 0, 41, 2,144, 0, 6, 0,144, 0, 0, 0, +144, 0, 1, 0, 2, 0,157, 0, 2, 0,181, 1, 7, 0,180, 1, 0, 0, 38, 3,145, 0, 31, 0,145, 0, 0, 0,145, 0, 1, 0, +144, 0,156, 3, 2, 0, 84, 1, 2, 0, 11, 0, 4, 0, 85, 1, 4, 0, 86, 1, 4, 0, 87, 1, 40, 0, 88, 1, 40, 0, 89, 1, + 28, 0, 44, 0, 7, 0,244, 0, 7, 0, 92, 1, 7, 0, 93, 1, 7, 0,105, 0, 7, 0, 94, 1, 7, 0,245, 0, 7, 0, 95, 1, + 7, 0, 96, 1, 7, 0, 97, 1, 7, 0, 98, 1, 7, 0, 99, 1, 7, 0,133, 0, 4, 0,181, 0, 0, 0,101, 1, 0, 0,102, 1, + 0, 0,103, 1, 0, 0,104, 1, 7, 0,113, 1, 7, 0,114, 1, 7, 0,135, 3,146, 0, 4, 0,146, 0, 0, 0,146, 0, 1, 0, + 40, 0,199, 2, 11, 0,157, 3, 76, 0, 4, 0, 26, 0, 25, 0, 11, 0,158, 3, 11, 0,159, 3,144, 0,160, 3,147, 0, 7, 0, +147, 0, 0, 0,147, 0, 1, 0, 7, 0,161, 3, 7, 0,162, 3, 7, 0,163, 3, 4, 0, 24, 0, 4, 0,164, 3,148, 0, 6, 0, + 26, 0, 25, 0, 11, 0,165, 3, 4, 0, 24, 0, 4, 0,166, 3, 4, 0,167, 3, 4, 0,168, 3, 69, 78, 68, 66, 0, 0, 0, 0, +}; diff --git a/source/blender/src/Bfont.c b/source/blender/src/Bfont.c new file mode 100644 index 00000000000..adeb73f4ca3 --- /dev/null +++ b/source/blender/src/Bfont.c @@ -0,0 +1,134 @@ +/* DataToC output of file <Bfont> */ +/* + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +int datatoc_Bfont_size= 25181; +char datatoc_Bfont[]= {"\x80\x01\xe4\x01\x00\x00\x25\x21\x50\x53\x2d\x41\x64\x6f\x62\x65\x46\x6f\x6e\x74\x2d\x31\x2e\x30\x3a\x20\x42\x66\x6f\x6e\x74\x20\x30\x30\x31\x2e\x30\x30\x31\x0a\x31\x31\x20\x64\x69\x63\x74\x20\x62\x65\x67\x69\x6e\x0a\x2f\x46\x6f\x6e\x74\x49\x6e\x66\x6f\x20\x31\x30\x20\x64\x69\x63\x74\x20\x64\x75\x70\x20\x62\x65\x67\x69\x6e\x0a\x2f\x76\x65\x72\x73\x69\x6f\x6e\x20\x28" \ +"\x30\x30\x31\x2e\x30\x30\x31\x29\x20\x72\x65\x61\x64\x6f\x6e\x6c\x79\x20\x64\x65\x66\x0a\x2f\x46\x75\x6c\x6c\x4e\x61\x6d\x65\x20\x28\x42\x66\x6f\x6e\x74\x29\x20\x72\x65\x61\x64\x6f\x6e\x6c\x79\x20\x64\x65\x66\x0a\x2f\x46\x61\x6d\x69\x6c\x79\x4e\x61\x6d\x65\x20\x28\x42\x66\x6f\x6e\x74\x29\x20\x72\x65\x61\x64\x6f\x6e\x6c\x79\x20\x64\x65\x66\x0a\x2f\x57\x65\x69\x67\x68\x74\x20\x28\x52\x65\x67\x75\x6c\x61\x72\x29\x20\x72\x65\x61\x64\x6f\x6e\x6c\x79\x20\x64\x65\x66\x0a\x2f\x49\x74\x61\x6c\x69\x63\x41\x6e\x67\x6c\x65\x20\x30\x20\x64\x65\x66\x0a\x2f\x69\x73\x46\x69\x78\x65\x64\x50\x69\x74\x63\x68\x20\x66\x61\x6c\x73\x65\x20\x64\x65\x66\x0a\x2f\x55\x6e\x64\x65\x72\x6c\x69\x6e\x65\x50\x6f\x73\x69\x74\x69\x6f\x6e\x20\x2d\x31\x30\x30\x20\x64\x65\x66\x0a\x2f\x55\x6e\x64\x65\x72\x6c\x69\x6e\x65\x54\x68\x69\x63\x6b\x6e\x65\x73\x73\x20\x35\x30\x20\x64\x65\x66\x0a\x65\x6e\x64\x20\x72\x65\x61\x64\x6f\x6e\x6c\x79\x20\x64\x65\x66\x0a\x2f\x46\x6f\x6e\x74\x4e\x61\x6d\x65\x20\x2f\x42\x66\x6f\x6e\x74\x20\x64\x65\x66\x0a\x2f\x45\x6e" \ +"\x63\x6f\x64\x69\x6e\x67\x20\x53\x74\x61\x6e\x64\x61\x72\x64\x45\x6e\x63\x6f\x64\x69\x6e\x67\x20\x64\x65\x66\x0a\x2f\x50\x61\x69\x6e\x74\x54\x79\x70\x65\x20\x30\x20\x64\x65\x66\x0a\x2f\x46\x6f\x6e\x74\x54\x79\x70\x65\x20\x31\x20\x64\x65\x66\x0a\x2f\x46\x6f\x6e\x74\x4d\x61\x74\x72\x69\x78\x20\x5b\x30\x2e\x30\x30\x31\x20\x30\x20\x30\x20\x30\x2e\x30\x30\x31\x20\x30\x20\x30\x5d\x20\x72\x65\x61\x64\x6f\x6e\x6c\x79\x20\x64\x65\x66\x0a\x63\x75\x72\x72\x65\x6e\x74\x64\x69\x63\x74\x20\x65\x6e\x64\x0a\x63\x75\x72\x72\x65\x6e\x74\x66\x69\x6c\x65\x20\x65\x65\x78\x65\x63\x0a\x80\x02\x92\x5e\x00\x00\xd9\xd6\x6f\x63\x3b\x84\x6a\x98\x9b\x99\x74\xb0\x17\x9f\xc6\xcc\x44\x5b\xc2\xc0\x31\x03\xc6\x85\x70\xa7\xb3\x54\xa4\xa2\x80\xae\x6f\xbf\x7f\x98\xf7\x5a\x84\xba\xce\x2d\x03\x6a\x6b\x51\xb8\x48\x49\x31\x59\x1d\x92\xe5\x06\x9e\x62\x26\xd5\xad\xcc\x5d\xe4\xf8\x10\x7a\xa6\x9a\x35\xb5\x5f\x6a\x9b\x4b\x4f\x93\xc5\x6c\x23\xbc\xc6\x1d\xd7\xbf\x8f\x32\xf2\x1d\x58\xe4\x1a\x5f\x79\x0c\xee\x2f\x02\xaf\x49\x86\x95\xe9\x0c\x1d\x0b\xd2\x59\xe7" \ +"\x5b\x02\x19\x30\x0b\x0f\x69\x2c\x33\x77\x9c\x2a\xa6\x7a\xe8\x51\x7a\xbe\x12\x30\x08\x45\x22\x4a\xf6\xad\x5d\xa9\xdb\x9a\x1a\x3a\x40\xfb\x06\xb3\x6a\x9c\xcd\x69\x12\x55\x07\xfc\x2d\xe9\xd0\x41\x84\xc7\x60\x42\xf0\x3f\xcf\xd1\x53\x84\x00\x23\x97\x2a\x81\x2a\xb9\xb3\xcb\x56\x70\xc1\xce\x27\x59\x71\x1c\x75\x29\x42\x62\xd6\xf2\x91\xaf\x9b\x7c\x76\x07\x1e\xda\x7e\x7a\xd0\x26\x21\x62\x32\x22\xb9\x36\x08\x7a\xb2\x7f\xfe\x5f\x07\x86\x47\x06\x65\x92\x18\x3d\xc3\x47\xae\x92\xe6\xbf\x56\xb1\x7b\xed\xce\x13\x68\x46\xf6\xa2\xa3\x76\xab\x8c\x0b\xc0\xff\x4e\x34\x7d\x20\xfd\x0e\xc7\x7e\xfa\xb1\xf0\x63\x31\x00\x14\x8d\x2a\x7d\x2f\xd2\x1f\x12\x5a\xaa\xcd\x8f\xdb\x99\x79\x83\x2b\x67\x0d\x8a\xaa\x76\xd2\x12\xba\xb5\x61\x46\x19\x90\x96\x0c\x35\x6e\xb8\xd8\xe9\xf3\xc6\x5d\x9d\xfe\x7f\x8c\x2c\x8a\x7b\x2b\xe9\x9e\x63\xff\x6c\x86\x88\x3c\x1d\xe5\x07\x8d\xa3\xb9\x1e\x03\xe4\x84\x0d\xdd\x6d\x30\xe3\x3c\xe3\x87\x75\xdc\x80\x43\xc3\x93\x20\x76\x47\xbe\x83\x0b\xf5\xc8\x5d\x1e\xe2\x20\x72\x1a\x27\xe8\x8a\x21\x6d\xe8\x01\x0b\xe9\xd4\x4e\xdd" \ +"\x58\x9e\x87\x5f\x9f\x0e\x26\x1f\x0c\x6a\xff\x33\x93\x2a\x8b\xfe\xd2\x77\x06\x60\xdd\xe2\x8c\xb7\xd5\xde\x05\xcd\x0d\x8c\xfd\xd6\x7d\x67\xe3\x34\x3c\x66\x1f\xfa\xa3\x93\xe4\xa7\x3a\xcf\x9c\x44\xa6\x96\xa7\xa9\x74\x53\xc2\x96\x68\x98\x1f\x07\x9d\x26\x4c\x1d\x0a\xf7\x3f\x39\xc2\x6a\xe6\xb7\x78\x87\xbb\xc9\xd3\x52\xea\xa8\xb6\xa7\x5a\x38\x25\x6d\xa0\x90\x0d\x30\xcc\xbe\x0e\xa9\x67\x7f\x88\x66\x18\x51\x3d\x20\xe9\xe4\x9e\x12\xeb\xbd\x1c\x00\xde\x43\x11\x6e\x8f\x47\xdf\xb5\x21\x11\x42\x51\xd2\x07\x17\xba\xf5\xe5\xc6\x8f\x3e\x71\x21\x50\xec\x57\x94\x41\x2a\x1b\x6f\x80\xdf\xc4\x8c\x2d\x20\x5b\x7b\x9e\x88\x99\xa6\x90\x7e\x73\x85\xdc\xfe\xea\xc0\x7b\x0e\xef\x4b\xc7\x74\x1c\xf1\x19\x1e\x42\xe2\xf8\x9f\x8e\x2e\x29\x0a\xed\x6f\xcd\x1f\xe6\x48\xc4\x31\xc8\x32\x1d\x73\x99\x8d\xc6\xe1\xda\x9d\x56\x38\x43\xf9\x63\x32\x19\x97\x0e\xc8\x23\xba\xfa\xcc\x97\xbb\xd1\x33\x81\xa1\x44\x76\x82\x1f\x19\x86\xff\x4b\xaa\xf0\xe1\x71\x90\x05\xb2\x85\x2d\x55\xf2\x42\x0a\x0a\x41\x8a\x5d\x93\x48\xd2\xfa\xd1\x7b\x94\x87\x0c\x9c\x5e\x0d\xfa\x1f" \ +"\xd3\x9d\x52\x80\x84\x8f\x0b\x9b\x2f\xd3\x97\xe8\x8e\xfd\x52\x68\xea\xe7\xbe\xa9\x4e\x20\x5a\x02\x29\xc9\x7a\x8e\xcd\x90\xea\xcc\xc6\xe3\x38\x39\x06\x3f\x08\xed\x59\xc7\x1e\xe2\xa9\x30\xc6\xbf\x26\x72\x57\x87\xbd\x62\xfb\xe0\xd2\x9a\x3a\x57\x1a\x38\x29\xdb\x77\x7c\x6d\x53\xb6\xa9\xa6\x7b\xff\xbe\x23\x79\xb1\x25\x5c\x80\xf2\xf7\x84\xda\x95\x8c\x74\xb8\xa3\x0d\xf8\x8a\x44\x7c\xe5\xd3\x59\xd2\x65\xac\x95\xdd\xb6\x71\x24\xb6\x2e\x05\x8d\x7f\x93\x36\x76\x43\x6b\x69\xbb\x28\x35\xd0\xaa\x19\x2d\x71\xd8\x6e\x87\x38\x07\x1a\x0e\xe1\x3d\x4f\xe4\x48\x1e\x27\xdc\xc3\xe3\xe5\x99\xc4\x1c\x06\x6b\xf0\x36\x43\x06\x5e\x8f\x00\x22\xb4\x31\x0e\x29\x6f\x09\x29\x5e\xcb\xb8\x8b\x8e\x22\x8c\x8a\x5a\x19\xd8\x59\xfc\x2d\x2e\x84\xa9\x9a\xe6\x83\x0f\x14\x64\x63\xeb\x6a\x49\xb9\x59\x06\x42\xe6\xab\xca\x16\xd5\xe3\xb7\x20\x8a\x74\xfd\xd0\xe6\x79\x10\x3f\xee\x84\x45\x1c\x87\x58\x73\x12\x15\x0b\x66\xac\xc8\x25\xde\xff\x64\xdd\x50\xad\xda\x35\xd2\xfa\x94\xd3\xf1\x61\x96\xb9\x2b\xfa\x8a\x0e\x7a\x85\x1e\xbf\x36\x9e\x76\x16\x0c\xe8\x19\xe4\x3c" \ +"\x65\xce\x77\x1d\x39\x0c\x63\x24\xa7\xb6\x99\x56\xc3\x15\x46\x9a\x66\x6a\x2d\xec\x46\x97\x8f\xb9\xcf\xfc\x6a\x2e\xa8\x50\xd8\xce\x9d\xab\x76\x4d\x52\x99\x18\x36\xa5\x80\xa0\x1b\xc3\x75\xf1\x8d\x5d\x97\xe9\xef\xf4\x49\x7b\x85\x2a\x8a\x7b\x44\x9f\xe1\xd1\xab\xf2\x46\xd4\x06\xa8\x13\x74\xe4\x00\x0e\x94\xbf\x84\x0a\xfe\x53\x7d\x14\x11\x47\x7e\x8e\x38\x50\x37\x30\x7d\xb8\xac\x9c\xa3\xa1\x48\xf9\x69\xcc\xcf\xb3\xd9\x73\xb1\x02\x52\xdc\x8e\x0e\xb4\x8a\xfe\x53\x8b\x24\x46\xcb\x5b\x51\x52\xe5\x14\xfd\x4e\x84\xd5\x40\x9a\xa3\x3b\x5d\xf5\xa8\x26\x94\x30\xe4\x0d\xba\xcc\x5f\x8c\xb8\x76\x16\x82\x6f\x1b\x26\x8b\x7f\x6a\xac\xa1\xfe\x88\xbb\xa6\x30\xa2\x98\x7c\x45\x1b\xba\x32\x7e\x07\x90\x2b\x4b\xb0\x91\x9f\xca\xf4\x07\x4e\xcb\xfa\x20\x2a\xc3\x47\xba\x5a\x5c\xa2\x7e\x62\x2c\xc3\xa3\x2f\x58\x7c\x2b\xb1\x7a\xfb\xfe\x1d\xa1\x46\x62\xeb\x85\x34\x0c\x1c\xb8\x43\x91\x49\x58\x63\x45\x3c\xe3\x8e\x0f\xda\x52\xa7\x39\xe1\xe6\xda\x83\xfb\xab\x0b\x3f\xbf\x41\xec\xb2\x3f\x9f\xd5\xd3\x72\x40\xc8\x55\x49\x28\x5e\x7b\x6c\xab\x59\xa9\xce\x63" \ +"\xc4\x1f\x0f\x98\x8a\x4d\x89\xd2\xc5\xe4\xff\x49\x7e\x78\xf9\xd6\xaa\xd4\xa8\x49\x36\x7d\x71\x4e\xe2\x25\x89\xf9\xbc\xef\x21\xe7\xf4\x7d\x74\x89\x7e\xbb\x1f\xc1\xc2\x76\x79\x13\x50\xfa\x57\x30\x50\x3e\xf6\x1d\x79\xf7\x87\xc6\xc1\xfd\x94\xd3\x11\xd2\x11\xf7\x2c\xcd\x5b\x01\xbe\xc3\xec\x42\x5f\x90\x3a\xeb\x02\x2a\x4f\x19\x52\xa4\xa7\xf4\x72\xbc\xc0\x65\x17\x37\x45\x8d\xa8\x1c\x59\x3c\x74\x5b\xa2\x79\x1c\x7b\x60\xfc\xa5\xb4\x45\x38\xe8\x36\x7a\x8a\xdf\x9e\x83\x5e\xab\x52\x04\x70\x0d\xa0\x75\xaa\x92\x1c\xf1\x9a\xd3\x77\x10\xe9\x8d\x60\x5e\xa7\x0d\x25\x76\x69\x49\xd3\x61\x6d\x94\x83\xbe\x77\x2d\x7c\xd0\xe1\x27\x5e\x30\x3e\x21\xbc\xf8\x9a\xe9\x2e\x9e\x07\x90\x01\x79\x00\xeb\x47\x19\x34\x0d\x2e\x01\x19\xab\x1b\xb3\xaa\xa4\xe7\x02\x19\xb6\xe2\xfa\x60\xc0\x17\xb9\xda\xda\x10\x8c\x24\xb4\xd8\x3b\x5f\x31\xa5\xa2\x86\xfc\x2f\xa8\x41\xf2\xb2\xd3\x3e\x0a\xef\x99\x41\xdb\xf7\x48\x11\x69\x31\xfe\x55\x88\xd3\x75\xf0\xda\x4d\xdd\xa6\x29\x91\xc6\x04\x68\x88\xf1\x30\x00\x9e\xd2\xec\xcf\x1a\x91\x8c\x5f\xa4\x75\xc6\x00\xb7\x68\xa1" \ +"\x3b\x09\xbd\x08\x20\x2c\x1a\xff\x9d\x77\xf5\xfa\x31\xb0\x9c\xe3\x66\xe4\x69\x53\x18\x99\x55\xc4\x81\x85\x80\xd0\x81\xca\x3e\xcc\xad\x89\x5b\xdf\x70\xd0\xf3\x57\xb4\x6d\x52\x8d\x38\xef\xd2\x28\x56\xc8\xad\x1f\x20\xe6\x8c\xca\x3d\xdc\xb0\x5c\x6c\xcf\xb1\xd5\xa9\xee\xac\x9e\xfe\x26\xf2\x8d\x06\x73\xd9\xc1\x86\xa6\xe3\x24\xd0\x77\x56\x2c\x22\xc3\x47\x77\x5e\xea\xf1\x7a\x4f\xa9\xad\x24\xdd\x78\x44\x17\x03\x2c\x7d\x26\x4e\x48\xe6\x19\x3e\x12\xcd\xce\x42\x8c\x4f\x7d\xe5\xdf\x00\x5c\x19\x76\xfd\xa1\xdb\x33\xe4\xe5\xd4\x0d\x9b\x1a\x32\x36\x69\x36\x26\x55\x98\x31\x96\xe9\x58\xbf\x6f\x00\x7a\x93\x5f\xd7\x32\x21\xb0\xd1\x4d\x88\xc6\x06\x47\x61\x64\x98\x00\x9f\x5e\x5b\xca\x07\x94\x7d\xfe\x3a\x26\x6b\x31\x65\x0e\xc2\xa3\x0c\x4f\xfd\x99\x96\x36\x1e\x25\x8c\xbd\xf1\x8d\x2f\x39\x8b\x91\x4a\x58\x0f\xb2\xb3\x3f\xf1\x5b\x81\x1e\x4f\x13\x68\x48\x38\xd7\x25\x7c\xf2\x4d\x51\x6d\x9b\x00\xe9\x7a\xba\x6b\x5b\x91\x5c\xa2\x5a\x04\x71\xaa\x54\xd3\x84\x8e\x40\x1b\x5d\x98\xf8\x6b\x5e\x5d\xa0\x6d\xf9\xf1\xfb\x66\x82\x42\x60\x33\x70\x8c\xf5" \ +"\x97\x41\x2d\xbd\x9d\x75\xbc\x5b\x61\x31\x8a\x6b\x6a\x87\xcc\xcb\x26\x77\x21\x95\x57\x7a\x9e\xc6\x08\x8e\xda\x03\x38\xf9\x50\x56\xfd\x52\xf6\xcb\xe7\x39\xa0\x32\x34\xbb\x18\x6c\x82\xfd\xc1\x18\x33\xc9\x32\x03\x43\xb0\xbb\x7c\xa5\xac\x8e\xfc\x9c\x9b\xdc\xfc\x33\xed\x69\x5e\x30\x2c\xe9\xbb\xbc\x7b\x64\xda\xdf\x24\x72\x36\xdb\xdf\x27\x9c\x70\xce\x2e\x13\x0a\xd5\x8b\x45\x0c\x8a\x86\x2c\x82\x5e\x88\x04\x6f\x4d\x15\x73\xe1\xa2\x0f\x26\x9f\xda\x8a\x66\xab\x02\x8e\x30\x9e\x39\x5e\x3b\xb6\x11\x7f\xbe\xdf\xc4\x42\xee\x6b\x32\x9a\x02\x8e\xa7\x98\x12\x19\xe2\x01\xfd\xfb\x11\x66\x14\x6f\x1c\x61\x88\x0f\x3c\x41\xe6\x27\x31\x19\xa6\x1f\x12\x36\x04\x18\x59\xd3\xe2\xfa\x4a\xe2\xb9\x43\x8a\x1d\x12\x55\x9c\x7c\x91\x54\x11\xaf\xa7\x33\x0d\x36\x52\x61\x40\xce\xc9\x6f\xc7\xd6\xd2\xeb\x94\x37\xb5\xf1\x88\x56\xfe\xdb\x7a\x40\x67\xb3\x4f\x71\xa3\x7e\x4b\x6b\x4f\x66\xf4\x15\x93\xc6\xd2\xfb\x23\x88\x49\x0f\x20\x2d\x96\x86\xfd\x71\x53\x6f\xa1\x6e\xd4\xf2\x21\x0c\x0c\x10\x8f\xc2\xc7\x25\xe4\xfb\x6e\x07\xd5\xc6\x37\x50\x20\xd1\x8c\x22\x2f" \ +"\x66\xf9\xd9\xa6\x76\x1f\x6a\x02\x12\x6a\x2e\x92\x94\x7d\x00\xd0\x59\xd1\xf7\x37\x8f\xb1\x13\xb7\x7f\x47\x76\x14\x88\x03\xe9\x6d\x77\xb5\x73\xdf\x6e\x8b\xb6\xab\x6d\x68\x48\x3e\x98\x8f\x0e\x9d\x52\x9a\xfd\x8e\xd7\x3b\x01\x0b\x62\x6b\x8c\x0c\xf0\x90\x38\x26\x0e\xdc\xed\x9a\xae\x97\xb3\xcf\x68\xea\xde\x54\x7e\x9d\x5a\x34\x76\x7e\x60\x17\xcb\x87\x86\x29\x10\xc4\xd2\x2c\x7d\x44\x91\xe8\xec\x34\xde\x66\x83\x50\x65\xed\xda\xf4\xd7\xcd\x5f\x3a\x60\x12\x42\xd5\x5b\xf7\x3a\x2c\x39\x96\xc1\x8b\x87\x24\x8f\xec\x5e\xd1\xec\xd5\xe3\x2a\xb0\xad\xce\x57\x97\xf0\x91\xb9\x2d\xd1\xb1\xc9\x7b\x20\xc4\x2c\x9e\x53\xcb\xca\x06\x6a\x36\x5d\x2b\xd1\x0c\x72\x4c\x64\xf2\x68\xa5\x8a\x0f\x8f\x05\x21\xe4\xc3\xf3\x6f\x51\xf9\xae\x0f\xa7\x28\xa5\x33\x61\xb9\xd7\x96\x76\xfd\x16\x67\x09\x15\xb9\xee\xbd\x5e\x31\x68\x64\x62\xa5\xc4\x1f\x94\x70\x7d\xc7\x2e\x67\xfc\x4f\x64\xa5\x70\x68\x52\xf9\xdb\xcd\x22\xc6\x1f\xc6\xbf\xb5\x48\xd4\xb6\x3e\x57\x0d\x35\xab\x54\xde\x9c\x83\xc9\xa2\xad\x2f\x2c\xbb\x69\x77\x84\x2f\xe4\xb8\x24\x55\xda\x0b\xfb\xf2\x7c" \ +"\xcd\xa8\xfc\x18\xf5\x31\x54\xa1\x6b\xd3\x15\x3f\xdb\x59\x0f\x74\xc0\x12\xd0\x56\x5f\x4b\x47\xef\xf7\x69\x7c\x55\xae\x90\xdc\x18\xbc\x5e\x28\xd1\x84\xea\xe1\x35\x45\xf0\x2a\x2f\x5c\x12\xf0\x78\xd2\x8c\xa8\xda\x69\x3c\xf6\xf7\xee\xbc\xf7\x0a\xa2\x18\x88\xe2\x5b\x6b\x9d\xa8\x33\xba\x0f\x4f\x44\x9a\xe1\x34\x29\xe4\x7f\x23\x29\xe0\x61\xe1\x2c\x55\x10\xe1\x63\xc6\x30\xb6\x62\xeb\xff\xb2\x18\xd2\x3a\x0e\xc8\x54\x12\x84\x89\x23\xab\x3f\xc3\xee\xc3\xa7\xa7\x08\xcf\xe8\xd6\x64\x5b\xc3\x5a\xe9\x56\x62\xcf\xb9\xe5\xc4\x8c\xfd\xec\xdb\x96\x3e\x3e\x02\x0f\x33\xe8\x9d\x2c\xea\x6b\xbc\xdc\xd6\xd1\x2a\xa5\x12\x5e\x8f\xeb\xf1\xc0\xfe\x6a\x9b\x30\xf6\xef\x7b\x11\x8c\x0c\x65\xfb\x66\x9c\x7e\x82\x02\x26\x3e\xff\x1b\x86\xb6\x78\x17\x9e\x67\x04\x30\x9a\x4e\xec\x0e\xfe\xde\xef\x2a\xe4\xe0\x8a\x57\xd3\xec\x4e\xd4\x01\x6b\x8b\x51\x05\xee\xb9\x54\xcd\x33\x53\x43\x34\x2a\x87\xff\xf4\x7b\x9d\xb9\x74\x72\xa0\x74\xf6\x1e\x93\x7f\x81\x9c\x33\xe5\x27\x7a\x02\x7a\x91\xe5\x19\x7a\x02\x97\x07\x7d\xf6\x4c\x81\xd1\x6e\x8a\xf6\xd3\x21\xb7\x3c\xc0" \ +"\x6c\xa7\xa1\x9d\xad\xbc\x86\xc0\xb3\xcb\xc3\x88\x54\x29\x6e\xc1\x7a\x83\x0b\x4b\x7c\x53\x8b\x50\x0c\x47\x5d\xd6\xb3\x2b\x46\x8b\x5b\x35\xe4\x61\x69\x43\xe6\x76\x5c\xb7\x83\x72\xe7\x4a\x8c\x30\x87\xb4\x0a\xb8\x94\x2e\x4b\xb6\xcd\x53\x2f\x97\xce\x54\xf3\xe8\xe9\x7e\x8e\x1e\x0b\x71\xdb\xfc\x99\x12\x10\xd7\xee\x79\x9b\xff\x15\xd6\x59\x06\xc4\x03\xc9\x83\x30\xbb\x9f\xeb\x0e\x1b\x9b\xf5\x4d\xe5\x82\x70\xa8\xa4\xfd\x45\x17\xfd\xf2\xaf\x13\xe8\x9b\xa1\x1b\x9e\x5f\xa0\x5a\x4f\x6d\x85\xcb\x2a\x46\xb5\x78\xf7\xf4\x55\xbf\xa7\xff\x24\xfb\x73\x36\xbf\x4e\xd3\xb6\xfc\x05\x0c\x64\x20\x30\xc8\x1a\xea\x7b\x19\xa1\xfd\x86\xa8\x3c\x0f\xbb\x3e\x18\xef\xb1\x62\x5c\x6d\xc3\x70\x4e\xf2\xa1\xfa\xe0\xd2\x5e\x6f\x22\x64\xc4\x47\x67\x4a\x7b\xd8\xd9\xb4\xa0\x21\x40\x69\x7b\xb7\x7d\x54\x4d\x50\x63\x6d\xf7\xad\xa8\xef\x7a\x58\xe9\x75\xed\x94\x2b\x90\xc3\xff\xde\x7c\xd6\x85\x9c\x75\xf4\x07\x49\x0d\x64\xa4\x44\xaf\xbf\x5d\xe1\xfc\x80\x60\x4d\xe7\xc4\x96\xdf\x78\x38\x17\x65\x5e\x17\x32\x4c\x26\x1b\x59\xb8\x5d\x8c\x25\x4f\xf9\x42\xc7\x1b\xdc" \ +"\xe6\x72\xb0\xb3\xe4\xc9\x0c\x38\x71\x01\x19\xcf\x68\xb1\xbf\x4f\xed\x8f\xe2\x68\x5c\x15\xf9\x62\xcd\x16\x69\xd7\xb8\x8e\xb2\x6b\x08\xc2\x0d\x20\x9c\x54\x6d\x92\x98\x39\xf1\x48\x3e\x4a\x7a\xd4\x58\xb3\x39\x17\xba\x4a\x49\x52\x25\x50\xb6\xa5\x28\x59\x1e\xf4\xd1\x6e\xa3\x18\xb6\xc9\x8b\x91\xe1\x94\xdb\xb8\x01\x6d\x63\x9c\x25\xf7\xb1\x6f\x32\xd1\xdd\xd0\x4e\x00\x48\x06\xec\x4c\x4f\x3f\x84\x1a\xe3\x48\x8e\xe5\xf8\x78\xa0\x94\x9b\x5b\x33\x3d\x28\x16\xc0\x60\x8b\xc1\xc0\x29\x74\x4f\x8c\x74\x9e\xf8\x40\xa8\xe3\xae\x38\x72\x5c\xa0\x1f\xc8\x5e\x52\x63\x8b\x43\x5f\x2f\x4c\xb4\x98\x2b\x83\x95\xb1\x04\xd4\x38\xd1\xbe\xd1\x66\x7a\xe0\x48\xea\xf4\x6f\xaf\x8a\x78\x17\xcb\x09\x92\xea\xef\x5e\xf1\x1c\x15\xaa\x33\x02\xb0\x7d\xb3\xd9\x63\x53\x11\x10\x71\x7b\x6f\x44\x5e\x9c\xc8\x5a\x75\x1e\xae\x83\x2a\xa1\x5b\x4c\x55\xc7\x2c\x4b\xc7\x00\x9f\x6f\x9e\xec\x3f\xfc\x49\x43\xdc\x71\xa9\x9e\x4a\x07\x51\xd6\x95\x9b\xde\x81\x5b\x3f\xa9\xc4\xa8\xd0\xe6\x53\xa8\x04\x13\x1b\xb0\x9d\x92\x38\x2a\xfe\x8f\xab\x77\x3c\x7f\x39\x25\x6b\x54\xff\xf6" \ +"\x4c\x9f\x26\xb0\xe9\x0d\x61\x6b\x40\x37\xce\xc9\xcc\xda\x03\x8b\x7b\x96\x97\x6e\x1c\xc6\x63\xf7\xa7\x9b\x25\xb8\xfd\xd6\x15\xfd\xfa\xb3\x1a\xe9\x62\xcd\x75\x6d\x5e\xde\x0f\x97\xb8\x77\xdb\x9f\x1a\x34\xea\x37\x42\x64\x6c\xaf\xae\x11\x6f\x87\xbd\xf4\xee\xad\x17\x11\xf1\x88\x4e\x7c\x4b\xcb\x72\x87\xe4\xdd\x4f\xf4\xb4\x54\xd7\x78\x3a\xc1\xea\x11\x15\x84\x6e\x0a\x5d\x5d\x00\xb7\xf5\x86\x3d\x5f\x44\xbf\x8d\xed\x5f\x7e\x57\x3a\x95\x86\xd5\x6e\x74\xd8\xc0\x0a\x70\x26\xe8\x32\x23\x78\x39\x2d\xac\xe8\x25\x4d\xe2\x99\x6e\x83\xfd\xd2\xa8\xb4\x53\x38\x33\x38\xbd\xde\x61\xc1\x88\x8a\x2a\x94\x32\x6f\x18\x13\xfe\xb1\x6d\x2a\x04\x41\xac\x60\xfb\xa0\x36\x3a\xa5\xca\x40\x4b\x26\x3a\x4b\xb0\xd8\x62\x92\x7d\x76\xf8\x0e\x6a\xe4\xe2\x51\xf1\xfb\x7f\x1b\x17\x5c\x9d\x8c\x0c\x3b\x56\xfc\x7a\x0d\x80\x0e\xb8\x37\x9b\x2c\xfd\x1d\x2f\x7b\xbf\xb9\x9a\xa3\x72\xfa\xd8\x30\xda\x18\x29\x89\xba\xc8\xd1\x93\x56\xea\x0b\xfb\x2a\x38\xb5\xf3\xee\xa6\x87\x5c\x97\x56\xae\x59\x4f\x47\x0e\x18\x05\xb3\x57\x83\x87\x66\x3b\xba\x42\x01\x06\x48\x05\x1c\x4f" \ +"\x31\xba\xc2\x3e\xb3\x35\xba\x1f\x8f\x0f\x69\x20\xfb\xbc\x8a\x0b\xf4\x24\x64\x65\x50\xbb\xfd\x35\x5a\x9a\xd4\xb5\x7e\xd1\x3a\x0a\x37\xa8\x1b\xec\x73\x65\xe0\xc1\x67\xe7\xe7\x4c\x82\xa9\x40\xf7\x8f\xa0\x06\x0c\xbb\x3e\x73\x55\x85\x61\x83\x9d\xa4\x05\x12\x33\x45\x35\xe2\xaa\x20\xf8\x85\xc2\x3a\x72\xf3\x9c\x35\xdb\xe4\x25\x33\x96\xf0\xe3\x4a\x64\x42\x8c\x73\x64\x67\x2f\xa0\x91\x27\xa0\x4b\xde\xda\x1c\x6c\xe8\x6b\x5b\x00\x39\xfa\x88\x06\x21\x76\x73\x67\xb3\xdd\x6c\x28\x8e\xaf\xb9\x02\x0c\xc0\x42\xd5\x98\x29\xe9\xdf\x29\xd4\x55\x11\x34\x3a\xd3\xb5\x2e\xd3\xce\xbd\x1a\x08\x5a\x73\xe0\x97\xc3\xe0\xd5\x22\xa2\xbd\xde\xda\x9b\x4e\xc9\x65\xf2\x09\x38\xd7\x98\xef\xf7\x79\x03\x10\xdd\x38\x2d\x23\xf3\x92\x80\x2c\x72\xd7\x84\x65\xdc\xe9\xb4\x02\x1d\x57\xcb\xb9\x90\x10\x25\x71\x3c\xf4\xd6\x8c\xbf\x18\xc0\x25\xff\xa1\x93\xd8\x1e\x28\x9b\x58\x3c\xba\x87\x0b\x17\xe4\x2b\x9d\xcb\x66\xc4\xc5\x01\x01\x57\xda\x7e\x50\x4c\x1e\xb6\xcf\x99\x87\xf8\x06\xb5\xd7\x4d\x80\xc8\x0a\x13\x6b\x8a\xca\x54\x78\xbf\x8c\x75\x32\x20\x1b\x69\xae\xe0" \ +"\xaa\x7b\x35\x4c\x30\xd2\x06\xe3\xc3\x72\xeb\x57\x91\x96\x1a\x15\x11\xd6\xc6\xf5\x7d\x6d\x9c\xaa\xcc\x8f\xe4\x3e\xc4\x80\x15\xf3\x99\x5b\x47\xa4\x71\xa4\xff\x30\x24\xee\x69\xdc\xa3\x5d\x03\x21\x2f\x96\xf1\xd3\xbe\x6f\x9d\xea\xbd\x19\x3a\xf7\x4b\x76\xf7\xa7\xab\x76\xdf\x01\xb4\x62\x53\x00\x02\x6d\x11\xff\x74\xf4\x6b\x65\xdc\x64\x46\x15\x85\xb3\x5a\xd2\x74\x20\xc5\x18\x52\x72\x78\xda\x0e\x93\x50\xc2\x50\x45\x4e\xdf\x9d\xb7\x82\x31\x8b\xa2\x22\x0c\xb0\x2d\xf2\x67\xe8\x80\x44\x58\xe1\xb5\x95\x03\xd2\x14\x26\x9b\x06\xce\x88\x16\xaa\x5c\x9c\xa5\x74\x8e\xfa\x48\xcb\xeb\xc1\x74\xf4\x04\xd1\x37\xba\x1d\x08\x21\xc1\xdd\x49\x1b\xd4\xcc\x16\xc5\xb3\x08\x7a\x86\x08\xff\x60\x33\x02\xa9\xc1\x60\x80\xb2\x6d\x8f\x83\x32\xdb\xd0\x3a\x9f\x67\xe9\x64\x1a\x02\xb1\x81\x7a\xa8\x78\x47\x27\x73\xe4\x6c\x72\xa1\xf3\x18\x0a\xdd\x69\x00\x20\xe6\x4b\xd0\xe9\x04\x46\xf9\x62\x25\x2e\x57\x9e\x91\x3c\x55\xe5\xc7\xec\x7e\x50\xb7\xb5\x0c\x44\x03\x0f\x17\x24\x5c\x92\x6d\x3d\x18\x80\x4e\xef\x58\xe6\xd7\xcc\x5a\x93\x76\xab\x33\xa8\x5f\x5d\x17\x5a" \ +"\xf4\xa4\xac\xc9\xde\x70\x8f\xc1\xd1\x82\xc9\xcf\x76\xaf\x33\x03\x53\x90\x35\x07\x02\xdf\x92\x32\x65\xa8\x9f\x85\x1c\x42\x1d\x40\xe9\x4c\xb6\x85\xac\x44\xdf\x72\xfe\xec\x6f\x1e\x49\x89\x82\xa4\x83\xc4\xbd\x6f\x9b\x93\xd9\x40\xc2\x73\x8f\xc9\x4d\x16\x99\xe4\x53\xbf\x35\xd2\x57\xea\x15\x22\xbb\xb8\x1c\x3f\xb3\xd6\x53\x0e\x70\x20\xa9\x9f\x85\xcf\x13\xa9\xbc\x93\x6f\xba\x72\x2b\x76\x98\x19\x47\xb8\xf7\xef\x3e\x27\x7d\x08\xb0\x5b\x2e\x7f\x25\xa9\xf7\xba\xaa\xe7\x6a\x7c\x5d\x52\xcb\x87\x32\xb1\x55\x4a\x73\xdb\x4c\x60\xad\x2c\xf2\x26\xa3\xab\x0e\x00\x5f\x4c\x63\x4b\x0e\x27\xd5\x74\xb6\x48\x02\xea\xb0\x41\x62\x96\x24\x46\x56\x89\x97\xda\xf5\x8d\x11\x18\xe9\x29\xb9\x3a\xb2\x38\x36\x7a\x94\xe7\x97\x29\xd6\x60\x04\xf3\x2e\x3f\xc8\xe9\x80\xa1\x5f\x8a\xf4\xb7\x8d\x91\x0e\x19\x5b\xc5\x46\x03\xe3\xbb\xcb\xdf\x30\x78\x71\x07\x00\x82\xc1\xa0\x43\x6c\xb9\x47\xed\xab\x65\x9f\x60\x62\x22\x04\x8e\x72\x9b\xa0\x93\xc1\xaa\x30\x73\xfd\xac\xf5\x3b\x91\xb0\x37\xcb\xf5\x3c\x18\xf7\xeb\x4f\x0c\x75\x4a\x12\x97\x0e\xd0\x07\xe3\xe6\x8a\xb6" \ +"\x6b\x21\xac\xd3\xe8\xf4\x5b\x56\x50\xed\x37\x9a\xaf\x20\xdd\x11\x97\x4f\x68\xee\x19\xe2\x4c\x9b\x48\x27\x5a\xd1\x5d\x77\x36\x11\x09\xde\x3e\x12\x88\x19\x0f\x3b\xc2\xcb\x39\x96\x00\x34\x7a\x68\x54\xc7\x68\xb4\x9a\xb4\xb1\x8d\xad\xa9\x9a\x71\x23\x4b\xc6\x9d\x96\x50\x2c\xd4\xf8\xae\xe8\xfb\x8c\x4a\xd6\xbd\x29\x78\x71\x9c\x41\x10\x0f\xc9\x12\x2d\x10\xd2\x68\xf7\x26\x21\x28\xf9\x3d\x77\x99\xb3\x48\x58\x7a\x6d\xd0\x5b\xba\xe7\xf6\xc9\x9a\x1a\x24\x73\x7e\xd9\x2c\xc2\x8c\x67\xe5\x0f\xfa\xe3\x8c\x6a\xcc\x76\xa9\x9d\x54\x96\x1f\x80\xc2\xfe\x90\xdd\x54\x4f\xd3\x94\x21\x3c\x6b\xd3\xaa\x9f\xf8\x69\x3f\x72\x00\x17\xea\x5c\xe6\xf0\x76\x06\xfa\xb5\xb8\xe3\x40\xba\x28\x5e\x43\xe1\x85\x59\x0f\x10\xae\x90\xa5\x3b\x06\x49\x0d\x12\x1d\x0a\x2e\xed\x17\x33\x21\x1b\xc1\xd4\x3f\xc2\x05\x4f\x42\xb1\x51\xc8\x54\xfe\xe1\x24\x6e\xd0\xe1\xca\xd5\x59\xd6\x8c\x8e\xe3\xdf\x3c\xd6\x13\x91\x5c\x5c\xa4\xcf\xde\x9e\xfa\x0c\x92\x96\x43\xcc\x78\xd3\x6d\x5f\xba\x28\xa7\xb2\x5a\x22\x2e\xea\x1c\x6d\xab\xb6\x53\xc5\x24\x33\x45\x98\xa8\x79\x30\x47\xb3" \ +"\x16\xda\xa8\xb6\xa0\x93\xc3\xb1\xb0\xc9\xea\xd5\xd1\x87\xde\x09\x01\x9d\xaa\xf0\xaf\xf6\xda\xff\x5c\x35\x66\xab\x16\xeb\xb4\xf8\x76\x0a\x55\x0e\x18\xda\xb8\x84\xbf\xe1\x70\x42\x03\xe7\x24\xeb\x22\xd6\xb5\x39\x68\x97\x4c\x45\x65\x53\x14\x27\xaa\x6c\xa1\xef\xec\x7e\x09\x90\x1b\x75\xd1\xae\xad\x5c\x10\xb9\x19\x08\x41\x1d\x86\x43\x01\xf8\x3e\xdd\xef\x86\x0c\x0f\xfc\xcb\x8c\xb3\x34\xf7\x03\xe6\x22\xb8\x66\x52\x76\x4c\xda\xfe\xf2\x18\x73\x16\x77\x5a\x04\x95\xec\xb0\x74\x44\x4d\x7b\xc9\xc0\xff\xbc\x6b\xc3\x03\xd9\xb8\x6a\xdb\x74\x51\xcf\xc1\xe3\x65\x29\x1d\xe8\x48\x55\xec\x97\x4a\x5d\x96\xa6\xab\x9b\x51\x83\x51\x6d\xab\xb8\x25\xbe\x72\x6a\x71\x90\xea\x4c\x8f\x5c\x62\xbe\x70\x97\xc6\x97\xb5\x63\x07\xb6\x32\xbe\x9d\x8d\x11\xc7\x94\xe6\x0e\xf0\x5f\xee\x8b\xa1\x60\x55\x89\x9a\x4f\x43\xa8\x65\xfd\x7e\x17\xa5\x8f\x2f\x21\x9d\x64\x06\x82\xfd\xbc\x42\x15\xcd\xf3\x74\x3e\xf1\xa1\xb1\xc7\xea\x3d\x87\x37\x71\x19\x99\x1b\x81\x95\xbd\x8c\x70\xd3\x31\xb0\x26\x2c\x6e\x1d\x87\xb2\x7a\xe9\x03\xa6\x61\xaf\x3d\x9f\x62\x3d\x36\x2e\x3e" \ +"\xf6\x89\x11\x96\xf9\xa5\x63\xd3\xac\x4c\x07\x68\x27\x6a\x77\xdd\x9f\xd2\x60\x21\xec\x57\xa4\x70\x2f\xe2\xf7\xec\x8c\xb9\xb6\x14\xc9\x33\x58\x61\x34\xc6\x46\x31\xf8\x60\x33\x52\x73\xa9\x4e\x49\x70\x7b\x6a\x78\x71\xb8\x5d\xc2\xe0\x44\xd3\xc8\xed\xd1\x29\xa0\x7f\x59\xa3\x37\x09\x1b\xfc\x4e\x5d\x93\x8d\x0c\x9c\x2c\xe2\x6a\x7e\x9f\xb5\x6a\x54\x19\x27\xdc\x29\x86\xb8\xad\x45\x8d\x80\xdd\x39\xc2\x38\x29\x94\x6b\xf2\xf1\xae\x81\x98\x7b\x51\x65\x01\xcc\x09\x6d\x9a\x61\xa9\x3f\xa7\x34\x60\xef\x3f\x74\xa3\x7a\x9e\x5e\xdd\x23\x5a\xb8\x45\xba\xdc\x9b\xcd\x41\xbf\x1f\xd1\x3e\x78\x9c\x4d\x9a\xd4\x3a\xa5\xd0\xfe\x41\xcc\x94\xc8\x79\x4e\x81\x4f\x79\x27\x22\x03\xa9\x76\x78\x34\x23\x77\x8e\x1d\x0f\x90\x9c\x5a\x86\x65\x69\x0b\x70\x20\x4a\x00\xdb\x9f\x84\x64\x07\x6a\x58\x8e\x2a\x9f\x9f\x85\x0b\xaf\x5c\x58\x90\x0c\x37\xb9\x2f\x8e\x1f\x2b\x27\x10\x53\x7a\x36\x07\x96\x9e\xd7\x0e\x8f\x88\x93\x8d\xe7\x9d\x43\x98\x77\xa4\x72\x9f\x47\xd2\x90\x62\x7f\x2c\x84\xda\xaa\xb7\x06\xb9\xd2\x5e\x5f\x63\xf0\x74\x1e\x7e\x4c\x73\xd4\xf6\x66\x5c\x60" \ +"\x9f\xfc\xb1\xad\xee\x57\x91\x78\xef\x53\x67\x94\x6f\xc1\xc8\x9d\xc7\x54\xf5\xa7\x44\x2b\x09\x45\x37\x53\xa4\x6d\x5a\x2e\x65\xd7\x24\x17\x4a\xaa\x49\x1f\x97\x3f\x0d\xe9\x97\x6b\xf8\x1c\x5c\x23\x46\x05\xeb\x55\xdb\x14\xd5\x99\x9d\xf9\xb0\x25\xff\xbf\x31\xdd\xc3\xf3\xcd\x96\xee\xea\xa8\x89\x99\xc9\xde\xcd\xc7\xa2\x77\x92\x29\x59\x69\x72\x90\x1b\xc2\xa7\x0f\x11\x66\x9b\x51\x14\x40\x19\xeb\xd9\x3f\x9a\xf2\xe1\x0d\x21\xb6\x26\x74\x2f\x6b\x32\xcf\x6e\x1d\x88\x37\x21\x8b\x88\xd6\x3f\x5c\x7d\x5a\x76\xca\x07\x0d\x2d\x2b\xa2\x6a\x35\x8f\x0d\xbe\xab\xe2\xc4\x90\x11\x31\x88\x78\xf6\x63\x1c\xdb\xb8\xab\x91\xe8\xf2\xe1\x56\xd8\x1d\xfb\xf9\x29\xf4\x90\x6f\x02\x0d\x43\x45\x61\x3b\xca\x5c\xfe\x47\xbd\x06\x77\xb4\xba\xcb\x22\x12\x55\x73\x67\xb2\x0f\x8b\x2a\x9a\x27\x18\x00\x13\x16\xf0\xff\xfc\x5d\xd9\x97\x76\x59\x4c\xe4\x75\xc8\x89\x0d\xbe\xf7\xff\x18\xfd\xa2\x18\xb8\x14\x46\xad\xf2\x41\xff\x0e\x55\xeb\x63\x67\x83\xb5\x54\x50\x3f\x9c\xb8\xcc\xbf\x3d\x9c\xfc\x3b\x25\x6d\xe5\x66\x8b\x5e\xb2\xb2\xa4\xe7\x31\x9b\x23\x38\xc4\x0f\xa9" \ +"\x90\xfb\xd7\x59\x81\xe6\x48\xdb\x8b\xc5\x4e\x6d\x66\x19\x30\x2c\x7b\xd3\xd8\x6a\xb9\xed\x7c\x85\x27\x25\xa2\x14\xd3\x86\x9b\xa8\x0b\xde\x98\x8f\xd3\x70\x85\x88\x15\xa9\x59\xbb\x5c\x3d\x90\x7e\x8e\xa5\x5b\x40\x2d\x29\x38\xa4\x6c\x31\xf1\x89\x63\x2c\xbf\x64\x0b\xe1\xa6\xf4\xb7\x0e\x45\x8d\xb8\xc1\xdc\x48\xd3\x43\xdf\x10\x2b\xe3\x22\x57\x5b\x20\xe5\x54\xa2\x71\xfb\x7d\xda\x76\x1f\xfe\x10\x21\xaa\xc9\xd1\x31\x1e\x71\x68\xc1\xd4\x52\x40\x50\xd6\x20\x95\xd9\xf4\xed\xc1\xdf\x68\x4d\x80\xe4\x8c\x37\xfc\xcc\xe5\xbb\x24\x63\x99\xf1\x8a\x87\xab\xa9\x3e\xfa\xb8\x3f\xa7\x8b\xb7\x39\xaa\x24\xd9\xc9\x81\xa9\xde\x4e\x99\x41\x99\xc3\xd3\xe5\x9f\xbf\x00\x91\x0c\xd1\x19\xf7\x7a\x13\x6c\xad\xa3\xbb\xeb\xfe\x57\x50\x19\x6e\xb3\x9e\x30\xe8\x14\x8a\x51\xc6\x4e\x12\x2c\x4b\xb5\x12\xee\x60\x3d\xf7\xe5\xfe\x02\x37\xa9\x20\xb4\x88\xb1\xa1\xd5\x84\x80\x6c\x5d\x9f\xc9\xd4\xee\xdf\xe9\xba\xf3\x04\xf8\x05\x21\xd6\xc1\xd6\x5f\x33\x8d\x3c\x48\x3f\x8e\xb8\x25\x7a\x76\x88\x61\x5d\x8e\xf5\x08\x93\xe0\x7e\x43\x5d\xaa\x69\x79\xe7\xab\x55\x69\xbf" \ +"\x7e\x58\x39\x2a\xfd\xb3\x55\xfb\xc1\xa3\x70\x47\x1c\x89\x68\xc7\x79\x0d\x7a\x3a\xe7\xa0\xb0\x32\xc8\x50\x41\x63\x19\x43\x81\x5b\x61\xb2\x83\xc3\x6f\x94\x86\x47\x39\x91\x71\xd1\xb1\x33\x9a\x1d\x1c\xb4\x4a\x0d\x45\x93\x60\xd2\x6c\xb0\x59\xf8\xee\x40\x8c\x55\xc4\xa9\x14\xfb\xee\xc2\x29\x38\x27\x3b\xe2\xbd\x82\xb2\x5a\xb0\xe2\x2e\x6c\x9c\xcc\xae\x55\x76\xa5\x89\xb8\xa0\x85\x59\xaa\xb8\x25\x30\x41\xf1\xe0\x75\xa4\xf8\xd5\x70\x8f\x80\x17\x82\x85\xd8\x42\xbe\x3f\xee\xb3\x54\x47\x1b\x32\x53\xc7\x5b\x7e\xa4\xc0\x4c\x6b\x64\xe5\x06\x19\xa4\x59\xeb\x75\xf7\x3d\x6d\xcd\x4c\x80\xe6\x29\xf3\x55\x3a\xbd\x80\xd8\x15\x35\x44\x50\x01\x19\xab\xcb\x47\xb0\x2e\x06\x54\x23\x96\x5f\x90\x90\xfd\xd2\x4e\x0a\x1f\xda\xb3\xf8\x5f\x51\xf4\x4f\xd7\x3f\xc4\x64\xa5\x78\x36\x0e\xb4\x7d\x98\x6a\xad\x7d\x0e\x6c\xd3\xa1\x83\xe5\x72\x38\xfc\x10\xdd\x10\xf2\x4a\x57\xa8\x79\x7f\xf7\xd4\xc8\x47\xcc\x74\xf6\xff\x9a\x18\x89\x7f\x2d\xb1\xd4\x11\xd4\x66\xec\x1d\x58\xb1\xa6\x87\x6b\xd2\xe6\xdb\x7c\x47\x62\x32\xe6\x6b\xde\x4f\xde\xbe\x25\xf1\xf2\xa7\x1b" \ +"\x75\xfd\xc9\x4c\xfb\xba\x12\x87\x60\xbf\xcf\x0f\x6b\x43\x92\xfb\x69\x66\x19\xc8\x47\xd1\xa5\x7d\xc0\x12\xe4\xa2\xee\xd6\xdd\x8a\x31\x28\x64\x7a\xf9\x14\x79\x39\xc7\x0b\x00\xf3\x4c\x39\x17\xd3\x6e\xd4\xfa\xda\x5f\x9a\x91\xb3\xad\x2d\xe9\x9b\xf6\x43\x23\xcb\x5d\x05\x02\x5b\x79\x74\x5d\x40\x45\x1f\xb6\xb3\x4a\x3b\xc6\x29\x13\x66\x33\x4c\x7e\xe0\x99\x41\xfe\xba\x5a\x10\x5b\xdc\x9a\x82\x14\xbb\x67\x8d\xf8\xbc\xf5\xfa\x8b\xbf\x30\x8a\x28\xc7\xc9\x9b\x93\x53\x3e\xfe\x50\x03\x6b\x68\x24\x67\xba\x5e\xba\xe1\x6b\xa7\x76\xe6\xc7\x55\xf1\xdb\x8b\x14\x1c\xe9\x05\x83\x90\x65\x15\xe4\xec\xf9\x73\x52\x3e\x93\xaf\xfb\xae\x80\xb0\xff\xf8\x8e\xef\x71\xa5\xfe\xee\x16\x63\xa2\xca\x6c\x4f\xeb\xf6\x20\xdc\x0b\x33\xef\x6d\x04\xcc\xb3\xd4\x56\x26\x05\xe8\xaa\x4c\x97\x83\xa5\xce\x7a\x69\x7c\x6b\x1c\x89\xc4\x63\xc2\x06\x7a\x1d\x4b\xb2\x1a\xe8\x46\x21\xe7\x18\x49\x21\xbb\xb5\xf0\x4b\x16\x72\xa3\x62\x72\x06\x5d\x02\x20\x10\x4f\x5d\x77\xdb\x99\x0f\xb6\x81\x7b\xf2\xa2\xb6\x98\xc8\x18\x0e\x5f\x30\x23\x3c\xed\x47\xb7\x98\x5c\x86\x1f\x52\xae" \ +"\x35\x9b\xaa\x60\xdd\x5d\x89\x5a\x1f\x80\x14\x83\x0f\x56\x9a\x5d\xbe\xb2\x7c\xd6\x82\x2b\x40\x86\xf9\x00\x30\xd7\x5c\xec\xca\x18\x2f\x3c\xe8\xbe\x7c\x03\x47\x91\xb7\xd7\xf0\x01\x64\xeb\xcb\xb9\xcd\x7a\xde\x29\xc7\x7f\x04\x4a\x39\x5c\x50\xe3\x6d\x51\xc5\x20\x26\x23\x35\x5e\xf5\x09\x8d\xf5\xdf\xdf\x5f\x2a\xaf\x9d\xd1\xd7\x5a\x40\x00\xf8\xf4\xf6\x19\x3c\x07\xa9\x8a\xf6\xb8\x60\x9b\x44\x5e\x9b\x16\x0f\xf1\xa9\x14\x31\xd7\xd1\x6f\xef\xc8\x90\x05\x21\x99\x8e\xef\x94\x6e\x75\x6d\xf8\x43\x62\x6d\x9d\xbb\xac\xa0\xa9\x55\x36\x00\x99\x81\xd9\x96\x43\x7c\x97\x65\x6a\x83\xcf\x86\x05\xff\x8b\x92\xc0\x00\x73\x5b\x06\x81\x3a\x3c\x67\x6a\xdf\x34\xd3\x66\xfc\x99\x07\x24\x22\x20\x88\x6f\x18\xe7\xda\x65\x72\x31\x80\xb9\x3a\xeb\x1a\x6c\x94\xd8\x02\x6d\x7f\x4c\xaa\xe6\xa7\x4d\xe6\x90\x78\xea\xb7\x4e\xf6\xcc\xe4\x86\xf9\x58\x64\xc4\xc6\xa8\x71\xd8\x2a\x23\xc1\xea\x22\xc3\x98\x7d\x4f\x4f\x18\xa1\xad\x10\xae\x2e\x43\xaa\x83\x9c\xe8\x56\x59\xad\x1e\x27\xd1\xb1\x32\x89\x54\x6d\xcb\x19\xb3\x69\x2a\x97\x8d\x38\x2f\x92\x6d\xaf\xe1\xf3\xd2" \ +"\xce\x51\xc4\xed\x9f\xc9\xa5\x37\xb5\x99\x45\x99\x75\x76\xd9\x82\x41\x8b\x44\x76\x3b\xc9\xca\x52\x81\xa2\x17\x66\x3d\x9b\x6d\xce\x7d\x29\x6f\x8b\x53\xae\x85\xf2\x2c\x02\xeb\xba\x3a\xf7\x63\x88\xad\x6a\xfa\xf8\x22\x98\x85\x03\xd0\xaa\x81\x17\x3c\x49\xd4\x2e\xbf\xbe\x58\xcf\xdd\xa4\xb2\x2d\xd7\x83\xcc\xe1\x75\xad\x8a\xb4\x03\x00\x0f\x0e\xdd\x49\xb8\x16\xa7\x53\xd8\x1f\x89\xfe\x6c\x5a\x15\xeb\x05\x44\x8f\xec\xda\xb1\xaa\xef\xb4\x08\xa8\x8c\xe2\xbd\x10\x91\x3e\xa3\xe1\x5d\xcd\x25\x78\x62\x81\xf9\x81\xfd\xd5\xae\xc8\x13\x8f\x8c\x09\xb1\x32\x69\x86\x45\x71\xf4\x85\x06\x78\x19\x9b\x84\xfe\xe2\xcf\x2b\x38\xa8\x45\xa9\x5f\x53\xa6\x22\x45\xd5\xbb\x62\xf3\x77\x8f\x79\xf9\x77\x81\xa5\x67\x92\x8c\x0d\x88\xee\xa0\xaa\xfd\xab\xd4\x62\xef\xac\xc3\xf9\x44\xcf\x3c\x18\x82\x80\xa7\xa3\xb2\x82\xdc\x06\x8b\xc6\xc9\x6e\x1a\x5b\x9b\x90\x8f\xd4\x55\x6a\x32\xc6\x4a\xd2\xa8\x92\xe8\xac\x1e\x98\xce\x45\x2c\x2f\x58\xa5\xb4\xdd\x2d\xfc\xf8\x2f\x1a\x21\x8e\xbd\x4d\x4d\x14\xb9\xf7\xf9\x58\x43\x75\xf9\x97\x76\x39\x12\x89\x80\xbd\x86\x94\x55" \ +"\x07\x2f\x3c\x8e\x6e\x69\xfc\x2d\xa5\xbb\x86\x32\xff\xb4\x38\x82\x89\x4c\xbd\xda\x98\x2e\x94\x2c\x01\xef\x2f\x48\xc0\x46\x0e\x4a\x5a\x88\xf5\x23\x28\xab\x1d\x11\x61\x4d\xb8\x20\x26\x26\xfc\x0c\x00\xe2\x0b\xde\x84\xb7\x79\xd1\x53\x03\xa4\xf3\x20\x6f\x6d\x91\xcb\x39\xf1\xc0\x05\x6b\xa4\x80\x03\xda\x45\xb2\xc8\xde\x2d\x41\x69\x6e\x73\xb8\x4b\xf3\xdd\x31\xe2\xaa\xbd\x31\xf6\x81\x21\x96\x26\xcb\x03\xd6\x6f\xce\x96\xa8\x89\xa2\xe4\x03\x60\x69\xb8\x1b\x6a\x51\x20\x93\xe6\x3c\xdb\xc7\xb0\x4a\x64\x12\x50\x8c\x46\x80\x73\x77\x6f\x52\xac\x08\x06\xa8\xbc\x38\xc5\x70\x9f\xa9\xd8\xc8\x5a\xfb\x68\x70\x13\xb3\x47\x3b\xb5\x8a\xe0\x9e\xfc\x94\x32\x41\x37\x21\x78\x8e\x89\x6c\x14\x8e\xec\x90\x59\xc5\xbe\xbc\x13\x66\xe3\xf0\x26\xaa\x81\x7b\x45\x7b\xc1\x0d\x25\x85\x2c\xa7\xd2\x8d\xac\x9a\xd0\x2a\x9c\x23\x7e\xb0\x01\x62\xc1\x87\x66\xeb\xe5\x16\x22\xbb\x12\x6f\x40\x53\x6b\x11\x9d\xf1\x75\x3b\x08\xd3\x3c\xc8\x57\xb8\x59\x84\xf9\x3c\x12\x51\xed\xe1\x35\xdd\x83\xff\xda\x40\xef\xc2\x07\xb5\x28\x03\x2e\x6c\xdc\x34\x6c\x3e\xfe\x8c\x25\x74" \ +"\x0f\x28\xa9\x5a\x2f\x88\x66\xfd\x07\xdf\x84\xcf\x3c\xea\x15\x86\x9b\x3f\x70\x25\x48\xde\x37\x3b\x14\x22\xa7\x47\xde\xdd\xa4\xa1\x5c\x83\xf4\xeb\xf3\xed\xb8\x81\x4d\xa5\xa0\x8b\xab\xea\xea\x45\x71\x80\x5d\xd7\x09\x54\x29\xd5\x23\xa4\x18\x78\xcc\xb4\xb2\x99\x2f\xf5\x39\x16\xaf\xce\x0c\xaf\xcb\x81\x27\x5d\x7f\x12\x0c\x37\x2b\x24\xfc\x01\x68\x74\x3b\x87\xc1\x91\xb7\x29\x3e\x4e\xa5\xbd\xe8\x80\xe0\x0b\x8e\xff\x02\xdf\x5f\x50\xdb\x57\xf9\x79\x1f\xb5\x32\xf1\x1f\x7f\xae\x63\xee\xb0\x74\x41\xdc\xa0\xbd\x19\xcc\x67\x14\xe7\x2a\xc3\x22\xb4\x69\x79\x6e\x63\x95\x8b\x01\xdd\x7c\x43\xac\x2f\xbd\xcf\x0e\xe5\x4f\x9e\xbb\xcb\x7e\xec\x0e\x35\x79\xf3\x84\x4e\x27\x48\x07\xa5\x16\x4e\x29\x65\x80\x14\xa8\x88\xc6\x6d\xe2\x20\x87\xa8\x68\x9b\x73\x39\x32\x42\x11\x48\xf5\x7c\x46\xbc\xc2\x90\x59\x8c\x55\x08\x0a\x81\xe3\xa7\x0f\x0f\xc9\x36\xef\xc2\x9a\xcc\x81\x1b\xbe\xf5\x66\xa6\xb2\xc9\x07\xc5\x4e\x95\x45\xf5\x04\x8f\x04\x54\x0d\xd9\x3b\xf2\xdf\xe2\xc7\xe7\x76\xbc\x37\x73\x38\x0f\xd9\x03\x00\xb5\xbe\x03\xa2\x7f\x78\xce\xb5\x08\xe1\x9b" \ +"\x94\xca\x75\x46\x60\x51\xf6\xa5\xfd\x73\x94\xd9\x8a\x2c\xcb\x24\x2c\xdd\x3b\x7a\x44\xaa\xf8\xeb\x58\xf2\xd1\x2a\x47\x1f\x75\x05\x95\xdd\xd8\x9a\x74\x29\xe7\x8a\x7b\x55\x80\x47\x6d\x6f\x11\x48\xa3\xe1\x6d\x07\x28\x85\x4a\x4c\x9b\x6b\x22\xc1\x72\xf0\x3d\x1f\x18\x2e\xd7\xc5\x60\x72\xd5\x12\xd6\x39\x77\x32\x12\x05\xaf\xfe\x15\xf6\x40\x91\xab\xd9\xf3\x9f\xfa\xe7\xe4\x40\xa4\x61\x3d\x96\x09\xe6\x0b\x8a\x84\x5f\xd1\x8a\x61\x57\x8b\xbe\xab\x87\x9e\xaa\x63\xc6\x12\x7f\x2c\x66\x01\xec\x5a\x49\xd6\x87\x74\x6b\xf7\xaf\x2e\xee\x33\x4f\xa3\xf9\x05\x89\x91\x5c\x8a\x17\xcf\x9e\x32\x6d\x83\x54\x3d\xb8\xfc\xe8\x14\x43\x6b\xbd\x3d\xc6\x1b\x06\xbd\x77\x22\xec\x5e\x69\x41\x8c\xb5\xf8\x20\x0c\x77\x7e\x00\x0e\xe2\x4e\x07\x79\x6f\x2f\x1e\x31\xce\xbb\x7d\xf7\xeb\x06\xe5\x22\xa1\xae\x48\x9a\x25\x5e\x08\x58\x7d\x36\xb6\x64\x2e\x54\x90\xd5\xfb\x3e\x47\xb1\x78\xff\xc2\x0e\x69\xce\x97\xb3\x90\x8c\xbf\xa7\xf8\x2c\x46\xe3\x9a\x8e\x20\xae\x9f\xc7\x9a\x4e\xa5\x44\x60\x49\x08\x0d\xf6\xa2\x9b\x30\x07\x79\x5a\xad\x28\xe2\xa6\xbd\x23\x57\xe1\x2d" \ +"\xd1\xdc\x46\x16\x9c\xd8\x27\x7e\x54\x8e\xcf\x64\xdb\x9b\xa6\x2b\xfd\xa1\xff\x8f\x94\x5d\x11\x07\x6d\xb0\x70\x0e\x57\x93\xba\x7b\x20\x9f\xfc\x53\x6f\xb6\xfa\x1c\xef\xcf\x5c\x40\x11\x1a\xd8\x00\x29\x18\x8e\xf6\x13\xac\x20\x89\xea\x45\x93\xfb\xea\xcf\x5f\x06\x71\xd1\x6b\x45\x7a\xc6\x94\x0d\x12\x1c\xee\xbf\xa8\xcd\x90\xea\xb5\xf7\xc0\x97\xb0\x5f\x9d\x3c\xe0\x1a\x78\x18\x10\x42\x66\x33\xb9\x6f\x27\x06\xcd\xbb\x10\x01\x8d\x2d\xea\x30\x90\x1a\x5c\x9b\xd5\xda\x58\x97\x00\x6f\x6d\x1c\x2c\xac\x18\xd7\xcd\xba\x2a\x77\x7c\x30\x29\xc7\x55\x51\xf4\x18\xaa\x47\x9c\x8d\xf9\xea\xc1\xae\x4d\xb8\x2f\x6b\x70\xeb\x7c\xfe\x07\xa3\x9c\x47\x3b\x7a\xe0\xc4\xd7\x47\x51\x91\xcf\xb2\x61\x76\x2d\x9a\x6d\xbe\x8f\x3f\x53\x87\x6e\xa6\xae\x2f\xc3\x21\x00\xea\xd4\xdf\x0b\xf8\xd2\x9e\x11\x8b\xef\x0f\x39\x85\xb9\x98\x47\x38\x02\x3e\x0a\x67\xf3\xf7\xb6\x51\x0a\x26\x31\x07\x83\x0a\xca\xb8\x4f\x95\x54\xd5\x7a\x85\xd0\x18\x8d\x84\x0c\xf4\xfb\xa0\x29\x38\xdb\x7b\x78\x17\xf0\x28\x1d\x20\xd5\xde\x24\x31\xad\xb0\x0b\xd1\x91\x68\x9a\x9a\xb6\xb7\x05\x3c" \ +"\x83\x46\xe0\x2f\x7d\x6e\x2f\xf6\xb4\xde\x7d\xf3\xfb\x37\x19\x93\x4d\xa4\x74\xda\x98\xbf\xf4\x2f\xc7\x44\xd0\xd1\x31\x5a\xc5\xb0\x02\xbf\x7f\xc6\x30\x10\xa8\xf3\x29\xc3\x32\xaf\x21\xac\x5c\xb9\xfe\x60\xdd\x41\x18\x24\xbb\x0a\x68\xf2\x65\xb9\xb0\xce\xd7\xa6\x52\xbd\xf5\xd0\x3e\x26\xcf\x61\xc0\x2d\x2e\x62\x42\xc9\x45\x5f\xce\xd3\xcc\xe1\x89\xcc\x64\x6e\x3a\x54\x1d\x70\x90\x33\x0f\x01\xaa\x4f\x29\xef\x4d\x01\xd0\xd1\x50\xd0\xd6\x1b\xa8\x99\xe5\xbc\x28\xfa\x0d\xf0\x17\x60\x36\xeb\x17\xca\xa5\xd7\x6d\x8f\xa3\xa1\x88\x65\x6d\x62\x66\x36\xe7\x8d\x9d\x16\x05\xc9\x59\x0a\xf1\x71\xe1\xb9\xea\x80\xd4\xce\xba\x3b\x72\x4f\x45\x2b\xab\xd0\xdb\x3f\xdb\x70\x36\x4d\x9c\x74\x96\x8c\x71\xba\x4f\x83\x6d\xe7\xcd\xaa\xfd\x83\x61\x8d\x6b\xf2\x05\xee\xa7\x20\x87\xc2\x8f\x97\x47\x16\x51\xfe\x54\x78\x67\x83\x3d\x56\x7e\x42\x33\xc9\x00\xaa\x46\x12\x26\x98\xe1\x03\x75\x62\x64\x8d\x72\x27\xa1\xbd\x92\x94\x2b\x37\xbd\x12\x9d\xb5\xb9\x07\x75\x4d\x38\xe5\x5b\x50\xe9\x4f\xa5\x8c\x18\x62\xc5\x82\x32\x46\x2c\x6f\xe6\xf1\x5c\xcc\xf6\x4e\x13\x12" \ +"\xe7\xdb\xc9\xcf\x54\xcd\x89\x8a\x71\x2d\x04\x48\x91\xcc\x03\x56\xe6\xc8\xd0\xa6\xda\xb7\xd9\x15\x59\x17\x28\x6b\xa1\x44\xe6\x60\xec\x5b\x6a\x0f\x26\xff\x84\x0d\xf8\x62\x6a\xb1\xdf\x36\xf7\x72\x52\x93\xa1\x2a\x2b\x0a\xc0\x0c\x5e\xc8\xf8\xc8\x55\xe7\xf7\xf6\xc9\xdd\xb4\xd9\x71\x0c\xde\x58\x35\x15\x06\x1a\xd6\xdc\x98\xfd\x5c\x38\x9e\x11\xe9\xda\x5f\xea\x5b\x61\x47\x94\x0b\x03\xe2\xc7\xfa\xc9\x84\x5c\xf4\x12\xd2\xf8\xd4\x59\xb6\x60\x49\x79\xfa\xde\x3b\x79\x76\x13\x1c\xdd\x7e\x30\x77\xbe\xd9\x48\xc2\x5b\x04\xd5\x11\x89\x22\xf6\x07\x06\x8f\xf5\x61\xc0\xfc\x37\x91\x52\x0a\x4d\x6f\x1f\x50\x4a\x9c\x0e\x44\x6f\x52\x4c\xa8\xcb\x09\xdc\x36\xe9\xaf\xba\xa9\x68\xf3\x02\x8f\x6d\xd5\xf7\xa3\xc4\xb5\x25\x10\x32\xda\x1c\x81\x76\xa2\xbb\x62\xca\xe2\xf4\x27\x1b\x5a\xff\xeb\x7d\x62\xce\x9b\xb3\xd3\x3a\x87\x50\x61\xdc\x20\x88\x12\xe2\x3c\xfb\x33\xaa\xa5\x2f\x04\x3f\xa0\x29\x69\x55\x17\x7a\x20\x91\x45\x55\x9f\x93\x49\xd1\xc9\xa9\x19\xe1\xa4\x06\x97\x5c\x09\xdf\x37\x89\xca\x43\xdd\x64\xa1\xf8\x0a\xd1\xc3\x1b\x92\x04\xdb\xe3\xbe\xcb" \ +"\x86\xe4\x0a\xa0\x22\xdd\xfa\x6e\xcb\x21\xba\x3c\x88\xb9\xeb\x48\x2d\x69\xb0\xa1\x24\xa9\xb9\xae\xa8\x92\x17\x39\x80\xc6\xa2\xc2\xc5\x3e\xfe\x66\xc8\x9a\x8c\x62\x28\xd0\x80\x5f\x97\x4d\x28\xbe\x58\x4b\x9c\x2f\xcf\xdc\x0b\x7d\x9f\x18\x59\x8e\x3c\x02\x9c\x19\x2c\xcb\x27\xde\xa6\x7a\x5d\xd7\x5b\x57\x39\xc7\x45\xd3\xf4\x8c\xf1\x6a\x2b\xc1\x0a\x96\x41\xe2\xa3\xca\xa5\x9b\x5d\xdb\xcf\x1c\xae\x9d\xc9\xc7\xa9\xae\x1c\x24\x75\x6a\x9b\x57\xd1\xdf\xab\x68\x48\x4c\xb4\x65\xc4\xf8\xa3\xfc\x96\x21\xe0\x76\x80\x82\x91\xd3\x1c\x50\x11\xae\x21\x9c\x6c\x8b\x78\xe1\x6f\x09\x2e\xe4\x4f\x70\x79\x23\xb5\xaa\x0c\x83\xad\xa9\x04\x28\x08\x65\x22\x9a\xe3\xc8\x39\x32\x76\xdc\x80\x15\xd0\x3e\x83\x44\xc1\x34\xa3\x23\x60\x2d\xe1\x1a\xdb\x32\xc2\x2c\x16\xb5\x53\x15\x52\x23\x64\x0a\xf1\xda\x0c\x68\xf0\xfe\xbe\x36\x30\xd5\x57\x41\xb7\x1b\xe8\x17\xf6\xa9\xb3\xa4\x37\x42\x46\xdb\x07\xd6\x80\x3a\xf4\x78\x34\xff\xd5\xaa\x51\xeb\x10\x2e\x12\xe5\xba\x8b\x76\x7f\x0c\x4a\xad\x6a\xab\xa1\x03\x6c\x03\x71\xd3\x02\x58\x5a\xe3\xca\xc4\xc3\x45\x58\xa8\x28" \ +"\x57\xf7\xd2\x05\x1a\x75\x9f\x2a\x03\x49\x94\xf7\xec\x6e\x10\xec\xa9\xb3\x16\xc6\x20\x4f\x8a\x60\x46\x06\xa1\x1b\x47\x9b\xf1\x70\x3c\xbc\x33\x86\x9a\x00\xcf\xcb\x2b\x66\x58\xb4\x8b\xef\x48\x1a\x2e\xae\x4c\x41\x0e\x87\xca\xd3\x7c\xc9\x04\xe3\x28\x77\x2e\x66\x17\x47\x8f\xa7\xa4\x4d\xc0\x87\x10\x1b\x94\x7f\x7b\xbf\xd1\xa0\x31\x5d\x8a\x5e\xa1\xb5\xcd\x50\x50\x21\x49\xcb\x2d\x24\xc2\xad\x56\x07\xea\xc8\x8a\x14\x3e\x14\x6e\x54\x10\xee\xcf\x7b\xaf\xe9\x28\x87\x33\x55\x88\x40\xcc\xc6\xcf\x97\xa2\x85\xcf\x3a\xf6\xbb\xc9\x5b\xb9\x4c\x2e\xd1\xad\x99\x47\x9e\xf1\x6d\x42\x81\x6d\x13\x46\x1e\xba\x4c\xf9\x7d\xc5\xf3\xdf\xdb\x10\x5d\x86\xe8\x3b\xbc\x2a\x04\x9b\x81\xec\x91\xa6\xf4\xde\x67\x03\xa6\x91\x96\x39\x81\x13\xfd\x9d\xf2\x42\x61\xa5\x6b\x57\xb4\xf5\xf7\x2f\x13\x22\x87\xdb\x5e\x4c\x76\x9c\xf7\x94\x2c\x8e\xa4\x14\xb8\x60\xb3\x8a\x36\x27\xd4\xeb\x60\xd7\x27\x2d\x33\xd7\x27\x2f\x77\x78\x16\xc5\xa6\x9e\x1a\x73\x15\x10\x6e\x17\xa6\x84\xd1\xe8\x67\xf8\xc8\x85\xee\xe0\x0d\x32\x6e\x21\xd3\x9a\x05\xef\x89\xe2\x57\x83\x98\xe1\x3b" \ +"\xd0\x31\xcc\xed\x51\x95\x22\xa7\x2e\xb5\x79\x6e\x1f\x6c\xe2\x0a\x50\x06\x2f\x54\xb4\xb0\x56\x46\xab\xdd\x55\x8f\xac\xe3\x78\xe5\x4b\x8c\x85\xc3\xb0\xad\x5c\x52\xb3\x61\x73\x74\xec\xe0\x46\x2c\xa6\xce\x17\x63\x00\xd5\x2f\xcb\x99\xdd\xb2\xf6\xc4\x1e\x4a\xd0\x64\xf5\x55\x88\x84\x06\xd5\x49\xc7\xf8\x3d\xce\x8d\x4a\x3d\x64\xb5\x9d\x33\x83\x5f\x74\xd9\xda\xa2\x20\x88\x0a\x73\xdd\x41\x10\xdf\x13\xa3\xac\x49\x8c\x61\x45\x43\xc7\x74\x89\xfb\xbc\x6a\x44\x4e\x19\xe1\xca\x28\x75\xa1\x72\x0a\xd0\x1d\x30\xd9\x52\xea\x4b\x86\x9c\x09\xfd\xf1\x90\x16\xba\x8b\x65\x6f\x25\x48\x5f\x21\xb1\x14\xf6\xd2\x84\x01\xff\x54\x99\xab\x8c\xde\x39\x56\x22\xb5\xe4\x27\x0d\x9e\x23\x39\x71\x10\x3d\x61\x6f\x27\x30\xc0\x58\x66\xc9\x53\x49\x71\xe3\x74\x14\x49\xa9\x87\x6b\x08\x60\xfa\x17\x19\xf2\x33\xa6\x1d\xa0\xa9\x2b\xef\x5a\xfe\xc6\xd1\x36\xf9\x1f\xd9\x17\x76\x39\xc0\x14\x45\x4d\x32\x18\x22\xbe\xa6\x1c\xb5\x31\x7e\xde\x85\xab\x00\x55\xd4\xe2\x5e\x23\x0b\xba\xfd\x2a\xa2\xe7\x6f\x29\x35\x15\x00\xc4\xd3\x11\x49\xb4\xd3\x2b\x0a\x0b\xa9\x2a\xd9\x64" \ +"\xdc\x6a\xd3\x08\x44\x2c\x41\x7c\xd6\x67\xc6\x1e\xbf\x19\x47\x36\xaf\x26\xb3\xc7\x46\x8a\x61\x6c\xff\x8a\x7d\x28\xe3\xa1\x4c\xed\x89\xb5\x97\x82\xc7\x93\x32\xca\x3f\xcc\xc9\xd2\xb0\x60\x22\x38\x43\x7b\xb7\x01\x4c\x9a\xeb\xb3\xd8\x0c\x75\xbc\x2e\x9c\xfc\x71\xa0\xe9\xc5\x55\x88\x1e\xf8\x8c\x0c\x5e\x86\x41\x56\xc3\xea\xf6\x5b\xa9\x16\xf6\xb3\x32\x09\x72\xdd\xb5\x75\x4b\xf8\xfa\xb2\x0d\x1b\x11\xfd\xf2\x2e\xd9\x26\xad\x29\xc7\x1d\x4a\x28\x23\x44\xd2\xd0\x3a\xb4\x85\xf4\x8a\x71\xcf\x22\xe1\x7a\x5c\x6f\xdd\xb7\x18\x96\x31\x07\x15\x42\x38\x3a\xa5\x72\x53\x1b\x1f\x30\x0e\x06\xa0\x42\x2d\x40\x57\xb8\x07\x1d\x7b\xf8\xe7\x4c\x01\x85\x52\x7a\x36\xc6\x2b\x8f\x87\x05\xad\x5a\xea\xc1\x0b\x0d\x9e\xc8\xd2\xeb\x22\x10\x93\x22\x0c\xa2\x7d\x11\x2a\x78\xb2\xfe\x46\xf7\x62\xef\xfd\x79\x06\xe4\x88\x8e\xe0\x54\xb5\xf4\x7a\x82\xa5\xf7\x1a\x28\x07\xc2\x4b\x45\x6d\x9a\x08\x45\x49\x13\xbb\x5d\x8d\x85\xa3\x8e\x66\xe6\xa7\x40\x3c\x52\x8c\x49\xcd\xdd\x2c\x8b\x6a\x43\x4b\xe8\xc0\xc9\xc7\xc6\x03\x8a\xe4\x8c\xa1\xd4\x39\x37\x33\x5e\x26\x59\xe1" \ +"\x5c\x25\xef\x38\x23\x32\xcb\x7b\x91\x8c\x3e\x25\x4e\x11\xdf\xec\xd3\x03\x98\x30\xc8\x49\x12\xca\xcb\x64\xb9\xab\x33\xfe\x8f\x27\x8d\x7d\x1c\xec\xb3\x2d\xea\x7e\x14\x41\xae\x61\xf1\xf2\x2d\x3f\x31\x0a\x89\xea\x89\xba\xe1\x84\x24\x36\xc3\xad\x15\xb9\xa3\x76\x7d\xf4\x42\xac\x91\x7c\xf2\x05\x15\xe6\x33\xa5\x18\x47\x9d\x74\xac\xb7\x93\xb0\x94\x88\x58\x54\x0a\x53\x16\xad\x43\xe4\x11\x25\x88\xf8\xea\x4d\xe9\x91\x6f\xfd\x1f\x4d\xd4\x6f\xde\xd7\x2e\x4d\x1d\x0a\xc0\x79\x11\xad\x46\xfc\x35\x88\x10\xb1\xa2\x1c\x71\x7c\xb5\x92\xeb\xf8\x50\x50\xf2\x5e\x15\xc0\xa2\xec\x15\xa3\xf4\xd9\x0f\xa7\x54\xc3\x2b\xd8\xdc\xb1\x45\x63\x23\x3a\xd9\xfc\xc3\x66\x0d\xc4\x69\x06\xd9\x30\xd1\xc7\x8f\x8b\x33\xe3\xb4\x50\x94\xce\xb7\x99\x1f\xf5\x3c\xb6\xcd\xc7\x99\xf4\xe8\xfb\xd1\xa9\x2a\xa3\x43\xd9\xb5\x1b\x39\x73\x6b\x4e\xc0\xfe\xec\xb7\xe6\x72\x2a\x9b\x13\x8e\x53\xcf\xac\x35\x14\xfa\x02\x96\x25\xd6\xba\x23\x08\xb3\xaa\x5a\xd6\xa0\xda\xfb\x82\xc5\x18\xbf\x17\xec\xe3\x9d\x03\x60\x20\xa8\xad\xf8\xd7\x29\x0e\x0e\x50\x86\x22\x41\x6c\x6a\x2e\xc3" \ +"\x96\x96\x7b\x67\x38\x79\xca\xd5\x6b\xf5\xbf\x81\xc0\x28\x5a\x05\x1e\x64\x77\x9c\xd0\x16\xce\x77\x30\x45\x36\x16\xe6\xd9\x61\xa7\x72\x69\x9b\xbc\x4e\x03\xaa\xe2\xd1\xa7\x93\x9a\x5a\x7e\xc1\x0c\xfd\xe4\xa5\x03\x1f\x66\x6a\x02\xeb\x12\x27\x98\xad\xb6\xc2\x7e\xb7\x72\xca\xd1\x20\x44\x62\x63\xb9\x37\x15\x74\x59\xe0\x4f\xa0\xa6\xab\x27\xb3\xad\x92\x4f\xa7\x24\x4b\xc3\x16\xf8\xb1\x61\x7a\x0e\x56\xea\x63\x14\x8a\xfc\x02\x1f\x2f\xbf\xbb\x88\xe0\xe9\xac\x1c\x3b\x4d\xe7\x7c\x56\x43\x19\x09\xde\x77\x9d\x1d\x1e\xa6\x6f\x6b\x8a\x99\xfe\x1a\x69\xf3\x5b\xd0\x02\xf9\xbc\x28\x22\x8a\x5b\x20\xab\xf6\x40\x39\x07\x91\xf3\x9b\x5d\xe4\xe4\x9e\x5e\xb9\x95\x3f\xec\xb0\xba\x23\x91\xab\xd1\xd5\xd6\x01\x9e\x8f\xb9\x21\xf8\x54\x01\x5b\xc9\x00\xae\x70\x34\xa5\xca\x18\x14\xea\x7d\xff\x8e\x23\x8a\x15\x57\x9d\x28\x57\x96\xde\xe2\x72\x77\x7f\xbe\x7b\x19\x0a\xaf\x14\x42\x23\x08\xfd\xcb\x11\x4f\xef\x4f\x31\x5c\x6f\x3e\x40\x5e\x96\x5f\x32\xf6\x13\x4e\x59\xf7\x04\x19\x92\x8e\xc9\x65\x89\x24\xb3\x5d\x50\x9e\x90\x22\xf8\xad\x14\xf5\xb4\x1e\x84\xf1" \ +"\x0a\x78\xcd\x0a\xc8\x77\xc3\xc1\x30\xcd\x8f\x30\x35\x9b\xf2\x32\x63\xb5\x9a\xb6\x2c\xf3\x05\x12\x79\x8c\x3c\x38\x8d\xd5\x9c\x9e\x7a\x1c\x7d\x2a\x98\x53\x2f\x84\x10\x36\xf6\xa4\x7b\x44\xed\x97\x14\xa1\x80\x18\xfb\x99\x24\x09\x64\xe3\xeb\x0f\xcc\x21\x45\x5a\xaf\x47\xc8\xd7\x18\x1c\x88\x7b\xe0\x70\xcd\xb7\xab\x82\x77\x9d\x57\x9b\x37\x59\x32\x79\x8f\x0c\x76\x33\x83\x6d\x6f\x27\xc2\xce\x77\x96\x59\x09\xc7\x56\x58\xcf\x20\xf1\x8d\x6a\x0b\x13\xf1\x8c\x4a\x13\xf1\x74\xba\xe0\xd8\x8b\x53\x23\xba\xbd\x7a\x40\xa8\x79\x3f\xb6\x65\xe8\x98\x60\x04\xa2\xbf\x98\x49\x0c\xf0\x37\x33\x70\xda\xd8\x81\x1e\x27\x31\xd1\x84\x18\x8c\x16\x11\xd8\xda\x78\xdd\xf8\x28\xa9\x18\x4e\xc6\xdb\x63\x56\xe1\xe9\xff\xef\x76\x0d\x2c\xbe\x91\x98\xcf\x65\x66\xa8\xcc\xd4\xb3\x6d\x36\x65\x30\x9b\x5b\xaa\x0a\x57\x83\x31\x5f\xa5\xc7\x3e\xa2\xbb\xef\xba\x07\xe1\x80\xb2\xc9\x27\xdf\xd5\xc2\xca\x41\xd8\xbc\xcc\xa1\x35\x67\xc8\x6c\x38\x77\xcd\x98\xe3\x69\x08\x37\x63\x64\xe2\xe3\xce\x68\xac\xf9\x7e\x27\xb9\x01\xf3\x86\xe2\x68\x24\xb0\xf2\x33\x1b\x53\xfc\xfa" \ +"\xdb\x02\xc9\xc5\x40\x9c\x66\xab\xac\x3b\x23\x3c\x9a\x70\x20\x0e\xfc\x4e\x5b\xa2\x36\x8b\xdf\x9a\x61\x9d\xec\x31\x21\xfd\x43\x3c\x64\x7f\xcc\x53\xeb\x07\xd9\xd7\x88\x55\x4c\xac\xa1\xb4\x36\x3d\x2b\xbb\xcf\x7d\x32\x9d\xf6\x60\x9f\xcb\x11\x3d\x1a\xb8\xce\xce\xe8\x49\x20\xde\xfc\x40\x9c\x4e\x8c\x29\x79\x49\xde\x85\x48\x62\x2d\xa1\xac\x2a\xe6\xa4\xf8\x8b\xff\x8c\x54\x05\xf4\x83\x9e\xb9\xb1\x05\x1b\xc9\x44\x45\x25\x20\x0b\x4f\x0f\xda\xc9\x29\x3d\xdc\x52\x66\x8f\x89\x5d\xa1\x5d\xb8\x85\x8c\x09\x76\xdc\xd9\xb8\x9d\xe3\xb8\x01\xdb\x23\xb7\xb7\x9a\xc3\x7b\x3b\x7c\xa6\xfb\x97\xf8\x53\xc7\x9e\xa3\xce\x04\x83\x20\x45\x89\x5d\x34\xd5\x54\xdb\xe1\x55\x92\x1a\x15\x7a\x8a\x6c\xbd\x5d\x1d\x24\x13\x7f\xb9\xfb\xba\x86\x01\x8b\x82\x94\x18\x93\x71\x99\x12\x9c\x71\xdc\x88\x63\xcf\x10\xe0\x76\x05\x7d\xf7\xdf\xbb\xff\xb0\x2d\xe1\x64\x41\xe6\x5e\xf7\x6a\xec\x8b\x30\xaa\x87\xbc\x6e\x48\xf5\x4d\xe5\x77\x79\xdd\x75\x50\xa1\x0b\x53\x6f\x68\x07\x10\xd7\xc8\x4c\x46\x1e\xeb\x6d\xff\x6c\x33\x16\x27\x76\xa6\xb9\x0a\xc9\x19\x87\x8b\x7b\x2f\xe7" \ +"\x5e\xed\x2c\xcd\xe0\x65\x9f\xdb\x34\x4b\xdb\x75\x7f\x5e\x25\x62\xa6\x1a\xda\xb6\x87\x4f\x61\x80\x2f\x50\x0b\x81\xe8\xc7\x49\xee\x14\x60\x49\x08\x0d\xf6\x96\x71\x10\x5d\x1d\x3f\x63\xb8\x7f\x30\xb8\x0f\xc9\x29\x08\x49\x14\xfe\xba\xbe\x55\x39\x6a\xdb\x32\xde\xf5\x13\x01\xe0\x7e\xcc\xb0\xd4\x2e\xca\xfd\xf6\x8b\x8b\x9d\xa5\xe0\x64\x10\x30\x32\x92\x92\xbd\xd7\x69\xfa\xdb\x07\x69\x1b\xc3\x3a\xb9\xdf\x18\x84\xc7\x79\xb7\x1c\x0f\xf2\xaa\xc4\x78\x74\x10\xc5\xd1\xe2\x39\xdd\x06\x14\x9a\x62\x32\x64\xd1\x44\x23\x39\x4d\xa8\x8b\x65\xb3\x49\xb6\x9e\xed\x36\x8c\x27\xb5\x6c\x9a\x8b\x70\xb9\x70\x58\x33\x7d\x5d\x1a\xca\x4d\x9d\x30\x58\x42\x4a\x40\x37\x99\x4e\x7b\x9c\xab\x3b\x2b\x0b\x8e\xf9\x89\x19\x88\xdb\xf4\xd2\x75\x2c\x9c\x88\x50\xe0\xec\xd5\xbe\x47\xfc\x87\x25\x5f\x07\x05\x1c\xac\xf1\x1b\xd9\x8c\x13\x2a\x8a\x6b\x47\x0c\x4b\xb3\x70\x1d\x81\xbf\x09\x8d\xb3\xff\x01\xa2\x07\x76\x69\x2f\x31\x69\x2c\x14\x56\xb9\x02\x7d\x92\xf1\x9f\x69\xb0\xdd\x73\xd5\x0e\x42\xca\x5f\xfa\xd5\x2b\xf8\xb0\x04\x2e\x27\x54\x13\xba\x50\xf2\x35\xb6\x9c" \ +"\x03\x2b\x08\x4f\x58\x9c\x7f\x0b\xf7\xb3\xc7\xd0\xfb\x25\xd9\x16\xcf\xbf\x80\x35\xa0\x10\x9f\xc5\x13\xd6\xf0\x1d\xc1\xd4\x49\xbf\xf4\x1b\xbd\xe5\x63\xfb\xfe\x32\x2a\xbf\xc7\x0f\x95\x8d\x51\x3c\x19\x87\x78\xe7\x28\x54\x7f\x3b\x96\x7f\x2d\x9a\x87\x7c\x6d\xfc\xba\xcc\x62\x94\xa2\x85\x0a\xea\xe8\x98\x58\xd8\x36\xf2\xce\x4e\xa0\x0c\x4e\x0a\xe4\x02\xee\x32\x09\xe6\x74\xcc\xce\xa0\x09\xc7\x0c\x0c\xe0\x0d\x99\x51\x33\xfd\x8c\xc5\x94\x2f\xc0\x0e\xbb\xff\xd8\x6e\x8d\xc6\x23\xd4\xf4\x43\x4d\x30\x57\x2e\x2e\x71\xcd\xdc\x51\x69\x6d\x09\xf8\xc2\x64\x47\xbb\xa0\x09\xdd\xb2\xb0\x77\xc4\x24\x88\x0c\x44\x22\x71\xdd\xfa\xfa\x04\xfb\x14\x89\x46\xf1\xac\xb2\xb9\xd6\x17\x37\xc4\x1f\xa0\x4c\xd6\xe6\x8b\xc0\x90\x78\xbc\xe1\xd7\x84\x21\x69\xb2\x53\x45\x5c\xc0\x70\x7b\xdd\x22\x07\x49\x91\xe9\x38\x0c\x43\x6a\x98\x4d\x8f\x4d\xd9\x66\x06\xc7\x35\x0e\xa2\x0c\x86\x5b\x3b\xa9\xb5\x12\x2f\x0b\xce\x45\x41\x42\x1b\xa0\x62\x95\x16\x18\x35\xc4\x77\xe7\x54\xd3\xf6\xe7\xda\x63\x78\xc5\x97\x1e\x99\xc0\x78\xfd\x46\xea\xfd\xef\x22\x4a\x06\xe9\x95\x9b" \ +"\xd6\x0c\x7f\x39\x5c\xe1\xc9\xe9\x74\x30\xe2\x5e\x9f\xd4\x4e\xde\x63\x74\x1d\xbb\x03\x3b\xa7\x44\x6c\xa2\x92\x7d\x06\xb2\xe6\x3c\x9e\x3c\x55\x5e\x71\x5d\x02\x4b\xc3\xea\x42\xc8\x94\x80\x32\x38\x3a\xcd\x4f\xe2\x0b\xbd\xbd\x58\x20\x43\x53\x54\xbc\x1f\xb4\x4f\xfc\x09\xb1\xc7\x35\xa3\x42\x36\x6e\xf5\xae\x71\xe1\xcc\xb4\x95\x06\x8d\x12\xfa\x96\xa8\xe5\x63\x6b\x6e\x6c\x3f\x46\x2b\x92\xd8\x40\x2a\x03\xe3\x92\xdf\xe9\x06\x8c\x6c\xee\x15\xf5\x46\x0e\x98\x5c\x6d\x8a\x68\xc8\xc3\xf8\x7d\xe6\x08\x04\x8a\x7d\xe4\xdd\xe1\x62\x92\xe6\x5b\xe1\xf7\xcf\x1d\x70\xb9\xca\x9d\xda\x12\xc1\x2d\x36\x2f\xd7\xa2\x1d\x5c\x5f\x0d\x58\x28\x81\x01\x96\x6a\xcb\x75\x4c\xb0\x9d\xa9\x3d\x2d\xc9\x43\x23\xee\x95\x15\xae\x32\xa2\x96\x78\x16\x90\xc3\xbb\xd6\xef\xb2\xe7\xa5\xc8\xa7\xaa\x6b\x62\xf2\xcd\x48\x71\xa6\xa3\x06\xc5\x39\xd2\x6a\xe7\xc0\x11\x70\x4d\x53\xab\xd8\x7f\x49\x8f\xb6\xe0\x6f\x68\x89\x7b\x77\x34\x99\x2a\xcd\xa1\x91\xae\xa7\x26\x75\x82\x52\x1f\xe4\x66\xea\x1e\xc7\xc2\xcf\x49\x6d\x40\xe7\x37\xdd\x41\xe1\xcb\x1c\x71\x02\x78\xc9\x16\x7d" \ +"\xd3\x4c\x52\x3a\x4b\xb5\x21\x79\xbd\x8a\x46\x7a\x9b\xfc\x85\x33\x23\xf1\xc1\x79\x94\x30\x2c\x9b\x7b\xf0\x09\xa9\x91\x0f\x4f\xd5\xb4\xa0\x1e\xc6\xe1\xd1\xba\x7c\xba\x35\xf0\xf6\x0d\xbc\x34\xd3\xdd\xb5\xd4\x8c\x8f\xbb\xb2\x0b\xb5\xca\x4e\x32\x37\x77\xe4\x71\x78\xe7\xb8\xa5\x7a\x79\x5e\xb5\xde\xf8\xe1\xcc\xf5\xae\xcd\x3f\xdb\xc0\xf6\x52\x65\x6d\x73\xa0\x99\x52\x83\x26\xdb\xe5\x3a\x72\xcd\x8a\x8d\x89\xed\x59\x5e\xf5\x54\xb1\xa6\x00\x26\x10\xad\x38\xf8\x43\x37\x72\xfc\x59\xfb\x92\x5d\x18\x68\x71\xb5\x25\xa4\x25\x9e\x60\x89\xbf\xd6\x15\x33\xd7\x3a\x7b\x6f\xa1\x74\x9d\x70\xd3\xbc\xd2\x34\x69\xdb\x5b\xd5\xbf\x85\xab\x2f\x66\xae\x33\xaa\xb4\x0a\x1e\xb5\x11\x2b\x4c\x0d\xf2\x88\x29\x2d\x9b\x18\x2d\x4f\x92\xda\x06\x6b\x2f\x8e\x20\x8d\x5e\xa5\x0c\x95\x54\xaa\x7a\xca\x43\x82\x7e\x27\x81\xf4\xbb\x13\xe3\x16\x6c\xea\x5e\x62\x3d\x9b\xfb\xe4\xd4\x2b\x25\xfe\x51\xde\x29\x43\x05\xe1\x7c\x35\xcb\x6f\x18\xd4\x40\x11\x55\xc2\xff\x38\xbe\x73\xc0\xcb\x37\xaa\x98\xbb\xa6\x74\x55\x42\xa7\xd5\xf7\x81\x0f\x76\x56\x68\xe0\xc3\x6c\x6d\x06" \ +"\xc8\xbf\x22\x8a\x75\x4a\xb6\xd1\x12\xcc\xb6\x8b\xb8\x1b\x6b\xaf\x0e\x91\x9b\xc5\xfb\x35\x8d\xd1\x62\x82\xe6\x02\x5b\x5b\x5a\xfe\x83\xfc\x5b\x55\x27\xd4\x49\x5a\x39\xb8\x90\x1a\xa3\x06\x20\xf3\xea\xa2\xea\xec\xa7\xea\x49\x71\x32\x4d\xa5\x81\x7a\xd3\x06\x22\xc2\xb8\x1d\x87\xe2\x5b\x72\x0e\x60\xf6\xf3\x16\xc8\xf2\xdc\xae\xe3\xf4\xa8\xc7\xc5\x37\x72\x3e\xd7\xac\x3a\x3c\x52\x29\xcd\x08\x6b\xfd\x3e\x6c\x7a\xf9\x4e\x89\x27\xa7\x0e\x23\x99\x88\x3e\xc1\xd3\x78\x31\xed\xe8\x16\xd7\xbe\x84\xa1\xfa\xf9\xae\xfd\x5a\x5d\xd2\x23\xde\x23\x3e\x3c\xcc\x6b\x3f\xc6\x79\x93\x44\xd5\x4b\x31\x32\x03\x05\x4a\x1e\x5c\x77\x0b\xdf\x85\xde\x1d\xe9\xf8\x5d\x57\xc2\x8b\x54\x34\xd6\x2c\x92\x13\xf1\x52\xcc\xa3\x9a\xfd\x82\x9f\x58\x94\x74\xcf\x1d\x72\x75\x96\x9a\x18\x51\x4e\x5f\x01\xd0\x54\xc5\xac\x8d\x03\x6b\x12\xc0\x78\xc4\x5b\x1e\x52\x5a\xe8\xa3\x0a\x8e\x60\xc6\x3e\x7e\xd4\x99\x64\xcf\x92\x7a\xe9\x5c\xbc\x93\x1b\x09\x66\xcc\x77\xd1\xf2\x47\xde\x6c\x72\xf9\xad\x3b\x0e\x43\x1a\x68\xf0\x88\xc7\x46\x83\x27\x86\x12\x01\x98\x4f\xe0\x82\x68\xc3" \ +"\xb3\xd7\x5a\xba\xf4\xee\x0c\x5a\xb5\x91\x4b\xee\x54\x9e\x6f\x3f\xbb\x79\x98\x84\xa7\x96\x8a\x3e\xcb\x28\x46\x8a\x9a\xd2\x25\x32\xe2\x45\xfd\x8f\x1a\x00\xf3\x83\x05\x8b\x4f\x30\x30\x73\x7a\x3d\x47\x29\x01\xe8\xef\x04\x60\x4a\xd1\xfd\x80\xe0\xde\x9e\x61\x96\x10\x1e\x84\xf0\xc7\xc5\x76\x0d\x47\x38\xa0\xbe\x23\xd7\x6e\xa5\xfe\x1a\x45\x2b\xc3\xa3\x1e\xf5\x8a\x30\x50\x8c\xf5\x59\x53\xa5\x41\x27\x14\x53\x73\x77\x6f\x5a\xca\x65\xac\x5b\xb2\x23\x11\x78\x2d\x76\x5b\x3c\xbd\xb4\x85\x22\x13\x89\x98\x8f\x10\xba\xd6\x04\x2e\xf2\x17\xb3\xe5\xcc\x37\xda\x16\xbc\x05\xde\x8c\x45\xc3\x2b\x1f\x22\x9f\x83\x35\x1c\x53\xd0\x9e\x70\xa3\x10\x3d\xaf\x03\x45\x71\x86\xae\x15\x7d\xa2\x5b\xb6\xfb\x78\x11\x5e\x64\xfc\xc7\x76\x23\xf8\x40\xce\xb3\x26\x79\xb0\x54\xc5\x09\x02\x2d\x6f\xf4\xa1\xfa\xc7\x82\xd0\xa7\xfa\x00\x9b\x39\x00\x5f\x27\xce\xed\x05\x17\x3a\x8e\x89\x4d\xa4\x98\xdb\x5e\x39\xed\x10\xdb\x77\x39\x3a\x65\xbd\x68\xcd\xe4\x1c\xed\x77\x8f\x63\xf1\x05\xa0\x73\x5b\xd7\xf6\xc6\x99\x3c\xba\x40\xf8\x7e\x43\x38\x9b\xb3\x37\x66\x03\x2f\x44" \ +"\x91\x29\xd1\x2d\x94\x6a\x0b\x47\xbf\xab\xf5\x21\x06\x85\xd8\x01\x6d\x80\x38\x78\xf7\x11\xa9\x96\xad\x3d\x6f\x00\x41\x02\x5f\xe5\x3f\x3b\xb9\x94\xd5\x95\x8c\xbe\x39\x97\xa3\x49\x09\xe7\xfa\x4c\x7e\xd3\x0c\xaf\x0e\x26\x92\x1e\x66\x16\x7c\x3a\x89\xef\xb5\x63\xb0\x02\xb8\x30\xc4\x84\xf8\x8c\x5a\xc2\x5f\x06\x5a\xf2\xab\xfe\xbd\xeb\x08\x44\xf4\x73\x59\xd9\x0a\x3d\xac\xfc\x4b\xba\x75\xd4\xd8\x3e\xfd\x62\x9c\xe9\x60\x8b\x37\x5b\xfb\xa8\xdd\x43\xe7\x12\x8c\xfa\x26\xe8\x8f\x41\xdc\xea\x81\x6a\xb8\x3f\xab\x77\x60\x20\x09\x2d\x97\x4a\x47\x51\xa2\x6d\x3a\xc2\x7d\xbf\xa9\xf4\x09\xbe\x25\x26\x62\x24\xee\xb0\x26\x96\x1e\xe3\x00\xbf\x3c\xbd\x00\x04\xb2\xc4\xee\xb6\xe9\x08\x7e\x0e\xec\x49\x64\x10\x96\x31\x1a\x68\x98\xc5\x84\x35\xe5\x64\xc4\xce\x07\x4a\x5b\x8f\x17\xce\x78\xfc\x34\x49\xa1\x94\x29\xa0\x89\x1d\xcf\xde\x0d\x80\x90\xbf\xa2\x3c\x18\xe2\xbb\xfa\x49\x4c\xf6\xf0\x1f\xfe\x6d\x90\x66\xf8\xcf\xd7\x2c\xb6\x1d\xca\x36\x8d\x6b\x7c\xef\xcd\xf3\x36\x9e\x00\x94\xca\x62\x41\xe9\xc9\x3c\xa9\x22\x40\x51\x3e\xcd\xe1\xe4\xe9\xfa\x17" \ +"\x92\x35\x68\x78\x44\x47\xb3\x1a\x9c\xe6\x19\xe1\xeb\x8a\x14\xc4\xdf\x48\xb0\xed\x43\x6b\xca\xd3\x20\x1f\xb8\x1a\xb2\x40\x86\xe1\x73\x08\xe3\x09\xc8\x21\x1f\x1f\x3a\x52\xfb\xf9\x36\x2e\x3c\x0c\xe9\x42\xde\x90\xf3\x6f\x6e\x19\x75\x4d\x6c\xdf\xd3\xd1\x17\x4e\xa2\x9a\x4d\x54\xfb\xa6\x59\xcf\x2d\x4e\x33\x55\x12\x33\x0e\x38\x09\x83\xba\x6f\xe5\xe6\x0b\xc5\xc4\xc9\xb8\x86\x93\x34\x0e\xb9\x91\x0e\x09\xa4\x9d\x52\x03\xfc\x2a\xf4\x8c\xcf\xbd\x4d\x0d\xe8\xf8\x8b\x0a\x89\x1e\xbd\x5b\x5c\xca\x3f\xf9\x61\xd4\x8b\x27\x9b\xfb\xfd\x0a\xf9\x0d\x73\xee\xcb\x70\x93\xba\xb9\x2e\xef\x33\x8f\x94\xfb\xa3\xd0\xfe\x79\xf0\xf3\x16\xa2\x2f\xc4\x2c\xf9\x00\x3b\x7f\x90\x52\x0b\x45\x7c\x4c\x83\xe7\xec\xa9\x61\xac\xa8\x9d\x18\x11\x3d\x6c\xe5\xb6\x99\x00\xc4\x17\x76\x28\x46\xa7\xb2\x4f\x2f\x71\x4b\x5d\x2e\x87\x94\x79\x39\x14\x96\x1c\x42\xd2\x8d\x8e\x5b\x83\x70\xef\xbc\x23\x05\xb5\x80\x02\x3b\x78\x06\xe4\xce\x82\x84\x68\x1e\xdb\x93\x52\x0c\x30\x09\x62\x33\x22\xc4\x87\xec\x73\xb2\x0a\x19\x08\xcd\x1c\xe7\x8c\xc7\xe0\xe0\xa2\x7b\x58\xc2\xca\xda" \ +"\x74\x31\xe9\x89\x70\x48\xeb\x9d\x7d\x89\x4a\x84\x31\x45\xe8\xf9\xf7\xf1\x2f\x08\x70\x05\x48\x8a\x95\x79\x02\x94\xcc\x5d\xe7\x2c\x81\x8c\x95\xce\x68\x25\xd0\xb5\x56\x43\x7a\xa7\x72\xa6\xc8\x86\xb4\xb3\x8b\x78\x10\x6a\xab\x5d\x3a\xb3\xaf\xb3\xf4\x94\x24\x53\xab\x9d\xb6\x92\x6f\x16\x00\x90\x6e\x69\x2f\x5a\xec\xb1\x2f\x2c\x23\xfa\xed\x6f\x8d\x59\x06\xba\x16\xc4\x20\xa6\x17\x8f\x11\x60\x7f\x3a\x8b\x89\x1d\xfa\xa4\x34\x8d\x01\x0d\x75\x52\x5d\xf1\xfe\x78\x8b\xa5\x01\x72\x69\x07\x87\xb4\x39\xfc\xca\xe9\x45\xfd\x26\x0b\x58\xdf\x11\xcb\x40\xa2\xaa\x7f\x3b\xa3\x5a\x08\x3a\x95\x14\xd6\x9f\x1a\xa0\x78\xf4\x7b\x5b\xcb\x1f\x56\xed\x14\xf2\x42\x0e\xb6\xce\x7f\x36\x77\x24\xb6\x29\x81\x80\xc1\x51\x13\xb6\x78\x55\x17\xd2\xdc\xb1\xca\xcc\x66\x8f\x51\xf3\xe9\x0f\x43\xb7\x9d\x60\x7a\x78\x82\x4f\x9a\x76\x24\x4e\x98\x18\x7b\x5a\x56\xa9\xc8\x14\x1d\x39\xd2\x85\x10\x34\x18\xca\x14\xad\x65\xe6\x3d\x2f\x69\x5e\xf4\x2f\xd9\xcf\x57\x57\x5d\xcc\x8a\x6e\x08\x96\xc8\xf8\x81\x8b\x86\xe1\x22\x22\x96\xf7\x46\xc2\x90\xa7\x15\x62\xa1\x07\x26\x4e" \ +"\x03\x24\x2a\x86\xa1\x9d\xcb\x57\x22\xab\x1c\xc7\x40\xba\x82\xdf\x67\x79\x58\x82\x32\xae\x0a\x32\x4f\x0d\x5c\xa2\x63\x01\x55\xa8\x7a\x3d\x84\x50\x55\x70\xee\x06\xb3\xcf\xa2\x35\x10\xc6\xfa\xda\xce\xca\xf2\xf8\x1f\x4a\x56\xc5\x85\xc1\x24\x63\x85\xa0\xdf\x37\x24\x99\x65\xa5\xbc\xb8\xb3\xbd\x24\xc6\xfe\x33\xc7\x0d\x74\x18\x0a\x87\x65\xd0\xa6\x36\x6b\x01\xa6\x61\x26\xc9\x2d\x56\xda\x2c\xa3\x3c\xad\x81\x45\x11\xcc\x37\x55\x8d\x50\x64\x58\x7f\x6c\xcd\x41\x49\x9f\xcc\xd8\xfa\xf0\x11\x79\xc4\xc4\x79\x2e\x40\x19\xd7\x58\x66\xdd\xf4\x23\xf8\x60\x72\x42\x7d\x86\x07\x53\x61\x00\x50\xa6\xe0\xd8\x16\xd5\x12\x2a\xf2\x7e\xb6\x51\xe0\x0a\x25\xc1\x2b\xae\x4a\x9f\x93\x3a\x41\xd9\x93\x6e\xd6\x5f\x7a\xae\x7d\x79\x4a\x42\x90\x4a\x63\x34\x84\x68\x69\x8b\xe1\x80\x3e\x01\xbc\x07\x2b\xb9\xde\x86\x06\xd8\x34\xd3\xd5\x53\x6d\xb0\xa6\x98\xa1\x30\xd3\x7c\xc6\xf1\x34\xed\x8b\x9b\x14\xe9\x8c\x37\x93\x44\x4d\xa6\x6a\x51\xd5\xfa\x4a\x7d\xa5\xd5\x41\x93\x5c\x1f\xd0\xf2\xa9\x5a\x1e\xef\xa5\x8f\xc4\x55\xf7\x79\x93\x26\xb5\xaa\x4b\x1e\xe0\x69\x79" \ +"\x1b\xc5\xf6\xac\x27\x6d\x06\xd1\x2a\xd0\x0d\x94\x99\x61\xf7\x26\xa8\xb9\x4c\x2a\x66\x91\xa6\x1b\xf2\x25\x88\x2d\xf5\x20\xc8\xb1\xe1\xf8\x9a\x75\xac\xb8\x25\x9c\xd0\x64\x97\x40\x10\xc1\xfe\xd5\xcd\x8c\xcf\x99\x40\x9b\x39\x2f\xed\x3b\xe7\x0a\x82\xcc\x48\x1e\x11\x3c\x4c\x73\xa1\xed\x68\x05\x26\xfe\x5a\x98\xd0\x31\xc2\xa0\xf3\x6a\x4e\x29\xfb\x8f\x68\x82\xb4\xf1\x62\xd3\xee\xc2\xe0\x24\xf2\x27\x6d\xb4\x43\x82\xd2\x2c\x08\xa2\x96\x10\x4c\x53\x28\x56\x61\x57\xbb\x2a\x32\x3f\x23\x62\xc0\x17\x8a\xec\x5a\x03\x9d\x13\x05\xfc\xe4\xd3\xef\x01\x55\xbe\x36\x90\xda\xdd\xb8\x13\x59\x4b\x8a\x35\x73\xce\x1f\x64\x63\xbb\x50\xa2\xde\x86\xa7\xee\x75\x54\x24\x3e\xb2\xe0\x93\x77\xa0\x41\xf4\xf5\x9d\xbc\xb8\xde\x2a\x35\xbc\x54\x33\x05\x16\xd6\xe5\x5c\xf9\x11\x4e\x06\x4f\x91\x5c\xc9\x35\x3a\x2d\x57\x5a\x13\xc2\xfd\x12\x44\x57\x3a\x30\xce\x55\xf1\xad\x28\x00\x26\x4b\xd2\xe3\xfe\x96\x75\xa8\x58\x29\xb4\x1f\x4d\xef\x88\x25\x6a\xde\x21\x3f\xef\xd9\xf5\x1d\x0b\xff\x5e\xb5\x84\x5b\x50\x98\x0f\xe0\xfd\xbb\x68\xbf\x5f\xb4\x37\x6c\x18\x41\x20" \ +"\x1b\x93\xc9\x66\x66\x40\xf5\x0e\xc4\x9a\xa9\x85\xbf\x75\x31\x6c\x4b\x85\x48\x5f\x30\x7e\x01\xa6\xbb\x81\xdf\x5e\x60\x27\xe1\xde\xc4\xd2\x81\x23\x18\xba\x91\x06\xad\x52\x43\x82\x61\xa7\x8a\xa7\x39\xb5\xe4\xf9\xf7\x2c\x1d\x09\x8c\xf5\x31\xa4\xd2\x77\x5b\xb0\x0f\x1f\xce\x58\xe5\x9b\x17\x48\x72\xe0\xed\xbe\xc2\x93\x85\xe9\xaa\x16\x40\xf1\xa2\xcc\x34\xd0\x8a\x9f\x1d\x5e\x19\x75\x67\x84\xe8\x41\xc6\x5a\xb7\x71\x06\x4c\x34\x8d\xc7\xa6\xaa\x80\xc7\xfb\x3c\x89\x56\x4e\x34\x10\x48\x40\x70\xae\x43\x36\x49\x3f\x37\xb7\x1e\x0b\x30\x83\x07\x5e\x97\x11\xa6\x73\x3e\x05\xdd\x47\x1e\x89\x23\xb5\xfa\xbb\x44\x1a\xbb\x33\xca\xf9\x4c\xa2\x3f\x0a\x90\x7b\x77\xd9\x9b\x0f\xd6\xd4\x34\x27\xd0\x6d\xd2\xce\xe6\xf2\xba\xfe\xaa\x8a\x34\x28\x82\x07\x66\x43\x1c\x26\x6a\x98\x7a\xac\xb8\xa6\x51\x1e\xec\x95\xd5\xec\xae\x82\x8c\x2c\x8f\xc7\x09\x76\x3a\x0b\x1e\x7e\x8b\x27\x80\x5c\x53\xf2\xcf\xc8\x9d\xf5\x93\x54\xcf\x8c\x78\x3b\x38\xe4\x91\xb1\x82\x30\x8b\x4e\x65\x7c\x2a\xe4\x81\xac\x0e\xf8\x90\x8e\xbd\x26\x9e\x3a\x55\x54\x4b\x88\xb4\xaf\x0d\xb8" \ +"\x00\x1a\x80\xea\x97\xa7\x28\x06\xa3\x08\x17\x39\x45\x2a\x59\xae\x32\x00\xd8\xba\xa6\x07\x8f\x7b\x5f\x17\x1a\x86\x7f\x7d\xc7\x75\x1a\xd7\x81\xd4\x77\x53\x02\x42\x60\xf7\x7e\xf1\x31\xab\xba\xde\x92\xea\x73\xc7\x7b\x70\x4f\x93\x35\xd2\x5f\xc0\xa6\x31\x89\xf5\x50\x78\x0e\xb8\xf2\xed\x83\x1b\x8d\x64\xb2\xb9\x36\xf5\x98\x37\xf3\x58\x2d\x7a\x30\xe5\xd6\x37\x76\x69\xde\x1a\xbd\x44\x2a\x15\x22\x39\xa5\xf6\x6d\x23\x54\x2d\x4c\xc4\x74\x7f\x58\xb4\x0a\xb3\x67\xe2\xd0\x21\x5b\x6f\x0c\xe7\xdd\xa6\x40\xc7\x5d\x57\x3a\xa4\x6c\x17\x7e\xa9\xd8\x77\x44\x68\x18\x33\x9c\x47\xaf\xb5\x5d\xb8\x7c\xab\x22\x48\x73\x5f\x94\x48\xa6\xf1\xb2\xdf\x24\x0a\x0c\xdb\x32\xac\x8b\x98\x1a\xe8\xb9\xf9\x5f\xf9\x08\xf4\x14\x4e\x88\x8d\x91\xa9\xa8\x02\xd0\x09\x1e\x25\x32\x95\x2f\x32\x11\x40\xd6\xa8\x20\x17\xe4\xe8\x1f\x4e\xdb\x4d\x08\x50\xfd\x29\x4f\x08\x7b\x41\xea\x24\x4e\x97\x17\x44\x12\x46\x0a\x09\x09\x21\x8e\x81\x73\x8f\xbf\x7f\xd1\x8d\xca\xbd\x37\x78\x10\x94\xb8\x7a\xb2\x4d\x0a\x95\x12\x1e\x06\x65\x35\x5a\x9b\xef\xfd\x52\x39\x0b\x7d\x54\x07\xaf" \ +"\x74\x3e\xd2\xe8\x70\x82\xfd\x69\x99\xcb\x1f\x78\xfb\xf1\x2d\x29\x7f\x60\x92\x0b\xbb\xb4\x73\x15\x3f\xb6\xd5\xc4\xaf\xff\xa2\x1f\xe9\x41\xc5\x6e\x2a\x88\x36\x76\xea\xb0\x03\xfc\x53\x04\x6b\x85\x13\xe2\x22\xa3\xe8\x1f\x27\xab\xb2\xf2\x24\x45\x40\x21\xa7\x8b\x51\xb8\xa0\xcf\x77\x25\x89\x28\xa5\x32\xa7\xf3\xbc\x52\x8e\x5b\x02\x00\xd1\x10\xa6\x98\x86\x71\xb9\xec\xfd\xa1\x78\x5a\x5e\xbd\x51\xc9\xe0\x3c\x42\x52\x17\x0c\xc7\xc5\x56\xc6\x10\x36\xae\xed\x79\xba\xf4\x8d\x32\x1a\x98\x78\x4e\x34\x47\x73\x28\x5e\x9c\x16\xa2\xf1\xdb\x5a\xd4\xec\x15\x99\xaa\x8e\x14\xc8\xfb\x31\x62\xc0\xad\x0e\xa7\xc7\xa7\xb0\xeb\x6f\x3d\xf3\x1e\xd7\x23\x71\x7f\x7a\xfa\x4f\xa2\x28\x82\x51\x1f\x33\xb1\xf0\x09\x1f\xc0\xd2\x97\xab\x4e\xc9\x32\x66\xe3\x4b\xc4\xef\xe8\xaf\xf0\x77\xcd\xbf\xb4\xd1\x44\x7b\x56\xf4\x72\xf4\xd1\x07\x23\x11\x10\x59\x85\x59\x2a\x09\x12\x7c\x15\xfc\x65\xf4\x58\x4f\xd6\xea\x91\x8c\x34\x76\x2f\x2c\x79\x2b\x0e\x06\x9d\x1a\x10\xac\xfc\x55\x5e\x54\x3b\x86\x13\x77\x0a\x46\x5b\x9d\xf6\x08\x4a\x20\x0f\x17\xe6\x02\xcd\xbc\x67\xed" \ +"\x5c\x13\x58\x15\x93\x87\x75\x7c\x6b\x8c\x27\x98\x33\x38\xf6\x7a\x99\xae\x6a\x91\x8c\x92\x4e\xb4\xf3\xd4\x3e\x2e\x03\x83\x89\x4e\x38\x4f\xa0\xfc\x75\x54\x7e\xc7\xc2\xf0\xe3\x17\xbc\x28\xce\x48\x44\x28\x3a\x5b\xb7\x50\x28\x1f\x41\x09\x46\x17\x22\x40\xc7\xd5\x8a\x50\x8c\x3a\xca\xd7\x73\xdf\x5c\xb5\xda\x74\xfc\xd2\xbe\xd2\x36\xa6\xf1\x42\x84\x3e\x62\x6d\x9e\x33\x34\x59\x45\x18\xab\xb0\xeb\x74\xaf\x12\x6f\x50\xa7\xd1\xaa\x96\xc2\x98\x17\x60\xa2\x29\xf4\xe8\x50\x55\x4c\xe2\x7e\xf0\xc4\xd6\x51\x28\xb7\xe1\x66\x0a\xa6\x39\xe7\xe6\xe8\x95\xa4\x74\x70\x7a\x00\xb6\x35\xc7\xfc\x37\x32\x6f\xf3\xc8\x40\xbf\x1d\xf0\x56\xbb\x7e\x85\x79\xf9\xf9\x25\x3a\xae\xd1\x27\x98\x67\x97\x83\x7f\xcf\x9a\x0e\xbc\xef\x1c\x6b\x21\x0a\x39\x52\x9e\x74\x3f\xe1\x1d\x67\x50\x86\x54\xf5\x25\x0d\x01\x46\x5f\xb4\x52\xbf\x00\x43\xf3\x43\xda\x94\x1e\xf8\xa0\x85\x5c\x53\xbe\xc5\xfb\x96\x75\x1c\xb2\x79\x11\x10\xd1\x04\xbc\x9b\x37\x52\x86\x80\x03\x68\x8e\x84\x90\x20\x65\x00\xdf\xa6\x4f\x31\x6c\x40\xe7\xa2\x06\x1b\x5e\x74\x44\xeb\xa8\x24\x73\x27\xbf\x97" \ +"\x1c\xca\xe4\x23\x5a\x35\xac\xaa\xad\x97\xec\xae\xc5\x13\x55\xd8\xc0\x9e\x80\x23\x06\x58\x15\x19\x9e\x5c\x12\xd5\x16\x88\x77\x95\x7c\xd5\x67\xc5\x06\xce\xae\x24\xc4\xc7\xd0\x44\x39\x54\x1c\xda\xfb\xd6\x4b\x9d\xfe\x2e\x3d\xe4\xbc\x57\x5d\x7d\x9b\x26\xaf\x04\x24\xa0\x1f\xb1\x46\xde\xf5\x55\xf6\x45\x6d\x2d\x4d\x97\xaf\xca\x17\x11\x8b\x42\x4d\xa6\x9b\xfb\x52\x9c\x0b\x4d\x66\xde\x14\xaa\xff\xe8\xa2\x29\x49\x1a\x59\x76\x3a\x7e\xd4\xcf\x6c\x37\x05\x88\x96\xf0\xdf\xb9\x67\xe7\x73\xb6\xbd\x27\xa4\xa2\xb6\x70\x71\x0b\x5d\xfa\x6c\xf7\xe7\x8f\xac\x43\xdf\xdd\xe0\x18\x74\x80\x77\xe8\x8f\x5a\x1b\x95\x31\xe2\xc3\xee\x42\xe9\x0f\x61\x89\xaa\x9b\xec\x7c\xb9\x5f\xc0\x79\x24\x52\x4c\xf9\x1f\x2e\x66\xb9\x0e\xf3\x1e\xf4\xd9\xb8\x9c\x9c\xcf\x23\x26\x59\x6b\xd4\x8b\x4b\xa1\x10\x4e\xe8\x4c\xd1\x07\x5c\x5e\x50\x9f\x3a\xa2\x8a\xd8\xce\xe7\x5d\x55\xc6\x8c\x5a\xc8\xaa\x4f\x76\x1a\x34\xa8\x6f\xa5\xe0\x5b\x2d\x55\x2a\xa2\x8e\x37\x00\x13\xa7\x8e\x56\x4a\xeb\x2b\xe6\x03\xa2\x5d\x21\xef\x2b\xb5\xfd\x9b\x6a\x1c\x30\x96\x2b\xea\x66\xbb\xf7\xbb" \ +"\x28\x2b\x9e\x21\x30\xf2\xd6\x5f\xb6\x7e\x03\x19\xda\x2f\xa3\x8c\xd9\x06\xdd\xc7\x39\x4c\xb6\xf4\x6e\x31\xa8\xf0\x81\x1f\xe2\xb9\x23\x12\xb9\xbd\x02\x11\xbe\x86\x89\x1d\x4c\x76\x30\xd8\x21\xbc\x67\xa0\x42\x8f\x17\xe6\xff\x18\xee\x06\x6f\x12\xd6\xa3\xf4\x1e\x24\x04\xd8\x1f\xa2\x3c\x7f\xeb\xcb\x43\x22\x45\x14\xe3\xdc\x38\x6b\x4e\x51\x0a\xa0\xa9\x13\xff\xd3\x7e\x2e\x4d\x2e\x98\x2e\x72\x87\x8b\x17\x03\xac\x34\x50\x56\x0b\x05\xbe\x33\x56\xbe\x43\x00\x4b\x11\xa0\xe5\x0c\xfe\x98\xdd\x03\xd5\xdc\xd5\xf4\x33\x9d\x49\xfb\xce\xd5\x2b\x71\xf7\xf5\xbd\x34\xe2\xfa\x6d\xd4\x04\xa8\x84\x18\x89\xa0\xaf\xdb\xcc\x9c\x20\xfd\x79\x08\xd1\xc8\x60\x58\x5d\x42\xf3\x54\x4c\x94\x8e\xe5\x56\x1f\x6a\x0a\x17\x88\xc8\x84\x98\x96\x33\x7d\xca\x0d\xca\x3f\x6e\x26\x7d\x0c\x71\x11\xa2\x5c\xd9\x18\x6c\xeb\xd1\x51\x41\xca\xb3\x3c\xb0\x0b\x5b\x3e\x2d\x7e\x60\x09\x42\x99\x86\x0b\x28\xe7\xcd\x42\x05\xf9\x5c\x63\x77\xce\x69\x6c\xcf\x4f\x2c\x3d\x0a\xb3\x12\x07\x21\x0f\x44\xcc\x28\xd6\xab\xdf\xb1\x62\x5e\xb0\xf3\xa5\x98\xe7\x9a\x01\x43\xe2\xec\x6d\x89" \ +"\xca\x48\xea\xf3\x17\x9c\x29\x69\x76\x28\x48\x70\x93\x35\x4c\x7e\x9e\xff\x91\xd5\xd6\x2b\xf1\xc2\x7d\xe3\x68\xf1\xc4\xf4\xed\x8c\xd6\x3e\xd2\xf9\xcf\x8f\x3a\x6a\xb6\x0a\x4b\xf7\x72\x13\x7f\xd2\xd9\x66\xbe\xc8\x95\x24\x3b\x89\xcc\xde\xdf\x7b\x3f\xd7\x54\xf9\x31\x95\x53\x89\xcd\xe0\xc0\x2c\xa6\x65\x6d\xb5\x62\xdb\x11\xa9\xba\x23\x0b\x6c\x83\x4b\xb9\xdc\x3a\xd6\x81\x43\x0f\x6a\xdc\x43\x4c\x07\xf7\x9a\xc9\x92\x19\xe0\x33\xa9\xb4\x3d\x49\xa9\xd8\xa3\x40\xb3\x90\x3d\xb8\xa3\xa3\x08\x71\x28\x2a\x35\x2e\x50\x32\xc7\x9c\x06\x8a\x2c\x56\x82\x0c\xc3\xfb\xbf\x63\x7a\x7f\x74\x9b\xf8\xcd\x56\xac\x31\xc5\x84\x65\x7c\x20\x17\xe1\x4e\xfc\x17\xb6\x1b\x0a\x5d\x87\xdc\x62\xf6\x3e\x9d\x86\x66\x01\x71\xf4\x41\x27\x03\x6a\xa8\x16\x8e\x10\x40\x8c\x0f\x50\x63\x23\x16\xb3\xa5\xa6\x55\x64\xe9\x5a\xe5\x12\x4e\x5c\xcc\xff\xda\xe0\x79\xda\x95\x92\x65\x5a\xed\xd1\x8d\xac\x47\xc1\x5a\xaf\xbd\xa5\xa9\x58\x1b\x0f\xc5\xe1\x84\x20\x7a\xd7\x59\x5c\x82\xaf\xa0\xba\xc9\x14\x3d\x40\xa2\x85\x03\x2b\xf2\x01\xfd\xfc\xb5\x88\xfd\xda\xa3\x82\x6f\x24\x0e" \ +"\x85\x07\xdb\xcc\x91\x22\x20\xaa\xc1\xec\x97\x4a\x4a\x93\x4c\x8a\x6b\x79\x7a\x75\x9e\x1c\xf6\x32\xff\x87\x8a\xa4\x11\x26\xa4\xd2\x4b\xae\x74\xd0\x92\x91\xa3\x36\xa1\x8e\x68\xf2\xfd\x4c\x61\xba\x5c\x83\x45\xbd\xd9\xf1\xe1\x9d\x4e\x25\x4e\x60\xdc\xc2\x03\xf6\xd6\x79\xb2\x5d\x1a\x2e\xa5\x89\x04\xdf\x61\x0e\x5e\x32\x34\xea\x32\x56\x45\x8d\xa5\x79\xca\x98\x25\x55\x16\x87\xd4\xe9\x1e\x6a\xd0\x98\x0a\xc4\x17\x90\x02\xc7\x12\x2b\x2f\xec\x53\x1e\x36\xf9\x07\x91\x74\xef\x24\xbf\x73\xab\x65\x4d\x27\x66\xa7\xf9\x98\xea\xc1\x8d\x18\x8f\xfe\x84\xf1\x31\xdd\xdf\xbd\x67\x0c\xf5\x14\xf0\xd5\x79\x98\x52\x45\xb3\xc0\xba\x06\x42\x38\x16\x16\x90\xf0\x7d\x57\x0d\xf8\x5d\x6c\xe5\xf5\x94\x0e\x3e\x83\x2d\x64\xc9\x3f\x44\x76\xf9\x42\x62\x84\x8d\x4a\x8c\x14\xdc\x51\x86\x8d\xac\xbe\xc7\x95\xcd\x5d\x39\x2d\x71\xf0\x0f\xa1\x04\x7a\xe4\x1c\x96\xdc\xb7\x58\xe2\x33\x75\x06\x6b\x7a\x27\xa5\x19\x0f\xc5\xc7\x95\x9d\x83\xd6\x2c\xfd\xf0\xf7\xf1\x8b\xe5\xe8\xd4\xda\x71\x17\xbc\x84\x93\xfa\xfc\x0e\x91\x07\xf6\x65\x1b\xbe\x9b\x1b\xe0\x14\x25\x3f\x02" \ +"\x36\x26\x05\x22\xba\x02\x6b\xdd\xa1\x42\xf8\xd9\x3f\x4f\xca\x53\x35\xfd\x7f\x57\xfc\x6c\x85\xaf\x0e\x52\x8c\x84\x96\x5e\xea\x78\x78\xd6\x20\xea\x35\x51\x3c\x6b\xff\xa6\xbc\x59\x99\x09\xad\xea\x55\xf4\x0b\x4c\xd9\xbe\x16\x10\x93\x50\x17\x71\x7e\xf1\x54\x39\x86\x54\x98\x2a\x61\x9e\xb0\xf7\x8a\xf9\x36\x6e\x67\x70\xaa\x34\xee\x6d\x1b\x83\x89\x54\x25\x35\xa2\x2d\x0c\x87\xe4\xb3\xc5\x2c\xa3\x8f\x21\x00\x7d\xc6\x2d\x7a\x5d\xfc\x94\xd0\xa3\xf2\x63\x7e\xc3\x7a\xf7\x67\x8d\x16\xd0\x94\x71\xec\xd2\xdf\x39\xf1\x80\x09\x28\x69\xcf\x6d\x45\xe5\xcc\xee\x62\x7c\x64\xe3\x11\xb9\xe2\x12\x77\xc0\x32\x18\x62\xc4\xbb\xe6\xe0\x3c\xbf\x9d\x29\xb3\x5f\x4c\x99\x06\xd9\xe8\x5d\x02\x6e\x29\x94\x8c\xcb\x09\x9c\xe1\xae\x1a\x10\x01\xb6\x14\xf2\xdd\x72\x48\x15\x8d\xe2\xd5\xc8\x11\xc6\x10\x64\xb0\xd8\x49\xf0\x4c\x06\xed\x4e\xc8\x77\x4d\x27\xf0\x9e\x1f\x94\x83\xbb\x3f\xe8\xd2\x40\xb3\xfa\xe8\x35\x4e\x28\x12\x59\x21\x27\x8c\xd1\x38\x70\xf9\x92\xde\x07\x7f\xa1\x41\x92\x21\x92\x7f\x38\x72\x20\x54\x50\x18\x70\xe5\xe6\xd5\x5e\x5b\x94\xf4\x6d\x0d" \ +"\x9d\x6f\x33\xc9\xad\xad\x42\x88\x96\x06\x6f\x6f\x9a\x0b\x11\x74\x0d\x1b\xd1\xf2\x3b\x63\x15\xa9\xde\x44\x48\xde\xa4\x3d\xd9\xc9\x35\xcd\x21\x0f\x8d\x0a\x50\x0a\xd7\x52\x7d\x2b\xa5\x36\xb8\x1a\x97\x47\xcb\xce\x32\x3a\x39\xa1\x34\xa8\x16\xf2\xb3\x7d\x6f\x2b\x5b\x57\x03\x07\x7e\xb1\x36\xa3\x94\x5d\xff\x37\x7c\x2b\x8d\x48\xa6\x22\x93\xa3\x87\x00\x32\x7e\x98\xa5\x01\xf4\x76\x5f\x60\x50\x04\xbb\xce\x6e\xef\xd6\xb7\xd1\x7d\xfc\x28\xb6\x7e\x86\x02\x2d\xb6\x8a\xb3\x02\x66\x8a\x65\x13\x5c\x86\x27\x45\x78\x39\xbe\x39\x82\xf5\x49\xdd\x17\xae\xb7\x5d\x1c\x9d\x2a\xe7\xd9\xce\x8b\x73\x26\xbc\x81\x7c\x0c\x6e\x59\x6c\x84\x33\x8e\xf4\x87\xf5\xfb\x44\x80\x38\xda\x1a\xf8\x81\x22\x9d\xa7\x54\x8a\xf5\x5f\x40\xac\x4a\x09\xfc\x11\xbc\x49\x6e\xe5\x4e\xe6\x99\xe7\x2c\xbf\x2e\x7e\x27\xf1\x7b\xdf\x2e\x2f\x27\x45\x8b\x76\x07\xb8\xb7\xa6\xab\x3d\x70\xc8\x6f\xc4\x3d\x7b\xd9\xbc\xc1\x66\xd4\x69\x5c\x00\x9f\x1b\xb0\x4a\x32\xfa\x6b\x44\x1a\xc4\xcb\xef\x00\x2a\xb8\x23\x8f\x0e\x6a\xac\x4c\x93\x70\x64\x19\xd7\x29\xaa\x7e\x5f\x6c\xda\x52\x24\x09" \ +"\x74\xb1\xb6\x7b\xfe\xbe\x38\x35\x7d\xef\x42\xf3\x91\x0a\x3d\x66\x39\x6d\xc5\x50\x9f\x61\xfd\x78\x30\xf9\x61\xb1\x02\xb9\x99\x0e\xc9\x79\xa5\x6b\x85\x76\xf8\xdc\x44\xce\x60\x89\x9a\x79\xd7\xd9\xbd\x4a\x4c\xcc\xde\x23\xde\xe3\x53\x34\x4d\xb4\x7a\x7b\xb8\xf9\xd4\xf0\x16\xc8\x88\xc2\xce\x6f\x78\xa2\xfd\xba\x9b\xd5\x95\x27\x61\xfc\x84\x5f\x46\xf1\x2f\x36\x13\x8f\xbc\x95\x94\xee\xa1\xc2\x79\x11\x5d\x6f\x85\xf2\xc9\xd4\xb7\x8a\x98\xb2\x25\xe6\x8c\x6b\x89\x7a\xa3\x4b\x05\x87\xe1\xba\x20\x32\x83\x68\xc5\x10\x57\xa3\xb4\xfb\xaa\x1b\xb5\xf1\x55\xb3\x7e\x74\xdb\xce\x4f\xf2\x05\x65\x29\xa5\x50\xdf\x42\x20\x44\x47\x58\x35\x75\xd8\xd1\xac\x70\xd4\x81\x98\x31\x6d\x3d\xec\x4f\xde\x9c\x0b\xef\x1f\xca\x3d\x7b\xcd\x3a\x80\x07\x5f\x1b\x8b\x87\x5b\x77\xc0\xbb\x0d\x63\xa5\x67\xfe\x8c\xc3\xea\x64\x4f\xe7\x9a\xb0\xe9\x52\xd6\xbf\x3c\xc1\x35\x8f\xd5\xfa\x83\x5b\x28\x91\xe1\xd4\x6a\x4d\xc9\x6a\xb9\x78\x8d\xe1\xc3\x05\x6e\x84\xeb\xbd\x5f\x2a\x5a\x37\xc2\x74\xde\x93\x5b\xac\xaf\xdc\xe8\x17\x5f\xc9\x04\x96\x66\xfa\x17\xc4\x56\x78\x1c\x2a" \ +"\xbc\x30\x2e\x90\x42\x55\x7c\x2a\xbb\x89\xd4\xc4\xe6\xf5\x6f\x93\xcc\xa1\x3f\x23\x64\x16\x90\xe8\xd0\x58\x65\x97\x0a\x1f\xd2\x5a\x01\x04\xca\x87\x78\x66\x51\x79\xbd\xc9\x2c\xde\xd1\x30\xbc\x98\x6c\xfa\x41\xad\x0d\xf0\x01\x7b\x6d\x24\xa3\x89\xac\x45\xfa\xa2\x0a\x4b\x59\x39\x66\x93\x4d\x12\x5d\x04\x68\xd8\xe1\xcf\xe5\x18\x39\xbb\xe4\x63\xda\xcc\x3a\x73\x2c\x78\xd1\x63\xc8\xd6\x9c\xdd\x8b\x11\x83\x9f\xa4\xe9\xa0\x06\x02\x1b\x0f\x3c\xcc\xdb\x12\xbe\xa4\xd2\xcb\xbc\x22\x74\x24\x86\x65\xc1\x4b\x58\xbd\xde\xf5\xae\xcb\x00\xc7\xa1\x39\x16\x04\xdb\x4d\x18\x24\x8d\x46\xd7\xdb\x1f\x5c\x69\x0a\x46\x66\xa9\xf4\xd7\xe6\xa9\x58\xf0\x9d\xbe\x05\x82\xba\xe8\x4c\x75\x2d\xe6\xb5\x73\x43\x23\xac\x0f\xa5\x1e\x7d\xb4\x39\xf5\x19\x61\xf4\xaa\xb6\xb4\x6b\x18\xe7\xc3\x8c\x61\x32\xdc\xdc\xc1\xc4\x90\x31\x20\x5a\x3e\xce\x6d\x55\x23\x87\xdc\xf9\xff\x4e\x67\xcf\x62\x9c\xe4\xd5\xfe\x16\xe7\xf7\xbf\x98\xfa\x25\x08\xac\xcc\x88\xb5\x1e\x4b\x09\xae\xe2\xaf\xac\xee\xed\x6b\x1b\xe6\x2e\xc5\xf0\x8c\xa2\xe1\x41\xa5\xf9\xd1\x31\x98\x13\x66\x60\x60" \ +"\xce\x91\x28\x27\x9b\x44\x08\xe4\xb0\x00\x70\x06\x1b\xa4\x0c\xdc\xb9\x8c\x5f\x47\xca\x7d\xea\x0f\xf6\x34\xce\x05\x67\xc6\x06\x41\x0c\xd1\x57\xdf\x79\xef\x7c\x78\x80\x9c\xc2\xfa\xef\x85\xf7\xe3\x4c\x6b\x49\x26\xe4\xf1\x21\x13\x3d\x8a\x46\x25\x2d\x3a\xef\x0d\xb0\x1b\x11\x29\xca\xe9\x3e\xdf\xaf\x9d\x24\xea\xc0\x17\xb4\x40\x3d\xe7\x67\xad\x53\xa9\xf1\x33\xc9\x51\x43\xd9\x4f\xf6\xcb\xf7\xe9\x75\xfd\x99\xfc\x32\x36\xfb\x78\xfe\xd7\x69\xa8\x2f\x80\x3d\x8b\xf3\x5b\x8e\xa6\xb3\x1a\x61\x41\xab\xa7\xf4\x72\xbc\xc0\x65\x17\x37\x73\xcd\xde\xd1\x3b\x6f\x53\x93\xbc\x1a\xa3\x7b\xf4\xfc\x62\x94\x68\x6e\x51\x1b\xa7\x43\xc8\x55\xfb\x50\xa3\x75\x24\x4e\x89\x5f\x22\x3b\xa3\xac\xa4\x59\xf7\x48\x40\xb5\x29\x56\xff\xb8\x9e\xee\xb9\xe2\x46\x70\x7b\xb3\x03\x49\x01\x6f\x6e\xa1\x31\x1d\x70\x7c\xf4\x6e\xee\xf7\x0e\x0e\x4c\xc7\x9f\xc5\xb3\xfa\xf4\xf7\x55\xac\x38\x62\x46\xe8\x63\xcc\xe2\x4b\x79\x49\xef\xcd\xbf\xd2\x4a\x5c\x04\x00\xea\xc1\xc4\xc2\xad\x44\x2c\x0f\x28\x9b\xa6\xcd\xc5\x34\xcf\xa9\x7b\x8f\x05\xb3\xea\x1f\xca\x56\x38\x18\xe9\x3e" \ +"\x79\xd3\x85\x13\xd1\x58\x20\x9e\x55\x46\x55\xf8\xf9\x30\xe1\x2f\x56\x0d\x80\x06\x8c\x24\x1f\x80\x3a\xd7\xb0\x51\x81\x7d\xac\xe0\xd1\xcf\xf6\xad\xcf\xc1\x16\x61\x3c\xad\xb7\x4d\xfd\x9b\x12\xb2\x24\x71\xba\xd8\x46\x35\x2f\xb0\xb0\x6e\x58\x86\x51\xda\xa4\xe6\x2d\xf1\x1b\x50\x64\x61\x07\xf1\x76\x48\xc8\xa5\xbb\x9b\xbe\x5e\x28\x1e\xcd\x99\x47\x68\x8d\x0f\xdc\x0f\x99\xb1\xc8\x9b\xef\x78\x65\x88\x11\x99\xff\x58\xa3\xb9\xdd\xc7\xd8\x62\x45\x5f\x3b\xaf\xa4\xe9\xfd\x85\xe1\x02\x9c\x79\x5d\xe9\x0b\xac\xa4\xfc\x42\x19\x3b\x8d\xc3\x72\x83\xe0\x32\x8b\xe3\x87\xf0\x04\xab\x0e\xce\x8c\xcf\x37\xd3\x9f\x87\x08\xc1\xef\xe9\xcf\x35\xf4\xee\x54\x13\x49\x01\x5e\x68\x2a\x94\x1a\x03\x65\xc6\x99\xef\xef\x22\xe6\xfd\x6c\x06\x36\x3b\x36\xfc\x31\x56\x43\x5a\xae\xc4\x8c\xef\xb5\x40\x55\x0b\x2c\x09\xe5\xf9\x88\x48\x7d\xc7\xbf\xf2\x9c\x91\x51\x46\xc1\x2c\xb5\x85\x24\xd3\xf2\x1e\x90\xf4\x07\x59\x61\x62\xf4\x3d\xb8\x03\xae\x65\xad\xdd\xef\x91\xa6\xe1\xb6\x52\xca\x4c\x4c\x96\xc6\x5d\x78\x64\xfe\x2f\x15\xa8\x3d\x26\xa5\x30\x1f\x4c\x3b\x25\x59" \ +"\x6a\x57\xcb\xb3\xf8\x9c\xa2\x40\x32\x4c\x05\x7b\x71\x09\xd7\xe2\x17\xcd\x2c\xf5\x75\xb3\xfb\xa0\x6a\xcd\x82\xbb\xfd\x97\xe0\x18\x20\x6b\xd2\xdd\x3e\x09\x85\xc0\x77\x8f\xe8\x45\xcc\x62\x05\x56\x79\x11\xf5\xb4\xf9\xe9\x30\xb9\x38\x3e\x14\xd7\x8c\x06\xdc\x8b\x2c\x2e\xb4\xec\xd7\xfa\x51\xc3\xfe\x65\x87\x28\x87\xeb\x8d\x16\xb7\x01\x1f\x03\x59\xfc\x57\xcf\x3a\x18\xa1\xe1\x1c\xd9\xae\x7a\x47\x2e\x64\x19\x55\xbd\xb1\x2d\xb9\x35\xd2\x6d\xde\xf0\xf4\x52\x4b\xbc\x11\xbf\x2d\xb8\xdc\x84\x69\x4b\x97\x0c\x05\xec\x94\x96\x0a\x16\xc7\x1a\x8f\x8e\x9f\x89\x57\x8e\x46\xf1\x43\x05\x0f\xeb\x57\x14\xe0\xcf\xd2\x26\x3c\xf5\x22\xee\x6c\xc1\xcc\xc2\xb3\x07\x83\x9e\x3f\xf5\xff\x5f\x22\xf7\x3f\x64\x27\x55\x33\xb6\xdc\x45\x7d\x58\xdf\x27\xa0\xb0\x73\x64\xe8\x96\x14\x28\xcd\x84\xe7\xc9\x61\x28\x42\xcf\x35\xc3\x27\x3b\x04\xbf\x8c\xd2\x42\x2e\x68\xc4\x40\x23\x16\x97\xd2\x58\xdc\x6c\x60\x5f\xaf\x61\x46\x19\x5a\x6f\x70\x7b\x6a\xcc\x16\x3b\x6a\xf8\xe8\xb2\x95\x20\x24\x10\xfe\xbf\xca\x5f\xb1\xb1\x74\x5f\xd5\xcd\xaa\xfe\x60\xb8\xe9\xa6\x0a\x9c" \ +"\x5f\xfe\x69\xcd\x37\x9e\x3d\x81\xd7\x62\xe6\x6b\x03\x3f\x9d\x9b\xcf\xf7\x9d\x4f\xfe\x8a\xbd\x5e\xf8\xf4\x98\xa7\x6f\x10\xca\xea\x51\x26\xfd\x01\xb4\xd2\x18\x59\xb8\xfc\x55\x06\x23\xdf\x09\x22\x53\xfe\xe0\x45\x8a\xc7\x25\x5a\x18\x15\x88\x0f\x33\x32\x1e\x36\xd8\xe3\x9c\x75\xf2\x64\x34\xa3\x59\x21\xa4\x62\x11\x59\xb0\x15\x9b\x0f\x92\xd8\x56\x75\xa8\x03\x79\x4b\xfc\x74\x50\xc7\xa2\xd7\x4a\x04\x1f\x76\xba\xce\xf9\x74\xdd\x63\x41\x36\x21\x0d\x4e\xd2\x23\xd2\x35\x7a\xbe\xc6\xdd\xb7\x86\xcc\x4f\x08\x19\xd2\xbc\xfd\x55\xc9\x2e\xfa\x03\xe8\xd0\x25\x0c\xdf\x48\x97\x94\xee\xa8\xcc\xfc\x1f\x01\x1c\x76\xf8\xaa\x95\x49\x3b\x20\xca\x65\x97\x0f\x08\xbd\xa3\xd9\x8d\x96\x74\x41\x81\xa6\x93\x36\x01\x42\xd6\xe4\x4d\x4c\x0c\x69\x01\x52\x81\x7b\x1c\x32\x6a\xef\x73\xbd\x51\xa5\x59\x40\xa2\x48\xad\xa2\x0c\x8f\xa1\x2a\xc3\x34\x31\x4f\x82\xe7\xcf\x7d\x71\x15\x2b\xb8\x78\x61\x4f\xa2\x24\x7d\xcc\xfd\x17\xeb\x16\x57\xfa\x81\x2e\x33\x8c\xb8\x7a\x05\xb0\x5b\x4d\x79\x63\x5e\xf6\xd9\xf7\xb5\x64\xbe\x51\x2b\x47\x61\xd8\x52\x90\x32\xd7\x48\x58" \ +"\x88\xca\xa7\x92\x14\x6c\x6f\x30\x08\x80\x4d\x3b\xb3\xe3\x74\x66\x6a\xaa\x7b\xb7\x96\x0f\x14\xe2\xb1\xf4\xc7\xd2\xe1\x60\x0b\xe8\xe6\x6b\xe6\x5c\x58\x07\xc8\xfa\xa2\x8f\xf5\xd7\xc2\xae\x7e\x1f\x91\xd3\x9e\xd2\x7d\xde\x56\x50\x69\xcf\x60\xc5\xf0\x10\x79\xe5\x10\x2b\x20\x12\x61\x74\xf9\x69\x35\x0a\x6d\xa3\xe2\x5a\x2b\xcd\x1b\xbe\x14\x4b\x05\x77\x61\x51\x64\xec\x1e\x0d\x2a\x1e\x94\xed\xe1\x95\x23\x11\x11\x05\x8e\x23\xfa\xd7\xc5\x9b\x11\x6f\x91\x81\x35\x39\x00\xc8\xf9\x59\xb0\xbd\x01\x74\x24\x0f\x8c\xb6\x5f\xd6\x8f\x74\xeb\x52\xa5\x35\xc0\xb5\xb7\x83\x6a\x05\x8e\x23\x1f\xeb\xb1\x5a\xcb\x79\xa7\xd8\xa5\x21\x2f\xe1\x15\xe3\xde\xeb\x52\x4a\xc3\xc5\xd7\x4f\xcd\x6c\x91\xb9\x58\xe0\xcf\xb9\x2b\x94\xc7\x37\xce\x37\x35\x24\x53\xe4\x0f\x9b\xf0\x34\x8b\x24\xa9\xca\x8c\x0b\x94\xc9\x64\x74\x05\x04\x5d\xd1\xff\x0e\x68\x1b\x1e\x8a\xe0\xb6\x88\x44\x1b\x12\x7f\x3d\xe7\x0d\x4f\xd3\x81\xaa\x53\x85\x79\x2a\xc9\x5b\xa1\x9d\x5d\x5c\xe4\xe6\x55\x2a\x48\xfc\x8e\x55\x31\x31\x5a\xf8\x69\x40\x65\x11\xb7\x68\x47\x42\x58\xe7\xf3\xb9\x7f\x6d" \ +"\x60\x10\x90\x43\x89\x8e\x33\x0f\xb0\xe5\xc3\xf4\x79\xe1\xeb\x01\x2f\x1a\xbb\xc7\x1d\x54\x2a\xd1\xc0\x17\x18\x42\x8b\x69\x3b\x2a\x62\x2a\x3b\x79\x2a\x13\xfc\xd8\x53\xaa\x0f\x99\xe3\xd1\xf2\xc0\x54\x7f\xe1\x07\x6a\x34\x7a\x0b\xc5\x0d\x72\xc4\xc2\x43\xd9\x6a\xc9\x09\x21\xbc\x2c\x50\x9c\x8a\x0d\xea\xbd\x1d\xf0\xbe\xf7\xe7\xc2\x71\x91\xb6\x3f\xb8\x51\xcb\x58\xad\x2b\x94\x7e\x3f\x37\x1e\xb3\xa9\x08\x04\xd3\x07\x49\x30\x98\xa9\x41\x8b\xef\x27\x2a\x42\x43\xd1\x04\x14\x66\xc1\x3a\x16\x9b\xe5\xf8\xe9\x63\xee\x3e\xad\x47\x38\x2b\x99\x81\xfd\xa1\x45\x57\x5e\x32\x35\x01\x12\xa7\xb3\xfd\xe8\x05\xf4\xb4\x49\xca\xce\xc7\xb1\x9c\xa8\x90\x9c\x70\xf7\xbb\x5d\x79\xe9\x95\x10\x50\x91\x43\xaf\x39\xfc\xb9\xda\x38\x0d\x00\xa4\xa0\x54\x13\x44\xa8\x0e\x59\x4d\xe1\x02\x0e\x53\x7c\x38\x37\xa2\xe5\x27\xc4\xf9\x1b\xf0\x5a\x85\xf1\xed\x4f\xa9\xe9\xad\x8f\xff\x24\xf9\xa6\x74\x74\xb1\xd8\x95\xe0\x1a\x40\x2c\xb1\x19\x05\xfd\x0d\x32\x41\xed\x0f\x8a\x2b\x5f\x6c\x14\x81\xb8\x8a\x79\x6e\xf0\x5b\x0c\x66\xbb\xb7\xe8\xc4\xfd\x8c\x5a\xae\xab\x09\x96" \ +"\x9f\x58\x61\x38\xe3\x9e\x5c\xe3\xd1\xe3\x89\xf8\xf8\xb6\xa7\xe5\x6e\xbc\x55\x1e\x4a\x07\x48\x63\x6a\xb2\xb5\x5a\xf8\x65\x3b\xb8\x40\x1a\xbc\x01\x4c\x91\xbf\x76\x4e\xa1\x5a\x9d\x6c\x79\xeb\x9a\x5a\x70\xec\xcc\xe2\x43\xc1\xcc\x88\x54\xe0\x2f\xa5\x00\x2c\x2e\xe2\x90\x71\x92\x85\x49\x49\x65\x3d\x31\xb7\x2d\x88\xd1\x0a\xb9\xcf\x18\xf1\xfd\x86\x71\xf8\xe9\x71\x4b\xa1\xb1\x02\x42\xd8\x3e\xb0\x3b\x04\xa3\x5a\xaf\x60\xee\xf3\xc3\x3e\x20\x3d\xe1\x4b\xb2\x7e\x60\x6d\x7a\xe7\xef\xb4\xc4\xcb\x14\xc1\x00\xcb\x31\x92\x22\x7f\xfa\xc0\xcc\x59\xff\x56\x09\x9b\x78\xa1\xed\x40\x94\x32\x36\x78\x5f\xbe\x79\x5d\x41\x7d\xbf\xca\xbe\x10\x70\xbf\x4d\x1c\x7d\x5a\x54\x80\x07\xda\xfb\xb1\x47\x90\xa2\x3c\x2b\xd9\xff\x31\x35\x65\x83\x2a\xc0\x40\x7b\xbc\x21\xd9\x93\xf8\x3f\x4b\x3d\x45\x95\xf8\x5a\x70\x94\x84\x0f\x72\x72\x42\xeb\xc6\xde\xa6\x6c\x8c\xac\xf8\x0e\xfc\x3f\x9e\x99\x91\x3d\x73\xa0\xc2\x1e\xca\x22\x12\x9e\x8b\x84\xaf\x49\x4d\x24\x0a\x55\x9c\xb4\x2c\x5c\xf5\x43\x7c\x15\x37\x03\xb5\xd0\x10\x4e\x90\x2d\x96\x99\xab\x63\xcb\x78\x66\x90" \ +"\xcd\x95\x10\xa8\xf5\x3c\x43\xab\x69\xa3\x4a\x65\xc5\xf3\x4d\xce\xbb\x4f\x7d\x36\xe8\x32\x63\x3c\xd1\x15\xe0\xcb\xf0\x36\x05\x40\xbe\x71\x34\x2b\x72\x99\x39\x18\xf6\xf9\x43\x05\x74\x6c\xa7\x18\x98\x9d\x91\x91\xb8\x87\x09\x15\x13\x28\xd0\x57\xfe\x30\xf9\xff\xa2\x27\x4b\x77\x14\xbc\xf5\xa6\x17\x86\x45\x40\x07\xf2\xb8\x59\x11\xa6\x24\x9e\x4c\x69\xeb\xd4\x4b\x0e\xb3\xa8\x33\xcc\x2a\x32\xbb\x05\x76\x4c\xad\x3a\x9b\xac\xc3\xa8\x2c\x1c\x81\x09\xbc\x08\x72\x4f\x39\xe9\x96\xaf\x24\xd5\x3b\xb0\xcf\x19\x0a\x94\x50\x03\x74\x0e\x78\xa1\xe9\xfa\x24\xd4\x74\x1a\xcb\x25\x81\x2a\x18\x41\xbe\x9d\x41\xc1\x84\xc3\xb5\x1b\x7d\xa1\xed\x11\x35\xcb\x20\x1d\x86\x78\xda\x78\x54\x8b\x27\x79\xf4\xbe\xa7\xb3\xa5\x71\xa9\xdb\x1f\x89\x56\x0f\x2b\xed\x63\x47\x2b\x97\xa7\xdd\xb6\x70\x9d\x6f\x28\x5b\x85\x11\x57\xde\x53\xdd\x27\xbc\x95\x33\x2d\x87\x68\x1b\x94\xf6\xf8\x1c\xa0\xdb\x7d\xc6\x29\x97\xce\x1a\xa7\xa7\x5e\x29\x69\xfb\x04\x23\xfb\xa6\x01\x6f\x9c\xd1\x7e\x27\x5d\x69\xea\xc5\x40\xb9\xb1\x30\xb6\x99\x63\x22\x1b\x6d\x7e\xc0\xb7\x14\x75\x83" \ +"\xd1\x5d\x25\x47\x60\x57\x04\xb7\x34\x10\x04\x7d\x0c\x35\x09\x4c\x68\x97\xaa\x09\xba\x4a\x98\x8c\xad\xe7\x34\x71\x0b\x73\x06\x4b\x3e\xd0\xc0\x66\x47\x70\xcc\x4a\xce\x14\x52\x05\x99\x10\xc2\xba\xb3\xbe\xaa\xdb\xfb\x6d\x18\x58\xdf\x89\xb9\xbe\xd9\xa8\x50\x65\xd2\x69\xdf\x73\x7c\x47\x5b\xc0\x30\x2a\xce\xdc\x0e\x30\x03\xe8\x63\x33\xf7\x27\x92\x97\x94\xe6\x5c\x71\x7b\xb8\x7c\xa9\x37\x05\xf9\xe2\x9c\x56\x51\xa7\x90\xa4\xa9\x49\xf1\x3d\x38\x14\xf7\x74\xac\x93\xaa\x03\x06\x50\xbd\x03\xdc\x0b\x3e\x38\x81\xb3\x91\xcd\x5b\x2e\x41\x1d\x72\xb8\xd0\x76\xef\x67\x21\xe0\xb1\x6d\x96\x13\x13\x64\x88\xa6\x61\x65\xa8\x09\x07\x1d\x8f\xa9\x5d\xba\x4c\x17\x03\xe3\x5d\xf0\xeb\x5e\xc3\x02\x2e\xbc\x4b\x25\xfc\x3c\x3e\xba\xfa\x8f\x85\x60\x7f\xd0\x7f\x37\xb0\xf7\xe8\x63\xc4\x63\xc5\x6b\xa2\xea\x2f\x6d\x1b\x79\x42\x49\xa0\x01\x34\x1d\x48\x59\xfc\xe7\x41\xec\xfa\xc6\xba\x81\x15\x66\x62\x39\x14\xb8\xdd\xae\x30\x25\x0b\xb9\x7b\xbb\x66\x4e\x5c\x03\x45\xa1\xde\x21\x96\xfa\x75\x55\x76\x6f\x04\x91\xf2\x3e\xff\x1b\x30\x48\x57\xfd\x20\x9d\x82\x44" \ +"\x3f\xe0\xdf\xe3\x1d\xd9\xb1\xad\x3d\xce\x22\x0e\xcd\x46\xa1\xe0\x1c\x83\xc5\xcb\x69\x21\xb2\x83\x90\xba\x93\x77\xa7\xac\x07\x74\x34\xd6\x34\xbf\x10\x14\x8a\xf1\x96\x3c\x11\x1e\x5a\x16\x90\xbb\xe3\xa3\x86\xb0\x42\x79\x0e\x01\xe8\x63\x5d\x39\x19\x71\xb1\xf3\x7e\x2e\x31\x00\x43\xcf\xc6\xff\x26\xa4\x34\xdd\x34\xdc\x5a\xc4\xbf\x49\x21\x88\x63\x4a\xc3\x1f\xe7\xc2\xc7\xb6\x8c\x52\x9d\xbc\x08\x0c\x51\x54\x6b\x02\x02\x23\x59\xa8\x3a\x82\x10\x3c\x58\xa3\xd4\x57\x84\xc2\xc2\x3f\xbb\x62\xf3\x73\x40\xf5\xaf\x09\xda\x00\x20\xd2\xc5\x28\xa6\x2c\x0f\xea\xee\x21\x99\xe0\xfa\x78\x33\x00\xe3\x78\xdb\x2c\x1e\x56\x40\x68\xea\xab\x89\x4e\x7d\xcc\xfd\x3c\x86\xd3\xda\x2f\x0f\x91\x32\xe7\x6c\x8f\x7e\x63\x50\x6d\xf2\xd3\x92\x8e\x53\x16\xea\x96\x30\x7b\xe3\x34\xd0\xd5\x89\x53\xd9\x52\x2b\x9b\xd4\xe6\xa2\x8b\x6b\xf3\xdc\x2d\xfd\xdc\xfa\x61\x67\xef\x36\x0e\x16\x83\x4a\xab\x63\xdb\x62\x28\xd8\xb0\x9e\x52\xfa\x6a\xfe\x02\x63\x31\x38\xa8\x77\xb8\x8c\xb6\x74\xba\x1d\x67\xdf\x14\x09\x5f\x06\x24\x1c\x86\x5a\x08\x39\x41\x9e\x21\xee\x9b\x3d\xd2" \ +"\xec\x7e\x6d\x90\xfc\xde\x2c\x68\x6a\xd4\x8c\xc3\x1f\xde\x8d\x83\x37\x01\xa0\xec\x34\x9b\xaa\xad\x9a\x55\xee\x06\x9a\x5d\xf4\xac\x14\xcf\x03\xf9\x8f\x34\x16\x4d\x64\x0e\xe3\xfe\x23\x42\x1b\x25\xde\x62\x07\x16\x91\xca\xd6\x74\xd6\x21\xde\x8a\x20\x9a\x33\x56\x68\x77\x1c\x6b\x44\x0d\xd9\x9b\xc4\xdf\xcd\xb4\x5e\x16\x95\x9c\xa7\xca\x2d\x7d\x25\x69\xcf\x91\x1a\xa2\x9b\xa7\x07\x9b\x33\xc9\x03\x48\xb6\x9a\xd1\x0e\xc5\xd7\x8c\x72\xba\x79\xac\x5e\x4d\x10\x8e\x00\x67\xb8\x17\x1d\x37\x65\xd3\x3c\xe5\x36\x4e\x79\xf6\x4f\xd4\x60\xef\x34\xb6\x84\x2a\xd6\xd0\x1c\x30\xfc\x4f\x71\x91\x5a\x6e\x2e\x91\xbe\x50\x3f\xa6\xd2\x4d\x22\x6f\x7d\x33\x66\x0a\x03\xc2\xd1\x09\xa0\x0f\x9b\x24\xeb\x8e\xfc\x7d\xae\x2c\xba\x4e\xab\x36\x3e\x0e\xe3\xbf\xc0\xea\x2b\x54\x63\x60\xc9\x01\x0c\x65\x62\xed\x0c\xf9\xba\x94\xdd\x11\xd1\x0b\xb5\x94\xa6\xb1\x2c\xa2\x10\x55\x23\xd6\x55\x72\x64\xf9\x4c\x52\x4a\x46\x1e\x92\x63\xe6\x0f\x9d\x75\x9a\xdb\x83\xa3\xc1\xaf\xd8\x1e\x93\xb0\xe0\x74\x52\x90\xe0\x83\xf9\x32\xf7\xc4\xed\x41\xb2\x66\x69\xfc\x14\x1f\xa6\x11" \ +"\xd9\xcf\x8c\xd8\xfe\x7b\x3b\x4d\x11\x6f\x62\xa8\xd2\xed\x4c\x6e\x6b\x10\x64\x28\x2e\xd0\x51\xc9\xa0\x34\x89\x19\xb4\x88\x25\xd6\xad\xac\x5f\x71\xd2\xc3\x5f\xde\xac\x76\x77\xbd\x62\xfd\x7b\x6b\x12\x62\x6f\xc9\xe0\xc5\x6d\x88\x96\x95\x05\x57\x7c\xbc\x25\xc9\x49\xc6\x1a\x06\x3e\x86\xbc\x88\xce\x7e\x65\x2e\xea\x11\xca\x2f\x87\xdf\x39\x3b\x35\x72\x26\x59\x1f\x01\x4c\x4c\xee\x8f\x0b\xbe\x1e\x4c\xe6\x2e\xa2\x33\x00\xba\xcf\x7e\x6b\xdb\x9c\x12\x68\xf7\x9e\xf4\x91\x14\x54\x1f\x44\x8d\x37\xbe\xdd\x69\x66\x38\x51\x9a\x7d\x47\x7b\x7e\xec\xb3\x51\xe7\xdc\xa7\x77\xce\x73\x6a\x3b\xa6\xa6\x03\x89\x2b\x38\x20\x05\x2d\xd7\x91\xa2\x2f\x94\xea\x72\x12\x03\xa6\xf8\xd1\x75\xc0\x67\x23\x53\x4f\x13\xd4\xe6\x0c\x80\xd6\x8e\x94\xad\xea\xd4\x3e\x4e\x90\x08\x8d\x3f\xfc\xff\xbc\x1b\xbf\x84\x35\xd7\xdc\x13\xbf\x4b\xfd\x91\xe6\x7a\x9c\x73\xfa\x49\xab\xd2\x16\xe9\xf4\x5b\x3a\x2f\x4b\x44\x74\xb6\x62\xb6\x4b\x42\x24\x9f\x40\xcd\xb0\x66\x32\xed\x26\x6b\x94\x3a\x3d\x40\x01\xf9\x44\x4b\xeb\x68\x19\xe4\x93\xe9\x2e\x19\xbe\x76\xc4\x22\x27\x01\x3c" \ +"\xc9\x43\x4d\x40\x09\x2b\x00\x96\x29\x49\x39\xfe\xd3\x60\x5d\x81\xe7\x3f\x0c\xb1\x6a\xee\x46\x49\x57\xfb\x07\xfe\x33\xd4\x22\x22\x89\x7f\xd1\xcf\x46\x3c\x44\x47\x4a\xd0\x77\xd3\x99\x64\xad\x15\xb2\x5f\x71\x06\x67\xf4\xcc\xc8\x8d\x3a\x9c\x0d\x15\x6d\xa9\xd7\xce\xb8\x0a\xf8\xd6\xdb\x02\x16\x6c\x25\xf7\x9d\x66\xa7\xfd\x8e\x8b\xb1\x3e\xf3\x3b\x93\x45\xe7\x96\x7b\xb1\xe7\xe0\x21\x1d\x4b\xb8\x73\x8f\xda\x04\x0a\x7d\x23\x32\xc9\x8f\x2c\xaf\x6c\xce\xf7\x98\x51\xf9\x87\xdd\x17\x84\x50\x68\x18\x06\x0a\xd0\x9b\x61\x2d\x09\x34\x1d\xe8\x98\xb0\x4b\xf2\xf1\x6f\x80\x7f\x90\x60\x9f\xab\x49\xfa\x34\xa3\x2b\x9e\xe8\x59\xe3\x41\xdb\x97\x99\xe3\x3d\x2e\xe8\xb1\xaa\xcb\xed\x09\xfd\xe1\xde\xe0\xc8\x56\x92\xb4\x68\x08\x0f\xbd\xb8\x5e\xb1\x24\x39\xaa\xce\x3e\x2f\x98\x43\x4d\x6a\x0a\x1a\xb4\x2c\x7c\xaf\x05\x51\x60\xd7\x8f\x8e\x98\x3d\x02\x51\xd8\x42\x8e\xd8\x47\x08\xaf\xf5\x33\x90\xba\xa6\x1c\xe6\x40\x9f\x96\x5a\xf9\x41\x97\x0a\x88\x5b\x26\x92\x01\xf3\x17\x8d\xe0\x7d\x6c\x04\xa6\xba\xf1\x37\x0a\xca\xfb\xe6\x60\xfc\xf8\xc5\x30\x1d\xef" \ +"\x81\xcc\xb8\x0f\x0a\x59\x82\xaf\x90\x3b\x9b\x21\xab\x79\x20\x13\xfc\x6d\xdc\xbf\x73\xed\x25\xf3\xe9\x79\x7a\x5a\xfa\x42\x8e\x2c\x23\xcb\xda\x91\xf3\x8c\x1c\xa1\xd5\x99\xe7\x4c\x8a\x4c\xfb\x97\x07\x0b\x40\xc1\x49\xe6\xbf\xc4\x99\x53\x05\x5e\x6b\x68\x01\x41\xcb\x95\x99\xd1\x4c\x52\x3c\x00\x15\x99\x3f\xac\x77\x6a\xdf\x33\xd4\xf4\x90\x19\x19\x7e\xd8\x09\x5d\x2a\x2e\xbc\x86\x9a\xc3\x54\x2e\x7e\x80\x88\x6f\x15\x5a\x67\xdb\xc6\x27\xa1\x35\xff\x97\xd5\x69\x87\x73\xe2\x5e\x1c\x30\xfc\x50\x21\x3c\xd5\xce\xf7\xbf\xaf\xc3\xe3\x76\x36\xb9\xcd\xc3\xf8\x0b\xee\xca\x0d\xec\x26\xb6\x01\x01\x33\x6f\xbe\xea\xf9\x57\xbd\xea\x23\x94\xe2\x48\x83\x4d\xf9\xd6\x30\x24\x74\x3a\xe4\x4d\xa8\xde\xbe\x73\xc1\x9d\xae\xd5\x69\x78\x17\x62\x86\x16\xcd\x96\xc0\xca\x80\x41\x80\x55\xfe\x63\x87\xe3\xaa\x50\x60\xea\xe1\xad\xac\x9c\xb3\xea\x51\xb9\x22\xe3\x9b\x29\xf2\xf4\x8a\x94\x3a\xff\xe8\x3f\x92\xb8\xe9\x9d\x69\xce\xb5\x35\x2a\xa5\x3b\x4d\x47\xce\xdb\xa9\xa8\xf6\x3d\x72\xab\x93\x16\x65\xda\x5c\x5d\x3a\x67\x50\xf0\x98\x50\x89\xb3\xb5\xaf\xcb\xf5" \ +"\x6f\xe7\x04\x29\x9e\x5e\xe0\xbd\xac\x7a\x61\x5c\x5d\x7e\x2f\xe5\xef\x34\xe1\x66\x26\x19\x3d\xc4\x79\xe3\x5e\x1b\x94\x85\x3d\x62\xf7\x07\x52\xbb\x9f\x6a\x4a\x33\xf5\xab\x2a\x45\xbc\xe3\x22\xb2\x88\xd2\x89\x3e\x56\x65\x08\xcc\x6a\x06\xea\x69\x85\x33\x45\x32\xa4\x54\xb6\x49\x5e\x6b\x0a\x86\x13\xa5\x6f\xbf\x91\xee\x00\x08\xbc\x39\x7b\xb9\x84\x09\xa9\x2b\xd7\x5c\x4a\x6c\xb0\xdb\x58\x1a\xe3\xff\xac\xc6\xaf\x28\x6a\x78\xe3\x94\x18\x97\xc3\x79\xb6\x46\xb1\xfb\x69\x1b\xa8\x10\x8e\xcf\xb0\x4a\x2f\xd9\xa1\x8b\x1c\x3c\xe4\xc4\xf6\xe9\xf9\xb8\xd4\x24\xc4\x60\x7d\x4f\xc5\x25\x11\x85\xfb\x59\xe2\xbb\xe8\x26\xee\x9e\xb7\x5c\x60\x23\x03\x1c\xf7\x44\x6f\x67\xae\x6e\x51\xa4\x92\xa5\xc3\xdb\x72\x1b\xcf\x53\xff\xfd\x7e\x58\xf2\xc6\x6f\x66\xda\xf9\x72\x09\x99\xdd\xdf\xb0\xbc\x58\x11\xd0\x2e\xb2\xee\x24\xfd\x6d\xe0\xde\x4f\x9a\x7d\x12\xc8\x65\x74\x39\x01\x81\x61\xc9\x97\x6f\xb7\xde\x8c\x87\x72\x9c\x5f\x54\xb2\xf1\x9f\xb1\x70\x3e\x19\x7d\x73\xe8\x66\xfb\x3e\xcb\x0e\x05\x96\x5c\x63\xf1\xdb\x35\xfa\x45\x30\x41\x8d\xf3\x82\x7c\xe1\x1e" \ +"\xb0\x3b\x11\xaf\x91\xfe\x31\xf1\xeb\x89\xe2\x88\x2a\x00\xfb\xa0\xcd\x9c\xc0\x0a\x09\x55\x37\x0e\x3b\x26\xac\xc0\x18\xdd\x42\x36\xed\xee\x93\x5a\xe4\xbd\x16\x09\xdc\xa4\x64\xda\x4c\xb0\x80\xb8\x88\x98\xfc\x43\xa2\xe3\x77\x85\x05\x0f\x6c\x82\xa5\xd3\x18\x13\x22\x4a\xea\xd1\xce\xcb\x05\xe8\x05\x85\x5c\xfb\x6f\xf2\x51\x39\x64\x0c\x74\x8b\xbd\x71\xa7\x8d\xb5\xae\x2f\x0a\x69\xed\x0a\xaa\xc3\x8c\xf5\xb8\xce\x2c\x07\xaf\xb6\x94\x9f\xd1\xef\x8d\xc0\xc2\x07\xbd\xe1\x5d\x25\xa1\x5a\x51\xa7\x61\x20\xa1\x0c\x93\x6e\x51\x80\x0e\x4e\x92\xfc\x13\xfc\xdd\x39\xc4\xe9\x62\xc0\xa6\x31\xc7\x96\x60\x1e\xf7\xa9\xb7\xfc\xd2\xc9\xe2\x17\x72\xc1\xe5\x7b\xfb\x5d\xbb\xbf\x2c\xc3\xd6\xde\xf3\x09\xb4\xd7\x22\x59\x43\xdc\xa2\xc3\xc8\x43\x7e\xf7\x3b\x8e\x23\x52\xee\x80\x19\x33\x87\x98\xee\x64\x34\x3b\x76\x98\x93\x6f\x85\x8a\x29\xc4\xd2\x18\xf1\x0a\x23\x49\xa3\x5e\x61\xb5\x20\x90\x18\xac\xbf\xcd\x0c\x19\xe6\x6c\x82\x8a\xf8\xa4\x62\x8d\x5c\x63\x38\xb4\xc0\x37\x3f\x46\xad\xa4\x39\x1a\x5f\x87\xf3\xff\x9f\xd3\xa3\x2f\x80\x47\x9b\x62\xbb\x51\x9f" \ +"\xbf\x01\x37\xe1\xf1\x10\xae\xf0\xa8\x7a\x25\x28\x61\xcf\x9d\x9d\xb0\x07\xfc\x51\x85\xd6\x80\x53\xf9\x21\x48\x8f\x04\x57\x08\xc5\xe7\x15\xde\x4a\x8a\x84\x95\x6c\x66\x18\xdd\x9a\x53\xbb\x50\x1f\x07\x3f\x74\xb4\xa9\x54\xca\x12\xbc\x0e\x76\x62\xa6\x4b\xf4\x0a\x01\xdb\x4f\x69\xa3\x00\xf9\xfd\x60\x56\xc9\x27\x61\x53\x53\xae\x30\xf9\x49\x27\xbf\xd0\xa8\x22\x43\x97\xfe\x10\x12\x87\x5c\x9d\xe0\xe1\x29\xfe\x2d\xcb\x29\xc5\xd8\x8d\x0f\xd2\x21\xdb\x43\xbd\xdc\x45\x32\x13\x4f\x2b\x4b\x7a\x01\x5d\x2c\x41\xc5\x0f\x1d\xea\x27\xaf\xe9\x88\x05\x41\x7b\x74\x6d\x88\x3f\x5c\x3b\x1f\x9e\x01\x28\xdb\x9e\x5e\x27\xec\xcf\xc6\x7c\xf7\xd1\x96\xa8\x92\x1b\xa4\x50\x6d\xfb\xdc\x65\x96\x1d\x8e\x2c\xc7\x47\xe8\x1b\x24\x76\x45\xe6\x54\x1a\xac\xfc\xe3\x2e\x13\x23\xa8\xef\x05\x0f\xdc\x80\x5f\xd4\x6a\xcd\xf2\x38\x80\x09\x14\x1c\x18\x21\x0b\xb1\xf4\x6e\xed\x83\xe9\xb7\xdf\x79\x73\x5a\xe1\xdf\xa0\x53\x42\x88\x46\x3a\x99\x0d\x68\x88\xcf\x27\xea\x81\x8c\xf7\xdb\xb0\x48\x78\xd3\xb9\x85\x76\x83\xd4\x3b\xba\xb2\xc7\xe4\x36\xe7\x61\xbb\xe0\x61\xed\xce" \ +"\xd7\x09\x16\x0c\x0c\x93\x15\x26\xa5\x4e\x95\xf5\x91\x76\x67\xf5\x81\x78\x05\x8e\x31\x00\xd3\xe0\xef\x4d\x72\x30\xac\x9e\xab\x13\xe0\xc9\x52\xda\x4e\xa8\x5b\x86\x0f\x28\xbb\x72\x2a\x1a\x08\x8e\xd3\x3d\xe9\x08\x9b\xb1\x93\x95\xe8\xa0\x01\xb1\x87\xf5\x90\x45\x16\x9d\x9c\xc8\x6d\x85\xc9\x9d\xd4\xfe\x86\xd5\xbf\xff\x65\xff\x14\xeb\x69\x3e\xdd\xd2\x9f\x40\xf6\x88\xb5\x3c\x29\x95\x81\xe0\x2e\x4f\xad\x88\x69\x7d\xc0\xf4\x10\xec\xac\xc2\xf7\x88\xa0\xbf\xdb\x18\x65\x97\xcc\xbd\xfe\x45\xa0\x4f\x54\x95\x2b\x6c\x5a\x41\x10\x4b\x31\xb6\x1d\xd3\xbc\x87\x91\x83\x6c\x8f\x61\x5f\x26\x26\xf4\x75\x5c\x9d\x5b\x26\x76\x76\x86\x6c\x7b\x53\xd7\xef\xe4\xba\x2d\x70\xca\xa6\x7f\xc7\x50\xb7\xfb\x70\x71\xed\x31\x94\x5c\x1f\x36\xf2\xd0\x0c\x2f\x65\x4a\x4f\x13\x4e\x7a\x3c\x7d\x55\x85\x03\x34\x7b\xec\x3c\x3e\xb2\x65\x6f\x5b\x59\xe4\x3f\x3e\x74\x35\x94\x47\x2e\x99\x85\xf4\x3b\x57\x75\xab\x43\xb6\x77\x03\xcc\xd7\xcd\x80\xf8\x0b\x3b\x22\x0f\x73\xf9\xb1\xf0\xc6\x3a\x34\x17\x65\x84\x76\x27\xb5\xc7\x31\x27\x62\xc4\x17\xb3\xc7\x3e\x41\xa5\xf6\xda" \ +"\xa1\x96\xa3\xfd\x5e\x7c\xd7\x0a\xf5\x47\x87\xa8\x3b\xfb\xe5\x9d\x27\x4b\xb3\xd3\x53\x21\xac\x51\x02\x1e\xde\xae\x42\x50\x0b\xc4\xbb\x7b\xff\x7f\xbb\xd0\xec\x6a\x58\x36\x5d\xfd\x25\x21\x9b\x52\x1a\x9c\x39\x57\x94\x82\x2c\x54\xcf\xab\xc8\x83\x52\x1c\x3d\x7a\x9b\x72\xa0\xfd\x1d\xb1\x32\xa8\x64\x49\x12\x84\x5c\x88\x43\x18\x9c\x95\xa4\x78\x6d\x82\xaa\x9c\xa4\xf8\x68\x53\x98\xe7\xd3\x64\x4e\x3b\xaa\x93\x65\x56\xfe\x7f\x8f\x7c\xb2\xe8\x23\x23\xf3\x03\xdc\xc6\xb6\x92\x47\xfa\x32\x3d\x98\xfd\x65\xdb\xdb\x9f\x3a\x22\xef\x6f\x90\x1d\x08\x63\x18\xd4\x7b\xb0\xab\x00\x84\xfd\x23\x8c\xa6\x9d\x44\xd7\xd9\x69\x4e\xe0\x12\x76\xd8\x4f\xe3\x65\x3b\x99\x1b\xd9\xf3\xfa\xc1\xd5\x64\xb8\x45\x4e\xe5\x07\x90\x6b\x05\xd6\xdf\x8b\x7b\x2c\x8c\xa5\x83\xd7\x41\x4d\xb5\x8f\x65\xda\xc6\x57\x2f\xbf\x0a\x66\xe7\x00\xef\x17\x80\x53\x0b\xda\x3e\x68\xb9\x49\xd3\xd8\x28\x46\xe7\x5c\xbb\xac\xff\x42\x9f\x5d\x9c\x23\xac\x7b\x02\xe6\x7b\xec\xf1\x9a\x58\x88\xb3\x93\xae\x59\x32\x05\x9e\xa9\x80\x7f\xd7\xe7\x52\x53\x9f\x42\xf1\xcd\x67\x8f\x14\xf8\xef\x8f" \ +"\x1f\xd2\xf9\x27\x19\x08\x08\xf2\x6f\x6f\xbc\x23\xbe\xfb\x11\x72\xa4\x31\x18\x71\x9f\x32\x73\x38\xbe\xb4\x5b\x7d\xed\x63\x74\xd3\x24\xd0\x73\x0c\x49\x3d\x63\x6e\x51\x40\x53\xa3\x83\x9a\xd3\x09\xa5\x0b\x1e\xb1\xb1\x2b\xf1\x07\x6c\xcb\xe0\x4b\x19\xf6\xa0\x21\x94\x20\x83\xb7\xbe\x00\xdb\x1c\xd0\xf2\x86\xae\x5b\x5c\x33\x24\xf0\x2b\x8b\x93\x65\xb7\x33\xd8\xf9\x2a\xa6\x34\x85\x73\xf9\x06\xf0\x17\x1b\x17\x4d\xb4\x28\xaf\xf0\xad\x68\x46\x89\x53\x52\xab\x9b\xd7\x88\x83\x04\xac\x13\x64\xff\x92\xa0\xc7\x80\xb1\x82\xa3\x38\x68\x6b\x66\x2c\xb2\xc4\xbb\x00\x26\x35\xe6\xbf\x94\xda\xcf\x69\x42\x6a\x67\x34\xf1\x77\xe9\x3f\x3f\xb6\x2d\x65\x3d\xd2\x59\xaf\x65\x62\x59\xac\xfc\xec\x24\x36\x8f\x83\x37\x23\xbd\x80\x39\x49\x22\xe5\xfa\xce\xfd\x2b\x25\x35\x88\xac\x49\xdd\x1b\xcd\xcf\x15\x78\x5c\x06\xdc\xa6\x42\x5f\x2d\xf1\xd1\x70\x48\x16\x1f\xdd\xe8\xdc\x9d\xf8\x4e\x69\xd6\xe6\x29\xc1\xd3\x2e\xf9\x1a\x0b\xf2\x2a\xe1\x74\xcf\xa6\x8d\x74\xb9\xdf\x56\xda\xbe\xff\xb9\xfa\xc7\xb5\x38\xbc\x84\x25\x1b\x55\xf8\x70\xa1\xb6\xa4\x99\x81\x28\x25" \ +"\x0d\x08\x43\xec\x24\xb6\x97\x82\x60\x83\x41\x1a\x67\xef\x41\xf3\xea\xa2\x07\x5a\xed\x18\x63\x91\x2f\xb5\x63\x41\x26\x24\x70\x9d\xef\xe1\x7f\xa1\xa8\x06\x42\xe7\xfc\x8e\x9a\xe1\x8a\xbd\xf3\x42\x8e\x47\x3d\xef\x37\xe6\x3b\x28\xe0\x86\x68\x64\xbd\xa6\xf9\x42\x5b\x92\x9a\x1c\x43\x4e\x8a\x28\x72\x47\xac\x03\xa8\xe9\x09\x6a\xe4\x8f\x38\xc1\xe3\xf3\x90\x33\xde\x5e\xe0\x2b\x4f\x95\xd4\xf5\x34\x44\xc8\x11\xeb\x2d\xa4\x93\x3e\x76\x34\xd8\xc3\x4e\x0d\x42\xbe\xbc\xf1\x8e\xea\xb6\x55\x30\x94\xd6\x7b\x39\xdf\xbc\xe5\x77\xa9\xb4\xc1\x46\xfa\xd7\xf9\x1d\x58\x7b\x58\xe2\xd2\xab\xaa\x20\x50\x55\x03\x1a\xdb\x6d\x61\x86\x0b\x60\x76\x47\x82\x56\xb6\x4d\x74\x89\xd6\x1c\x8c\xf2\xe3\xb2\xa7\xc8\xd6\xaf\x6b\x60\x84\x21\x28\x40\x5d\xce\x5a\x81\x84\xdd\xaa\xf2\x71\xeb\xfb\xac\xc1\x23\x3a\x55\x46\x09\x4b\x68\x47\xa1\x63\xd6\x06\x21\xcc\xfa\xac\xc7\x21\xb7\xf6\xfa\x6d\xfb\x32\x6a\x72\x10\x86\x96\x13\xdb\x15\x3c\x3f\xfb\xcc\x9d\x2d\x6a\xe9\x85\x9a\x91\x87\xc9\x4d\x3b\xb2\xb0\xd9\x6d\xec\x13\x13\xc8\x05\xa5\xeb\x51\x0e\x2a\x99\x28\xbd\x56" \ +"\x5c\x5a\xef\x4d\x35\x88\x41\x70\x5e\x82\x68\x47\x37\x4f\x16\xfa\x22\xb2\x0e\x5b\x18\x91\xfa\x04\xc5\x60\x48\x76\x8e\x1f\x53\x89\x0e\x39\x73\x24\xca\x90\x0a\x13\x7b\xb0\x17\x5d\x23\x5a\x91\x49\xa3\x7c\x42\x9c\x08\x52\xf3\x16\xcc\x3b\x4d\x31\xde\x01\xf6\x07\x4b\x0f\xea\x6e\x09\xe8\x1d\x9c\xef\xfa\x58\x18\xf4\x7b\x0f\xa9\x42\xb4\xfe\xd2\xe9\x86\x1b\x64\xa2\x67\x9e\xdf\x95\xe2\xa7\x8c\x35\x22\x39\x69\xdd\x70\x74\x48\xcf\xa9\x62\xc8\xbd\x21\x48\xb5\xa2\xa6\x04\x1d\x62\x9d\xb8\xf4\xbc\x7f\xba\x23\xba\xca\x18\x15\xb9\xa0\x3f\x11\x70\x4e\x60\x31\x57\x3c\x9a\xd7\x31\xc4\xb3\x7a\x3c\xfd\x9a\x56\xb1\xe3\x46\x01\x50\xcd\x3a\x42\x67\x92\xaa\x6c\x22\x86\x95\x86\xa0\xe1\x98\x3f\x12\xc7\x65\x9e\xc7\xeb\x7c\x62\x69\x08\x3e\x64\x5c\xf8\x51\x3b\x6c\xbe\x9c\xd8\x6a\x67\x5a\x45\xc7\xa0\x15\x42\xcb\x7d\x9d\xbd\x08\x73\x0f\x9e\x4d\x69\x7c\xab\xb4\xe3\x86\x32\xd0\xf5\xfe\x23\xe7\xd7\xe7\xc1\xda\xd8\x44\xcc\xe5\xe9\x5f\x78\xb1\x69\x6c\x5c\x09\xb5\x77\xc4\x13\x61\x05\x91\xfe\x70\x9c\x46\x09\x44\x27\x54\x21\x50\x02\x15\xe4\xb8\x91\xda" \ +"\x13\xca\xe7\x90\x03\x1d\x16\x0e\x92\xc1\x5a\xd8\x3f\x5f\xc5\x46\xc6\x44\xeb\x84\x10\x1f\x64\xb3\x13\x69\x13\xb2\xd2\xde\x76\x94\x25\xca\x32\xde\x54\xf6\x59\x24\x19\xb7\x50\xaf\x4f\x9a\x26\x77\x59\x7d\x85\x38\x15\x3d\xbb\x7b\x50\xe0\xbb\x0f\x54\x2e\x13\x01\x18\xf6\xfa\x20\xe2\xc1\x31\x76\xfc\x01\x2f\xac\xa1\xaf\x3c\x71\x38\xf8\xc6\x64\x75\x4e\x8a\x9a\x28\xe7\x76\x78\x17\xdf\x08\xef\x91\x33\x2b\x52\x92\x53\x81\x2b\x92\x4b\xab\x14\xba\x9d\xae\x89\xcd\xbb\xc6\x25\x0a\x6c\x41\x9a\xd4\xcf\x3f\xb2\x0b\x33\x05\x3e\xac\x7a\xdb\x93\x10\xdf\xf3\x86\x92\xa1\xad\x76\x71\xb9\xd4\xc7\x1d\x53\x05\xf1\x2a\x36\xa0\x39\x64\x74\x6f\xda\xc1\x27\x42\x43\x8d\xa1\xb3\x8d\x36\x57\x10\x2b\x0f\x5d\x29\xf0\x3e\x42\xe7\x3b\x2a\x30\x2e\xcf\x8d\x1b\xa0\x9c\xf7\x8a\x81\x82\x44\x22\x42\x45\xb1\x2d\x6c\x1a\x24\x32\x6d\x2e\xee\x52\xbb\xdb\xa6\xe1\x73\xcc\x79\xe4\x7a\x5c\x41\x43\x45\xa2\x68\x0a\x75\x11\x21\x71\x6e\x0a\x09\x02\x29\x18\xe3\xad\x31\x0a\x02\x93\x73\xc5\x5d\x85\x8b\x56\x26\x8a\x66\x5c\x11\x5e\x73\x4a\x65\x05\x0c\xde\xba\xe5\x10\x7e" \ +"\x10\xea\x69\xbf\xb8\xb6\x1b\x3b\x98\x76\xb3\x72\x4e\x41\x0f\x15\x2b\xd7\x07\xd7\x6e\xcf\x98\x80\x0e\x6a\xbc\x49\xe6\xb7\x17\x65\x5c\x5f\xfa\x73\xf5\x28\x3a\xa7\x9d\xc9\x01\xe5\xe9\x27\xf3\x67\xfd\x68\x87\xf8\xdb\x4a\x7f\x5b\x87\xe0\xf0\x2a\x06\x46\x46\x30\x17\x34\x4e\x0c\xd4\xcb\x37\x86\x6c\x6b\xb9\xed\x81\x78\xea\x36\xf3\xfc\xe7\x13\xbe\xbe\x2e\x30\x73\xc8\x91\x77\xc3\x8c\x7a\x15\x55\x78\xbd\x21\xd0\x3b\x27\xb5\x39\x37\x80\x90\x95\x78\x41\x4d\x71\x4b\xcb\xc2\xfb\xd9\x4d\x6e\x38\x36\x5d\xf0\x65\xdb\x34\xae\xa3\x99\xc1\x18\x10\x70\x67\xb2\xfc\x39\x02\x07\x37\xb8\x50\xb0\xf8\x80\xec\x49\xfa\x42\xda\x3f\x10\xe6\x95\x20\x95\xed\xc7\xa8\x51\x93\x3f\xd3\xfb\x70\xdf\x3e\x5c\x3c\x72\x9c\xcb\x0c\xe1\xe8\xfa\xa6\x7b\xc2\xe3\x38\x52\x04\x68\xa8\xaa\x26\x5d\x7a\xe8\xcf\xe4\x44\x3a\xf7\xa2\x60\x80\x14\xf9\x72\x5d\x25\xc7\xe5\x98\x86\xa8\x0e\xd4\x99\x89\x1f\xf1\xbd\xa3\xdf\xf7\xc4\x16\x43\x1b\x69\x0a\xeb\x1c\x18\xb1\xf9\xe6\x13\xf7\x91\xe4\x97\xc3\x11\xc9\x5d\xe2\xa7\x4c\xe3\x55\xcf\xc8\x8b\x25\x94\x28\xf3\xd6\x3c\x37\xf1" \ +"\xb7\x7e\xa0\x61\x06\x81\x68\xb6\xcf\xfa\x4d\x7b\xeb\xd3\x9e\xab\x34\xab\xba\x35\x79\x18\x89\x69\xa4\xf7\xac\x84\xc9\x1f\x87\x7b\x00\xa4\xa4\xeb\xa7\x67\x3f\x28\x36\x66\x2e\xc5\xb9\xc2\x0e\xc3\x9f\xb6\x78\x04\x24\x0e\xc2\xdb\x9b\x17\xe9\x94\xa9\x71\x9e\x5c\x67\x44\xf7\x85\xd6\xfc\x09\xdc\x32\xc6\xfb\x4b\x22\x0a\x73\xd1\xac\x93\xa8\xb9\x51\x46\xae\x9b\x50\x6f\xf6\x4e\xc7\x9b\xc0\x02\xf1\xa2\x7b\x7b\x4d\xe4\x65\x16\xf1\x59\xf5\x3f\x03\xeb\x4c\xa2\x14\x0c\x51\xe4\xfe\x32\x92\x4c\x95\x70\xe2\x58\xe7\xa7\xe5\x1b\xfa\x15\x62\x54\xeb\xfb\xd5\xee\xd1\x6f\x22\x90\xb5\xbe\x16\x3c\x70\xf4\x62\xf1\x13\x33\xa3\x04\xc6\x08\x32\xc2\xc8\xf1\x9b\xc0\x61\x5f\xad\x31\x5e\xa9\x70\x15\x57\x17\xe5\xe2\x4b\x3c\x86\x7e\x15\x0a\x56\x54\xee\x71\x13\x4d\xcd\x03\x9e\x69\xf1\x62\x56\xed\xe9\xbe\x61\x88\xca\xea\x93\x79\xfd\x9c\xb0\xee\xde\x47\x23\xb9\x7f\xd4\xd3\x00\x56\x81\x83\x5d\x6f\xa7\x79\x8a\x45\xfb\x04\x5a\xe5\x2b\x30\x90\x8a\x00\x30\xf9\xca\xcb\x2e\x75\xaf\x1b\x60\xe6\x77\x5d\x9c\x81\xba\x7a\x85\x72\xa0\xc4\x32\x51\x61\x3f\x0d\xbc" \ +"\x92\x3f\x04\xdc\xde\xa5\x09\xec\x7c\x75\x91\x5b\xf4\xba\xe9\x23\x4e\xf1\x2d\x26\x7f\xb3\xa5\x14\xfd\x83\xab\x29\xe6\x9e\xa2\x53\x32\x13\x17\x53\x80\x79\x43\xf8\x11\x91\x62\x70\xbe\xfa\xed\xf3\xf8\x40\x92\x29\x10\x2c\x9a\x21\x3c\xa2\xa1\x9c\xe5\xb0\xac\x31\x2a\xf0\xeb\x55\x5a\xa2\x97\xaa\xb7\x1b\x15\xb7\x28\x86\xbb\xc1\x4b\xb7\x4c\x3f\xeb\x1b\x5a\x85\x1a\x8a\x53\x96\x4d\xce\xe9\xa6\xcc\x5a\x7d\xd3\x85\xe5\x0a\xa6\x0c\x92\xb8\x98\x6b\xf2\xf5\x34\x91\x9a\x22\xf9\x0d\x66\xfd\xd1\x14\x03\xe1\x58\x9c\x89\x1e\xb6\xce\xd3\xff\x95\x27\x40\x85\x10\x7d\x05\x73\xdc\x33\x7a\xf2\x79\xde\xd4\xef\xed\xd0\x1f\x48\x62\x24\x83\xb9\x09\x7c\x0e\x37\xec\xc4\x26\x44\x52\x11\xc5\xff\xa8\xc7\x9e\x5e\x34\x3a\x7e\x64\x39\x76\xb8\xd6\x2a\x41\xf9\x9c\x80\x52\x8b\xea\x3f\x77\x37\x59\x6c\xcf\xd1\xe2\x22\xc6\x86\x36\x83\x9a\x57\x60\x1f\x0b\xf1\x01\x0b\x61\x3d\xa7\x14\xdf\xbc\xa3\x1f\xfa\xbd\x0d\x1d\xc4\xd1\xda\x77\x66\x0d\xac\x95\x95\xdb\xfb\x40\xee\xd3\xd4\x88\x52\xed\x96\x8c\xbc\xc9\x7b\xbf\x53\x85\xc1\xfd\x19\x1b\xf6\x48\x3c\xd4\xe3\xf1" \ +"\xd1\xce\x8e\x1d\x0b\x0b\x92\xb6\xcb\xd6\x19\xc0\xec\xc5\xb0\x06\xd8\x69\x91\xbf\x73\xa1\x6b\xaa\xc2\x79\x94\xcd\x41\x74\x9d\x60\xad\xd9\x1e\x60\xae\xef\xb2\x97\x79\x2e\x03\x56\x41\x20\x78\xc3\x42\x56\x90\xce\x5b\x24\x94\x2a\xd8\xd0\xa4\xcb\x95\x45\xe6\x31\x4e\xe0\xb1\x17\xaf\x67\xbf\x6f\xb5\x82\xff\xd7\xbd\xad\x86\xbd\x40\x24\xe2\x86\x59\x74\x8a\x5c\x51\xf6\xca\x0a\xf3\x15\x51\xa5\xd2\xeb\x31\x63\xd9\x13\xb8\x36\x47\x66\x84\x31\x87\xe4\x9c\x43\xaa\x26\xad\xc8\xef\xf4\xff\x41\xd3\x64\xa1\x76\x6f\xda\xdb\x57\x17\x39\x09\xf6\x66\xfc\x9d\xcd\x62\x0c\x61\xc6\xb7\x8d\xdf\x9a\x17\xb4\x7b\x50\x9c\x90\xe7\x5f\x2a\x87\x1f\xf4\xa4\x79\x8a\x74\x9a\xcf\xde\x8a\x20\x54\xb9\x38\x72\x09\xf4\x0b\xd5\xed\xa6\x5b\x1f\xd9\x14\xb3\xa8\x79\x8b\xed\xb5\xdd\x5a\xae\x02\xb0\x22\xd2\x82\xf1\x82\xf0\xb2\x59\xb0\x82\xb9\xf3\x34\x65\x74\x70\x06\x3c\x54\x06\x6e\x1d\xf6\x42\x0a\xa4\x82\x2e\x4b\xa3\xb3\x2d\xfa\x20\x39\x30\x4a\xa9\x85\x2c\xa7\xf1\x67\x1f\x77\xf3\x4a\xd0\x04\xa2\x11\x0b\x48\x7e\x0a\x51\x75\xbc\x67\xde\xa3\x4e\xce\x48\xd8\x49" \ +"\x02\xdd\xe6\x7a\x6b\x8d\x7e\x01\xec\x3f\x33\xa9\xa0\x0e\xa5\xd0\xae\x09\x5b\x4a\xfc\x92\xc6\x4f\xee\xaf\x27\x66\x4b\x96\x28\x6d\x8f\x75\x4d\x99\xea\x52\x26\xa2\x17\xf2\x6b\x7c\xd9\x0d\x33\x37\x5c\x01\x1c\x8a\x3e\xd1\x45\xde\x3f\x3e\x96\xdd\x4a\xe8\xdc\xb5\x15\x24\xcb\xb6\xc1\xb7\xad\x71\x9d\xf1\xd0\x83\xac\x00\xb0\x37\xe5\x3f\x36\x54\xc5\x69\xc4\x9a\x3c\x34\x32\xbf\xe6\xca\x81\x55\xeb\x4b\xf5\xac\x3a\xe6\x00\xfb\xfa\x68\x7b\xf7\xe0\x78\x76\x1e\x32\xdf\x90\xe9\xf3\xd5\x3a\xe4\x7c\x18\xa8\xc2\x18\xc0\x04\x3f\x6b\x27\x37\xca\xc4\xfe\x95\x8d\xbd\x88\xda\x6c\xcb\x64\xc6\x79\xf0\xfc\xd0\xc8\xe6\xb2\x75\xc7\x02\x37\xa5\xd6\xd2\xf6\x8e\xb2\x3f\x56\xf9\x9c\x64\xac\xca\xc5\x94\xde\x4c\xb9\xdd\xf8\x47\x07\xe7\xe0\x9e\xec\x1b\x2c\x35\x3a\xb5\x41\xb0\x92\xdf\xfe\x05\xf9\xcf\xda\xa0\xd4\xf5\x0e\x72\xf6\x99\x8b\x37\xe6\x59\x8f\x7d\x85\x67\xf9\x7b\x5b\xe5\xc3\xd6\x41\xfb\xdb\x0b\x30\xa7\x48\x09\x83\x6e\xcf\xf4\xc5\x9f\x17\x33\xa1\x87\xfb\xdc\x34\xf2\x7a\xc7\x15\xe7\x22\xb9\x54\x8c\x70\x03\xa4\xe7\x40\xa2\xc0\x67\xb6\xa2\x70" \ +"\x02\x8e\x16\x94\x3e\x47\x4f\xe8\x55\x26\x0f\x57\xe6\xe8\x70\xcb\x5e\xe6\xac\xe9\xdb\x9e\xf6\x57\x3d\x9b\x16\x0e\x9d\x17\x3d\x63\xc4\x61\x46\xd8\xad\xec\xd3\x78\xc5\x1c\xe7\x2f\xd7\x42\x47\x2e\x42\x1c\x1d\xdf\x4d\xad\x90\x52\xdc\xde\x63\xe5\x4a\x35\x58\x74\x7b\xa2\xf0\xa8\xd8\x8e\xcd\x90\xb7\x7f\x87\x04\xa2\x5b\xb0\x4e\x1a\xb2\xf9\x68\xc3\x4c\x69\xce\x8f\x14\x9e\xdc\x16\x43\xc9\xed\x4e\xf1\x38\x6f\x3f\xa0\xf0\xa8\x83\xfd\x3e\x08\x33\x58\x2b\xae\xd9\xeb\xf3\x47\x32\xd2\x07\xeb\x38\x3f\x80\x6f\x20\xf4\xbb\xd9\xaa\x4d\x98\x41\x07\xc8\x1e\x2f\x53\x7e\x8b\xaa\x8e\xdb\xb8\x9c\x36\x66\xf9\x5e\x20\x02\xcc\xce\x4d\xe6\x3c\xb8\x8f\xa7\x6e\xf1\xcb\x3c\x2c\xae\x80\x96\xba\xd7\xda\xbd\x57\x6b\xd8\x54\x4c\xa6\xab\x5b\x17\x10\xd0\xd3\xb5\xea\x3d\xcb\xe0\xac\x80\x81\x42\x07\xf9\x00\x4b\x9d\xeb\x31\xf4\x9a\x9d\x6b\xcd\x46\x92\x26\xbc\x06\xda\x85\xe7\xcc\xa8\xea\x85\x11\xf5\x55\xfd\xa3\xf2\xa8\x38\x09\x63\x8e\xec\xed\x43\x14\xe2\x3c\x04\x56\x53\xd0\xf3\x13\x7f\xa8\x06\x9c\x43\xb3\x42\xaa\xf2\xd3\xaa\xc7\xbc\x47\xe7\xbf\x43\x2a" \ +"\x6d\x25\x75\x9a\xe7\x74\x3f\xe8\xce\x6b\x8d\x11\x7f\x8f\x4f\xf7\xa0\x3e\x97\xea\x74\x7e\x0e\xdf\x08\x05\x34\x52\x08\x63\x11\x09\x07\x04\xd0\x6a\x0b\xd0\x9c\x9d\x55\x33\xec\x80\x29\x42\x63\xf3\xdc\x99\x83\x6f\x4e\xbd\x5f\xdb\x33\x64\x29\x96\xbc\xda\x23\x25\xb0\x1f\x7a\xfc\xcf\xde\xd6\x8e\x5f\x13\x88\x9f\xc3\xd1\x27\xb6\x13\x61\xb9\x48\x53\xa5\xd0\xf9\x53\x04\xf4\xe6\x1e\x07\x0d\xa1\x5a\xc8\x79\x8a\x43\x97\xfc\xc5\xa5\x2c\xd7\x09\x51\x76\xb3\x9f\x0f\x03\x9c\x69\x97\x68\x6d\xa1\xca\x8f\xc7\x29\xbb\xac\x9a\x40\x69\x45\x43\xad\xe2\x22\xea\x6f\x45\xf4\x2d\xe6\x31\x0b\x12\x9e\x38\xb8\x37\x7c\x2e\xfc\xd7\x6d\xec\x7c\x9c\xac\x94\x9f\x2c\x93\x81\x32\x31\xe6\x80\xd5\x89\xa1\x7d\x8c\xde\x24\x5a\x75\xdf\x92\xed\x7a\x27\x76\xbc\x5d\x0b\x28\x31\x72\xe6\x50\x1f\xdd\x3a\xc7\xae\xc0\x70\x1f\xec\x62\x38\x4c\x1b\xc7\x4e\x1c\x30\x3e\xf6\xcf\x1e\x55\x32\x1f\x04\x8f\x3a\xf1\x83\x53\xcb\x46\xf1\x7c\x96\xa0\x58\x1e\xe3\xb1\xd5\x4b\x8b\x7a\x53\x53\x29\x61\x8c\x4e\x9d\xbc\xac\x55\x34\xca\x4c\x2f\x91\x4c\x7e\x90\xe4\x31\xef\x67\xc4\x95" \ +"\xcb\x85\x9f\xc9\xd7\xf1\x47\xf5\x72\x31\x7d\xe4\x16\xc0\xeb\xe6\xf6\xf7\x64\x6e\x4c\x4a\xd6\xe2\xdd\x78\x8c\xfa\x6c\x09\xcb\x28\x5c\x13\xb8\x88\x56\x4c\xfa\xb1\x40\x4c\xd6\x4f\xbe\x56\x08\x83\xb2\x00\xc8\xab\xf5\x90\x5e\x02\xec\x0b\xbb\x77\xa5\x53\x82\xfc\x31\x7e\xfe\x83\x26\x2b\xf5\xaa\x35\x07\xb7\xcd\x54\x47\x10\x7f\x56\xf9\x1f\xa9\x41\x21\xcf\x92\x6f\x9b\x2b\x91\x55\xfa\xd8\x26\x5f\x12\x81\xba\x0e\x03\x9e\x2b\xb7\x2c\xcd\x5a\x25\x8d\x1b\x82\x73\x04\x79\x43\x71\x2b\x6d\xfb\x47\x67\x20\x81\xa3\x49\x74\xfc\x20\x95\x11\x96\x75\xa8\xda\x38\xa3\xad\x7d\x54\x67\x88\xc3\x59\x2e\x1b\x2d\x99\x06\xb8\x51\x5d\x83\x1c\x2a\xab\x57\xb1\x87\x6d\x18\x4e\x50\x67\x6e\xa8\x03\xfb\xa5\x8b\xab\x19\x4d\xa6\xfa\xc1\xa6\xa8\xc3\xa0\x0c\x19\x6e\x24\x00\x84\xf7\xc7\xc3\x1e\xb1\x0e\xb0\xc5\x3a\x8e\x5d\x2b\x97\x7e\x1c\xb8\xe7\xb3\x71\xe3\x1a\xa5\x62\xb4\xb7\xda\xb6\x96\x7d\xe7\x66\xe7\xce\x27\x39\x79\xc1\x2b\x0b\xfe\xad\x1d\xfb\x2d\xab\x6a\x57\x72\x26\x3a\x99\x48\x54\xc1\x24\x02\x8e\xd7\x79\x93\xa0\x0b\x25\xf3\xd5\xd9\xb5\x98\x70\xbf" \ +"\x9b\xd9\x88\x75\xaf\xb6\x7d\x86\xda\x3a\xd4\xef\x27\xfa\x77\xdc\x71\xd6\x8f\xcc\x7c\x0b\x99\xc8\x9e\xd7\xfd\x28\x23\x11\xe8\x2d\xd9\x2f\xbf\x9f\xc7\x52\x29\x6a\x9e\xf4\xde\xfe\x85\x6d\x97\x2b\xbb\xcb\xa5\x3d\xa3\xcd\x07\xd9\x0c\xfc\x7b\x5a\xff\xff\x58\xdd\x7a\x4c\xad\xb9\x55\xb9\x21\xe4\xe2\xa1\x48\xd9\x22\xc5\x8c\xbe\x12\x07\x8e\xb1\xcb\x31\x5d\x5b\x0c\x0c\x1d\x23\x64\x88\x3a\x16\xae\x31\x47\xd1\xda\xc7\x7d\x33\x6e\x75\x2d\xcd\x8d\x51\xc0\x94\xd3\xee\xda\x54\xe3\xbf\xa0\x31\x6e\xcf\xbe\x08\x9c\xb8\xa7\x94\xe4\x45\x13\x27\x03\xd2\xcc\xc4\xe6\x7b\x40\x7b\x85\x73\x21\x55\x0f\x2d\x90\xda\x1f\xc0\x22\x3c\xd0\xa6\x71\x97\x7a\xf9\xab\xcf\x08\xa4\xcf\x8a\xf6\xd9\xfb\x22\x1b\x91\x90\x39\x3c\xa5\xcb\x75\xc7\x50\x8d\xda\x24\x41\x18\x73\x21\x98\x8b\x98\x22\x48\x63\xc0\xdb\x31\x41\xbb\xd9\x0e\xd0\x38\x3e\x8f\x0c\x33\xe1\xbb\x26\x13\x72\x53\x76\x75\x11\xf9\xe0\xb9\xe1\xed\x47\x4f\x43\x4b\x33\x00\x5c\x7b\x9b\x7a\x9a\x69\x65\xeb\x11\xa0\x23\x98\x6c\x2d\x97\x9a\x5c\x95\x3f\xff\x4d\x99\x68\x62\xd0\xfb\x70\xbd\x26\x66\xcd\x75" \ +"\xff\xe8\x96\x6d\x33\x46\x05\x0b\xe0\x29\x8d\xc8\xe3\xaa\x01\xdc\x22\x67\x70\xb9\xa9\xcf\x8d\xb7\xac\x3d\x81\x71\x7e\xc8\x3b\xc5\x5d\xf5\xf0\x3a\xe8\x28\x5a\x7d\x25\x86\xd2\x52\x76\xea\xc8\x73\xa9\x7c\xbc\x01\xac\xec\x1f\x4f\xd3\xd5\x92\xc3\xce\x69\x39\xf1\x3b\xed\x91\x20\x06\x18\xfd\x17\x3c\xd3\x02\x5e\x2a\xbe\xb4\xd5\xb1\x17\xa7\x68\x03\xe2\xab\xd0\x5f\x60\x39\x35\x8d\x73\x58\xae\x0a\xce\xea\x96\xb6\x9d\xf2\x5d\x61\x50\x09\x9a\x98\xa6\x5e\x8d\xee\xd4\x44\xe7\xf4\x00\x24\xa7\x02\x09\xa9\x10\x97\xaa\x21\x33\x01\x69\xd2\xc2\xe0\x92\xdd\xe3\x89\x3f\x90\x0e\x05\x8c\x1e\xc1\xcb\x2f\x5a\x14\xe9\xa9\x42\xc0\x5b\xfc\xa1\x8c\x43\xca\x0c\x18\xbe\xf2\x2e\xd0\x79\x08\xc2\xa4\xa4\x7d\xd8\xc2\xf2\x7d\x83\x23\x05\x2d\x12\x98\x9d\xf0\x23\x38\xf6\x90\xaf\x02\x07\x7b\x0d\x9e\xa8\x73\xdd\xc3\x36\xec\x23\x84\xf6\x07\x64\x6c\x78\x11\x17\xd2\x3d\xee\x26\x49\x95\x1c\xf9\x1d\x05\xe8\x1c\x83\x54\x4f\x9b\x1a\x52\x60\x96\xdb\x7a\xa7\xe7\x38\xe9\xb0\x9a\xd5\x7e\x0e\x9b\x0d\x44\x9d\x19\xec\xf4\x40\x7d\x4a\xf7\xf1\x7b\xb1\x66\x2b\xf4\x7a" \ +"\xad\x4b\x84\xf4\xf8\xec\xf6\xa1\x8a\x44\x56\x02\x34\x79\xe8\x60\x64\xcf\xee\xdb\x40\xc5\xa2\x08\x61\x90\x59\x79\x42\x92\xa6\xe9\x07\x91\xd9\xdf\x33\xfe\x80\x01\xd3\x01\x00\x00\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0a\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0a\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0a\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30" \ +"\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0a\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0a\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0a\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0a\x63\x6c\x65\x61\x72\x74\x6f\x6d\x61\x72\x6b\x0a\x80" \ +"\x03"}; diff --git a/source/blender/src/Makefile b/source/blender/src/Makefile new file mode 100644 index 00000000000..4741f695a75 --- /dev/null +++ b/source/blender/src/Makefile @@ -0,0 +1,106 @@ +# +# $Id$ +# +# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# +# + +ORGLIBNAME = src +LIBNAME ?= $(ORGLIBNAME) +DIR ?= $(OCGDIR)/blender/$(ORGLIBNAME) + +CSRCS ?= $(wildcard *.c) +PUB_CSRCS ?= $(CSRCS) $(wildcard pub/*.c) +CRE_CSRCS ?= $(CSRCS) $(wildcard cre/*.c) + +OBJS = $(OCGDIR)/blender/makesdna/$(DEBUG_DIR)DNA.o + +ALLTARGETS = creator publisher + +include nan_compile.mk + +# Cflags stuff ------------------------------------------ + +CFLAGS += $(LEVEL_1_C_WARNINGS) +#CFLAGS += $(LEVEL_1_C_WARNINGS) -diag_error 1196 + +ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows")) + CFLAGS += -funsigned-char +endif + +# PreProcessor stuff ------------------------------------------ + +CPPFLAGS += -I$(OPENGL_HEADERS) +CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) +CPPFLAGS += -I$(NAN_GHOST)/include +CPPFLAGS += -I$(NAN_BMFONT)/include + +# External interfaces of modules: +CPPFLAGS += -I../render/extern/include +CPPFLAGS += -I../renderconverter +CPPFLAGS += -I../blenkernel +CPPFLAGS += -I../blenlib +CPPFLAGS += -I../bpython/include +CPPFLAGS += -I../makesdna +CPPFLAGS += -I../imbuf +CPPFLAGS += -I../blenloader +CPPFLAGS += -I../verify +CPPFLAGS += -I.. +CPPFLAGS += -I../misc +CPPFLAGS += -I../../kernel/gen_system +CPPFLAGS += -I../../gameengine/SoundSystem + +# Only used by py_demo.c !!! +CPPFLAGS += -I../radiosity/extern/include + +CPPFLAGS += -I$(SRCHOME)/sumo/include +CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include + +CPPFLAGS += -I$(NAN_DECIMATION)/include +CPPFLAGS += -I$(NAN_BSP)/include + +CPPFLAGS += -I$(NAN_BLENKEY)/include +CPPFLAGS += -I../readstreamglue +CPPFLAGS += -I../include + +ifdef NAN_BUILDINFO + CPPFLAGS += -DNAN_BUILDINFO +endif + +ifeq ($(OS),linux) + ifeq ($(CPU),alpha) + CPPFLAGS += -I$(NAN_MESA)/include + endif + ifeq ($(CPU),i386) + CPPFLAGS += -I$(NAN_MESA)/include + endif + ifeq ($(CPU),powerpc) + CPPFLAGS += -I/usr/src/MesaCVS/include + endif +endif diff --git a/source/blender/src/blenderbuttons.c b/source/blender/src/blenderbuttons.c new file mode 100644 index 00000000000..b4aedcc9e95 --- /dev/null +++ b/source/blender/src/blenderbuttons.c @@ -0,0 +1,1210 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +/* DataToC output of file <blenderbuttons> */ + +int datatoc_blenderbuttons_size= 37540; +char datatoc_blenderbuttons[]= { +137, 80, 78, 71, + 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 1,190, 0, 0, 0,242, 8, 2, 0, 0, 0,189, 2, 55, 29, 0, 0, 32, + 0, 73, 68, 65, 84,120,218,236, 93,121, 92, 84, 85,251,127,238,189,179,177,175,130, 10,138,128,184,164, 40, 8,238,187,130,146, + 75,101,130,154,246,166,239, 91, 57,152,190,165,102,106,153,111,249,102,165,253,114,169,232, 21,244,173,172,183, 69, 69, 91,204, + 76, 19, 76,115,201, 13,247, 13, 68, 80, 4, 4,129, 25, 6,152,253,222,123,126,127, 28,184, 14,195,204,157, 59, 3, 40,213,253, +126,248,232,157, 59,243,220,229,220,115,191,231,123,158,115,206,243, 16,147,158, 94, 9, 34, 68,136, 16, 33,194, 25,144, 98, 17, +136, 16, 33, 66,132, 72,157, 34, 68,136, 16, 33, 82,167, 8, 17, 34, 68,136,212, 41, 66,132, 8, 17, 34,117,138, 16, 33, 66,132, + 72,157, 34, 68,136, 16, 33, 66,164, 78, 17, 34, 68,136, 16,169, 83,132, 8, 17, 34, 68,234, 20, 33, 66,132, 8,145, 58, 69,136, + 16, 33, 66,164, 78, 17, 34, 68,136, 16, 33, 82,167, 8, 17, 34, 68,180, 16, 36,246,190,216,243,229, 91,220,182,107, 33, 66,240, + 17,156,181,109,206,121, 45,109, 93,190,108,167,174,220,234,140, 46,156,215,181,251,181,121, 94,151,143,240,176,158,145, 88,175, +196,122,213,118,234, 85,203,168, 78,171, 18,180, 87,160,246,108,241,159, 11, 21,171,153,231, 21, 88, 15, 92,171, 61,173,129,166, +247,251, 96,206,222,130,229,252, 32,109,197,122, 37,214,171, 22,183,109,121,213,201,145,247,131,124,228, 86, 45, 6,126,228,194, + 91,105, 43,219, 7, 86,191,155,217,202,113,230,194,207,222,244,140,194,109,185, 95,206, 93,182, 6, 0, 54,175, 93,142,119, 10, + 47,103,108,232,172, 45, 7,203,243,138,245, 74,172, 87,127,208,122, 69, 58,172, 46,206, 18,232,164,167, 87,226, 63, 23,158,244, +195, 13, 30,106,245,252, 30,204,233, 44,111,217,229, 18,112,161, 15,203,221,102,115,238,215, 41, 91,171,226,197, 27, 98,189, 18, +235,213,195,173, 87,173,162, 58,255, 64,176,122,186, 46, 60,242,230,212,239, 7,239,103,105,230,205,138, 16,235,149, 88,175, 90, + 94,117,182, 5,112,222, 25, 23,188,197, 15,247,145,187,236,140,123, 96,142, 17, 92, 50, 92,191, 6,111,252, 69,222, 16,177, 94, +137,245,234,207,172, 58,185,135,221,156,114,119,202, 81,210,204, 46,149,149, 83,201,133, 83,187,112,205,205,151, 6, 46,120,133, + 38, 61,189,114,207,151,111, 61, 96, 55,165, 88,175,196,122, 37,170,206, 86,175,223,150,110, 29,129,237,109,115,234,183,149, 23, +201,101, 79, 28,119,156, 7, 57, 40, 55,119,217, 26, 23,238,186,153,247, 43,214,171, 7, 83,175,240,195,229, 30,177, 88,175,254, +228,170,179, 69,116, 1,215,136, 53,179,169,116,161,173,126, 40,197,229,154,160,176,116,171,111, 94,187,220,169,155,253,195,245, +194,196,122, 37,214,171, 63,179,234,108, 78,253,126,144, 62,157,182,112, 94, 17, 98,189, 18,209,230,168,211,170,231,248,128,189, +227, 45,114, 34,167,170,157,101,151,217,178,163,228,218,155,246, 0, 76, 90, 4, 86,238,124,215, 94,105,167,234,198,195, 29, 70, +248,171,213,171,135,229, 55,252,235,212, 43, 73, 91,123,171,155,158, 84, 72, 41,224,158, 84, 75, 45,152,107,230, 53, 11,127,228, +156,251,223,133,107,118,185, 73,227,206,107, 89,185, 93, 94,228,215,156,183, 75,172, 87,173, 90,175, 92,123,190, 98,189, 18, 8, + 66,156,183, 37, 66,132, 8, 17, 45,208, 97, 23, 33, 66,132, 8, 17, 34,117,138, 16, 33, 66,132, 72,157, 34, 68,136, 16, 33, 82, +167, 8, 17, 34, 68,136,212, 41, 66,132, 8, 17, 34,117,138, 16, 33, 66,132, 8,145, 58, 69,136, 16, 33, 66,164, 78, 17, 34, 68, +136,120, 8,184,191,154,104,242,240, 80,225,102, 63, 30, 41,182,252,104,101, 91,120,229,119, 32, 13, 29, 66, 67,106,245, 90,117, +149,182, 91,207, 97,194,109,143,158,189, 9,172,188,188,164,196,195,205,195,207,223, 99, 96,124,184,112,219,230, 92,115, 73,105, +166, 76, 65,203, 21, 18, 74, 66, 49, 64,120,203,166, 8,183,245,245,143,243,243,243,115,115,115, 3,130,184,122,105, 55,255,121, +221, 66,174, 11,191,102,125, 73, 15,203,143, 29,221,203,133,219,150,234,130, 27,217, 26,157, 56,111,169,188,209,121, 67, 76,185, +194,109, 75,100,221,219,130,109, 47, 91,229,188,118,109,230,178,101, 41, 77,247, 95,105, 92,206,110,161, 38, 39,158, 81,177,172, + 81,221, 8,113,226, 25,253, 88,210,232, 25, 25,140, 30,194,109, 21,114,109,163, 67, 61,150, 38,220,118,242,238, 5,150, 31, 95, + 46, 75, 23,110,187,174,125,106, 43,189,131, 15,204,182,133,169,211, 38,158,191,246,198,150,158,171,132, 28,168,224,242, 47, 4, +176,158,114,183,207, 50,190,254,252,243, 15,134, 38, 12,165,181,186, 71,122,140, 96, 89,152,191,148,121,228,145,238,249,249,183, + 13,122,218,171,195,208,166,182,199,206,221, 67, 64,212, 25,245,202,197,171, 87,125, 56,190,244, 74, 14,128, 98,239,133, 98,146, +132, 15,222,124, 61, 47, 47,183, 75,151, 48,185,155, 36,192, 79,222,212,246,218,143, 63,203,229,114,119,119,119, 47, 47, 47, 95, + 95,223, 0,255, 0,127,127, 63, 31, 31, 95, 79, 15, 15, 74, 34, 97, 89, 70,175,215,215,214,212,158,215,105,236, 93,121,126,222, +118,185, 66,239,233,165, 80,184,203, 37, 50,138, 32, 9, 82, 66, 33,234, 23, 51, 77,200,232, 68,254,187, 46, 44, 34, 3, 3, 3, + 21, 30, 6,163,209, 64, 82, 36, 65, 64,199, 78,195,171,171,213,186,218,203,173,215,220,109,222,188,121,238,220,185, 98,179,239, + 16,246,136,210,217,223, 0, 64,123, 55,247,146,146, 18,169, 66,206,186,187, 63,200, 91,208,169,206, 31,207,222,102,185, 39, 33, +101, 77,219, 44,237,255,125,241,133, 92, 38, 99, 89,214,195,211,115,242, 99,143,253,133, 84,103, 83,220,216,186, 2, 6, 74,158, +215,124,179,197,231, 41,254,163,164, 60,214,213, 56,198,223, 92, 87, 45, 97,200, 1,125, 66,103,207,126,169,222, 29, 64,194,137, +223,183, 6,118, 14, 97,235,106, 70, 14,140, 46, 45, 85,103,157,163,173,108,149,202,119, 64,230, 67,184,123, 35, 10, 93,184,250, +247, 79,183,237,199,251, 89, 22,146, 6, 15,134,186, 50, 0,175,155,151,174, 73, 3,125,135, 14,234,237,233, 27,212,244,236, 4, + 16, 4, 65,144, 4, 73,145,148, 68, 66, 73,164, 82,169, 84, 42,145, 74, 37, 18, 9, 77, 19, 36, 73, 17, 4, 97,239,202, 47,156, +219,236,227, 35,241,242,244,108, 23, 20,224,233,229,206, 32,198, 96,212,155, 25,198,221,211,189, 93, 80, 7,134,189,117,231,122, + 23,155,134,251, 14,228,121,121,121,250,250,250,233,116,110, 58,157,187, 66, 33, 39, 72, 0, 0,189, 94,175,211,233, 42,213,222, +149,149,149, 85,149,229, 67, 7,119,178,105,158,185, 54,147,191, 72, 19,230, 36,248, 5,251,217,228,205, 22,100,207,215,254,239, +255, 0,224,157, 87, 94,113,193,246,213,247,222, 3,128,119,151, 46, 21,110,114,185,164, 36, 47, 47, 15, 0,158, 28, 61, 90,160, + 73,198,142, 29, 0,192, 61, 65,132, 16, 65, 16,248, 95,252, 17,127, 59, 55,197, 6,253, 45, 91,150,194,207,140, 66,120, 51,220, +207, 95,111, 50, 2,128,204, 77, 97,210, 27, 88,173,174,178,236,110,135,232,104, 30,147, 14,145,221, 28,222,151, 79, 88,207,235, + 7,127,112,248,179,227,217,219,134, 37,204, 80,248,197, 8, 42,172, 20,149,195,159, 76,155, 54,109, 71, 74,150,205,175, 70,103, + 85,112,219,143,248, 74, 0,224,158,129,213,211, 8, 0,180, 52, 2,128,140,129,190,221,188,164, 54,109,223,127,255,253,215, 22, + 46,121,252,201, 41, 6,131,254,131, 13,235,211,210,210, 22, 44, 88,240,215,165,206,168, 57,111, 47,221,186,226,189,129,215,159, + 7, 7,236,105,172, 83,181,239, 58,118,245, 43, 79,110,205, 56,132,247, 28, 62,158,174,213, 25, 39, 36,188, 52,100,232,156, 25, +211,198,184,185,201, 77, 12, 93,171, 51,117, 27, 52,179,137,245,109, 48,193,147,179, 54, 61,191,184,190, 35,144, 52,100,148, 66, + 33,255,254,224,254,189,199,126,255,226,179,255, 24,244, 70, 25, 37,241,116,151,121,203,152,252,162, 50, 43, 99,132, 0, 1,106, +248, 23, 33, 4,136, 69, 8, 33, 22,177, 12,195, 48, 12, 67,211, 52, 77,211, 54, 47,251,228,239,155,131,218, 81, 94, 94, 30,157, + 58,117,238,222, 51,202,211,211, 93, 85, 93, 85, 90,118,183,162,170,146,165,145,135,187, 71,247,110,143,248,248, 22, 93, 62,225, +105,101,184,251,251, 83, 32,145,235, 37,164, 76, 46,211,233, 20, 58,157,155, 66, 33, 39, 8, 4, 64,232,116, 58,157,174, 78,167, +211,106,235,106,170, 42, 74,191,220,122,214, 39, 50,206,230,217,255,239,139,255,179, 87,158,175, 60, 99,155,203,212,106,181,229, +182,191,191, 63,230, 17, 63, 63,191,155, 55,111,102,102,102, 58,197,167,178,224,250,222,162, 26,192,207,101, 9,156,153, 57,127, +254,124,243,189,123, 66,120, 51, 40, 40,232,201,113,227,204,114,249,186,117,235,166,142, 25,131,137,143, 31, 4, 65,188,255,230, +155,245,253,202, 55,222, 88,183,106,149,205,109,123,230,150,236,185,118,109,102, 92, 92, 92, 86, 86, 65, 66, 66,132, 64,222,236, +209,190,131,175,183, 55,230,104, 15,133,219,221,138,123, 53,234,106, 79, 95,191,219,167,207,132,245,143,231, 49,124,108,238,146, +167,167, 78,142,234, 82,223,238,190,177,238, 35,238,171, 85, 47,255, 19, 0,138,126,206, 30,208,173,147,160,142,185, 64,222,172, +111,147,253, 29,253, 34,193,225, 49, 60, 36,196,133, 85,207, 18,222,129, 76,193, 5, 99,193,149, 60,149, 54,254,103,190,231,155, +158,145,177, 88, 57,255,153,231,254,145,249,213,182, 46, 93,186,172, 94,251,158,215,155,171,191,255,254,251, 39,158,120,226, 15, + 65,130,174,197,223,113,208, 97, 23,206,158, 0,178, 71,122,118, 39,201, 67,121,213, 85, 0,215, 52, 37, 55,164, 10,249, 15, 63, +125,168,171,100,102,253,125, 17,203,194, 99,147, 7, 51, 18, 79,123,198,121,121,215, 88, 22, 38,244, 37, 0, 58, 2,132, 25,140, +166,228,164,113, 10, 95,242,139,175,247,145, 36,236,220,182,149,162,107,123,134,201,243,139,160, 9,117, 34,150,101, 89,150,101, + 24,134,102,104,147,217,100, 52, 26,245, 6, 61, 65, 16, 36, 73,210,180, 89,167,211,233,244,122,155,227, 97, 62,222, 72, 42,149, +250,251, 7,116,141,140,234,214,181, 7, 73, 17, 52,195,222,171, 80, 25, 13,102,134,213, 86,148, 87,134,134,232,123, 68,245, 56, +123,238,123,128,246,150,134,114, 18, 33, 86,111,214,209, 90, 10, 20,114,153, 66, 33,151, 74, 37, 44, 75, 19, 4,161,213,233,238, +149,151, 94,185,120,166,234, 94, 41,203, 50, 36, 33,116, 32,238,211, 77,159,226,141,127,204,251,135,221,247, 34, 51,211,114,123, +241,226,197, 69, 69, 69, 4, 65,100,100,100,184, 80, 99, 62,254,248,227,242,242,242,157, 59,119, 78, 28, 49,194, 47, 40,200, 89, +243,119,151, 46, 85, 3, 32,132,210,210,210, 0, 64, 57,109, 26,255,239,243,242,242,158, 28, 55, 14, 0,100, 50, 89,183,110,221, +118, 29, 60, 40, 68,126, 10,161, 87,126, 44, 91,150,146,149, 85,144,147,147, 3, 0,220,191, 41, 41, 41, 14,121,179, 91, 80,176, +175,183, 55, 69,146, 47, 60, 61, 75,111, 48,174,251,228, 19,119, 55, 55,131,193, 96,208,235, 73, 9,117,231,220,185, 78,177,177, +246,108, 49, 63,222,184,117,203,242,163, 11, 24, 56,102, 70, 86,230,242,196,199,158, 69,242, 40,129, 38,196,180,250,246, 21,237, +240,179,183,199, 30, 30,241,149,220,174, 99, 14, 39,182,147,190,148, 81, 51, 43, 92,226, 23,228,144, 55,179,179,179,187,116,232, +248,220, 11,169,203, 23, 45, 77,251, 44,125, 64,191,126,233, 31,165, 47, 92,186,228,171,193, 3, 47, 93,186, 20,205, 43,207,219, + 26,111,130, 51,129,168, 37, 86,158, 77, 91, 79, 79, 82, 82,199,132,148, 58,100, 79,150,162, 40, 0, 0,240, 6, 8,245, 9,233, +126, 59,119,231,166,140,207, 72,163,251,184,209, 67,247,101, 31,211,233,192,221,223,167,169,153,155,123,119,189, 46,151, 97,152, +134, 29,101, 0,165, 36, 53,234,153,217,207,178,114,237,158,159, 62,125,108,242, 63,220, 61, 64, 87,165,182,226,175,250,179, 34, +150, 97, 88,154,166,205,102,179,209, 96,212,233,244, 82,169, 20, 8, 48,153, 76, 36, 65,210, 52,173,211,233,234,234,234,192,199, +218, 69,117,248,215,140,246,193, 4, 65,146, 18, 74,202,176, 72, 85,165, 49,209,166,242,178,170,106,117,173, 78,107, 2, 61,205, +178,101,148,228,114,199,208, 48, 15, 55, 55, 91, 94, 2, 0,218,164, 87, 87,220,211,215,177,102, 3, 69, 17, 52,109,190, 87, 94, +114,245, 98, 78,121,233, 29,132, 16, 73, 82, 36, 73,130,125, 95,129, 11,192,162,114,243,230,205,201,201,201, 49, 49, 49,114,185, +124,253,250,245,174, 29, 10, 75,206, 65,189,123, 7, 7, 7,167,165,165, 77, 26, 57,178,163,243,236,233, 7,160,156, 54, 77, 26, + 20,148,150,150, 38, 13, 10,114,168, 61,205,114,185,212,104,220,181,107,151,165,252, 20,222,121,119, 25,152, 49,185, 6, 70,169, + 84,102,102, 58,150,156, 90,157,174,157,191,255,223,147,147,171, 53, 53, 21,170, 42,169, 84,130, 33,149, 74,229,110,238, 53, 85, +149,181,119,138,189, 58,217, 29,172,184,113,235,214,151,187,126,180,164, 78,172, 61, 7,246,235, 51, 97,244, 72, 1, 87, 93, 11, +224,229, 21, 16,147,240,152,199,129,221,159, 60, 24, 47,231,197,207, 55, 26,247,125, 22,180,229,236, 35,190, 18,202,219,159, 86, +223,139,255,249,158,135,132,208,210,136,178,163, 1, 10,243,243,247,238,254,233,243, 45,159,127,248,201,127,210,215,111,244, 15, +240, 95,253,206,234, 47,190,254,106,248,160,161,159,126,242,233,147, 41, 79, 14, 31, 58,188,141,243,166,107,249,223, 27,149,199, +210,147, 52,254, 43,169, 99, 0, 64,107, 70,218,206,253, 43,122, 61, 46, 27,248,164, 86,226, 9,165,215,159,215,124, 99,243, 40, +187, 15,170, 0,106, 30,159,253, 18,203, 2,128, 10,192, 11,192, 28,214,189,159, 66, 46, 97,104, 35, 50,209, 0,224,229,229, 85, +165, 82, 55,181,221,184, 97, 49, 0, 92, 61,241, 9, 89,127, 45, 44, 0,176,250, 43, 6,163,153,146, 42, 8,153, 20, 0,106,107, +106, 2, 2, 2,108, 19, 54,203,178, 44, 67,211,102,163,209,164, 55,232,235,234,234, 52,154,154,106,117,181,170, 74, 85, 85, 85, + 85,165,170, 82, 87,171, 53, 53, 54,198,136,228,114, 19,195,176, 38, 19,173,174,174,201,207, 47, 60,147,115,254,212,169,115,215, +175,223, 44, 45,169,168,171, 51,214,213, 26, 42,238,169,175, 94,189,113,242,100, 78, 73,137,141, 49, 83, 78, 11,153,244,186,146, +194, 27, 23, 79, 29,255,110,251, 39,251,118,111, 43, 46, 42, 96, 88, 6, 8, 2,136, 6,134,229,133,189,190,185,221,182, 78, 82, +223,218,249,249,249,121,121,121, 45, 91,182,204,181, 74,243,241,199, 31, 39, 39, 39, 3, 64,120,187,118, 68,243,248, 29, 51, 38, +214,158, 60,189,117, 0, 88,183,110,221,141,187,119,159, 28, 55,110, 88, 76, 12, 0, 92,188,120, 17, 0,190,253,245, 87,254,227, +191,252,198, 27, 75,222,124, 19,247,202,241, 6,222,198, 27, 60,189,117,140,172,172, 2, 75,222,228,182,241,126,123,240,149, 72, + 12, 38, 35, 69, 81,215, 11,110, 22, 20,223, 57,121,254,130,201,100, 38,129,144, 72, 36, 4, 65,176, 12,163,215,234, 14,236,216, +206,115, 4,142, 55,159,158, 58,185,145,155,232,236, 69, 78,141,242,194,171,161,166, 70, 97,210,204,202, 92, 46,165,111,180, 46, +151,168,238,202, 58,119,187, 55,127,200,197,207, 55, 74, 2, 59,224,125,247,230, 15, 9, 84,144,222, 18,219,149,164,123, 84,119, +119,119,143, 15,255,251,241,232,145, 35, 7, 14, 30, 84,152, 95,120, 61, 63, 15, 88,164,144,203,135,198, 13,253,105,247, 79,223, +125,247,221, 31,197,125,233, 84, 74, 37,137, 85,247,220, 82,123, 18,243,119,121,244, 28,122,228,247, 43, 0,240,232,115,233,117, + 27,167,120,220, 62,241, 60,250,102,139,175, 13,237,217,213, 59,244,242,197,111, 27,232, 88, 11, 96, 6, 48,131,217, 40, 97, 41, + 18, 88, 0,248,238,251, 95, 0, 96,232,163, 54,186,117,251, 46,161,164,216,222, 22,122, 78, 2, 32, 5,169,130, 38, 24, 22, 8, + 0,152, 62,235, 69, 0,184,125,124,179, 77,234,164, 25,134, 52,211, 36,105, 36, 73, 18,128, 96, 24,218,104, 52, 72, 36, 82,130, + 0,134, 97, 76, 38,147,209, 96,148,119,234, 96,101,200, 48,172,201,204,130,222, 84, 89,169,214,233,140, 20, 37, 49,153,204, 70, +147,201,204,152, 89,196, 34,130, 0,210, 92, 91,103,170,168,168,213,234,105,128,110,118,152,179,126,195,104,208,107,170, 85, 36, + 73, 17, 4, 16, 78, 74,205,220,219,185,221,195,186,243,244,211, 45, 29,127,110, 13, 18, 88, 34,145, 20, 20, 20,172, 93,187, 22, + 0,150, 45, 91,230,227,227,163,209,104,170,171,171,133,244,112,177,228,108,223,190, 94,197, 47, 88,176,224,163,143, 62,114, 77, +120,114, 71,224,161, 78,206,203, 73,120,121,173, 93,187,118,233,210,165, 82,169,212,172, 86,251,248,248, 44, 95,176,192,161,246, +180,244,105,218,243,123,218, 28, 2,114, 40, 69,177, 26,181,233,225, 82,171, 84,158, 94, 94,149,106,245,175, 39, 79, 74, 72,202, +104, 54,235,244,122,150,101,177,115,153, 54,155, 76, 70, 35,127, 81, 55,237,164,175,122,249,159, 88,120, 70,117,233, 82, 84,144, +239, 84, 9, 39,164,172,209, 86,156,252,249,187, 79, 92,208,158, 14,251,233, 28,206,239,216, 18, 51,123,145, 60,188, 15, 0,208, +149,119,243, 84, 90, 0,144, 15,158, 84,196,208,238,105, 39,109,154,212,212,212,200,221, 20, 93,195,195, 11,139,239, 84, 85, 84, + 77,127,122,214,222,236, 3, 31,172, 89,247,221,222,221, 81,225, 81,207, 76,253,219,239,103,143,125,183,107,215,148,169, 83,255, +228,195, 68,247,251,236,189,198,186,247, 24,210,101,202,202,210, 74, 13, 0, 44,126,106,204,187, 83,223,128,245,143,194,221,235, +224,107,227, 64,249, 53, 53,221,124,189,105, 35,228, 31,250,178,235,168,241, 0, 20, 0,152, 77,102, 41,144,117, 6, 35, 0, 36, +141,234,231, 22, 16, 98,243, 34,146,162,137,189, 23,144, 84, 1,178,206,227, 77, 69, 71,176,240,148,202,228,102, 48,120,186, 41, + 0, 96,247,222,111,244, 85,119, 6, 69,250,218,162, 78,196, 48, 12, 77,208, 36, 73, 96, 38, 53,153, 76,122,189, 30,171, 51,150, +101,105,154, 54,153, 76,237,154, 24, 26, 12, 52, 69, 17, 52,205, 26,141, 76,109,173, 30, 33,160,105,214,108,102,128, 4, 82, 66, + 1, 73, 32,130, 64,136,160, 89,173,222,192,240,213, 75,142, 63,235, 41,147,211,155,248, 51,209,130,146, 19, 0,220, 27, 38,199, + 88,242,102, 68, 68, 68,109,109, 45, 77,211,248,197, 22, 40, 57,187, 4, 6,226,143, 93, 2, 3,137, 22,117, 44,216,243,114,162, +218,218,149, 43, 87, 26,171,170,204,184,185,109,223, 30, 0,164, 70,227,228,201,147, 75,238,221, 11,105,209,121, 63, 92,127,156, +115,116, 90, 33, 46, 46, 14,143, 23, 1,192,149, 18,235,111,105,163,169,218,164, 50, 24, 12,190, 62, 62, 10,153,220,204,208, 8, + 33,220, 18,155,205,102,150,102,248,203,249,198,173, 91,220, 24,145,101,207,221,114,236,200, 89,120,180, 27, 8,224,138,130, 19, +238,235, 28,121,160,226, 94,151,157,178,206,221,136,240, 62, 97,159,157,171, 52,176, 30, 18,194,116,244,251,220,130, 66,123, 21, + 68, 79,155,114,126, 63,181,241,253, 13, 67, 70, 13,123,253,223,111,238,255,121,255, 87, 95,252,111,240,136, 97,157,186,116,150, +184, 75,179,143,100,127,253,249,255,190,253,126,215, 79, 63,253, 52,113,226,196, 63, 19,117,146, 77,121,115,233, 73, 26, 0, 32, + 52,102,245,103,251, 48,111, 2,192,250,111, 14, 18,157,248, 71,250,170,243,170,139, 36,114, 72,122,108,209,215, 31,174, 1, 48, +129,206,200,232,225,251, 95,207,103,157,190, 10, 0,161,157,195, 73, 9,101,207,120, 66, 95,194,108,128,221, 63,237,139, 31,247, + 79, 0, 41,128,148,114,131,105,147, 82, 38,140,120, 28, 0,138,111,223, 68,102,198,206, 48, 2,203,178, 44,205,208, 70,147,201, + 96, 52,232,245, 58,173,182,174,182,182, 86,163,209,212,104,106,106,106,106,235,234,234,116, 58,157, 13, 79,150,150,213,235,105, +189,158,214,106, 77,181,181,134,154, 90,125,109,157,161,174,206, 88,163, 49,212,214, 26,107,107,140,181, 53, 70,141,198,168,169, +214,171,213,122,187,227, 23, 8,184, 65,126, 2, 44,136,178,158, 68, 29,163,231,224,158,199,246, 30,219,127,112, 63,102,210,220, +219,124,147,192, 41,138,146, 52,148,225,123,239,189, 7, 0,203,151, 47,143,136,136,128,134,233, 59,194, 37,103,112,112,163,201, +216,243,231,207,255,233,183,223, 74, 5, 12,148,219, 68, 90, 90, 26, 63,249,154,229,245,115,114,183,111,223,158, 95, 86, 6, 0, +123, 14, 29,226,118,230,230,230,182,107,215,174,149,170, 56,230, 71,165, 82,201,237,193,219, 28,111,218,110,162,188,189, 88,134, +169, 81,169, 43, 43, 43,171,170,213, 90,157, 78,171,211,213,214,213,105, 53, 53,181,213,213, 6,189,206,100, 48,176,180,221, 54, +213,146, 31, 57,222,196,219,150,163,237,252,168,171, 56,153,149,121, 63,105,132, 78,117,190,181,233,224,238,244, 46, 97,159,157, + 35,194,251, 24, 15,239,188,253,247, 88, 15, 9,113, 36,177, 29,173,169,136,223,119,207, 78,127, 29,146,147,147,159,127,105, 94, +126,110,238,239,135,142,248,120,249, 60, 53,253, 41,223, 0,255,179,167,206,120,202, 20, 30, 30, 30, 29,186,116,252,102,219, 55, +203, 87,188, 86, 87, 93,221, 6,233,143,203,107,196,253,185,162, 58, 57,222,252,219,152,126,160,189, 8, 85, 5, 43,255,177,100, +213,198, 45,164, 79, 40, 0, 12,243, 87,161, 59,252, 79,206, 19,160, 14, 0, 46, 92,252,177,111,204,228,127,189,254,197, 15,223, +174,255,229,215,107,163, 7,247,146, 72,228, 7,142,156, 69,148,196,196, 48,252, 87,147, 20,219, 99, 95,206,117, 88,183, 38,121, +242,132, 73,147, 38,239, 63,248, 29,109, 54, 76, 28,255, 20,201,152,165, 20,101,199,215,137,176, 74,173,159,145,196,178,148,153, + 38, 73,146, 36, 9, 32, 8,196,214,143,192,219, 26, 4,144, 17,132, 94, 42,165, 8,146, 0,132, 88, 22, 24,150,165,105,150,166, + 17, 65,209, 64, 16, 8, 8,154, 5, 19,205,234, 13,140,187,159, 93,197,105,185, 69, 16,152,194,136,198,195, 73,118, 37,103,207, +193, 61,235,149,209,214,172,172,173, 89, 0,112,108,239, 49,152,192, 87, 68, 44,139, 0, 96,231,206,157,184,214,134,135,135, 99, +113,109, 54,155,105,154,118, 72,157,178,224, 96, 44, 57,195, 91,142,170,164, 65, 65, 0, 48,113,164,221,161,143, 33,209,209,235, +214,173,155, 60,121,114,110,110,110, 94, 94,222, 19, 9, 9, 0,208,189,123,119,110,231,237,219,183, 3,229,242,246, 13, 42,184, +169,175,147, 83,211, 75,222,124,147,187, 71,135, 94, 78, 14, 41, 41, 41,153,153,153, 74,165, 50, 35, 35, 3,243,102, 92, 92, 28, +191,137,186, 82, 67, 0,109, 50, 25, 13,229, 58,153, 66, 33,145, 72,176,234,212,215,213, 25,181, 90,163,209, 88, 87, 93,157, 52, +107,150, 61,115,204,143,184,207, 62,176, 95,159,147,103, 47,114, 95, 89,185, 62,237, 14, 18, 85,156, 60,121,232,187,177, 19,102, +212,211,168,230, 70,238,197, 99, 46,136, 77,225,189,117, 0,200, 83,105,139,158,235,143, 10, 47, 6,109, 57,171,165, 81,205,172, +112,159,175, 11,107,254, 30, 32, 33,128,180,223, 52,206, 95,176, 96,229,154,213, 65, 1,129,102,150,185,113,167, 96,214, 83, 51, +191,248,242,203, 31,190,223, 61,115,214, 76,163,193,120,228,204,113,189,190,110,238,156, 57,217,191,255,110,115,164,247,161,179, +167,101,206, 84,225,249,145, 36, 86,195, 68, 81,115,222, 62, 1, 16,125,237, 34,156,249, 14, 69, 79, 52, 95,216,181,106,213, 42, +194, 39,228,141, 69,207,163,180, 39, 1,160, 66,207,218, 60,208,225, 67, 63,140, 28, 53, 22, 0,180,172, 57,191,186, 8,128,233, +234, 29, 62,122,116,159,224,192,246, 85,154, 26, 0,168, 54,209,119,171,181, 61,109,217,134,118, 30, 92, 92,244, 59, 0, 0, 33, + 73,234, 75, 0, 72,246, 93, 50,239,223,179,179,188,178, 52,192,215, 7, 0,124,101,210, 14,190,158,118,216, 11,177, 44, 0,176, +120, 86, 39,203,178, 12,201, 16, 36, 65, 16, 4,129, 5, 33, 66, 8,217,184,230,167,102,190,244,191, 47, 86, 41, 20, 18,138,194, + 61,125,196, 50,136,102,144,217,204,210, 44, 2,130, 96,129, 96, 24,100, 52,179, 47,205, 91,101,181,144,203,194,211,137,184, 15, + 28,105,222,255,143, 87,120,114,188,105,181,125,108,175,221, 55,132, 97, 24,163,209,152,156,156,140,169,115,231,206,157, 59,119, +238, 76, 78, 78,142,140,140, 36, 8,226,131, 15, 62, 88,190,124,185, 74,197, 55, 47,122,201,146, 37, 75,150, 44,217,183,111,159, +182,188,209,216, 87,120,187,118,133,133,133,192, 59, 61,190,233, 28,120,105, 80,208,199, 31,127,140, 16,154, 52,114,100,136,125, + 63,105,251,192,192, 33,125,250, 84,221,186, 21, 40,151,231, 53,140,179, 71,117,232,176,120,241,226, 99,199,142,117,235,214,173, +119, 72, 8,143,123,215,210,191, 41,220,215,105,233,244, 92,182, 44,101,217,178,148,130,130,122,189,201, 77,243,228, 25,100,247, + 12, 9,210,223, 45, 99,105, 70,171,209,104, 42, 43, 8,130, 68,136, 53, 24, 12,184,154, 21, 94,189,102, 54, 25,121,134,215, 27, +245,168, 70,143,156, 48,122, 36, 55, 52, 36,164,195, 94, 87,121,234,228,161,239, 0,192,211,195,227, 7, 11,225, 25, 63,124, 74, +171,242, 72,252,207,247,206, 60, 10, 49,113, 9,247,230, 15,105,255,159,227,121, 42,173,159,140,168, 82,169, 37, 4, 33,225,237, + 67, 61,243,204, 51,220,246,143, 63,254, 56, 97,226,163,123,118,239,217,177, 99,199,155, 43, 86,254,114, 40,155,146, 80, 33,161, + 33, 26,141, 6,100,109,142, 58,193,213, 60,125, 18, 11,222, 52, 71,205,121,167,222, 79,116,138, 94, 59, 64, 2,159, 61, 7,189, +198,190, 49, 40, 6,116,183,208,191,227, 65, 93,162, 53,163,239,251,217,102,229,220, 60,211,209, 19,239, 0, 0, 75, 41,112,231, + 50,191,230,238,191, 22,252, 67,167, 51,214,232,141, 0, 96, 34,229, 99,146,146,109,218,174, 92, 49,103,223, 79,241, 0, 0, 12, + 94, 59, 76, 39, 69, 19, 51, 94, 88,239,238, 46,247,118, 83, 0,128,148, 53,132,180,179,243,102, 34,132, 8, 96,217,250, 69, 38, + 44,193, 18, 44, 22,127, 4, 16, 13, 29,106, 59, 82, 76,167,115,211,235,107,165, 82,138, 36,128, 69,192,178,136,166, 89,154,102, +117,122, 26, 1,193, 34, 48,211, 8,145,132,173,115, 2,209,192,160,184,183,110,169, 64, 27,228, 38, 1, 0, 79,255,125,138,189, +245,179,215,126,191,230,180,191, 31, 33,189, 94, 31, 29, 29, 29, 17, 17,113,235,214,173, 29, 59,118,112, 10, 20, 99,205,154, 53, + 14,217, 19, 0, 82, 83, 83,155,238,156, 58,123, 54, 8,152, 30,143,151,247, 88, 98,242,168, 81, 14,199,151,218, 55, 76,144,176, + 84,160,183,111,223,142,239,222, 93,166,213,242,223,114,115,222, 10, 75,126,180,156, 21, 11, 2,214, 26,185,117,104,175,187,145, +207,208,116,141,186,154,166,105,220, 0,171,203,239,213,168,213, 8, 33, 30,201,105,229,244,252,114,215,143,150, 19,146, 44,221, +160,118,234,229,133, 19,191,226, 17, 87,248, 33,243, 19, 0,232, 55,114,134,127, 80, 76,107,178, 7,106,196,158,176, 37, 38,245, + 95,101, 44,219,119,235,169, 83, 73,193,189,246,148, 75, 8,240,146, 10,157,161, 60,121,242,228,131,135, 14,142, 73, 28,187,123, +215,247,111,173, 93,179, 76,163, 65, 44,187,125,251,174,192,192,192,162,154, 63,227, 48, 17,199,155, 0,208,117,246,219, 75,183, +174, 0,128,247, 32, 27,174,100,115,154, 20, 0,162,250,216, 61, 86, 59,255,216, 9,115,158, 97, 16, 39, 15, 81,157,182,134,146, +248, 0,233,190,244,125, 7,115,182,147, 38,246,254,254,227,229, 64,234,160, 65, 32,122,122,250, 48,102, 53, 32,237,237,227,155, +227,251,116,230, 29,165, 65, 0, 4, 2, 68, 32, 32, 8, 68,212,179,150,101, 7,195,246,235,167, 76, 93,154,246,209, 59,181,181, + 26,137,132,108, 24,113, 66,102, 51, 91, 87,103, 50,209, 44,139, 8, 74, 66,190,247,238,198,166,134,143, 62, 62, 8, 0,246,255, +120,130,161, 25,124,244,250, 5,129,245,163, 67, 0, 64,204,126, 46,153,231,126,159,123,235,185, 91, 55,111,185,240,192,140, 70, +163, 90,173,246,241,241,137,139,139, 27, 48, 96, 64, 69, 69,197,205,155, 55, 9,130, 96, 89,118,215,174, 93, 14,217,115,193,236, +217,110, 65, 65,147,108,117,174, 23,204,158, 13, 0,110,246, 73,240,149, 87, 94, 1, 0, 43,219,144,198, 62, 83,135,104, 31, 24, + 56,180, 79,159,170, 91,183,130,220,220,122, 15, 25,210,170,149,219,138, 25,227,226,226,172,198,139, 28,178,103, 64, 84,215, 90, +181, 90, 34,151, 25,141, 6,198, 76,179, 44,235,229,231,167, 81,169,146,102,205,226,151,156,220,148,120,236,232, 60,121,246,226, +132,209, 35, 57, 47,167,189, 25,242,221, 58,168, 43,171, 42,119,100,222,159, 2, 56,109,214,179, 42, 83,148,115, 44,216,164,135, +222,100, 15,225, 80,123,194,207,245,203, 40,187,254, 80,191,126, 79, 99,102,132, 95,195,152, 81, 99, 46,248, 93, 24, 55, 49,233, +249,191, 61,219,167,111,244,238, 31,126,252,253,124,206,220,185,115,139, 90, 33, 12, 71,115, 96,149, 57,217,169, 68,202,118, 87, + 19,225,137, 74,152, 64, 45,247,240,163,119,239,161, 31,126,248,197,139, 47, 61, 21, 18, 22, 5, 96,148,202, 21,197,119,107, 70, + 78,126, 70,200,165,196,198, 70,204,153, 51,109,235,167,223, 2,123, 27, 64, 66, 27,244, 33, 29,124, 58,123,211, 14,133, 24, 1, + 4, 34, 16,129, 0,107, 63, 2, 16, 96, 13, 42,224,164, 11,254,249, 26, 0,188,246,234,139, 20, 69, 34, 0,134, 65, 52,205,212, +213,209, 44,139, 72,146,216,180,137, 47,162,204,248,201,131, 0, 96,239,247,199,208,125,226, 36, 0,224, 89,229, 83, 14,207,171, +169,211,216, 92,162,238, 16, 44,203,234,245,122,134, 97,106,106,106, 40,138, 98, 24,166,125,251,246,102,179,217,114,222,226,154, + 53,107,236,173,200,196,242,208,207,165, 73, 72,254,184, 49,114,146, 43,155, 34,216,206, 20, 93,123,112,217,215,105,197,137, 54, +199,217, 29, 78,140,239, 50,160, 63, 0, 92, 63,124,216,160,211,179, 12,211, 51, 46, 46,122,200, 8,207, 16,222, 2, 68,196,237, +194,155, 0, 32, 3,248,199,147,245,174,235,219,133, 55, 45,183,109, 78, 96,203,187,235, 7,224, 55,125,214,115,183,239,148,157, +248,109, 15, 0,236,248,234,147,129, 35, 38,121, 5, 15, 19, 82, 80,211,166, 77, 19,178,206,146, 33,228, 54,247, 23, 77,105,255, +115,169,161,165, 88,169,111,223,190,125,251,246, 61,115,230, 76,246,137,195, 1,129, 1,109, 57, 96,141,107,249,223, 29, 47,196, +116,246,136,145, 61,250,255,180, 63,255,137,137,238, 65, 33,157, 84,181,244,200,137,127, 19,110, 59,184,127,143,193,253, 95, 83, + 42,255, 5, 80,238,231, 37,233,236,207, 58, 54,153, 53,189,249,101,247,206,187, 31, 2,192,139, 47,254,211,108, 50,177, 8,220, +221,221, 55,108,216, 32,208,118,194, 19, 67, 1,224,167,239,142, 18, 4, 57,247,133,167, 31,192,147, 70, 8, 25,141, 70,147,201, +132, 9, 5, 83,201,159, 53,150,146,195,245,157,194, 33, 36, 66,146, 61,244, 24, 57, 82,248,143,239, 22,228, 14,140, 10,117,249, + 92, 85,166,174,158,193, 93, 19, 82,134, 57,107,104, 47,174,135, 5, 72,154,144,235, 73,219, 35,132, 55,107,233,110, 94, 60,132, +224,202,244,181,248,248,248,182, 92,187,154,142, 11, 9,247,123, 18,174,185, 72, 69, 60, 92,184, 25,175,235, 27,135,212, 20, 33, + 66,196,131,132, 24, 37,254, 15, 9,145, 55, 69,136, 16,169, 83,132, 8, 17, 34, 68,234, 20, 33, 66,132, 8,145, 58, 69,136, 16, + 33, 66,132, 21, 90, 37,173,155,104, 43,218,182, 77, 91,188, 22, 83, 44,171,191,184,109, 11, 83, 39, 52, 14,145,192, 3,155,149, +175, 57,182, 34,156,130,189,247, 95,132, 11, 5,101,239, 55,114, 6, 25,169,251,211,113,138,138,138, 74, 74, 74,228,114,121, 96, + 96, 96,231,206,157, 31,216, 45,112,241,177,196, 55,168,237,170, 78, 12,135,235,222,120, 2,228, 88,217, 54, 13,128,198, 99,251, +249, 23,159,240,159,119,246, 51,207,182,181,215,146,255, 7, 11, 23, 46,236,217,179,167,203,230, 41, 41, 41, 9, 9, 9,246, 12, + 91,138, 61,199,143, 31, 15, 0,251,247,239,127, 0,182, 90,173,118,215,174, 93, 56,173,219,212,169, 83, 99,237,103,167,104,122, +191, 14,211,186,165,167,167,219,108,167,249, 11,138,231, 91,142, 55,239,221,187,103, 52, 26, 9,130, 80, 40, 20, 6,131,161,168, +168,232,244,233,211,125,251,246,237,218,181,171,189,195, 14, 29, 58,212,225,125,221,189,123,183,160,160,192,225,207,214,174, 93, +139,131, 10, 10, 41, 43, 33,115,123,167, 77,155,102,179, 94, 89,213,201,176,176, 48, 0,168,173,173, 53, 26,141,248,217,241,212, + 73,145, 58, 31, 62,142, 29, 61, 57,116,216,192,166,251, 73, 32,218, 96,217,253,144,158,100,239,171, 39,230,237,107,142, 0,183, + 71,172, 89, 89, 89,150,219, 92, 61, 46, 44, 44,196,105,221,156,226,211, 75,151, 46, 97,250,179, 60,148,179, 72, 77, 77,157, 63, +127,190,144, 20, 52, 56,175,198, 51,207, 60,163, 86,171,215,173, 91,215,165, 75, 23, 63, 63,199,235,169, 8,130,248,249,231,159, +241,118, 82, 82,210,190,125,251,108,110,243, 20, 50,199,143, 74,165, 50, 46, 46,142, 75, 38, 42,164,249,209,104, 52, 65, 65, 65, +152,163,221,220,220,238,221,187, 87, 93, 93,237,227,227,115,234,212, 41, 0,224, 97,207,222,189,123,167,164,164,112,148,103,169, + 28,113, 96,255, 19, 39, 78,204,156, 57, 83, 72, 9, 11,228, 77,140,141, 27, 55, 54,191, 98,123,120,120, 92,189,122, 85, 42,149, +154, 76,166,125,251,246,221,184,113,227,213, 87, 95,253, 19,147, 96,171,164,117,123,136,236, 73,146, 36, 23, 44,142, 5,212,246, + 31, 64, 72,252,106,188, 81,114,230,117, 23,204,113,150, 96,126,237, 96,149,214, 45, 33, 33,225,192,129, 3, 4, 65, 88, 5,182, + 16, 8, 46,173, 27,206,180,225, 44,246,239,223,159,157,157,205,165,117,115, 72, 67,121,121,121, 56,190, 14, 78,235,182,110,221, + 58, 33,242,179,249,105,221, 50, 50, 50, 54,111,222,108,153,214, 77,169, 84,166,164,164, 56,188, 96,181, 90,237,231,231, 71,146, +228,156, 57,115, 12, 6, 67,122,122,186,155,155,155,193, 96,208,235,245, 20, 69,229,228,228,180,107,215,206,199,199,199,166, 45, +230, 71, 78, 87,186,156, 7,101,217,178,101, 74,165, 82,184,240, 4,128, 69,139, 22,225, 13,110, 69, 92,211, 61,246, 16, 22, 22, + 86, 89, 89,249,250,235,175,123,120,120,236,220,185,115,228,200,145,127, 41,222, 4,151,211,186, 53, 19,220,203,207,179, 71, 56, +123,218, 12,178,249, 23, 7,167,158,146,147,147, 19, 19, 19,161,113,216, 36,167,112,233,210, 37, 0, 72, 72, 72,192,105,221,130, +131,131, 93, 72, 94, 56,118,236,216,177, 99,199, 94,186,116, 41, 45, 45, 77, 72,250, 67, 76, 70,174,201,207,230,192,102, 90, 55, +135, 66, 91,167,211, 5, 4, 4,204,152, 49, 67,163,209, 84, 85, 85, 73, 27,242,186, 73,165, 82, 55, 55, 55,149, 74,117,250,244, +105,158,131, 20, 20, 20,112, 77, 26,166, 78,172, 61,227,226,226,132,107,252,136,136,136,101,203,150, 97,195, 7,224,229,188,117, +235,214,225,195,135, 39, 78,156, 24, 22, 22, 22, 24, 24,120,248,240,225, 87, 95,125,213,195,195, 67,171,213, 82, 20,245, 39,230, + 77,156,149,200,169,180,110, 45, 73,157, 77,187,153, 2,199,142,132,247,220,219, 32,166, 46,216,191, 43,109,124,115, 10,173, 57, +175, 4,247, 94,185, 32, 57,177,216,140,142,142, 38, 8,162,188,188,220,229,188,175,216, 48, 45, 45,205,222,141, 96, 47, 39, 0, +172, 91,183,110,234,212,169, 92,108, 71,156,214, 13,239,228,209,158, 73, 73, 73,156,223,252,209, 71, 31,229,116, 40, 79, 63,189, +105,251,109,149,214, 77,169, 84,114, 61,119,155,200,207,207, 39, 73,146,162,168,252,252,124,132, 80,110,110, 46, 14, 26,128,211, +186, 49, 12,163,211,233,190,251,238, 59, 30, 18,228,120, 51, 37,197, 58, 10,137, 83,125,240,136,136, 8,124,193,206,202, 79, 23, + 96, 54,155,251,245,235,119,232,208,161,248,248,120,173, 86,139, 93, 34,135, 14, 29, 26, 63,126, 60, 77,211,127, 86, 69,194,101, +115,155,187,108,141,240, 64,241, 45, 73,157,205, 25, 38,250, 67,179,231,137,194, 71, 6,133, 95,117,173,159,142,229, 73, 68, 68, +132, 11,241, 59,172,210, 19, 9, 25,118,176,148,156, 86,105,221, 92, 19,158,220, 17,120,210,186,113, 50, 83,171,213,174, 93,187, + 54, 42, 42, 74, 42,149,202,229,114, 31, 31,159,213,171, 87, 59,212,158,150, 62, 77,123,126, 79, 33, 13,121, 83, 41,202,253,166, +169,202, 80,169, 84,124, 32,159, 8, 0, 0, 32, 0, 73, 68, 65, 84, 94, 94, 94, 42,149,234,248,241,227, 20, 69,225,132, 87, 92, + 90, 55,179,217,108,116,148,214,173,105, 39,157,107,231, 34, 34, 34,238, 57,153,203, 36, 35, 35, 3, 63,110, 23, 26, 90,225,177, +108,214,173, 91,247,202, 43,175,224,102,172,160,160,224,198,141, 27, 0, 16, 27, 27,155,155,155, 27,228,106,202,191, 63, 43, 36, +109,246,202,254, 16,188, 57,117,193,254,230,152,187,172,202,155,242, 38, 56, 51,158,128, 37,103,239,222,245, 89, 72,123,247,238, +221, 76,225,201, 15,206,203,233,225,225,177,114,229, 74,169, 84,138,247,199,196,196, 0,128,159,159,223,228,201,147,143, 30, 61, + 58,121,242,228, 22, 60, 41, 71, 49,156,163,211, 10,113,113,113, 92,115,213,116,222,159,201,100, 82,169, 84, 6,131,193,199,199, + 71, 46,151,227,228, 37, 92, 90, 55,134,113,144,214, 13, 55,135, 77,123,238,150, 99, 71,206,194,101, 67,225,190,206,213,171, 87, + 79,156, 56,177, 75,151, 46,238,238,238,163, 70,141, 82,169, 84, 30, 30, 30,106,181,122,235,214,173, 36,249, 39, 92, 62,131, 35, + 39,109, 94,187,220,178,195, 46,208,215,217, 70,139,227,143,162, 55, 1,160, 95,108, 76,246,193, 95,191, 62,232,142,153,244, 68, +225, 35, 78,153,199,197,197,101,101,101,225,161,115,165, 82, 41, 64, 57,214,191,177, 86,105,221,132, 3, 75,206,166,105,221,118, +238,220,137,191,114, 1, 14,211,186,169,213,245, 73, 25,183,111,223,126,254,252,121, 0,216,182,109, 27,183,179, 85,211,186,113, +227,233, 86, 45, 22,191,204,247,242,242, 98, 24, 70,173, 86, 87, 86, 86,170,213,106,157, 78,167,211,233,234,234,234,106,106,106, + 52, 26,141, 94,175, 55, 26,141,140,253, 92, 91,150, 15,197,106,112, 79,184,131,165,160,160,192,242,178,133,247, 42, 92,198,231, +159,127, 62,106,212, 40,119,119,247,171, 87,175, 30, 58,116,200,195,195,227, 95,255,250,215,209,163, 71, 95,125,245,213, 63, 37, +117,222,247,234, 56,153,211, 13,218,230, 48,209,240, 17,131, 5, 38,197,125,232,146,179, 95,108,125,218,131, 93,223,126,183,235, + 91, 0,128,236,131,191,194,152,209, 0,142, 39, 39,225,185, 50,220, 27,133, 95, 48, 1,243,132, 8,104,146,214,205, 41,222,196, +146,211,166,192,116, 77,120, 98,194, 93,176, 96,129,221,130,154, 58,213, 50,173,219,211, 79, 63, 13, 77,210,186,253,237,111,118, +227,186, 54,211,215, 9, 46,165,117, 11, 8, 8,168,170,170, 50,153, 76, 21, 21, 21,114,185,156, 75,235,166,213,106,117, 58,157, +209,104,212,104, 52, 86, 78, 76, 75,112, 29, 2,104, 18,157,158,199,170,105,175,130,235,245, 55,157, 27, 47, 80,108, 10,239,173, + 3,192,141, 27, 55,114,115,115,117, 58,221,224,193,131,117, 58, 93,102,102,230,244,233,211,119,239,222, 77, 81,212,159,155, 58, + 45, 85,231, 67,160,206, 22, 25, 38,250, 99,233, 77,155,219,217, 7,127, 21,168, 55,109,110, 91, 78,222,180, 9,123,105,221,112, +106, 13,126, 50,229,210,186, 89,237,143,142,142,198,105,221,120,166,184, 55,157, 3,143,137, 24, 33,180, 96,193, 2,174,251,223, + 20,177,177,177, 97, 97, 97, 56,131, 91, 94, 94, 30, 30,103,183,220,105,153, 20,204,186,161,104, 60,175, 83,184,175,211,178, 18, +102,100,100, 36, 36, 36,100,101,101,225, 10,201, 77, 84,224,241, 27,134,134,134,230,231,231,227,104,252,102,179, 25,115, 55,151, +214, 13,143, 26, 9,212,251, 9, 9, 9, 9, 9, 9,156,102, 20, 98,197, 17,101, 68, 68,132,229, 75,228,242, 36, 39,129,192,243, +144, 94,126,249,229, 67,135, 14,141, 30, 61,250,198,141, 27,158,158,158, 69, 69, 69,127, 86,234,196, 35,236, 86,195, 68, 46,142, +176, 59, 53,146, 99, 5,171,231,106,217,102, 90, 54,197,127, 14,222, 4,128, 59,197,101,246,190,114,115,115,119,104,110,211, 1, + 39,240, 85,228, 79,235,230, 80,138,218, 76,235,118,235,214, 45, 33,178,183,105,115,248,207,127,254,147,135, 55, 49,252,253,253, +177, 43, 83, 46,151, 91,138,205,215, 95,127,157,191,202, 53,179,243, 97,201,143, 86,179, 95, 29,174, 53, 26, 57,114,228,222,189, +123,105,154,174,174,174,230, 18, 53, 87, 84, 84, 84, 87, 87, 35,132, 4,122, 45,177,163,211,114, 66,146,165, 27,148,159, 55,185, +210,126,144,139, 47, 49,123, 46, 95,190,252,240,225,195,147, 39, 79,126,247,221,119,151, 44, 89, 34,145, 72, 20, 10, 5,136,224, +161, 78,135,205,154,107, 83, 97,254,124, 88,189,122,117,101,101,101,115,154, 25,151, 93, 87, 4, 65, 68, 70, 70, 70, 70, 70,142, + 29, 59,182,160,160,192,102, 90, 55,123,236,137, 83,179,165,164,164, 88,250, 58,177,164, 90,186,116, 41, 63, 79,217,180,117,182, +131, 47, 80,108,182, 84, 55,200,146,116,154,166,117,227,103, 79,130, 32, 38, 78,156,248,213, 87, 95,201,100, 50,163,209, 72,211, + 52,203,178,190,190,190,106,181,218,225,146, 68,110, 74, 60,230,235,156,156,156,132,132, 4,238,221,177,247,150,225, 42, 97,181, +244,200, 89, 95,118,211, 30,186, 83,125,118,204,158,220, 52,248, 23, 94,120, 1,111,212,212,212,252, 89,223,101,171, 97, 34, 23, +169,179, 57,204,216,212, 86,248,209,218,218, 18,117,135,104,215,174, 93,115, 70, 54, 34, 34, 34, 90,100,130, 30,119, 28, 75, 49, +184,102,205, 26,123,116,208,156, 53,200, 45,181,126,153, 83,160, 2,225,178,175,211,170, 16,108,202,124,135,130,110,214,172, 89, + 55,111,222,252,245,215, 95,113, 54,189,152,152,152,105,211,166, 57,124,118, 39, 78,156,224,164, 43,183,199,114,219,222,211,228, +154, 85,204,185,107,215,174, 21,190,114,124, 90,243,242, 56,253, 5, 3,139,112,185,137, 44, 73,211,149,213, 68,205, 41, 59, 49, +160,203,195,197,159,181,252, 91,240,190, 92, 62, 20,214,248,194,127,127,236,216, 49,129,235,211,121,154, 67, 23, 26, 42, 49, 54, + 71,115,216,211, 41,222, 4, 49,173,219, 31, 23, 98,102, 55, 17, 34, 30, 34,196, 40,241,127, 84,136,188, 41, 66,132, 72,157, 34, + 68,136, 16, 33, 82,167, 8, 17, 34, 68,136,212, 41, 66,132, 8, 17, 34, 44,209,138,105,221,156, 74,161, 69, 33, 36,101,192, 32, +177, 61, 59,218,221,204, 26, 36, 36, 75,136,169,172, 90,204,150, 97, 24,131,193, 64, 81, 20,142,195,200,133,228,104,141,243, 50, +130, 27,232,189,135,219, 68, 89,253,248, 88,154,112,219,201,187, 23,180,148,237, 15,147,157,176,125,252,199, 70,182,147,134,133, + 0, 0, 65, 16,102,179,185,176,176,208,100, 50, 73, 36,146,226,226,226,167,124,186,236, 63,115, 70,223,167,211,160, 65,131, 40, +138,194, 83,187,246, 28, 45,105,169,178,194,231,229,128, 23, 56, 92,185,114,165, 99,199,142, 42,149,170, 99,199,142,110,110,110, +208,176,180,193,234,188, 54,109,239, 92,254, 82, 57,188,232,235, 51,221, 36, 65,227, 60,189,188,237,217,182,173,180,110,252,224, + 95,216,208,252, 20, 90, 76,195,181,180, 63,113, 53,255,222, 93, 55,153,162,187,187, 79,254,136,222, 0,160,147, 62, 8,117,252, +151, 74,161, 69, 81,148,135,135, 71,243,143,147,155,155,187, 97,195,134,117,175, 1, 0,124,127,100,248,172, 89,179,172,126, 96, +201,155,119,138,238,148, 20, 23,231, 94,191,174, 86,171,195,194,194, 60,189,188, 18,199,143,227, 63,254,129, 3, 7, 28, 94,195, +206,157, 59,133, 63, 41,188,146,202,102, 46, 35, 62,164,168, 0, 0, 0, 1, 16,144,233,239,132, 97,220, 6,136,152, 13, 0, 80, +176, 21,114, 22, 59, 93,190,201,149,247,207,187, 51,144,231,135, 4, 65,104,181,218, 95,126,249,165,160,160, 32, 69, 26,208,190, + 83, 59,131, 86,239,166,163,135, 46,121,126,196,228,233,123, 62, 73,255, 49, 59,123,220,184,113, 15,160,106, 49, 12, 83, 80, 80, +208,183,111,223,110,221,186,157, 61,123,214, 96, 48, 68, 69, 69, 9,140, 74, 65,211,244,133, 51,231, 66,159,141, 93, 58,160,215, +137, 95,222,223,117,105, 84, 84,239, 49,109, 51,162,133, 32,234, 20,178, 20,189, 69, 82,104, 69,157,189,233, 87, 85, 71, 0, 50, + 49,148, 89, 85, 87, 92,169,185,149,150,227, 57,122, 96, 96, 47,190,209,228,156, 95,149, 61,234,103,221, 81,223,253,194, 30, 57, +141,230,206,128, 30,145,176,248,109,231, 72,208,169, 20, 90,246, 56,183,181,131,209, 2, 64, 74, 74, 38, 0,248,251,219, 88,234, +174, 82, 37, 0,128, 82,233,247, 96,166,248, 53,240, 38, 2,128,239,143,140, 56,122,244,104, 83,234,228, 16, 27,253, 75,121,241, +174, 47, 62,171,255,152,119, 61, 23, 0,158,251,251,183,154,186, 5,213, 53,124,235, 56,183,111,223,238,176, 25,112,170,249,111, +196,164, 74,101,186, 48,218,181, 76, 36,231, 4, 34,102,223, 15,195,225, 2,117, 54,220, 29, 79,148, 38,140,155, 55,111, 30,218, +177,227,223, 9,211, 98,102,189, 32, 11,246, 3, 9, 9, 64, 2,139,128,149,178, 70, 52, 97,246,220,162, 15,215, 28, 63,126,124, +200,144, 33,173, 77, 67, 36, 73,198,196,196, 28, 58,116,168,111,223,190, 3, 6, 12, 40, 43, 43,187,112,225, 66,159, 62,125,132, + 44,242,166, 40,106,236,152,196,119,215,239, 94, 54,231,210,160,164,121,131, 6,102, 45,249,168,184, 91,255,103,108,218,114, 41, +255,120,238,200, 94,202,191, 86,167,206,251, 85, 45, 97, 71, 70,138, 90, 56,123,186,144, 66, 43,244,102,121, 63, 55, 63, 89, 7, + 31, 6,144, 91,181,123, 89, 69, 69, 89,173, 38, 92,238,121,125,255, 81, 4,208,206, 62,123,246,136,132,235, 55, 73,132, 20, 12, + 33,127, 34,209, 60,101,156, 30,128,109,104,171,157,172,231, 78,178, 30, 23,222,230,204,153, 51, 0, 16,191,188, 96,109, 14,192, +218,105, 14, 9,212,229,140,152,247,213, 76, 92,156,173, 83,168, 5, 94,249,141,108,239,247,119, 60,133,183, 95, 78,249, 38,106, +172,198,217,240, 5,185,185,185,235,215,175, 39, 73,242,229,119, 96,248,240,225, 71,142, 28,225, 57, 66,108,244, 47,131, 6,238, + 26, 52, 16, 86,173,186,191,115,230, 76,152, 48, 1, 0,210,190,217,193,199,158, 20, 69,225,136, 39, 12,195, 76,159, 62, 29,175, +217,119, 72, 37, 54,245, 38, 94,177,202, 93,103,106,170, 80,222,116, 17,113,235,161, 33,213,218,134, 13, 27,160,223, 58, 56,251, +114, 43,157,234,224,193,131,155,166,204, 13, 31,147, 8,148,145,144,146,132,132, 36, 40, 41, 66, 4,171,165, 17,195, 32, 19,243, +252,236, 23, 94,248,215, 75, 55,131,131,157,154,222,239, 2,206,156, 57,211,161, 67, 7,150,101, 15, 31, 62,124,253,250,245,196, +196,196,193,131, 7,159, 60,121,178, 87,175, 94, 14,109,143,102,127,243,100,140, 46,167,150,154,249, 70,221,176,216, 15, 22, 44, +156,254,254,178,234,101,239,127, 21, 17, 59,147,135, 22, 57,122, 73, 77, 77,181,218,195,255,162, 89, 37, 38,186,239, 73,104,102, +130, 13, 75,222, 4, 0,101,166,159, 16,246,116, 45,133, 86,151,235,165,221,101, 30, 50, 68,187,189,255, 10,173, 51, 41, 94,126, +219, 71,166, 48, 72,245, 90,131,222, 13,136,187,135, 79,200, 66, 59,216, 75,161,117,253, 38,108,222,198, 2,232, 0,116, 0, 48, +188, 63, 57,101, 28,209,192,158, 48,119, 6,108,222, 38,232,145, 59,155, 66, 11,243, 38, 38, 77,204,155, 92,113,173, 21,192,158, + 55,215,220,180,247, 85,228,114,190,202,237,239,159,101, 25,166,183,241, 87,202,184,184,184,185,115,249,194,154, 85, 94,234,240, +122,218,227, 8,208, 96,255,215,135, 38,244, 58,122,224,202,186,204,153,144,137,222, 88,252,159,142,221,133,202,183,186,219,202, + 16, 5,232,170,174, 32,132,188,130,250, 96,222,220,180,105,147,205, 31,251,122, 95, 30, 52,112, 23,222, 62,121, 18, 6, 54,196, +120,121,171,161,222, 62, 53, 45, 45,253,191, 43, 16,116,226,233,146, 55,243,125, 86, 42,149,152, 55, 45,152, 84,153,158,110,187, + 90,146,211,212, 92,195, 75, 0, 0, 1,108, 74,227,111, 9,220,135, 38, 0,208,196,198, 58,155,156,174,198,221,107, 0, 96,217, + 57, 11, 23, 46,196,251, 23, 46, 92,184,113,227, 70, 50,234,217,250, 3, 35, 0, 2,172,108, 37,211,173,207,107,153,213, 66, 50, +157,239,188, 6,131,161,125, 88, 23, 96, 77,164, 28, 8, 9, 69,215,106, 12, 5,133, 21,197, 37,161, 67, 70, 17, 50, 95,194,108, + 2,138, 92, 59,111, 73,226,230, 55, 23, 47, 94,220,156, 98,228,161, 21, 44, 0,245,122,189,191,191,127,110,110, 46,203,178,133, +133,133, 91,183,110,237,217,179,103,117,117,181, 67, 81,143, 16, 10, 35, 79,118,232,156, 84,125,248,146, 70, 45,255,223, 30,122, +239,137, 47, 95, 76,113,147,232, 88, 0, 27,212,249,112,123,241, 18,126,210, 68, 8, 17,137, 13,241,102,178,166, 65,138,227, 38, + 26, 51,166, 78,247, 21, 0, 97, 48,124,234,239,159, 37, 36,133, 86,208, 93, 85, 80,176, 66,241,198, 11, 76,165,138, 46,173,148, +200,164,238, 4,229, 65, 80, 30,148,196, 95,170, 80,215, 86,223, 61,120,220,103,202,163, 54,109,173,152,241,200,105,118,202, 56, + 2, 0,214,175, 32, 16, 1, 4, 18, 42, 63,157, 77,161,101,201,155,214, 72,216,177,118,237, 52,167, 92,165,126,115,235,203, 92, +189, 57, 67,200,165,186, 38,156, 17, 66, 43,210, 30,195,164, 57,164, 87, 50, 0, 12,233,149,124,252, 74,175,163, 7,174,172, 90, + 63, 63, 35, 67,104,215,134, 32, 64,185,232, 50,174,241,195,134, 13, 59,114,228,136, 61,222, 4,128, 17,195, 78,115,219,253,251, +195,150, 45,240,235,175, 16, 21, 5, 17, 17,247, 85,106, 76,244,181,115,151, 58,217,243,157, 9,239,188,243,168,123, 43,161,106, +143, 55, 1, 32, 61, 35, 3,179,159,205,246,137,109,120, 99, 51, 54,111, 38, 8,248,241,183, 70, 67, 16,155,210, 51,240, 93,117, +233,210, 5, 33,244,193, 7, 31,224,253, 31,124,240,193,198,141, 27,247,239,223,143,131,251, 97,118,180,178,197, 18, 24, 33,244, +252,243,207,219,240, 3, 54, 92,255,230, 45, 91, 8, 2,246, 28, 41,177,122,178, 18, 47, 47,144, 82,140,174,250,218,222,236,175, +118,236,252, 79,105, 33, 0,156, 90,229, 29, 53, 98,130,177,232,206,149, 11, 57,151, 10,243, 52,101,101,151, 47, 95, 6,104,239, + 2, 89,224, 24,213,252,220, 87, 90, 90,186,114,229,202,247,223,127,223,100, 50, 81, 20,229,229,229,165,213,106, 79,157, 58,197, + 95, 45,177,109,117,241,177, 85,159, 21,125,178,176,163, 74, 43,147, 73,200, 80, 63, 69, 89,165, 73,249, 30,221, 55, 62,174,179, +253,158, 4, 38, 80,238, 65, 55,221,224, 65,211,102,192,158, 14,181,209,190,218,171,109, 56, 46,225,253,189, 89,130, 34, 11,224, +216,198, 58,221,215,152, 55, 57,239, 27,127,204, 99,201,161, 28, 31, 85, 45, 43,147,152,114,174, 24,175, 21, 24,126, 57, 2,122, +163, 12, 33,119,160, 36, 64, 24, 89, 90,101, 52,252,231,192, 30,123,230,235, 87,192,220, 25,247, 63,206,157,209,208,166, 3,202, +205, 71,139,223,118,162,105,194, 41,180, 64, 64,192,246,130,130, 2,203, 32,155,247, 37,167, 5,123, 62,128,176,222, 78,187,101, +207,107, 1, 8,142, 55, 1,224,201, 55,164,239,239,120,106, 88, 98, 47, 0,116,243, 92,157,144,131,124,253,245,215, 47,191, 67, +120,182,139, 70, 0, 73, 83,230, 29, 61,122,148,239,173,128, 59, 33, 29, 27, 69,187,232,219, 23,162,162,224,153,103, 26,245,238, + 59,117, 42,225,233,176, 83, 20, 53,125,250,116,170, 49,184, 61,252, 87,203,213,100,167, 60, 18,132,197, 91,141,209,244, 35, 97, +171, 81,230, 12,199,141, 27,103,165,239, 22, 46, 92,136,243,152, 54, 92,153,181,237,247, 25, 25,151, 47, 95,198, 7,231,110,211, +178, 16,240, 71,155,231,149, 33, 68,186,203,205,101,183, 51, 94,127,125,171,182, 90, 61,114, 16,222,255,201,151, 91,223, 92,242, + 92,183,197, 79,253,251,210,193, 29,234,194,196,199, 30, 19,216,169, 58,127,254,188, 82,169, 60,119,238,156, 69, 99,147,110,179, + 12,113,129, 92,186,116,233,240,225,195, 79, 61,245, 84, 90, 90, 90, 93, 93, 29, 14,211,103, 48, 24, 60, 61, 61,167, 77,155, 54, +116,232, 80,123,164, 73, 16,196,165,223,119,229,237, 95,188,248,213,117, 63,190,209,241, 90,137, 68, 83, 71,177, 4, 84,213,153, + 80, 64,228,162,215,222,158,244,196,211,118, 27,185,244,116,252,194,102,100,100,216,219, 16, 14,204,155,174,132,255,224, 72,211, + 5, 25,111,181, 7,243,166,165, 20,229, 73,161, 37,169,170, 86, 33,169,172, 74,165,248,254, 32, 33, 33,193, 96, 66,181, 90,130, +166,165, 0, 12, 98, 13, 12, 93, 75,155,128,181,235,219,194,195, 65,235, 87,216,120, 46, 61, 34, 93,241,120, 10, 73,161,101, 37, + 57,207,172,137,104, 74,163, 66,146,112, 69, 46,143,228,233,185,183, 56,222, 75,127,121,144,223,235, 28,111, 98,224, 61,131,253, +175,188,151,254,178,195, 11,254,234,171,175,126,251,237,183,170,170,177, 1, 1,217,158,129,189, 17, 66, 36, 73,242,120,226,139, +138,192,178, 5, 65, 8, 6, 12, 0, 0,184,113, 3, 62,254,184,126,167, 74, 5, 18,137, 93, 95,144, 67,183,166,107,121,110,185, + 10,201,127,203, 47,189,244, 18,167, 28, 45, 73,144,255,224, 56,232, 31,246,114,114,192,194, 51, 60, 60,252,190,240,108,140,103, + 67,186,229, 93,185, 90,226,231, 71,146,228,139, 47,190,248,225,135, 31, 10, 63,239,112,163, 47, 98,235,158,123,103, 69,116,114, +114,198, 59,239,112,145,137, 51,110, 92,174,239,141, 29, 57,114,224,192,129,194,194, 66,132, 16,118,109,241,243, 38,238, 70,100, +100,100,164,166,166,198,196,196,156, 59,119, 14, 33, 52,111,222,188, 59,181, 54, 26,167,226,226,226,199, 31,127, 60, 60, 60,124, +239,222,189, 56, 1, 9, 0,224, 36,154,227,199,143,231, 25,201, 65, 8, 21,228,158,127,115,233, 63, 2,162, 50,207,101,206,190, +120,135, 40, 42,151, 0, 34,141, 38,179, 10, 5,204,127,246, 5,215,134,215, 93,136, 59,236, 20,111, 66, 75, 77,137,207,104, 64, +131, 16, 67, 77,199, 52,184,223, 52, 53,191, 90, 92,116,186,178,244, 74, 97, 65,121,225,173,154, 91,197,181,119, 74,104,157,222, +108,166,107, 25,147,142,161,141,136, 97, 0, 33, 71,101,193,141,167, 95,191, 9,139,223,134,197,111, 99,189, 73,174, 91,225, 74, + 36,124, 33, 45,115,252,242, 2,142, 37,241,182,229, 30, 75, 50,117, 32,213,213,155,113, 63, 29,255,181, 54,123, 14, 75,172,247, +214, 95,191,183, 31, 0,190, 93,101, 94,186,240, 13, 0, 24,154,224,216,139,255,245,215, 95, 79, 25,241,155, 74,149,224,119, 34, +123,195, 10, 64, 8,141, 24, 49,130,167,171, 14, 0,157, 58,119,138,140, 4,238,239,250,117,192, 65,133,162,162,208,198,141,224, +239, 15,254,254,208,181, 43, 36,142,119,192,140,156,210,180,148, 96,248, 99, 51, 43, 45,207,111, 14, 28, 56, 96, 69,127,245, 29, +157,245,235,249,103, 77, 37, 36, 36,112,201,212, 44,177,104,209,162, 70,194,179, 49,126,187, 90,244,143,103,231,231,124,253,245, +171,175,190,218,148,175,241,121,179,179,179,109,242,194,136, 71, 58,127,250,201,199,113, 51,103,190,251,238,187, 54, 79,189,112, +225,194,177, 99,199, 10,164,161, 77,155, 54, 17, 4,145,145,145,129, 16,194,237, 34,150,156, 56, 19, 95, 83,152,205,230, 61,123, +246, 92,189,122,245,198,141, 27, 90,173,214,108, 54, 3,128,201,100,122,226,137, 39, 28,170, 49,163,209,152,179,107,166, 33,239, +163,253,135,111, 22,222,165,106,180, 36,131,160, 68,235, 54,127,241, 10,135,182, 74,165, 18,207, 54, 75, 77, 77,197,109, 33,206, +186,140, 16,194, 27,173,247, 30,145, 77, 43,147,101,247,196,178,251, 41,228,112,216, 55,228,238, 62,203,114, 76, 3, 28,165,208, +146,202, 40, 6, 65,177,182,186, 72,163,170,168, 81,107, 12, 6,181, 73, 95, 97,212,223, 53,232, 74, 12,117, 42,179, 81,205,154, + 77, 22, 14,126,235,246,182,191,109,215,231,115,211, 61, 17,200, 16,200, 4,142,249,184,150, 66,203, 70, 87, 93, 48,111,242, 15, + 7,181, 18,142,101, 93,193, 27, 61,130,198, 63,249,134,148,251, 91,183, 99, 38, 1, 4,127, 53,125,124,216,225,217,139, 19,252, + 78,100, 19, 4,241,195,177, 81, 0,192, 51, 27,137, 67,183, 30,221, 45,200, 23,210,210, 32, 63, 31, 6, 12,128, 85,171, 16, 7, +123,153,132, 57,213,201, 48, 12,195, 48,216,215,201, 52,192, 89,215,167,179,192,242,208, 74,235,189,244,210, 75, 4, 65,216, 83, +142,156,234,177,201,185, 54,119,222,119,211,203,171, 9,210,243,191,175,189,237,185, 39,107,238,220,185, 92,228, 58,101, 84,239, +151,226,134,184,187,187,143, 24, 49, 98,229,202,149, 89, 89, 89, 92, 70, 60, 14,159,148,228,221,237,245, 72, 72, 72, 8,203,178, + 54,105,215,230, 78,123, 15,154, 27,188,158, 55,111, 30, 52, 76,134,181,153, 92, 0,223,108,167, 78,157,138,138,138,142, 28, 57, +210,181,107, 87,137, 68,130, 91,187, 65,131, 6, 9,145,135,145, 61, 98, 55,255,226,123,113,239, 27,195, 7,247,244, 80,144, 30, +238,140,155,220,248,232,227,130, 60,132, 25, 25, 25, 28,179, 55,167,195,238,172,228,180,173, 58,173, 8, 20, 29, 72, 17,210,175, +225,128,179, 86, 97,198,196,255, 58, 76,161,213,115,200, 16,218,211, 93,141,152,171, 90,245,101, 77,213,149,154,202, 43, 53,170, +171, 90, 85,190, 78, 93,101, 52,212,209,116,169, 78,203,147, 12,107,202, 56, 98,253, 10,106,253, 10, 10, 1,133, 8,114,238, 12, +226,249, 25,178,103,167,183,139,140, 12,102, 65, 10, 64, 8,225, 77,103, 83,104,113, 63,198, 44,217,148, 43, 51, 51, 51,133,100, +146,193, 25, 49,151,231, 44,199, 76,138, 21,104,235, 97,201,180,111,126, 87,189,125,252, 74,253,128,245,183,171,204,131,252,234, +211,199,191, 61,127, 79,122,250,102,158,215,105,195,235, 48,103,241, 88,223, 19, 89,163,223, 27, 73, 78,132, 67,135, 14, 9,172, + 18, 97, 97, 97,220,246,152, 49,224,235, 11, 17, 17,240,104,227, 49,191,248,254,253, 29,250, 58, 45,245, 38,222, 35, 68,117, 90, + 57, 43, 45, 70, 24, 4, 73,146, 3, 7, 14, 88, 69, 89,223,184,113,163,144,137,250, 92,171, 96,249,145,181,175, 0, 0,192, 68, + 16,172,206, 40,109, 31,166, 92,189,122,142,135,175,239,161,223,235, 59,242, 79,207,121,243,253,255,222, 88,255,205,191,162,199, + 76,243, 11, 63,176,123,119,211,166,253,137, 84,101,175,222,189,241, 16, 22,215,180,112,109,143,229, 71,155,221,243,212,212, 84, + 60, 10,132,157,155, 28, 75,198,196,196,224,161,152,121,243,230,217,147,156, 8, 33,169, 84,250,196, 19, 79,104, 52, 26,181, 90, +237,230,230,214,174, 93, 59, 95, 95, 95, 33, 57, 57, 16, 66,114,185,124,106,234,135, 91, 79,199,223,186, 83, 19,236, 67, 13,238, + 78,244, 9, 71, 30,222,222,208,182, 33,225,161,243, 70, 46, 3, 97,170,211, 50,133,150,191,127, 38, 8, 75,161, 85,215,183,171, + 46, 47, 79, 71, 27,107,180,186,155,102,179,148, 5, 4,160, 49, 27, 88,132, 16,192,222,242, 66, 45,109,142,136,136,160,236,214, + 58, 98,241,219,247,171,197,250, 21, 0,192, 50, 96,188,150, 95,251,233,246, 26,129,188, 9, 78,166,208,138,136,136,128,181,211, +108, 22, 11,166, 81,135,142,206,200,229,145, 54, 51, 98, 66,107, 78,102,143, 26, 83, 3, 59, 16, 22,158,216,227,185,116,225, 27, +199,175,244,122,127,199,204,215, 62,158,152,145,206,119,193,179, 23, 39, 52,204,195, 63, 4, 0, 42, 85, 2, 66,153, 4, 65, 0, +160,204, 76,190,233, 80, 83,146,167, 30,216,255, 11, 0,204,156, 9,163, 71,215,215, 41,132,208,158, 61, 48,105, 18, 0,192,192, +193,131,122, 69,247, 22,226,235,116,118, 58, 39,247, 8,148, 74, 37, 73,146,150,204,149,158,158, 33,100, 62, 60,118, 14,114, 30, + 79,172, 64,249, 37, 39, 88,140,139, 90,142,149, 59, 76, 16, 75, 16, 4, 93, 91, 43, 13,244,167,220, 61,123, 77, 77,254,247,184, +196,215,240, 4,163,216,126,140,222, 32, 13, 8,142, 30, 52,170, 75,104,248,135,215,126,239,221,187,247,221,211,141,242,187,164, + 42,149, 88, 37,188,144,154,138,231, 48,209, 22,101, 37,145, 80,128,238, 79,123,154,216, 88, 94,197,196,196,224,142, 57,214,110, + 86, 29,243,152,152, 24, 30,222,196,151,237,235,235, 59,104,208,160,235,215,175,159, 61,123,150, 97, 24, 15, 15, 15,157, 78, 39, +208, 41, 25, 28, 28,252,248,227,143,159, 56,122,106, 99,230, 1,111, 66,214, 61,216,152, 95,233, 49,172,187,153,227, 86,123,142, + 75,130, 32,184, 23,150,103,168,189, 53, 36, 39, 56,156, 18,127,127, 90,169,128,153, 73,205, 73,161, 21,144, 60,161,234,203, 93, + 26,146, 45, 51,212,129,217,204, 32, 68, 0, 92,171,171, 46,209,213,112, 41,180,236, 59, 61,208,220, 25,196,230,109,136,243,117, +246,136,164, 41,208, 58,197,155,224,124, 10,173,101,203,150,173, 93, 59, 13,224, 12,199,152,241,203, 11, 48,111,198,199,199, 59, +148,156, 46,103,196, 84,169, 18, 0,212,137,137,155,155,250,100,241, 87, 74, 37, 95,106,182,119,230,239, 89,241,241,228,223,119, +160,193,254, 87,240,188,206, 19,234,213, 4, 16,111,207,255, 17,136, 82,158,243,250,251,103, 17, 4, 49,101,202,148, 45, 91,106, +112,101, 38, 26,198,122,241, 2, 39,140, 31,143, 12,110,106, 59,255,197,127,126,252,225, 71, 99,198,128,229,245, 78,152, 0,255, +250, 23,236, 63, 48,104, 12,239,220, 53,220,251, 75, 78, 78,222,190,125,187,205,233,241, 2, 57, 20, 79,137,183,244,157,165,103, +100,240,204,238,180,124, 34, 27, 55,110,196,212,185, 97,195, 6, 33,146,211,181,241, 10,133, 66, 81,118,251, 86,120,100, 20, 75, + 27, 9,154,145,120,121,123,245,139,247,140,237,207,106,105, 70,103, 68, 52, 3, 12,187,108,211,251,211,103, 78,111, 42,232,232, +109,126, 60, 71,182,250,246,241, 31,173,127, 48,111,222,188,244,244,116,252, 10,112,249,136, 44,217,147,255, 6,187,119,239,254, +209, 71, 31, 85, 84, 84, 36, 38, 38,158, 57,115, 70,167,211,197,196,196, 56,204, 64,131,109, 7, 13, 28,152,250,108,106, 97,113, +225,223,158, 77, 61,121,224,243,187,181,170,248,145,137,193,161,221,172,196,169, 77,197,202, 17, 84,211,153,240, 66,166,196,183, +138,234,180,217,116, 11,228, 77,112, 62,133, 22, 16,208,237,111, 83, 75, 50,182,130,155, 66,141,104, 19, 77,179,136, 13,240,241, + 41,214,106,184,117, 53, 44, 97,111,128, 8,217,242,117, 50, 78,241, 38, 56,191,134, 18,207, 3,197, 44,137,253, 9,150,188,233, +240, 80, 46,103,196,180, 52,111, 82,200,142, 36, 43, 1,129,189,239,101,108,250, 52,247,160, 98, 93,230, 83,191,239, 0, 2,136, + 37,211,190,233, 62,138,101,201, 82,135,117, 32, 37, 37, 19,160, 6, 0, 16, 2, 43, 78,216,186, 46, 27, 0, 60, 58,167, 3,216, + 8,181,208, 43,186,247,127,182,100, 4, 6,253, 2,240, 45,247,218,212,214,118,139,141,235, 29, 28,154,200,207, 47,246, 84, 39, +231,232, 20, 56,194,158,158,158,158,154,154,106,149, 20,215, 33,111, 90,122, 60,241, 11,236, 80,114,186,140, 49, 99,198,204,223, +177,249,223,181,213, 49, 35,135,145,193,126, 8, 33, 48, 35, 96, 17,128,148,160, 36,132,140,218,146,190,222,123,108,124,100,100, +100,139,207, 6,199, 29,243, 77,155, 54,165,166,166,246,237,219,215, 41,219,155, 55,111,102,103,103, 83, 20, 53,124,248,112,146, + 36,173, 92,156, 12,195, 16, 4, 97, 47, 23,241,217,179,103,191,216,250,185,140,146, 39, 63,149, 76,146,228,176, 9,207, 53, 98, +124,154,198,182,205,201,212,251, 48,169,211, 5,122,117, 45,133,214,104,229,156,130,155, 5,103,127,222,175, 53,154,104,134,137, + 28,208, 47,169,243, 83, 14, 57,200,229, 32, 29,152,251, 92, 75,161,197, 29, 1,207,100,138,143,143,231,248, 87,200,245, 52, 39, + 35,166, 82,233,103,239,174,149,202, 44,199,222, 37,210, 12, 0,221, 18, 76, 25, 9,220, 17,106, 88, 97,167,222,186, 46, 27,128, +152,189,184, 62, 34, 3,174,207, 91,215,101,123,116, 78,247,232,156,226,208,188,180,124,220,166,255,142, 35,224,142,143,183, 6, + 0,240,226, 75,135, 47,133,107,115,143,120,216,211, 5, 67,206,227,233,148,228,228, 81, 76,182,125, 56,145,145,237, 95,124,113, +227, 47,191, 20,188,245,125,138, 52,192,183, 83, 59,131, 86,175,215,209, 47, 45,121,149,114,247,223,251,121,198,133, 64, 98,156, + 51,139,208, 25,134, 22,226,235, 23,216, 49,183,119,119,121,121,121, 8,161, 30, 61,122, 84, 85, 85, 73, 36, 18,154,166, 3, 2, + 2,160, 33, 34,137, 76, 38, 3, 0,155,212,137, 16, 58,117,234, 20, 75, 19, 67,134,246, 45, 46, 46,150,201,100, 38,147, 41, 52, + 52, 20,127,165,209,104, 20, 10, 5, 65, 16,114,185,156, 71,177, 97, 86,181,220,112,170,195,238, 90,111,189, 37,169,179,197,232, + 44, 50, 34, 98,193, 60,171,157,102,163,129,148, 72, 91,240, 21,178,228, 62,215, 82,104, 53, 37, 80, 23,206,235,218,233,120,174, +182,181,163,126,120,116, 78, 7, 0,171, 94, 50, 63,105,218,242, 80,119,170,173,238, 4, 0, 66, 30,103, 98, 98, 34,207,108, 30, +129,111,183, 37,125,184, 22, 12,162,176,176,208,161,167,146,223,233, 41,144,134,220,221,221,167, 76,153,130, 3,199, 21, 53, 4, +142, 59,150,125, 0, 7,142, 27, 59,104,172, 61,219, 45,234,119,159,247,123,181,209, 46,222, 72, 75,246,216,211,133,123,236,223, +191, 63,158,194,201,178,172,201,100, 2,128,138,138, 10, 0,240,244,244, 4, 0,188,199, 42,170, 33,119,191,147, 38, 77,194, 63, + 96, 89,214, 96, 48, 0, 64, 81, 81, 17, 0,224, 25, 23,120,143, 76, 38,179,169, 58, 31,110, 96, 51, 49,173,155, 8, 17, 34, 68, + 56, 13, 49, 74,188, 8, 17, 34, 68,136,212, 41, 66,132, 8, 17, 34,117,138, 16, 33, 66, 68, 27,132, 68, 44,130, 63, 10, 98, 5, +135,195,226,112, 78,116,100,139, 16,209,218,212,249, 71, 76, 85,214, 47, 52, 87, 65, 92,147,144,165, 36,232, 8, 32, 16, 80, 44, +200, 0,128, 64, 8, 17, 8,175,194,164,192,244,202,219,106,104, 50,255,224,143,120,191,161,206, 12, 41, 22, 55,158,156, 33,166, +192, 19,109, 69, 91, 81,117,214,227,223,107,118, 60, 63, 67,214, 51,210,124,253, 38,194, 51,225,215,175, 32, 23,191,125,127, 58, +204,186,215, 73, 2, 53, 90,107,100, 3, 8,153,202,110,105, 76, 44,139, 16, 34, 72,223,224,142, 66,214,222, 90,194,203,203,171, +182,182,214, 80,153,167, 8,236, 38,182,198, 14,113, 45,247,172,201,160,235,219,119,152, 83, 86, 54,167,233, 9,156,158,210, 28, + 91,140,240,240,112, 60, 71, 10,199,109,115,234,202, 45, 99,223,184, 54,195, 73,196, 31,160,195,254,249, 23,159,240, 27,204,126, +230, 89,123, 95, 53,199,214,101,108,217,102, 90,191,194, 50, 80,252,125,222,156, 59,131, 32, 16, 2, 64, 61, 34, 97,253, 10, 56, +120,219,206, 33,104, 83,210,249,255,156,170,100, 74,244,236, 61, 19,113, 91,230, 43,141,140,123,100,200, 88,133,155,155,144, 11, +216,115,232,250,238,255, 72,192,104, 2,160, 65,126,245,248,113,253,153, 43, 94, 10, 31,231, 56,212,112, 47, 79, 17,244,231,167, +221,139, 23,178,186,132, 26,163, 35, 17,203, 50,154,138,109, 37,229,100,157,177, 67,124,220,112,129,230,154,138,255, 82, 84,253, +226,218,252,141,203, 99,254,109, 18,126,106, 75,190,219,181,107,215,146, 37, 75,156,186,242,196,196,196,133, 11, 23, 18, 4,177, + 97,195, 6, 23,232,207,197,148,112,127, 13,240,135, 85,195,226,102,243,150, 45,246, 90, 68,110,202, 39, 94,237,206,173,121,231, +226, 91, 63,156,180,110, 45, 8, 18, 90,126, 41,213,186, 21,114, 2,140, 0,128, 83, 96, 2, 0, 0, 53,188, 63,151, 20, 19, 89, + 38,197,156,100, 39,212, 52, 5,108,120,160,103,173,174,130,162, 25,130, 70, 76,173,190,236,196,143,251, 47,156, 24, 62,123,145, +127, 64, 0,255, 5,124,249,107, 41,209,229, 49,128,189, 64,146, 32,117, 7, 74, 50,100,148,103,244, 35,101,159,125,127, 91,225, + 30,230,152, 49,213,121,241,221,107,135, 12,116, 3, 35, 13,112,117,200,198,254,129,149, 57,147, 70,244,120, 96, 15,133, 39,182, + 2, 15,206,159,203,146, 75, 84, 18,210,100, 48, 48, 26,173,219,176, 17,142,227,131, 93,189,126,214, 75, 81, 53,102,168,188, 75, + 88,164,183,183,143,153,166, 43, 42, 42,131,139,238,220,184, 89,112,252,152,106,200,208,199,133,156,151,162,106,152,252,183, 93, +190, 89,151, 87,190,226,184,197,220, 26,118,158, 88,197,109, 13, 89, 89, 89,187,118,237,106,180,108,191,117,120, 4,215,166,250, +116, 54,206,154, 21,125, 75,156,124,174,161, 66, 66, 67, 0,254,251, 71,122, 46, 93, 59, 96,250, 71, 54, 27,164,159,127,254, 25, +111, 39, 37, 37,237,219,183,207,230,182, 99,245, 99, 49,138, 32,124,158,187,109,234, 60,118,244,228,208, 97, 3, 91,182, 92, 89, + 71,209,218, 5, 70,237,110,116, 76,130,188,145, 15, 61, 34,155,155, 20,243, 86,113,233,158, 50, 40,214, 1,141,192,147, 4,137, +148,146,213, 85, 28,218,190,229,137,212,165,246,214,222, 2,192,182,239, 14, 18, 49, 74,188,206, 12,140, 38, 96, 89,144, 48, 64, +146, 94,126,254, 83, 71,221,219,181,223,168,240,227, 19,146, 6,237,237,191, 63, 86,237, 21,220, 30, 24, 22,128, 6, 51,237, 22, + 28,174,241, 15,249,242,200,161,167,135,119,124, 48,175,150,179,188,121,249,234, 89,100,188, 21,214,193,224,227, 45, 39, 73,119, +189,158,174, 82,233, 15,103,109, 84,120,247, 27, 56, 96, 4,143,161,130,170,232, 22,142,122,245,234,121,183, 76,157,115,238,108, + 93,157,214,199,199, 43, 34, 34,140,164,164, 12, 83,116,238,252,209,216,152, 97,109,150,128, 18, 19, 19,185,224,193, 11, 23, 46, +220,176, 97,195, 22, 91, 34, 72, 72, 67,245,128,175, 28,175, 46,219,185,115,103,107,167, 50,231, 4, 96, 70, 70,186,179,231, 33, +195,166, 98, 91,102,187, 47,167, 32, 31, 88,121, 90, 37, 35, 18,190, 46,211,174,234, 60,118,244, 36, 0, 56, 75,160, 71, 95,188, + 97,115,255,176, 15,163,132,151, 5,126,159,133, 16,232, 43,171,245, 0,176,126,133,227,164,152, 61, 34, 9,123, 29,118, 51, 41, + 77,239, 56,181,212,151, 5,146,242, 2, 99,183,130,131, 69, 42, 93, 53, 73,105, 74, 11,239,220,185, 21, 22,102,123,185,228,233, +156,156, 74,223,254, 65, 82,169, 84, 38,125, 98,243, 12,227,182, 39,241,254, 57,243, 6, 79,159,220, 46,164,189, 34, 50, 80, 93, + 98, 63, 2,137,161, 42,111,234,104,141,151,159, 63, 24,140,192,178, 64, 51, 96,166,101,114, 25, 73,128, 41,106,228,182, 31, 50, +102, 60, 62,166, 13,146,136, 81, 91, 18, 30,162, 15, 12,240, 8, 13,105,239,238,225,126,251,118, 9,195,176, 33, 29,189,174, 92, +251,253,188,155, 71, 76,180,237,192,172,151, 46, 29,237,211,205,212,185,115,248,213,107,183,115,114,174, 85, 84,214, 34, 4,126, +126,110, 58, 93, 93,108,108,175,234,106, 77, 73,206,185, 11,151,220,250, 70,199,181,193, 91,182, 74,149,225, 48, 73,134,101, 63, +212, 74,212, 19, 4,193,117, 78, 93,232,245,191,245,214, 91,147, 39, 79,118,118,173,100, 66, 66, 2, 65, 16, 59,118,236,224, 17, + 1, 92, 14,222,251, 29,139,243,231,113, 40,144,216,216, 88, 43,138,108, 74, 43, 92, 88, 0,132,144, 82,153,234,148,176,181,180, +165,166, 87,179,219,125, 31,202, 83,230,110,170, 89,105,221,172, 8, 20,115,168, 64,216,164, 72,129,188,137,113,248,240,225,146, +146,146,146,146, 18,167,162, 69, 53, 77,138,137, 27,174,245, 43,136,117,175, 19, 61, 34, 9, 4, 82,187, 69, 64, 73,162, 6,142, + 27, 57, 58,105,228,200,196,216, 17, 19, 60, 31,123,105, 84, 0, 2, 96, 37, 4, 92,190,100,247,222,243,111, 22,122, 5,132, 74, +101, 18,153,148, 2, 0,249,140,111,241,223,229,139, 5, 96, 48,128,193, 16,211, 89,195,115,193,145,126,234,144, 96, 5,232, 13, +213,247,106,182,126,117,161,123,255,143,183,108, 62,105,214,106,164, 50,169, 84, 42,173, 12,236,127,186,121,113,149,156,194,185, +115,231,184,252, 4,252,146, 83, 33,185,235,230, 38, 85,200,101,225,225, 93,226, 7, 12,240,243,243,147, 72, 40,153,140,242,247, + 83,148,220,185,101,183,125, 70, 37, 94,158,110, 58, 61,125,249,242,141,210, 50, 77, 81,113, 77, 94,129,233,110, 89,109, 69, 69, +245,141,188,130,174,145,145, 33, 29,189,171, 42,138,218,172,228,180,138, 18,207,159, 36,163, 81,213, 34, 73,123, 41,225, 92, 19, +173,155, 54,109,226, 79, 75,217, 20,217,217,217,153,153,153, 56,178, 23,143, 76,179, 76,223,102,153,152,200,242,116,246, 78,141, + 15,139,227,201,187,166,196,119, 44,242,176,253, 45, 0,127,248,146,164,164,164, 71, 31,125, 20,247,202,241, 6,222, 78,106,128, + 16,201,105,217, 24, 76,122,122,165, 43,105,221, 90, 86,129,186,140, 27, 55,110, 0, 64, 73, 73, 73, 72, 72,136,176,206, 59,177, +126, 5,186,126,243, 62,129, 54, 78,138,137,247,155, 38, 61, 45,164, 3, 75, 34,239,160,238, 1, 10,162,200,192, 0,232,245,181, +246,126, 89, 92, 84,212,161, 23, 41,161, 36, 20, 37,101, 24, 51,183,113, 87, 65, 17, 0, 0, 32, 0, 73, 68, 65, 84,255,206,205, + 90,208, 27, 0,144, 55,226, 27,196,136,233,160, 1, 61, 9, 64,220,204,171,120,239,211,219, 35,166,204,169,233,216, 83,118,183, + 76,234,227,143, 88,198,171, 93,104,254,249,253,253,227,226, 90,137, 40, 45,165,196,185,115,231, 4,202, 4,181,234, 94,160, 23, + 65, 51,172,201, 76, 87, 84,170,164, 50,133,209,104, 54,211, 12, 77,179, 52,131,170,213,149,246, 12,101, 82,173,194, 45,180,170, + 74, 83, 83,171, 83,169,245,222, 1,125,135,244,233,115,234,216,190,142, 38, 90, 83,163,233,222, 61, 82, 46,147,104,107, 85,109, + 83,114, 90, 38, 4,198,216,184,113,163, 64,143, 39,206,189,222,116, 39,127, 79,147, 11,126,154,154,234, 63,118,236,253,120, 31, + 37, 37, 37, 0,176,123,247,238,202,202, 74,129,113, 94,178,178,178, 48,111,226,223,239,218,181,203, 30,127,113, 9, 42,160, 33, + 49, 17, 14,223,137,227, 31,115,126, 82,123,188,143, 67, 46,205,155, 55, 15,107, 85,155, 55,104,239, 93, 78, 73, 73, 73, 30,156, +181, 29, 96,250, 6, 45, 57,189,218,166,237, 0, 59,217, 0, 44,125,154,246,252,158,173, 84, 55, 90,126, 53,145,149,198,116, 74, +114,106, 52, 26, 75, 2,221,184,113,163, 67, 41,244,252, 12, 10, 0, 45,126, 27, 54,111,131,245, 43,234,255,122,220, 79,249, 67, +244,136,116,212,200, 35,228,165,175,242,214, 87,186,105,171, 60,180, 21,221,203,115,206, 85, 25,170, 89,130, 6,240,105,207, 51, +119, 12, 49,198, 90,138, 34, 41,201,253, 50,140, 58, 52,119,194,232,112,172, 58, 11, 74,229, 60,231,244, 70, 38,208, 25, 64,111, + 40,190, 81, 30, 28,210,169, 71,207,158, 0,224, 43,161, 37, 18,137,132,146, 80, 20, 89, 92, 84,212, 74,188,105, 41, 37,240, 71, +252, 62, 56, 84, 13, 12, 3, 90,157, 89,171, 53,213,212, 24,203,203,213,165,165,149,181,181,198,186, 58,115, 93,157, 73,171, 53, +107,170,237,170,108,163,145, 54, 24, 24,179,217,228,229, 37,235, 20,226,237,238,225, 1, 0, 17,145, 93, 66, 59,122,251,120, 43, + 16, 98,204, 52,107, 52,106,219,166,228,180, 74, 8,204,209,159, 67,225,217, 52, 51, 7,198,134, 13, 27, 28, 70,179,182,232,255, +222, 7,126, 76, 37, 37, 37,153,153,153, 66,250,100,217,217,217, 59,119,238,228,120, 51, 33, 33, 33, 57, 57,217, 30,241, 17, 4, +209, 52,193, 6,174, 18,220,126,132,144,163,144,125,200,202,237,102,233,172,176,103, 19, 24, 24, 72, 52,104, 75,103,109, 91, 10, +123,190,124, 11,255, 9, 55, 17,164, 58, 31,152,222,108,120, 69, 25,129,241,229,158,159, 46,239, 25,105,186,222,144,139,119,241, +219,245, 41,133, 27, 20, 40,238,179, 83,235, 86, 16, 12,120,254,102,199,215,201,210,230,110,199, 51,228, 4, 91, 97, 34,129,161, +239,220, 45,249,111, 9, 41, 5,164,161,136,129,177,118,231,205,132,134,134,252,246,197, 43, 19,150,127, 71, 42, 20,222,222, 62, + 95,244,122, 9,144, 17,134,117, 4,130, 0,163, 1, 88, 56,125,213, 11,186,218,189,242,130, 50,121,223, 64, 3, 0, 49,190,127, +112, 96,213,141, 28, 67,105,164,127,213,209,208,101, 82,138,161, 40,146, 49,212,186,144, 3, 89, 8,176,222,196,210,192,114,222, + 6, 78, 24,203,111,235,231,223,174,180,240,178, 92, 70,153,204,172,193, 88,124,167,184, 74,165,174, 81,169,116, 85, 42,125,149, + 74,239,235,223,197,158, 97,121, 37, 42, 43,175,236,217, 51,178, 90,173,150, 74,200,154,218, 98,109, 53,251, 72, 87,109,112,187, +118,238,238,238,114,185,219,221,178, 90,130,242,107,155, 29,118,155,137,216,176,199,147,223, 16,107, 82,171, 92,196, 2,243,115, +112,152, 54,109, 26,167,194,112, 84, 89,130, 32,166, 78,157,154,152,152,200, 63,205,219, 74,111, 98, 88,106,216, 70,125, 32, 59, + 9, 54,240,254, 77,155, 54,225,236,105,120,255, 29, 91,231,221,180,105,211, 11, 47,204,195,113,163,231,205,155,199, 5,250, 75, + 79, 79,199,215,207,195,185,155, 54,109,250,120,180,223,244,141, 58,171,158,251,244,141, 58,108,251,143,209,210,214,230, 77,203, +237,150,233,176,187, 70,154,195, 62,140,194,227, 69, 78, 73, 78, 14,150,188,153,148,148,196, 19, 91,190, 71, 87, 22, 79,219, 28, +222, 31,142,156,182,225,250,124,110,186, 39, 2, 6, 1, 65, 34,187,250, 26,177,204, 15,151,138,170,204,200, 64,131,150, 1, 21, + 77, 34, 64,149,122,212, 61,105,178,183,167,151, 93, 14,234, 23, 91, 92, 92, 92,122,229,215, 46,253,146,100, 50, 57, 24, 77, 64, +146,192,152,112,235,185,251, 55, 19,219,117, 18,207, 61,158,206,147,245,141,172, 5, 2, 20, 36, 49,244,209,136,161,230, 11, 64, +200,183,151, 75, 77, 38,150, 49,212,157,248,239, 43, 35, 6,246,109,165,138,130,131,129,227, 60,177,184, 61, 23,194,155, 0,208, + 55, 58,238,218,229, 28, 84, 82,163,211,155,213,114, 3, 2,181,193, 64,215,212, 24,239, 85,234, 74,239,214, 13, 31,109,119, 50, +150,222, 20, 88, 80, 88, 17, 17,222, 57, 60, 60,180,170,170,210,207,151,137,138,242, 9,106, 23,161,112,115,171,174,174,203, 57, +123,189,184,164,166,125,104,175,182, 67,151, 8,128, 32, 0, 83, 22,199, 92, 54,231,102,218,104,223, 44,230,213,224, 92,196,150, +212,185,126,253,250, 95,126,249,197,158, 45,126, 34, 56,148, 53, 78,250,100, 73,118,152, 58,147,147,147,121,122,235, 22,157,253, +108,167,226,118,219, 75,176,129,247, 59,204,136,137, 16,250,207,127, 54, 97, 79,110, 76, 76, 95,206, 65,217,160, 34,237, 70, 2, +197,182,228, 52, 53,182, 77, 25, 44,231, 10,102,218, 6, 45, 56,138,132,157,148,148,196, 77, 30,120,244,209, 71,185,167,227, 84, + 63,125,238,178, 53,247,169, 99,237,114,129,236, 41,105, 35, 74, 19, 99,198,140, 25, 78,253,158,104,112,104, 78, 25, 71, 76, 25, + 71,214, 87, 71, 2,205,157,129, 16, 72, 89,228, 19, 25,233,205, 66, 5, 1, 12,107,127,194, 25, 2, 66,195, 82,149,102,150,102, + 81,141, 25,213,154, 89, 19, 37,137, 24, 61,118,228,136, 71,121, 78,221,163, 91,247,187,241,165,103,206,124,149, 87, 83,217,117, +240,147,208, 21,192,100, 2, 32,206, 23,212,158, 43,244, 48, 71,205,228,191,114,182,199,200,221,135,182, 61, 54, 88, 86,255, 14, + 33, 18, 88, 19, 0,152,245,181,165, 23,127,141, 8, 9,136,237, 23,219, 74,133,140, 83, 41, 96,189,137,187, 96,194, 7,109, 67, +195,186,159, 57,177, 63, 40,208,221,221, 93, 2, 0, 70, 35, 83, 83,107, 82,169,245,157,194,123, 13, 27, 50,210,158,213,132, 9, + 83,127,249,249,179, 19,167,174, 12, 31,218, 55, 44, 44,204,108, 50,196,198,244,241,240,241,185, 93, 80, 84, 82, 90,125,236,247, +107,234, 90,159, 41,131, 71,182, 29,234,156, 87,159, 44,147,152,167, 84, 98, 42,100, 45, 24,147, 36, 9,158, 20,105,169, 74,165, + 69,108,101,130,101, 89, 78,120,226, 44,196, 73, 73,227, 27,232, 25, 38,206, 90,217,180,103,106,143,239, 8,130,224,231, 77, 75, + 36, 39, 39,219,211,152, 60,181,162,105,130, 13,110, 63, 79, 0,121,142,115,113,226, 76,203,129, 29,135, 94, 32, 75,219, 29,139, + 60, 45, 27, 20,238,227,254, 11,102,123, 5, 98,233,223,124,192,190, 78,219,212, 57,100,232,128,102,250, 23, 92,211,155,220, 13, + 11,196,181,155,168,103,189, 91,211, 65, 82,204, 97,253,205,190,221,237, 81, 39, 50, 48, 64,179, 8, 33, 36,235, 24,213,177,125, + 88,239,254,131, 67, 59, 58, 94, 33, 59,122,212,104, 79, 79,207, 67,191,238,251,225,224,231,240, 83,125, 62,150,205, 23, 99, 98, +250,245, 23,114,241,101, 97, 51, 62, 59,240,117,108, 39,109, 76, 23, 47, 64,168,186,206, 92, 91, 81,148,127,244, 91,195,245,253, +241,241,113, 61,186,117,111, 61,106,136,141,141, 77, 77, 77,197,217,162,172,102,159, 56,120,172, 67, 70, 2, 64,222,245,171,165, + 5,183, 73,146, 96, 24,164,112,243,239,214,179,247,148, 39, 28,100,215, 8, 10,233,115,226,212, 62,131,129,142,238, 29, 17,210, + 49,176,232, 78,185,250,210,205,220,188,162,236,131, 23,111,151,160,231,158,255,167,192, 11, 40,220, 83,235,242, 93,223,186,117, + 75,224, 47,217,237,126,194,191,157,188,155,215,246,230,103,156,240,220,184,113, 35, 20,108,181,252,129,149,173, 77, 17,106,201, + 50,206, 9, 11, 39, 95, 97,123, 9, 54,132, 36,222,224, 40,210,234,103, 66, 90,101,246,246,174,157, 27,159, 1,128,148,193,141, + 58,230,220, 71,123,212,249,112, 87,103, 73, 90,164,208, 91, 4, 46,132,203,223,178,141,105, 32, 74, 7, 73, 49,143,158, 54, 77, +178,203, 69, 68,173,137, 54,209, 80,110,130,105, 79, 61,239,237,237, 35,252, 2,250,199,247,239, 31,223,255,244,153,211, 0,245, +158, 84,129,188,137, 97,238, 53,115,243,217,211,212,241, 43,213, 21,249,103,202,125,114,139, 30,143,236, 20, 60,106,244,168,254, +241,253, 91,187,180, 99, 99, 99, 93, 91, 88, 50,108,200,200, 97, 67, 70,158,191,148, 83, 94, 86,238,225,225,193, 35, 54, 27,189, + 66,125,226, 98,250,196,125,245,101,198,213,220,147, 29,130, 61, 21, 10,105, 93,157,169,228,110, 13, 33,233,244,220,243,207, 8, + 60,181,167,255, 98,151,239, 23, 79,207,124, 8, 56,251, 50, 68,254,253,254,244,166,156,197,173,199,125, 0,144,154,234,223, 64, +184,174,208,138, 61,166,115,200,128,174,101,230,224,110,211,178,159,254,224,177,121,237,114,203, 62,187,139,212,217,156,101,230, +173,177, 68, 93, 8,174,223, 36,123, 68, 66,143, 72, 52,183,161,187,223, 48,194,206,206,157, 46,217,188,157,118, 80, 4, 50,185, +193, 47, 84, 91,107, 0, 15,228,238,238,238,194, 5,244,143,239,223,243,133, 67,241,161, 26,223,128,174,209, 78,230,209,137,233, +215, 31,160, 63, 0, 12, 7, 56,125,230,244, 3, 32,205,150,233,245, 71,199, 65,180,211, 86,179,158, 86, 30, 61,126,184,162,170, + 66, 95,166, 83, 40, 2, 66,195,251, 8,100, 94,104, 94, 34,154, 22, 73, 98,131, 16, 11,174, 45, 38, 46,216, 90, 63,212, 94,240, +121,107, 63, 23,167, 58,233,109, 4,227, 38, 77,119,168, 31, 7,180,142,175,115,210,211, 43,241, 24,209,230,181,203, 45,119,186, +174, 58,255, 88, 64,245,119, 65, 91, 46, 90, 95,191, 2, 0,168,168,174, 10,128, 58,135,141, 94,210, 11,205,141,107,185,104,201, + 43,205,191,145, 63, 10,111, 54,203,147, 51,100,100,219,191,200,205,234, 53,115,253,150, 55,218,149,233,239,186,109,206, 98,167, +196,230, 95, 13,201,243,211, 30, 98,139,200,177,167, 83,188, 9, 98, 90,183, 63, 16,196, 80,199, 34, 68,180, 29,136, 81,226,255, + 48, 16,121, 80,132,136,182, 3, 49, 55,145, 8, 17, 34, 68,136,212, 41, 66,132, 8, 17, 34,117,138, 16, 33, 66, 68, 27,196,195, + 79,235, 54,114, 64,136,189, 95,106, 85,101,120,195,195,191, 61,222, 56,124,170,196,242, 7,198,118,193,246,108, 15,108, 88,128, + 55, 18, 23,213,143,223,201, 43,202, 5,158,183, 41,132,159,183, 41,172,206, 27, 31,107, 55,140,113,101,225, 21,188, 17, 24, 94, +191, 42,241,204,185,210,150,186,223,164, 3,182, 3, 68,250,116,236,248,183,134,128, 99,105,193,245,199,223,151, 56,183,165,158, +175,165,109,110,110,174,101, 68,140, 69,139, 22,117,239,222,189,149,234,149,104,219, 34,182,151, 46, 93,194, 27,209,209,209,206, +218, 54, 13, 94,254,151, 72,235,134,195, 7,224,109,167, 22,195, 54,211, 86,171, 42,243,240,111,143, 73,179,125,167, 46, 0, 80, +102, 63, 16,100, 83,250, 72, 92,148,134, 73,228,227,221,167, 0, 96,254, 99, 3,218,120,219, 85, 89,120, 37, 48,188, 23, 38,205, + 94,241, 67, 1,224,202,153, 99,173,125,191, 63,214,213,237,215,106,199,123,120,236,215,106,161,188,252,212,178,165, 0, 48, 96, +237,123,173,122,167,135, 14, 29,218,182,109,155,193, 96,224,246, 40, 20,138, 25, 51,102,140, 26, 53, 74,148, 48,109, 10,151, 46, + 93,138,142,142,198,164,233,108,157,196, 17, 39, 48,105, 58, 85, 39, 45, 99, 65,185, 54,235,200,133, 52, 19,173, 66,157,153,153, +153,158, 61, 83,184,109,167,232, 47, 51, 51, 51,197,163,157,179,182,152, 46,221,124, 2,180,170, 50, 76,154, 54, 21, 40,143,230, + 26, 48,107,249,129, 13, 11,240, 3,107,250,173,205,105, 88,150,135,197,169, 50, 16, 66, 44,203, 2, 0,195, 48,248,122, 72, 74, +202, 47,244, 0,160, 67, 80, 48, 0,152,106,170,141, 52, 13, 0,117, 52,131,175,199, 39, 40,148, 95, 99,250,116,140,172, 44,188, +130, 43,168, 45, 5,234,215,178,247, 11, 0, 11,202,203, 1, 0,243, 38, 38, 77, 0,200,253,229,128,229,183,147,120,159,148,198, +163,178,202,179,162,186, 42, 63,200,183,103,104,101, 87, 33, 15, 55, 55, 55,119,251,246,237,150,188, 9, 0, 6,131,193,205,205, +173, 67,135, 14, 86,218, 83,196, 67, 36, 77, 92, 39, 47, 93,186,212,180, 78, 54, 40, 80, 63, 30,230, 26, 48,107,185, 82,169,108, + 90, 39,241,183,246,234,164, 82,169,220,180,245,155,251, 31,231, 60,229, 44,253, 89, 50, 47, 79,192,160, 86,167, 78,165, 82,201, +241, 38, 0,120,246, 76, 17,126, 53, 74,165,146,227, 77, 0, 72,241,104, 39,196, 86,171, 42,115,243, 9,240,241,246, 2, 0,252, +175,213,183,237, 59,117,177, 39, 63, 15,108, 88, 48, 96,214,242,217,211,159, 4, 0,252,175,213,183, 31,239, 62,229,176,233,163, + 40, 42, 52, 52,148,162, 40,147,201,164,213,106, 25,134, 81,171,213, 2, 11,209, 83, 66,125,186,241, 59,185, 15,148,223,130,211, +117, 37, 21,101,249,255,219,240,170, 67,177,233,211, 49, 50,180, 99,123, 0,192,255,218,236,185,187,118,191, 60,171,240, 22,148, +151,143,247,240,120,107,193,124, 0,120,171,129, 52,191,204,203,187,207,155,142,150,240,221, 66, 71, 96, 64,201,140,206, 79, 27, +217,174,114, 22, 93,171,204, 62,119, 32,183, 43,251, 2,255,253,110,216,176, 65,175,215,111,221,186,117,206,156, 57,120, 15,222, +214,235,245, 10,133,162, 53,115,141,137,112,130, 55,125, 58, 70,230,157, 59,222, 43,126,168,101,157, 60,248,211,183,193,193,193, + 92,207,221,222, 91,207, 83, 39,149, 74,229,253, 80, 84,142,120, 19, 0, 54,109,253,198, 5,246,116, 1, 54, 3,116, 10,156,234, +222, 38,134,137, 44,121,179,145,186,169,169, 45,187,115,203,205, 39,160,169, 8,181,201, 35,150,248,124,251,183,243, 31, 27, 48, + 96,214,242,166, 13,160, 21,100, 50, 25, 69, 81,222,222,222, 5, 5, 5,106,181,154,101, 89,225,188,217, 33, 40,216, 83, 66, 77, +249,231,234, 71,103, 14,217,115,185,164, 76, 15,206,242,166, 37,138, 75,203,174,156, 57,214,206,207, 27, 0, 64, 66,185,112,191, + 73, 83,103, 3,128,159, 68,234,144, 55, 1, 96,101,218,199, 43,211, 62,198,188,185, 95,171,125,101,220, 36, 0,128,118, 50,158, + 43, 63,231,179,119, 92,114,199,191,135,189, 32, 37, 61, 61,192,157, 4, 42, 36,120,232,176,169, 99, 11, 58,110,224,239,170, 3, +192,231,159,127,142, 25,211,234, 95,238, 7, 2,113,228,200, 17,145,230, 90,137, 55,223,126,109, 81,102,102,230,127, 63,122,223, +146, 55, 51, 51, 51,211,210,210,120,234,164, 37,111, 54,173,147,143, 14,141, 5, 0,240,242, 16,200,155,247,217,211,153, 20, 59, + 15, 30, 18,123,146,115,221,235,207,206,157, 57, 30,239,217,252,245,254,151, 87, 11,146,193,156,228,124, 36,105,208,155, 59,119, + 3,192, 52,207, 32, 33,194,211,138, 55, 53, 53,181,122, 77, 21,238, 47,227,175, 52, 53,118, 67,230, 88, 61,179,207,183,127,123, +234,171, 53,184,239,128,191,250,124,251,183, 60,167,142,140,140,172,170,170,170,170,170,146,201,100, 36, 73,234,245,122,181, 90, + 77, 81, 20,195, 48, 14,227, 47,236,250,254,187,189,103,245, 27, 23,142,235, 16, 20,236,238,225,127, 71, 91,242,191, 13,175,122, + 74,168, 58,154,161,120,109,173,120,179,184,180, 76, 83,122, 19, 0,122,132, 6,221,170,168,150,187,203,141,122,163,179,247,251, +234,150, 61, 95,190,179,184,119,196, 35,215, 10,175,217,179,197,188,105,169, 52,247,107,181, 0, 80,160, 92, 53,229,167, 79,122, + 13,136,184,146, 99, 55, 10,239, 5,217,158,161,163,130,219,121,244,212,163, 90,202,164,149,209, 70, 13,201, 24, 8,196,202, 60, + 67,134,199,239,124,245,157,228,152,215,108, 26, 98, 23,167, 92, 46,231,252, 80,248,173,192,219, 6,131, 65,161, 80, 8,247,120, +126,249,229,215,195,135, 15, 23,201,174,197, 17,218,177,125, 74, 74, 74,102,102,102, 78, 78, 78,196, 79,223,118,139, 29,146,119, +238, 56, 30,180, 72, 73, 73,113,173, 78,190, 55,103,210, 71,251, 78,180,143,232, 80,118,187,188, 85, 47,158,115,176,186,224,235, +116,109, 69,165, 93, 95, 39,230, 77,175, 71,166,213, 94,221, 49,119,230,248,151, 87,127,226,212,113, 49,111,186, 0,174, 87,110, +165, 67,245,154, 42, 15,255,246, 0, 37, 60,182, 92,175,220,170, 13, 60,245,213,154,196, 69,105, 80, 97,251,225,209, 52,237,238, +238, 78,146,164,159,159,159, 78,167,211,106,181, 0,208,174, 93,187,170,170, 42,135, 81, 9, 12,106, 24,224,230,246,202, 71, 71, + 18,251,194,237,115,128,163, 45,191,242,209,145, 15, 23,141,102, 88, 70,200,253,114, 14,248,177,113, 61, 36, 94,228,254, 67, 87, + 99,123,116,242,246,148, 31, 62,147, 31, 24,222,235, 86,227, 17,118,123,247,187,251, 42,130,187,240,216, 88, 98,203,158,130, 0, +191,240, 39,135, 18, 60,247,139,121, 19, 51, 38, 0,160, 55, 55, 64,136,134,120,254, 13,180,234, 45, 32,245,196,169,119,210,130, +131,109,198,254, 51,244,184, 29,230, 59,161,134,169, 51,170,243,255, 87,244,245,209,199,212,143, 60, 55,122,220, 63, 61,221,252, +186, 43, 36,126,146,199, 52,167,191,229, 11, 95, 66,146, 36, 87,158,150,219, 78,225,200,145, 35, 4, 65, 28, 61,122,116,216,176, + 97, 46,216, 2,128, 72,187, 60, 24, 51,241,201,130,130,130,156,156,156,204,204,204,184,130, 2,156,185, 62, 46, 46, 46,105,100, + 60,174,147,209,209,209,183,120, 71,171,185, 58,121,247,251, 53, 94,189, 20,158, 81, 11,119,172,121,174,111,239,246,221, 39,173, +206,200,200,104,141,145,110, 75,246,124,152,170,147,243,114,122,253,127,123, 95, 30, 23, 85,185,255,255, 57, 51,103,102, 24,246, + 85, 80, 17, 17, 16, 92,114, 67, 43,115, 55,135, 44, 81, 43, 21,205,180,205,202,193,186,149,230, 66, 89,253,110,247, 86, 38,150, + 91,246, 77,161,155, 90,138,154,104,166, 32,165, 98,138,187, 41,154,107,130, 48, 34,136,128, 44,195,192, 48,251,156,231,247,199, + 35,231, 30,103, 57,115,102, 96, 16,189,231, 93, 47, 95,135, 51,231,115,214,231,188,207,251,243,121, 62,207,243,233, 53,213, 50, +162,231, 40,226,105, 17,229,100, 98,170,119, 7,235,130,165,214,192,210,210,218,121,103,145,156,204, 15,157, 53,105, 58,148,156, + 0, 80, 83, 83,211,161, 67, 7,172,137,140, 70, 35,238, 29,242,243,243, 19,137, 68,101,101,101,236, 83,251,111,200,205,123, 99, +252, 72,172,151, 10, 77, 80, 93, 89, 4, 0,163, 98,193,247,243, 67,243, 22, 12,113,120,206,183,110, 87, 2, 64, 68,135, 64,165, + 94, 79,250, 10,117,213, 26, 16, 8, 58,118, 13,223,255,199, 25,142,215,251,202,252, 47,110, 28, 63, 72, 86, 66,125, 40,120, 10, + 4,131, 35,187, 61, 57,146, 45,113,138,169, 55, 55, 79,123, 99,167,190, 0, 98,116,112,154, 4,111, 18, 38, 12, 12,159,240, 10, +155, 60,239, 28,104, 48,212,137, 76,198, 77,165, 91, 78,190,234, 55,226,249,103,123,116,232,121,121,255,225, 1, 73, 77, 34, 67, +147,169, 7, 85, 93,197,214,149,135,185, 18,199, 58,153,203, 78, 97,243,230, 45,105,105,107,147,147,223,114,150, 58,143, 30, 61, +154,145,177, 21, 31,151,103, 79, 22, 60, 61,121,102, 84, 84, 20,214,158, 88,111,134,118,236,232, 84,155,156, 61, 97,196,169,219, +119,124,250,249,148,239, 43, 6, 15,201,228,119, 94, 14, 12, 31,239,214,115,182,118,237,157,162, 81,215,166,255,112, 16,235,196, +218, 51,125,203, 62,215, 46,233,211, 41, 19,165, 62, 62, 4, 65, 0, 65,176,148,129,102, 74, 75,155, 65,207,102,201,201,134, 63, + 51,150,218, 12,184,220,149,156,246,209,208,208,208,216,216,168,215,235, 41,138,170,174,174,198,222,186, 70,163, 81,171,213, 14, + 29,246, 93,107, 62, 62,124, 25, 84, 37, 96,212,194, 55, 41,163,177,183,126,238, 60,252, 85,113,156, 75,113, 37,213,237,226, 64, + 63,175,160, 64,175,184,216,158,138, 27,213,133,229,181, 17, 65,126,250,170, 59, 38,163,137, 78,237,100,185,222, 33,163,158, 29, + 54,122,250,174,172,237,135,142,108,223,178, 98,254,228,249, 75, 46, 26,161,186,246, 14,203,245,210,145,205,215,134, 60, 62,163, + 87,215,237,187,254,184,120,177,100,197,165,252,109, 9, 47,195, 15, 39,202,203,171,233,212, 78, 27, 14,157, 78, 98, 54,212, 24, + 12, 42, 0,192,165,232, 26,164, 74, 0,208, 82, 26,129,190, 73,218, 36,172,170,176, 77,157,248, 54,234,116, 58,186,135,157,185, +236,172,228,196,204,235, 84,196,243,232,209,163,155, 55,111, 89,183,238,187,180,180,181, 25, 25, 91,249,104, 41,123,155,180, 88, + 67,183, 73, 58,181,147,165, 77, 14,127, 52, 78, 54, 52,246,139,127,127,189,124, 85,206,255,219,252, 71,242,147,131, 42,119,231, +168,148, 13,246,184, 44, 45, 45,109,206,171,211,173,215,207,113,166,155,168, 21,245,166,139,117,216, 45, 58,214,103,191, 56,118, +249,199,175,167,111,217, 71,123,235, 88,120,114,151,156, 55,142, 95, 1, 0,129, 80, 72,138, 68,211,252, 59,218, 44, 46,104, 33, + 45,109,118, 22,113,149, 96,182, 2,213, 14,109, 3, 2, 2,170,171,171, 37, 18, 73, 99, 99, 99, 72, 72, 8,238, 50,210,233,116, +245,245,245, 14,169,115,246, 23,219,190, 73, 25,237, 23, 9,135, 47,195,187,169,135,188, 73,225,164,247,190,188, 69, 85,102,172, + 88, 36, 20, 16, 92, 36,231,192,129,177, 33, 81,145, 29, 66,130,197, 2,194, 68,160,234, 38,173,178, 81,199,241,122,151, 47,253, +245,185,158,221,124,125,131, 60, 67, 58, 25,235,148,231,179,183,214,215,113,173,163,185,126,233, 63, 96,158,140, 52, 25, 34,155, +224,142,176,225,155,138, 51, 32,246,117, 16,157, 40,110,168, 17,104, 75,197,154, 65, 49,163,123,189,236,173, 8, 56, 28, 18,114, +190,203, 96,133, 74,208,168, 71, 90,205,102,202,195, 78, 41,167,214,154,205,123,243,230, 45, 51,102, 76, 7,128,153, 51, 95,220, +188,121, 11,119,195,140,140,173, 51,103,222, 45,121, 50, 99,198,244,140,140,173, 60, 69,218,107,147, 39, 79,158,196,241,205,129, + 3, 7, 2, 64,102,102,230,207,123,114,184,183,201,221,187, 62, 29,155,242,206,184,113, 99,130, 37,194, 70, 2,237, 43, 44, 59, +121,185,220, 33,241, 89,176, 39,254,179,205,186,137,112,237,117, 90,111,114,100, 79, 54, 37,184,252,227,215, 1,192,217, 40,231, + 61, 47, 91, 83,147, 65,167, 19,144, 66,161,136, 20,137, 37, 30, 30, 30, 14, 37,167, 5,105, 86,150,149,112,151,156, 22, 15,242, +237,137,143, 57,148,156, 0, 96, 54,155,195,194,194,244,122,125, 85, 85,213,237,219,183, 3, 2, 2,234,235,235,177, 86,114, 72, +157,213,149, 69, 31,127,126, 72, 85, 2, 95,205, 31,254,207,247,134,204,254, 98, 91,198,242, 69, 66, 82, 76, 18, 4,233,200, 86, +117,187,184, 99,176,191, 8, 68, 4, 16, 21, 55,174,220,188,163,234,228,231,163,213,232,206, 21,151,115,145,156,147,103,189, 47, + 10, 4,129, 16, 54,230,220,216,249,221,194,177,175,207,189,252,247,133,183,199,116,117,120,189,251,154,154,150, 79,156, 10,245, + 30, 64,136, 96,249,215, 83,206, 28, 93,250,216,115, 39, 78, 93, 34, 86, 46, 98,145,156, 0,112,161, 50,152,208,170,212,208,164, +241,240,136,158,236, 27, 62, 73,164, 26,235,173, 15,143, 53,153, 53,198,154,242,227,107, 84, 49, 49,209,238,107,223,199,142, 29, + 35, 8, 2,251,218,248, 95,142,226,241,232,209,163, 8, 33,218, 73,199, 11,199,142, 29,227,137,210, 26,133,231, 79,208,241,205, +183,102, 77, 77, 74, 74, 2,128,252,252,252,223, 78,156,227, 34, 57,167,201, 30,247,163, 2, 4, 32,218,185,242,157,239,178,255, +154,250,104,239, 27, 69,165, 83,150,108,114,168, 10, 49,123,210,255,211,219,187,155, 61,153,140, 9, 78,246, 23, 9,236, 73, 78, + 28,238,180, 23,241,116, 40, 57,167,122,119,152,230, 27, 38, 16, 8, 68, 18, 49, 41, 18,147, 34,177, 88,234,145, 20, 20,190,100, +201, 18, 46,146,147, 73,154, 14,121,211, 66,114, 50, 73,211, 33,143, 0,128, 82,169, 84,171,213, 34,145, 8, 75, 78,138,162,240, +191, 92,168,115,211,202, 15,207,149,231,121,135,193,194, 53, 71,125, 72, 97,117,101,145,175, 68, 84, 95,119, 75, 40, 32, 72,214, + 0, 5,150,156, 93, 2,125,174, 42,110,152, 12, 6, 9, 41, 86,171,117, 23,110,220, 14,238,214,219, 33,111,226,235,125,246, 31, +159,101,124,179, 90, 67, 65,151,232,240,203, 87, 78,189, 63,161, 31,199,235, 5,128,247,163, 7,101, 93,255, 3, 84, 38,240, 8, + 62,240,231, 85,226,203,119,190, 13, 13,101,231, 77, 0,232,103, 24,127,252,192,159, 96,104, 84, 19,141, 74,129, 90, 69, 26,141, +230, 6,137, 78,227,113,251,198,182,197,215, 35,251,199,178, 79,213, 44,149, 74,241,130,135,135, 7,253, 17,165, 87, 58,164,191, + 77,155, 50,214,173,251,142, 94,243,210, 75, 51, 54,111,222,226,144, 61,113,136,147,150,156,180,240,220,180, 41,131,119,219,173, +219, 36,221,159,254,241, 39,243, 36,164, 56, 52, 52, 20,179, 39, 61, 56,144,189, 77,190, 49,170,239,220,175, 87, 55, 86,221, 9, +241,237,112,229,106,233,171, 43,182,164,165,165,113,244,166,211, 24, 96,250,224,237, 54, 69,137,109,190,206,198,171,219,193, 86, +127, 17, 23,108, 87,223, 1,128, 25,193, 93, 0,128, 20,145,164, 88,172, 85,171, 3, 66, 67, 61,133,158,236,146,147,153,150, 36, + 66, 70, 48,105,238,106, 67,210,211,161,228,100,166, 37, 1,128,234,206,221,238, 60,150, 33, 61, 52,123, 2, 64, 88, 88, 24, 0, +212,213,213,249,250,250, 98,111,157, 75,113,152, 77, 43, 63, 4,248,114, 78,210, 72,248,230,232,119, 31, 37, 78,153,191,122,203, +210,183, 73,130, 16, 75, 60, 28, 74,206,171,165,119, 98,186, 4, 31,204, 61, 5, 0,126,157,162, 1,192,168,191,235, 25,137,236, +155, 99,201,249,249,172, 49,239,254,115, 99,151, 40,194,169,235,197,146,243,169, 93,235,247,207,152, 78,132, 15, 6,128,177, 94, + 94, 0,144,165,190, 59,151,254, 4,111,111,150,211,238,171, 95,116,225,183,108, 93,220,137,200,238,143, 52, 72,225, 6,220,108, + 44,169,174, 94, 98, 86, 43,195,231,189, 60,159,253, 70,173, 93,187, 86, 42,149,106,181, 90,186,183, 80, 42,149,174, 93,187,150, + 11,111,102,100,108, 77, 75,187,103,203, 97,195,134, 33,132, 50, 50,182, 18, 4, 97,175,203, 40, 57,249, 45,132,208,204,153, 47, + 90,244, 11,225, 63, 51, 50,182,102,100,108,101,210, 49, 31,229,252,226,211,143,127,201,250,109,236,176,120,186, 77,250,117,138, + 30,168, 80, 60, 61,121,102,105,173, 38, 34,200,147, 93,114,206, 77,207, 90,252,250, 83,157,194, 70, 97,254, 5,128,220,220, 92, +188,129, 83,195, 17,105, 50,197,188,233,190,209, 65,216, 55,111,229,228, 36,215, 72,211,195,219,139, 20,137, 1, 96, 86,151, 56, +145,135,196, 59, 32, 0, 0,180,141,141, 70,131, 1, 0,196, 82, 15, 41,105,100, 49,199,153, 73, 94,129, 97,148,217, 40, 66,119, +183, 52, 18, 34,123, 67, 33,153,192, 89, 17, 9,243,190,165, 25,132, 35,111,210,236, 73,167,193,215,213,213,113,186, 65, 12,246, +220,212,156, 18,254,253,146,230,113, 53, 70, 53,123, 33,177, 46,129, 62,127,214,212,255,117,189, 60,184, 91,111,154, 49, 29,242, + 38,198,179,255,248,108,103,188,215, 63,158,239,225,194,245,190, 31, 61,104,254,158,237,196, 23,255,252, 45,244,241, 85,234,203, +244,250, 1,164, 40,220, 67,226,240, 98,251, 25,198,255,182, 71,119, 75, 89, 92, 93, 91, 81, 85,232, 45, 52,251, 14,237, 59,124, +244,203,163,221,244, 62,211,244,103,253, 19,102,192, 77,155, 50, 54,109,202,176, 32, 86, 12, 22, 90, 28, 62,124, 56,223,207,110, +179, 77, 62,241,196, 19, 22,109,242,233,201, 51, 1,128,133, 55, 49,222, 24,213, 55, 33,247,244,140,127,254, 52, 98,196,136,208, +123, 61, 24, 23,120,147,201,158, 92,210,201,173,215,184,192,182,217,206, 20, 98,248, 47, 51,224,108, 88, 46, 54, 73, 73, 73, 90, +171, 53,119,109,155,170,239,238,151, 36, 69, 34,145, 68, 34,145, 72, 36, 82,169, 20,255, 91,128,180,227,198,141,251,171,196,110, +172,211, 43, 48, 76,104,210,128, 73, 35,100,144, 38,151, 1, 79,216, 61, 87,221,185,197,228, 17, 46,164,233, 23,210,201, 96,208, +187,246, 92,103,124,182,233,250,181, 43, 46, 55,211, 63, 11,203,112, 3,101,242,166, 67,210,196,120, 57,222,203,181,235, 5, 0, + 98,229, 34, 76,154, 52,111,114, 36, 77, 26,207,116,155, 2,248,179,192,173,134,221,186,117,235,240,192,161,181,107,215,210, 35, +136, 54,110,220,136, 37,231,198,141, 27, 89,178,214,216, 85, 33,207,128,173, 11,155,109,210, 33,105, 98, 36,124,252,125, 43,146, + 38,147, 61, 91,101, 27,238,140,233,116, 89, 55,153, 76,198,253, 58, 45, 82, 91,157,178,253,171,196, 50, 45, 22, 71, 51, 49,105, +130,147,164,137,163,123,174,145, 8, 0,152,204, 20, 23, 73,107, 19,119,234, 84,220, 15,196, 4,142,102,186, 70,154, 45,185, 94, + 28,205,204, 82,171, 93, 38, 77, 30, 15, 43,112, 47, 80,105,173,198, 5,210,196,204, 69,251,230,173, 69,154,109, 0,139,154,110, +192,151,117,227,193,131, 7, 15,183,130,159, 37,158, 7, 15, 30, 60,120,234,228,193,131, 7, 15,158, 58,121,240,224,193,131,167, + 78, 30, 60,120,240,120, 24,112,255,203,186,253,175,217,234, 42,203,184,219,122,132,117,105,221,115, 22, 34, 68, 82,160, 23,218, + 78,245, 23,153,193, 36, 0, 68,240,207,151,183,125,152,109, 31,126,213,233,236, 24, 44,133, 66,145,219, 12,133, 66,193,127, 24, + 45, 32, 49, 35, 51, 65,208,188, 89, 90, 90,122,242,228,201,115,231,206,149,150,222,157, 52,196, 40, 4, 68, 56,177,195,214,154, +215,131, 71,251, 71, 65, 65,129, 83, 27, 39, 39, 39,187,124, 32,151,109,239,143,234,108,111,112,150,251, 20, 10,197,210,165, 75, +167, 78,157,202, 52,143,138,138,226,110,174, 80, 40, 50, 51, 51,147,146,146,162,162,162, 28, 26,206,158, 61,219,225, 62,167, 78, +157,106, 51,187,237,192,129, 13, 92,108,149, 74,175,214,189,165, 52,105,222,185,115, 71,175,215, 19, 4,225,225,225,161,211,233, + 74, 75, 75,207,156, 57,211,175, 95,191,152,152, 24,167,118,200,101,160, 42, 0,200,229,115,184,108,102,115, 68, 80,203,108,229, +118, 54, 78,227, 94,127, 81,161, 80, 44, 9,158,140,246, 22,147,135,239,153,221,199,188,236, 79,148, 83, 60, 61,228, 23,144,244, +112,120,122, 99,199,142, 5,128,125,251, 92,153,188, 49, 41, 41, 19, 0,228,242,128,150,100, 74,226, 50,206, 14, 39,204,125,243, +205,217, 8,129,245, 83, 93,176, 96, 62, 23,115,186, 85,172, 90,181,106,228,200,145,201,201,201, 91,182,108,105,104,104,112,120, +208,123, 40,137, 20,190, 48, 68, 44, 79,150, 47,251,253,171, 5, 9, 11,240,202,239,191, 79,127, 48,168, 51, 55, 55,215,226, 57, + 89,175,105,111,212, 73,243,166, 76, 38,195,217,185, 10,133,130, 35,117, 98,218,197, 68,128,135, 69,165,164,164, 56,182,205, 12, +116,180, 99,187,119,172,105,130,131, 58,104, 32,229, 66, 73,174,204,240,170, 82,169, 58,116,232,128, 53,163, 84, 42,189,115,231, + 78,125,125,189,159,159,223,159,127,254, 9, 0, 92,216,147, 46, 22, 77, 16,196,228,201,147,101, 50,153, 67, 14,221,179,231, 87, +188, 48,113,226,115,246,150,237,217,106, 79,220,173, 60, 42, 29,242, 45,189,204,252, 83, 58,196,238,164, 39,191,255,126,207,132, +247, 71,142, 28,193, 19,208,208, 55,106,243,230,205,236, 13, 35, 53, 53,245,139, 81,253,129, 32, 44,202, 98,163,173,197, 64, 16, + 78, 53,209,182,127,137,152,188,153,150,150,134, 16,202,200,200, 56,118,236,216,184, 23, 63,178,183,241, 9,171, 82, 94,187, 50, +231,175, 92,185,146,162,168,244,244,244,140,140, 12,223,136,145, 54,233,146,118, 65,174, 93,187, 70, 16,196,244,233,211, 1,224, +197, 23, 95,228, 66,184, 95, 31,184, 91, 13,169,114, 95, 5, 65, 16, 91,222,243, 4, 32, 82,158, 94, 4,191, 3, 0,108,253,113, + 75,242,200, 54,210,161,220, 71,181, 11,108,190,144,153,153,153,233,233,233, 22,175, 10, 71,247,185, 37,158, 50,211, 22, 11, 64, +238,182,233,233,233,244,160, 38,153, 76,198, 93,111, 98,218, 37, 8, 34, 41, 41, 41, 45, 45, 13, 31,148,227, 85, 16, 83,149,248, +127,150, 53,246,224,157,189, 22,255,207,178,198, 33,111, 34,132,112,147,229,232, 59, 43,149, 74, 63, 63, 63,129, 64, 48,107,214, +172, 25, 51,102,136,197, 98,169, 84,234,225,225, 65, 16,132, 80, 40,204,207,207, 87,169, 84, 44,230, 87,175, 94,149,203,229, 59, +118,236,192,183, 11, 33,180,115,231,206,228,228,228,171, 87,175,182, 49, 29, 88,208,168,155, 62,222,169,169,169,105,105,105, 47, +118,216, 53, 61,120,167,197,205,255,232,241,191,200, 67, 47,112,217, 79,114,114,242,194,133, 11,187,117,235,230,194, 57, 36, 39, + 39,203,229, 1, 65, 65, 7, 91,174, 55,105,222,116,202,156,230,205,249,243,231,179,152, 51,155,223,170, 85,171, 70,140, 24, 1, + 0,211,167, 79, 31, 57,114,164, 67,222,176,176,157,246, 4, 9, 0, 91,222,147,190, 48, 68,188,104,236,194,182,108, 84, 78,141, + 97, 23,216,114, 16,238, 78,210,135,181, 27, 45, 49,184, 16, 25,110,109, 45,105,169,174,185,219, 54,217,208, 89, 19,154,118, 83, + 82, 82, 56, 14,231,191, 95,160,121,211,162, 9, 58,108,166, 26,141, 70, 32, 16,188,240,194, 11, 42,149,234,246,237,219, 34,145, +136, 36, 73, 60,225, 0,158,214,232,204,153, 51, 44, 77,124,245,234,213, 4, 65, 76,153, 50,101,221,186,117, 50,153, 44, 45, 45, +109,202,148, 41, 0,240,205, 55,223, 60,100,161, 61,154, 55, 1,160, 91,183,110,204,161,198,114,185,156,118, 74, 56,170, 72,153, + 76,182,110,221,186,204,204, 76,215,162,195, 31,126,248, 97,102,102,166,197, 72, 71,142,188,185, 98,197, 10,130, 32,146,147,147, + 51, 50,238,206,179,199,101,182, 42,154, 55,177,185, 64, 32, 56,123,246, 44,151,105,250, 10, 10, 10, 8,130,120,225,133,187, 31, +149,233,211,167,143, 26, 53, 42, 57, 57,121,247,238,221, 14,195, 62,149,251, 42,128,128,140,119,239,142,254,220,242,158,231,244, +161,146,148,167, 23,181, 67,222,180,237,176,203,100, 50,186,180,147,130, 81,218,201, 97, 43,105, 45,222,108, 21,234,108, 9,150, + 46, 93,234,242,133,180, 25, 92,120, 9,139,138,138, 4, 2,129, 80, 40, 44, 42, 42, 66, 8, 21, 20, 20, 24, 12, 6,130, 32, 72, +146, 36, 8,194,108, 54,107, 52,154, 93,187,118,217,123,208, 7, 15, 30, 4,128, 41, 83,166, 48, 55,192,203,248,197,102,105, 33, + 76,127,220,222, 50,139,192,180,231,185,179,184,234, 22,126, 58,214, 65,220,177, 36,120,242, 23,163,250,147,114,139,248,230,105, +148,163, 80,112, 9,230, 48,100, 35,254,186, 96,142, 56,120,240, 32,119,159, 29,219,118,239,222, 29, 56,135,149,153,152, 51,103, + 14, 29,154,152, 51,103, 14, 46, 79,194,157, 55, 71, 14, 21, 2, 0, 69, 81, 11, 22, 44, 88,181,106, 21, 54,159, 48,241, 77,246, +106,133,180,228,164,129, 61,247,156,156,156, 30, 61,122, 0,120,177,219, 78,123,226,158, 9, 37,182,188,231, 9, 0, 91,183,156, + 47, 8, 43, 96,183,109, 21,222,156,157,178, 52, 61,245,131, 22,197, 58,103,207,158,141,197, 38, 93,218,201, 41,222,180,169,125, + 88,194,112,246,108,153,235,221, 87,238, 46, 55, 55,151,158, 22,144,121, 14,174, 69,166,208,246, 0,151,207, 68, 61,222,113,151, + 8,125,146, 22,239, 18,253, 39,179, 78,175, 5,234,234,234,124,124,124,234,234,234, 78,156, 56, 33, 20, 10, 13, 6,131, 86,171, +197,147, 58, 35,132,140, 70,163, 94,175,103, 97,100,172,196,173,239,137, 76, 38,219,177, 99, 71,102,102, 38,203,237,106,121,172, + 83, 58,228, 91, 38, 81,226,101,142, 4, 58, 98,196, 8,103,217, 19,237, 45, 6,184, 27,223,164,131,230,104,219, 13, 0,130,123, + 12,157,249,117, 1,128,117,235,214,201,229,114,215,194,157, 31,126,248, 33,142,210,114, 55, 71, 8,209,113,198, 97,195,134, 29, + 61,122,212, 41,189,137, 16, 50,153, 76, 76,243,188,227,230,175, 83,147, 29, 74, 78,204,149,214, 88,185,114,101,226,140,143,237, +217, 50,162,156,247,106, 82, 14,182,173,197,155, 45, 85,157, 22,218,179,141,245, 38, 51,110,208, 54, 9, 70, 76,223,156,217,247, +202,206, 5, 44,209, 79,151, 57,148,142,114,178,115,232,158, 61,150,133,154, 55,109,218,244,210, 75, 47, 49,164,220,195,236, 55, + 66, 0, 0, 32, 0, 73, 68, 65, 84, 68,185, 92,110, 29,234, 54, 24, 12,117,117,117, 58,157,206,207,207, 79, 34,145,152, 76, 38, +132,144,217,108, 54, 24, 12,184, 20,168, 67, 37,107, 47,104, 51,101,202,148, 54, 8,113,216,235, 47,226, 2,204,158, 78,188, 24, +135,167, 91, 95,236,244,224,157, 78,133,224,153,146,147,254,194,113,252, 36, 51, 37,167,205,143, 37, 59,182,108,217,130,119,178, +110,221, 58, 23, 66,156, 88, 51,145, 36, 57,111,222,188,179,103,207, 54,155, 59,104, 30,171, 87,175,182,152, 3,112,219,182,109, +121,121,121, 8, 33,252, 45,103,201,175, 92,181,122,213, 11,131,239,145,156, 51,190,209,108, 59, 97, 68, 8, 13,120,113, 64,242, +200,100,183, 22, 34,118, 1, 2, 22, 45,134,111, 31, 29,244,100, 65, 84, 84, 84, 74, 74,138,107,103, 96,207, 22, 87, 52,229,174, + 28, 45,128,123,219,157, 13, 15,113, 73, 57,106, 15,152, 56,113,226,196,137, 19,233, 63, 49,111,210, 43,173,185, 21,195,199,199, +199,108, 54, 43,149,202,154,154, 26,165, 82,169,209,104,112,225,207,134,134, 6,149, 74,165,213,106,245,122, 61,174,165,108, 47, + 38,181, 99,199, 14,135,159,159,118,133, 35, 12,208, 43,107,106,106,232,101,150,248,157,245, 84,138,116, 52,220, 5,201, 73, 11, +207, 29, 59,118,184, 28,241,220,177, 99, 7,151, 38,157,145,145,145,151,151,135,187,134,146,147,147,241,181,115, 76, 45, 2,128, +143, 82, 70,230,229,229, 81, 63,251, 35,132, 86,174, 92,137,205,143,156,160,154, 37,160, 93,201, 73,187,231, 0,176,117,107,198, +156, 57,115,242,242,242,230,206,157,235,240,208,149,251, 42, 8, 32, 50,154, 37,231,139,171, 53,194, 23, 84, 91, 79, 24,230,206, +157,155,250,251,178, 54, 8,113, 58, 43, 57,237,170,206,244,244,116, 58,196, 73, 7, 61,217,105, 5, 51, 32,214,143,206, 58,215, + 22,182, 88,135, 70, 69, 69,185,230,164,211,201, 73,109, 9, 44, 54, 93,243,214,177,216,228,226,173,211,188, 73, 47,208, 44,105, +115,165, 5,130,130,130,106,107,107, 13, 6, 3,174, 0, 74,146, 36, 86,157, 77, 77, 77, 26,141, 70,175,215,171, 84, 42, 22, 73, +133,165,165,205,196, 53,252, 43,235, 57,183, 66,172,147,227,250,123, 66,150,182,106, 97,125,244,209, 71, 95,124,241, 69,112,112, +176, 91,155,132,181,228,164,225, 48,226,105, 45, 57,157,210,155, 51,102,204,152, 57,115, 38, 66,104,201,146, 37,139, 23, 47, 30, + 49, 98,196,140, 25, 51, 56,154,127,252,193,200,195,135, 15, 19, 59,130, 0, 96,255,199, 62, 79,125,222, 56, 98,196,136, 47, 82, +243, 16, 66,236,178, 23,231,114, 2,192,182,109, 91,242,242,142, 34, 2,205,155, 59, 47, 46, 46,142,203, 65, 87,173, 90,245,194, + 16,209,127,149, 38,160,121,115,231,133, 62, 21,230, 66,132,183,109,120,211, 54,117,210,122,115,224,192,129,204,160,167, 67, 71, +131,201,128,174,105, 79,108,219, 66, 63, 29,159,179,139, 12,232,230, 71,213,114,224,144, 2, 93,108,139,169, 61,109,174,100, 34, + 60, 60,188,168,168,200,108, 54, 55, 52, 52, 24,141, 70, 28,226,212,233,116, 56,195, 9,247, 26,177, 68,241,100, 50, 89,102,102, + 38, 22,158,116, 75,200,205,205,181, 88,211,102,177, 78,166,255,110,239, 94,217,139, 23,127,244,209, 71,211,166, 77,251,249,231, +159,185,135,149, 44,150,151, 4, 79,126,125,212,214,233,185,182, 83,226,199,142, 29,123,227,198, 13,139,172, 82,140, 27, 55,110, + 0,107,122,124, 82, 82,102, 82,210,152,132, 4,133,117, 80,181,182,118, 12,128, 82, 46,183,251, 38,210,133, 37,176,176,221,191, +127, 63, 0,112,231, 77,129,128, 64,219, 3, 0,243,230, 69,211,134, 67, 6, 0,248, 34, 53,143,203,171,129,155,211,156, 57,115, + 16, 66,243,222,159, 23, 23, 27,199,241,160, 11, 23, 45, 32, 8, 2, 33, 16,190,160,194,182, 97, 79,117, 4,196,174,113, 91, 19, +214, 93, 67,217,155, 63,115,152,218, 73,218,115,190,232,174, 33,186, 11,149, 75,236,175, 85, 60,119,103, 51, 58,255, 7, 65, 59, +200,204,194,129, 22, 43,109,198,134, 70,142, 28,153,147,147, 99, 50,153,234,235,235,113,172, 19, 0,170,171,171,235,235,235, 17, + 66,120, 36, 21,203,113,223,123,239,189,213,171, 87, 99, 2,101,198, 55,223,123,239, 61,119,127,117,180, 39,254,193,133, 46,109, +242,136, 53,165, 38, 39, 39,115,228, 77,107,254,106,238, 50,114,252,129,183, 57,160,176,164,164, 4, 56,116, 66,210,225,178,123, +207, 92,198,229,122,107,107,107,247,239,223,207, 12, 50,114,129, 92, 46,167,126, 14,216,127,209, 4, 0, 27, 15, 25,182,157, 48, + 32,132,142,158,116, 34,182,112,228,200,145,185,115,231,114, 84,154, 52,112, 35,252,249,164,113,238,220,185, 97, 99, 59, 54, 51, +113,123,127, 7, 73,155, 13, 11,167,151, 51,229,134, 67,135,221,162, 97,185,204,158, 45,223, 9, 61, 22,147, 35,236, 21,101,226, + 66,223,214, 30, 58,119,159,221,218, 67,231,232,179,211,125, 89,204,183,194,230, 74,155,210, 32, 49, 49, 49, 35, 35, 67, 44, 22, +235,245,122,147,201, 68, 81,148,191,191,191, 82,169,228,146, 71,209,171, 87,175,180,180,180, 3, 7, 14,224, 46,117,156,227,249, + 64,148, 82, 96,226,143, 63,254, 72, 76, 76,204,206,206,118,129, 55,105,150, 81,164,164,176,184, 71, 11, 23, 46, 4, 59,169, 41, +139, 22, 45, 98,143,117,202,229, 1,246,108,229,242, 92, 46, 12,232, 80,119,179, 96,236,231,141,255, 13, 4, 59,195,155,223,125, +231, 98,109,209,175,191, 90, 30,246, 84,199,251,210, 18,172,165, 37,247,209, 68,118,147,147, 28,174,113, 43,218, 50,163,211,169, +194, 74,247, 18,180,139,148, 49,117,234, 84,144,186,120,182, 56, 22, 97, 81,169,149,201,245,120, 37,251, 21,205,152, 49,163,184, +184,248,208,161, 67, 90,173,214,108, 54,247,239,223,127,234,212,169,220,239,121, 66, 66, 66, 66, 66, 2,214, 11, 28,197,102,107, +197, 58,237, 45,179,240,136, 69,159, 47,199,242,235,230,101,127,162,173,197,211, 67,238,161,206, 55, 26, 6,188, 62,122, 27, 41, +127, 1,167,196,227,159,108,170,123,150,251, 63,102,204, 24,135, 13,210,133,159,232,235, 37, 8,226,249,231,159,199,163,230,157, +133, 96,154,146, 32,136,137,207,206,198, 95, 89,156,138,196, 28,100,233, 14, 12,156, 25,255, 32,122,126,237,113,250, 15, 23, 62, +149,109, 47,124, 90,114,196,150,204,235,209, 90, 87, 26, 29, 29, 29, 29, 29,109,177,210, 96, 48, 8,133, 66,161, 80,216,218, 15, +116,237,125,178,181,209,144,102,206,156,201,201,139,204, 41, 6,130,192,113, 42,122,229,235,163,183, 1, 2,135, 97,141, 7,232, +197,177, 50,119, 28, 98,108,245, 36,161, 54, 27,159,222,186,224,203,186,241,224,193,131,135,243, 10,157,191, 5, 60,120,240,224, +193, 83, 39, 15, 30, 60,120,184, 29, 36,127, 11,120,240,224,193, 4, 97,189,132,232,127,120,240,212,201,131, 7, 15,155,188, 73, +220,253,207, 10, 8, 16, 79,160, 86,212,201,151,133,226,109, 31, 38,219,151, 39,246,161,151, 5, 2, 1, 78,162,162,243,108, 80, + 51,240, 6, 63,237,185,196,180,173, 47, 57,228,225,225,129,183,199,211,244, 49,109,241, 60, 41, 20, 69, 1,128,209,104,244,233, + 50,226,127,224, 62, 19, 66, 82,130, 40, 19, 69,153,178,143,221, 98,166, 42,217,179, 69, 8, 85, 85, 85,133,133,133,185,112,220, +150,216,114,185, 94, 94,117, 2, 0, 36, 39, 39,211, 47,128,179,201, 25, 45,183,229,152,136,206,163,229, 16, 24,154,200,218, 27, +221,117, 23, 59,155,202, 10, 81,183, 91, 62,189, 52,190, 93,197, 94, 62,246,182, 63,118,236,216,176, 97,195, 48,105, 98,250, 35, + 8,130, 73,127, 84, 51,110,222,188,105, 97,123,238,220,185,129, 3, 7, 74,165, 82,146, 36,133, 66, 33,109,142, 25,211,220, 12, +189, 94,159,159,159, 63,170,203,136,246,127,247, 16, 66,181,181,181, 39, 79,158,244,247,247,183, 72,116,117,172, 67, 9,129,196, + 35,208, 63, 32,174, 73, 93,174,110, 44, 35,128, 0,194,129,252,164, 40,106,199,142, 29,133,133,133, 0, 32,149, 74,231,207,159, +207,253,112,216, 86, 81, 92, 36, 20, 10,197, 18,201,220,185,243,218,103,245,192, 7,158, 58,241,164, 44,206,214,206,108,185, 45, +253, 56,221,157, 48,204, 3, 16,106,188,249,183,234,200,118,141, 70, 31,249,184, 64, 26, 78,116, 47,189,248, 40, 92, 80,234,189, +255,242,124,185,134,232,108,211,232,234,213,171, 66,161,112,248,240,225,100, 51, 48,141, 98,177,105, 50,153,204,102,179,209,104, +188,121,243,230, 31,127,252, 33, 12, 26,196,180,213,104, 52,231,207,159, 31, 60,120,176, 88, 44,166, 39,210, 23, 8, 4, 20, 69, +153, 76, 38,147,201,100, 52, 26,181, 90,237,249,243,231,213,106,117,123,190,115,139, 23, 47,166,151,167, 76,153,210,216,216,216, +191,127,127, 23,108, 55,109,201,151, 74, 59, 8,133, 98,117, 99, 25, 65, 0,194,217,159,246, 91,253,237,219,183,213,106,245,139, + 47,190, 24, 21, 21,133, 71,133, 6, 6, 6, 14, 26, 52,200,230,198,175,142,189,103,140,192,165,107,215, 14,251,120,190,191,242, +223, 3,226, 31,169,184,117,103,127,206,225,200, 71, 6, 52, 52,168,218, 59,117, 50, 53,148,189,229,246,134,150,156,155,203,182, + 76,215,143, 39, 55,183,194, 80,118, 85,114, 98,147, 94, 67, 77,138, 17,198,133,152,168, 64, 36, 10, 20, 54,214,138,165,141,218, +158, 23,190,205,143, 77,214,120,118,181,249,128,254,254,251,111,177, 88,252,228,147, 79, 98, 6, 20,137, 68, 2,129, 0, 79,234, +108, 50,153,244,122,125, 89, 89,217,161, 67,135,204,102,179,197, 24, 0,129, 64, 96, 52, 26, 47, 92,184, 48,124,248,112,169, 84, + 42,145, 72,176, 45,166, 78,189, 94,175, 86,171, 47, 93,186,164,211,233, 28, 14, 31, 40, 41, 41, 41, 43, 43,107,108,108, 20,139, +197,161,161,161,221,187,119,199,161, 0, 46,104,137, 45, 69, 81, 31,127,252, 49, 61,113,212,226,197,139,175, 94,189,218,161, 67, +135,160,160, 32,142,188,185,126,214,172,113, 3, 6, 0, 64,216, 59,239, 72, 61, 67,213, 13,165, 13,170, 98,132,204, 2, 1,129, + 40, 7,205, 62, 48, 48, 48, 56, 56,248,167,159,126,122,229,149, 87,246,236,217, 19, 24, 24,120,228,200, 17,131,193, 0, 16, 97, +115,251,218, 47,223,167,151,189, 13,198, 78, 38,221,220,133,255, 92,249,245,191,190,250,250,187,206, 2,243,119, 95,175,120,242, +133, 23,237,217,182, 28, 22,165, 53, 56,166,186,219, 78, 78,178,158, 39,198,122,185,253,160, 37, 19, 79,184,108,139, 39,220,198, +243, 59,240,222,186,251,160,171,175,137,185,177,215, 87,104,142,241, 67, 93, 35,144,176,175, 88,252,120, 79,159,254, 17, 30, 30, + 70, 19, 5, 66, 74,164,203,221, 36, 48, 53,218,104,217,205,165, 68,206,159, 63,239,233,233,233,227,227,227,235,235,235,239,239, +239,235,235,235,235,235,235,233,233, 89, 91, 91,155,151,151, 39, 16, 8, 4, 2,129, 77, 91,179,217,124,229,202, 21,145, 72,228, +235,235, 27, 16, 16, 16, 24, 24,136,205, 37, 18,201,223,127,255,173,215,235,177, 20,101, 57,249,139, 23, 47,254,254,251,239,217, +217,217, 89, 89, 89, 89, 89, 89,217,217,217, 71,143, 30,109,106,106,226,114,225, 46,219, 82, 20,165,211,233, 42, 43, 43,153, 43, +151, 44, 89,114,245,234,213, 17, 35, 70,120,122,122, 58, 38, 5,161,152,249,103,229,154, 53, 83,158, 11,175,174, 58,163,110, 44, + 3, 0, 28, 55, 38, 88,203,129, 30, 59,118,236,244,233,211,243,231,207, 15, 13, 13,157, 52,105,210, 75, 47,189, 52,102,204,152, +156,156, 28, 46, 47,228,230,162,138,157,103, 47,103,102,124,215, 53,188,195,251,239,188,180,228,179, 5, 47,245,138,226,100,219, + 26,188, 9,156,139, 20,145,109,195, 80,110,141,117,186, 76, 94, 45,177, 37, 8,194,162,156, 55, 15,119,160,238,202,185,219,229, + 13,157,252, 73, 17,101, 36,131, 41,242,137,167, 61,194, 62,161, 76,165,112,249, 21, 84,220, 80,171, 17, 71, 8, 53, 23, 46,158, +240,139, 31,107, 77,127,184, 92,221,245,235,215,131,131,131,199,140, 25,227,229,229, 69,146, 36, 69, 81, 90,173,182,160,160,224, +200,145, 35, 66,161,144, 36, 73,235,217,157,241,122,177, 88,108, 54,155, 11, 11, 11, 71,141, 26, 21, 24, 24, 40, 18,137,140, 70, +163, 74,165, 58,123,246,172,209,104, 20,137, 68,216,121,103,209,140, 7, 14, 28,168,172,172,140,142,142, 14, 11, 11,107,106,106, +186,118,237,218, 31,127,252,225,229,229, 21, 31, 31,207,174, 31, 75, 74, 74, 14,228, 30,172, 82, 25,124, 99, 6,135,133,116, 49, + 54,169,106,174,159, 61,144,123,208,161, 45, 69, 81, 13, 13, 13,133,133,133, 37, 37, 37,125,251,246, 93,188,120, 49, 22,158,216, +251,118, 40, 90, 5, 66,177, 84, 26, 44,245, 12,203,216,118,113,198, 11,125,215,207,154, 5, 0,179,214,175, 7, 0,163,241, 46, +107, 11, 8, 16, 16,132,153,176, 27,236,204,201,201,201,201,201,249,232,163,143,124,124,124, 0, 32, 61, 61,125,208,160, 65, 53, + 53, 53,177,177,177, 14, 31,247,234,243,215, 87,159, 43,220,189, 97, 25, 41,212, 18,102,243,178, 85,235, 39,142, 27,115, 91, 64, + 58, 59, 27,147, 83,188,201,148,153,220,139,187,145,220, 41,178,125,122,166,248,172,240,172, 7,220,231,193,110,185,109, 59, 15, + 98, 60, 52,240,213,213,230,148,234, 58, 43,133, 3,124,137,144,106,136, 33,253, 4, 68, 16,210, 85, 53, 85, 17, 87, 74,169,202, + 38, 29, 41, 16, 0, 85, 8,246,169, 83, 34,145, 20, 23, 23,119,238,220, 57, 33, 33, 65, 40, 20, 82, 20, 85, 91, 91,123,236,216, + 49,145, 72, 36, 22,139,241,176,125,202,202, 22,155,139,197, 98,132,144, 66,161,136,137,137,241,243,243, 83,171,213,231,207,159, + 55,155,205, 18,137, 68,175,215,235,245,122, 22, 61,113,230,204,153, 91,183,110,245,235,215,111,212,168, 81,225,225,225, 77, 77, + 77, 33, 33, 33,185,185,185, 39, 79,158,116,232,122,159, 57,115,166,170, 78, 21, 24, 59, 56,106,248, 52,255,240, 88,125, 83,125, +233,233,189,215, 15,254,232,208, 22, 71,105,111,223,190, 29, 26, 26, 26, 27, 27,123,241,226, 69, 76,154, 52,129,218,156,251,249, +238, 7,131,244,240, 15,136,243, 15,140, 19, 8, 68, 70, 99,211, 15, 27, 14,205,122,109, 52,182,125,243,205, 55, 67, 66, 66,176, + 45, 65, 52,135, 57,109,133, 59,143, 29, 59,150,149,149,245,214, 91,111,117,236,216, 17, 0, 14, 30, 60, 88, 82, 82, 34,149, 74, +165, 82,105, 98, 98,226,137,171, 90,150,171,222, 82, 80,182,252,204,181,255, 44, 77, 9,143,235,218,164, 86,238,254,237,204,197, + 75, 5,254,136, 18, 87, 86, 37,254, 99,198,241, 43,218,118, 29,235,196,147,180,179, 47,183, 43,180,132,185,120,214,107,255,168, +174, 41, 59, 81,161, 77,244,244, 60, 90, 70,117,138,151,116,211,231, 43,175,190,181,107,217, 69,170, 68,165, 54,160,242, 70,179, +148, 20,152, 84,149,126,182, 20, 0,205,158, 30, 30, 30, 55,111,222,188,118,237, 90,239,222,189,149, 74,229,169, 83,167,112, 4, +211, 94,176, 18, 87,165,167,109, 17, 66,101,101,101,125,250,244,201,205,205,165, 40,202,195,195, 67, 36, 18,225,158,119, 22,135, +189,180,180, 84,167,211, 13, 28, 56, 48, 60, 60, 92, 40, 20,250,250,250, 62,254,248,227,167, 78,157, 42, 45, 45,213,235,245,236, + 87, 93, 90, 90, 74, 9,196,157,251,203,252,195, 99, 5, 66,145,212, 55, 36,226,241,196,155,167,246,176,219, 34,132,234,235,235, +203,203,203, 35, 34, 34,134, 14, 29, 42, 20, 10,241, 44,241,175,188,242, 10,222,192,207,207,143,229,160, 30, 30, 65, 65, 33,253, + 12,122, 85, 77,237,121,189, 94,105, 52,170, 1, 0,219, 86, 85, 86,210,182,132,125, 95,189,162,162, 34, 35, 35, 99,198,140, 25, +125,250,244, 1,128,253,251,247,231,228,228,124,248,225,135,161,161,161,205,155,216, 77, 18, 42,108,208,164,228,253,181,116,129, +124,248,120, 89,147,186,102,251, 47,121,105, 63,236,252,237,253, 87,163,238,220, 74,109,168, 12, 12, 12, 98,177,117, 25, 22, 97, + 77,238, 51,206,217, 86,157,204, 89, 97,236, 45,183,127,180, 65,242,208,186,117,235,218,255,172,242, 15, 58, 46,212,105, 85, 6, +234, 66,181,233,118,189, 41,244, 20,217,119,123,209,205,146, 43, 5,167, 13, 38, 82,104,160, 64,103, 64, 74, 68,133, 4, 32,155, +244, 71,167, 37,225, 46,242,170,170,170,174, 93,187,150,148,148,224,148, 35, 92, 66, 25,131,139,131,194,236, 21,108,159,207,157, +162, 40, 28, 12,237,214,173, 27,243,147,112,246,236, 89, 0,136,139,139,195,133, 24,236, 77, 70, 78, 16, 2, 0,208,106,170,212, +141,101,102,179,142,105,187, 7,160,168,168, 40, 38, 38, 38, 37, 37, 5, 16,216,244, 63,149, 74,229,154, 53,107, 18, 19, 19,135, + 13, 27, 6, 0,199,143, 31,255,245,215, 95,223,126,251,109, 6,111,218, 69,133, 70,255, 82,206,169,185, 83, 19,167,188, 52, 89, +163,107,216,181,231,240,170,239,182,252,244,212,163, 81,119,218,168,148, 27,237,167,115,159, 14,169, 53,147,147,218, 85,239,188, +203,201, 67, 56, 0,186,110,221, 58,154,124,185, 7,127,185,219,242,224, 8,173,217,215, 72, 84,158,173,209,147, 4, 28, 84,232, +194, 50,169,166,142, 29,138,196,106, 82,169,212,131,192, 83, 8,128,144, 36, 40,204, 30,217,225,204, 77,179,217,108, 50,153,130, +130,130,188,189,189,187,118,237,122,249,242,101,188,198, 34, 49,158,105,139, 51, 55, 77, 38,147, 86,171, 69, 8,117,233,210,165, +188,188,188, 99,199,142, 87,174, 92,209,235,245, 6,131, 1,239,153,165,105, 69, 68, 68,220,186,117, 43, 63, 63,223,199,199, 7, + 59,236,167, 79,159, 86,171,213, 17, 17, 17, 18,137,132,253,170, 35, 34, 34,170, 46, 92, 41, 63,159, 43,241, 9,162, 29,118, 67, +147,146,221,150, 62, 25,141, 70, 67, 81, 20, 86,196, 88,120,226,245,113,113,113, 42,149,221, 44, 31,147, 73,107, 50,170,165, 94, + 97, 30,210,192, 38,117, 5, 0, 98,218,126,255,253,247,216,150,186,247,134,213,214,214,238,221,187, 87,171,213, 94,187,118,109, +218,180,105,131, 7, 15,198,242, 51, 43, 43,107,225,194,133,221,186,117, 99,185,204,218,218,218,156,156,156,223,119,239,250,227, + 80,222,191,223,152,250,220,171,211, 52, 6,245,141, 27,101,105,105,219,127,157, 48, 36,190, 67, 64,219,183, 55, 46,165, 53,238, + 70,117, 90,253,216,109,223, 59,111,179,175,134,230, 53, 71, 51,114,203,217,245,133,155,108,121,112, 68, 76,247,152,238, 94, 66, + 31, 2,140, 8,253,173, 52,100, 20,233,183,158,184,125,166,184,238,182, 22,106,117,230, 98, 53,170,208,163, 46,209, 49, 54,121, + 4,231, 18,225,114,243, 29, 59,118,124,228,145, 71, 0, 32, 48, 48,240,177,199, 30,195,244,135, 25,208,250, 97, 97, 90, 52, 26, +141, 6,131,129, 32,136,232,232,232,250,250,250,178,178,178,186,186,186,200,200, 72,129, 64, 96, 48, 24,244,122, 61,222,204,222, +153, 63,250,232,163,225,225,225, 87,174, 92,193, 29,229,184,139, 92, 40, 20, 62,241,196, 19,184,255,132, 5,143, 62,250,104,104, +160, 95,173,226,175,130, 3, 27,174,236, 93,251,247,222,180,155, 39,127,149, 8, 40,118, 91,146, 36, 67, 67, 67,125,125,125, 47, + 92,184,112,235,214, 45, 76,160, 76,237,153,145,145,209,187,119,111,123,230, 6,189, 74, 85, 95, 36, 18,121,249, 7,246,240,242, +238, 44, 18,121, 97, 29, 10, 0,183, 79,255,223,161,159,222, 77,232,161, 6, 0, 10, 53,143,199, 68, 0, 0,123,247,238,149, 74, +165,189,123,247,142,140,140,196,188,137,229,231,204,153, 51,217,121, 19, 0,114,114,246,250,250,122,143, 24,249,120,255,248,190, +207,191, 53, 75, 67,152,170,239,212, 37,191,243, 89,234,160,152, 54,230,205,241, 51, 63,161, 25,147, 99, 79, 81, 27,205,156,196, +226,224,184,137,101, 92, 78, 30,106,137, 82,110,255, 57,176, 15, 28, 58,199,246,234,211, 49,120,104,144,228,209, 0,113, 39, 15, +129, 4, 33, 15,189, 41,194,155, 84, 34,116, 89,109, 42,108, 50,117,238, 16,228, 21,217,203,166,247,138,147,222,117, 58, 93, 68, + 68, 68,191,126,253,148, 74,101,125,125,125,125,125,189,143,143,207,224,193,131,113,245,121, 92, 98,196,218, 22,231,189, 19, 4, + 17, 27, 27,171,213,106,171,171,171,239,220,185, 83, 93, 93,221,212,212, 20, 27, 27, 75,146, 36,182,101,169,189, 28, 25, 25,153, +144,144, 16, 29, 29,125,227,198,141,125,251,246,253,249,231,159,158,158,158, 79, 62,249,100,191,126,253, 28,246,116, 71, 70, 70, + 38,200,198, 68,119,244, 87, 23,159, 46,220,247, 67,249,159,187, 3, 36,102,217, 24,199,182,190,190,190,241,241,241, 8,161, 19, + 39, 78,228,231,231,151,151,151,215,213,213, 45, 94,188, 24,143,152, 26, 52,104, 16, 75, 49,122,138, 50,170,148, 69,117,213,151, + 36, 30,129, 97,157,158, 8, 9,123,204,199, 55,242,171,175,191,193,182, 91,223,243,220,118, 92, 15, 0,248, 91, 67,247,175, 23, + 22, 22, 6, 7, 7, 15, 27, 54,108,210,164, 73, 26,141,166,169,169,233,219,111,191,157, 54,109, 26,254, 80,177,163,160,160,176, +107, 68,248, 11, 47, 76,252,248,163,185,181,141,170,154,218,154,217,239,126,246,217,243, 99,198, 68,132,222,151,198,230,212,228, +197,100,219, 80, 36, 11, 63,186, 41,108,196, 39, 15, 61, 28,232,212, 45, 90,247,216,112,211,159, 57, 37, 42,240, 38, 68, 93,189, + 5,229,102, 66, 40, 33,143,220, 49,235, 40, 8,145, 8,163, 7,141, 80, 7, 68,218,164, 78,163,209, 40, 20, 10,187,117,235, 22, + 31, 31,223,208,208,160,211,233,112,114,146,193, 96, 8, 12, 12, 28, 54,108, 88, 86, 86,150,209,104, 52,155,205, 22,175,129,217, +108,198, 67,143,122,246,236,137, 11,136,234,116, 58,220, 80,177, 86,237,217,179,103, 93, 93,157, 90,173,102,255,240,247,237,219, +215,215,215,215,181,180,118,215,108, 5, 2, 65,167, 78,157,112, 61,206,107,215,174,149,150,150,250,248,248,248,251,251, 39, 36, + 36,252,231, 63,255,177, 55,158,135,225,179,107,234,149, 5, 58, 93,157,127, 64,172,183, 79, 23, 31,223,136,166,198,242,165,169, + 63, 76,127, 65,182,181,185, 72, 58,133, 61,246,102,238, 28, 55,110, 92, 78, 78,206,173, 91,183,234,234,234, 38, 78,156,248,227, +143, 63, 62,246,216, 99, 61,122,244,224,114,141,137,137,227,118,237,202,106,168,175,189,117,187,226,189,183, 95, 94,248,193,146, +231,159, 28, 50, 76,223, 0,162, 54, 26,229,232, 84,191,144, 27,169,243, 62,246,206,211, 20,201,212,122, 28,213,159,133, 45,109, + 37,151,203,237,149, 84,108, 21, 91, 30, 28, 17, 57,100,244, 69,189,169,250,143,131, 34,147,246, 98, 35,202,109, 52,137, 9, 34, + 8,161,209, 29,253, 71, 62, 53, 38,112,224, 40, 59, 26,138, 50,155,205,145,145,145,143, 61,246,152, 86,171, 53, 26,141, 98,177, + 24,211, 31, 22,140, 33, 33, 33, 67,135, 14,221,183,111,159, 77,213, 73,146,100,191,126,253, 8,130,208,104, 52, 88,186,210, 1, + 25,163,209, 72, 81, 84,159, 62,125, 78,157, 58,101, 48, 24, 28,234,199,200,200, 72, 23, 47,220, 37, 91,129, 64,224,239,239,223, +167, 79,159,206,157, 59, 43,149,202,234,234,106, 0, 40, 47, 47,127,230,153,103, 86,172, 88,225,208,220,108,214, 55,169,203, 13, + 6,149,180,161,196,215, 63,218,211,187,147,167,119,167,253, 7,171,136, 49,161,205, 50, 8,128,145,149, 52,100,200, 16,177, 88, + 92, 87, 87, 55,110,220,184,160,160,160,151, 95,126,249,240,225,195, 28, 79,245,137, 39,134, 72, 36, 18,223,171,249,111,191,253, +122,120,108,247,101,115, 95,223,248,221,143,223, 10,117,247,171,165,113, 79,234,108,125,213,121, 95,122,231,239, 87,126, 18,207, +140,109, 3,129, 64,208,127,204,216,160, 78,225,213,127, 95, 22,222, 84,196, 24, 43,124,130, 66,135,244,233,209,123,224, 35,218, +176, 56,150, 64, 80,183,110,221,134, 13, 27,134,131,146, 66,161, 80,175,215,227,193,148,180, 47,223,165, 75,151,161, 67,135, 90, +191,234, 82,169,180,127,255,254, 36, 73, 26, 12, 6,188, 37,221, 97, 77,207,253, 33, 16, 8, 6, 12, 24, 96, 81,236,183,253,128, + 36,201, 14, 29, 58,116,232,208, 33, 46, 46,142,162, 40,141, 70,163,215,235,135, 13, 27,246,209, 71, 31,113,176, 70, 70, 67,163, +209,160,214,106,171, 37,146, 0,145,216, 71, 32, 32, 55,103,236,157, 57, 35,241,238,247,227,222,173,177,152, 93,190,124,185, 86, +171, 5,128,216,216, 88,238,229,173,226,227, 7, 10, 31,125,116,214,167,216, 22,197,198,198,197, 62,247, 28, 73,182,145,234, 28, + 63,243,147,236,205,159,185, 54, 16,243, 97,158,175,211, 53,106,163,173, 92, 48,111,137, 45, 15,118,116,233,217,187, 75,207,222, + 0, 64,207, 83,196,158, 33,157,148,148, 20, 16, 16,128,187,209,113,119, 51,157,135,132,187,134,240,228, 73,209,209,209, 4, 65, + 28,187,124,207, 0,199, 85,171, 86,101,102,102,226, 13,204,102,179,189, 73,231,196, 98,177, 67, 23,184,157,124,123,188,189,189, +189,189,189,157,108,153,152, 64, 27, 5, 2, 18, 64, 0, 64, 97, 91,123, 17, 10, 60, 61, 18,221,179,207, 29,102, 51, 53,111,222, + 60,215,108, 91,139, 61,157,229, 77,224,203,186,241,224,193,195, 6, 47,128, 85,101, 76,126,146,227,255, 29,213,201,131, 7, 15, +215,128,128,175,167,225, 72,203,243,183,128, 7, 15, 30, 60,120,234,228,193,131, 7, 15,158, 58,121,240,224,193,163,253,129, 47, +235,198,219,242,182,188,237,255,150,109, 43, 83, 39,216, 25, 12,206, 49,155,161, 93,217,114, 52,191, 95,231,220,126,224,242,152, + 81,139,203,127, 80, 46,156, 31,167,192,195, 45,212, 9, 0,104,251, 61,163,238,137,169, 74,238,251,178,104,148, 78, 13,130,108, +137,173,197, 57, 59,117,218,247,235,156, 49,234,170,139,170,171, 43,170,106,212, 42,149,209,207, 79, 20, 26,236, 29, 18,210, 49, + 48, 36,134,139,237,185,147,223, 41,138, 11,139, 75,116,101, 21,168, 75, 71, 34, 58,210, 35, 42, 58, 54,254,137,183,218,158,112, +219,102,232,148, 66,161, 72, 77, 77,165,255, 76, 73, 73,105,179, 89, 16, 93,190,186,251,120,206, 60,218,154, 58, 31, 80,208, 92, + 73, 16, 64,253, 28,208,254, 79,216,104,104, 42, 43,189,100, 48, 24, 99,186,249,143, 26, 22,225,239, 39, 81,214,235,202, 43,212, +215, 21, 21,245,170,154, 46, 17,125, 68, 98, 47,123,182,202,154,194, 19,121,223, 11,161, 97, 90, 34, 12, 29, 8,209, 93,161,168, + 4, 29, 59,171,205, 57,116, 97,239,206,133, 67, 70,190, 25, 16, 28,203,241, 52, 92,214,155, 76,195, 54, 24,120,106,253, 89,194, +148,212, 6, 18, 18, 31,218,133,171,187,143,231,204,195, 41,184,150, 18,255,144,116, 19,209,194,243,129,224, 77, 0,184, 85,122, + 41, 52,216, 99, 82, 98,108,191,222, 29,130, 2,164, 4, 16,190,222,146,216,232,192,132,145,145, 33,129,146, 91,165,151, 88,108, + 79,228,125, 63,124, 96,195,246,111, 97, 86, 18,244,136, 6, 0,240,242,132,158, 49,240,239,121, 48,184, 95,195,137,188,239,157, +122,189, 93, 16,203,214, 47,191, 91,233,128, 57, 81, 0, 13, 23,148, 62, 77,130,174,209,159,107,134, 78,157, 51,247,241,139, 60, + 90,139, 52, 45, 70, 97,114, 31,198,254, 80,245,176, 63, 40, 51,182,215, 85, 23, 25,141,198,199,226, 59,254,247, 49, 8, 8,177, + 88, 40,245, 32, 69, 34, 65,116,183, 0,131,193, 88, 87, 93,100,207, 79, 23, 66,195,188, 89,160,211,195,141, 50, 80,170,160,190, + 1,182,236,129,119, 62,133,197, 95,195,144,120, 16,160,134,115, 39,191,123,104,158, 41,115, 18, 25,155,100,205,101,102, 25,166, + 40,166, 53,178,179, 31, 9,238,124,109,113,206, 7, 14, 28,200,205,205,229,114,206,109, 54,118,155, 7, 19,120,178, 78,122,202, +206,214,175,136,217, 6,110, 81, 75,181,103,107, 28,215, 53,199,211,158,162,177,185,171,234,154,138,184,232, 64,204,152, 22, 63, +121, 72,200,122,149, 62, 54, 58,176, 80, 81, 97, 51,232,169, 40, 46,156,150, 8, 0,240,251, 17,248,191, 77,240,212,112, 24, 55, + 10,174, 21,193,249, 43, 72,234, 65, 12,232, 13, 99, 71,194, 47,251, 10,227,159,112,151,195,110,243, 22,185,111,114, 63, 22, 39, + 23,147, 96,106,106, 42,151,171,176,142, 48,112,151,216,204,235,229,226,191, 51,207,249,192,129, 3, 59,118,236,192,235,101, 50, + 25,251, 57,147, 36,233,176,108, 17,143,214, 37, 77,151,109, 45,169,211,186,131,133, 35, 29,216,163, 33, 46,182,238,112,247, 56, +118, 1,219,236, 98,226,104,107,177, 25,247,222,170,170,106,245,232,161, 17, 8,193,209,147,101, 26,173, 17, 0,226,251,133,133, + 4, 73,203,202, 27,139,110, 40, 73, 82,208, 61, 42,224,248,233,166,184,158, 54,108,139, 75,116, 67, 7,130,222, 8,191,229,193, +161,147,168, 83, 40, 17, 21, 1, 99,134, 65,143,104,130, 20,130,136,132,193,253,225,171, 52, 29,203, 9, 51,235, 53,217, 91, 96, +105, 82, 76,213,246, 64, 76,237,108,147,230, 44, 8,145, 35,237, 90,248,239, 92,204,105,222,204,204,204,148,201,100,236, 27,243, + 14,251, 3, 4,199, 61,236,220,251,220,173,149, 8, 71,109, 98,147, 97,185, 83,182,205, 51,183,158,184,211,174,155,111,213,197, +196,209,214,230,102,120,111, 4, 0,181,221,110,212, 85,165, 50,250,249, 73, 0,160,236,118,131, 86,107, 2,128,152,168,128,144, + 32,233,133, 43,119, 10,174,215,121,120, 8,163,187,249, 43, 85,182, 39,130, 44,171, 64,209, 93,129, 0,120,122, 4,244,239, 69, + 72,196, 96, 50,193, 83,195,193,223, 7, 20,165, 48,118, 4,116, 13,135,178, 10,247, 14, 63,166, 25,211,230, 52,169,237,138, 52, +109, 82,158,245,183,196, 41, 5,234,212, 37, 39, 37, 37,101,102,102, 2,192,148, 41, 83, 28,135,207, 4,252, 16,149,251, 6,103, + 43,187,181, 23,135,221, 38, 13,113,164, 48,167, 50,168,108,239,161,149,250,229,137,169, 74, 46,187,242,243, 19, 41,235,117,193, +129,158, 73, 19,123,152,204,148, 68, 34, 20, 10, 4, 8,161,241, 79, 69, 39, 38, 68, 19, 4,212, 42,181,126,126, 34,155,182, 93, + 58, 18,197, 55, 81,143,104,120,242, 9, 64, 0,215,138,160,111, 15, 8,240,133,103, 70, 1, 69, 1, 41,132,194, 27,208,165, 35, +193,126,147, 29, 46, 56,155, 66,220, 6,201, 73, 22,135,224,114, 68,154,226,153,178,209,230, 50,247,163, 59, 37, 87,233, 45, 17, + 66, 9, 9, 9,124, 86,233, 67,195,155,240,112,116, 19,165,221, 11, 23, 68, 16, 66, 32,152,166,108,249,153,160,237, 1, 8,129, +192, 17,149,135, 6,123,151,149, 55, 2,192,138,181,103,254,186,124,199,104,164, 40,234,110,137, 90, 60,171,100, 89,121, 99,104, +176,183, 77,219,232, 72,143,227,249, 0, 0,193, 3,225,252, 21,152, 61, 29, 98,186,130,136,132,207,191, 5,177, 8, 4, 2, 56, +158, 15,209,145, 30,220, 25,193,181, 48, 37,173,215,232,123,238,166,112, 39,174,124,139,119, 78,247,174,224, 5,188,210, 94,105, + 92,118, 15,198, 89,222,180,247, 69,231,114,206, 50,153, 44, 33, 33,129,203, 57,179, 20,137,227,209,174,120, 19,248, 49,236,255, +109,181,173,148,213,132,182, 7, 32,112, 64,196, 33, 33, 29,139,110, 40, 41, 10,125,240,222,224,194,162,186,191, 11,107, 9,226, +191, 53,154, 40, 10, 21,221, 80,134,132,116,180,105, 27, 21, 29,187,247, 15, 48,155, 1, 41,224,208, 73,200, 58, 8,207,188, 6, +163, 95,132,195,167, 0, 0,204,102,216,251, 7, 68, 69,199,186,239, 70, 89, 4, 58,221,237,176, 51,115,200, 45,168,211,122, 3, + 46,206, 59,184, 63, 63,201,229,115,102, 41, 18,199,163, 93,241, 38, 79,157,173, 12, 98,170,146,139,207, 30, 24, 18, 35,145,136, + 79,231,223,166, 40,244,140, 44,234,226,149, 59, 95,172, 56,249,249,242, 19,152, 55, 79,231,223,150, 72,196,246,198, 20,197, 63, +241,150, 25,124, 87,174, 7,179, 25,214,125, 14, 63,253, 2,163, 7,195,128, 94,112,120, 43,152,205,176,114, 61,152,193,151,251, +152, 34,102,190,161,179, 98,211, 30,191,180, 46,152,140,131,131,134,204, 5,224,150,156,132, 79,152,217, 57,238, 84,124,211,217, + 47,132,203,231,108, 50,153,248,151,232,129,224, 77,158, 58,155,117,226,246,128, 86,220, 21, 23, 1,219, 37,162, 79,117,157,126, +103,118,193,237, 74,117,226, 83,209, 31,206, 27,156,252, 90,255,243,151,170,118,102, 23, 84,215,233,187, 68,244, 97,177, 29, 50, +242,205,163,249,190, 73,111, 67,254,101,248,254, 75, 88,252, 54,200, 95,132, 31,182, 67,210,219,112, 52,223,119,200,200, 55, 93, +144,144, 78,241, 38,199,245,173, 2,230, 64, 70,215, 54,176, 32, 62,151,235,166,112, 55,116,249,156,121,234,188, 47,104,157,138, +152,214, 93, 46,220, 59, 97,184, 36, 39,113,183,229,110,222,146,227,218,188, 58,215,142,235, 84,111,149, 72,236, 21, 21, 51,184, +174,186, 72, 81, 82,113,242,236, 45,122, 12,123,104,135, 78, 14,199,176, 7, 4,199, 38, 78,254,234,220,201,239,126,222, 91,184, +228,255,218,116, 12,123, 27,243, 38,180, 97, 54,155, 11,167,209,234,231,204, 59,236,247, 87,123, 58, 69,166,100,107,181,200, 86, +183,117, 54,231,174, 61,156,179,179, 8, 12,137, 9, 12,137,137,115,201, 54,254,137,183, 56,230,189,223,119, 70,104, 63,120, 32, +206,150, 32, 8, 65, 51,112, 4, 28, 87,145,195, 96,175,252,206,163,237, 30, 19, 95,214,141, 7, 15, 30, 60,156, 5, 31,235,228, +193,131, 7, 15,158, 58,121,240,224,193,131,167, 78, 30, 60,120,240,224,169,147, 7, 15, 30, 60, 30, 6,240,101,221, 90,199,150, +101,148,158, 91,109, 21, 10,133, 66,161,200,204,204,116,193,246,198,141, 27,197,197,197,153,153,153,233,233,233, 0,192,236,186, +229,159, 47,111,251, 16,219,182, 50,117,218,123,159,173,225, 48,195,163, 37,182,247, 5, 22, 53,100,156, 58,103,218,214,230, 28, +186, 28,109, 47,175,240,125,228,253, 6,231,107,165,161,190,218,111,145,193, 12, 0,233,233,233,179,103,207,118,230,162,209,163, +194,109, 70, 99,131, 84, 42,221,190,125,251,171,175,190,106, 54,155, 13, 6,131, 59,134, 81,187, 48,175,240,125,183,189,191,160, +243,147,112,114,146,193, 96, 16, 10,133,124,102, 82, 59, 85,157, 22,109,206,230, 67,162,199, 89,179,191, 36,174,217,114, 81, 97, +238,227, 77,155, 37,183,184,204, 7,142,167,173,149,203,229, 22, 51,129,115,180, 69,127,125, 66,244,255,236,167, 60, 3, 0,160, +191,238, 38,138, 17,253, 29,207, 83,237,115,245,125,132, 96,235,113, 3, 0, 60, 51, 64,212,187,243, 21, 44, 30,185, 16,104, 68, +224,233, 27,151,170,142, 85,116,109,242,246,122,122, 84,125,231, 16, 34,239,240,129,134, 70,221,184,113,227,244,122,189, 59,222, + 79,183,126,110, 89,108, 29, 94, 11,247,102,233, 66,187, 90,182,108,217,194,133, 11,163,163,163,157, 50, 20, 10,133, 36, 73,146, + 36, 41, 20, 10, 5, 2, 65,106,106,234,194,133, 11,205,102,179,201,100, 50,153, 76,238, 75,155,223,187,119, 47,251,205, 25, 55, +110,156,195,157,228,228,228, 56,181,253, 67, 69,157, 44,188, 57,112,224,192,252,252,124,135,205,215,102,115,100,177,181,216, 79, + 74, 74, 10,118, 66,219,172,206, 98, 90, 90,154,245,176, 98,124, 38, 44,106,148,182, 5,128,164,164, 36,153, 76, 70,207,101,203, +209, 22,115, 37,254, 55,245, 95, 64,243,230,162,103, 61,150,237,214,177,156,182, 95,193,252,222, 17,194, 38, 29,122,127,188,199, +169,235, 38,173, 30,105,141, 48,186,243,149,203,165,102,135,242,179,236,226,202,252,106, 47, 95, 47, 34,180, 67,104,135,206, 49, + 55,111,233,227, 98, 77, 18,225,157,172,236,154,173, 91,183, 78,154, 52,137, 23, 20,173,130,212,212,212, 9, 19, 38, 44, 91,182, +204,162, 13,199,199,199,255,235, 95,255,154, 48, 97,130,237, 23,146, 36,197,205, 40, 43, 43,235,222,189,187, 80, 40,244,241,241, + 41, 42, 42,242,246,246, 62,115,230,204,201,147, 39,223,126,251,109,123, 7,197,143,158,126,127,233, 55, 17,175, 33, 8, 2,127, + 95,109, 98,207,158, 61,214, 38,244, 26,132, 16, 23, 42,220,189,123,183, 83,219,183, 31,224, 49, 69,220,243,220, 73,167,120,147, +125, 95, 44,211,127,113, 28,104,140, 25,103,233,210,165, 31,124,240, 1,189,198,125,236,201,228, 62,155,103,194, 62, 43, 15,190, + 40,250,155,193,156,223,129,163,173, 77,117,185,232, 89,182, 41,227, 16, 66,193,215,231,119,239, 36,148,138,137,200, 16, 65,117, + 3, 50,153,133, 53,141, 72,165, 65,197, 85, 20, 65, 64, 48,117, 81,161, 80,216, 60, 58, 66, 8,170,119,196, 68, 68, 85, 87, 87, + 69,134,135,244,233, 29, 69,122, 7, 68,133,215,107,205,170,138, 10,115,185, 82, 39,213, 43,138,139,251,185,187,224,173,179,147, + 88,183,220,214,250, 91,238,110,207, 87,161, 80, 16, 4,209,171, 87,175,172,172, 44,230,227, 24, 56,112, 32, 11,111, 2,128, 72, + 36,242,240,240,168,169,169,137,141,141, 29, 48, 96, 0, 73,146,223,124,243,141,217,108,238,211,167,207, 47,191,252,114,230,204, +153,139, 23, 47, 10,133, 66,123,218,117, 32,192, 37, 0, 0, 18, 59, 73, 68, 65, 84,243,217,103,159,197,215,107,239, 45,102,161, +179,221,187,119,227, 59, 99, 83,250, 32,132,170,170,170,184, 80,167, 83,219,183, 19,198,108,169,234,196,237,210,158,102,108,179, +176,227, 7, 31,124,192,125, 78,135, 22,234, 2,123,238, 30,199,146,217,244,123,155,155,155,203,148,156, 92,108, 51,222,245,182, + 46,167, 52,227,155, 38,118, 43,132,144,135,152, 16, 10,192, 83, 2,245, 26,100, 48, 35, 47, 15, 66,107, 4,173, 1,117, 14, 16, + 80, 20, 20, 86,152,115,115,115,109, 10,207,198,202,211,126, 34, 47,145, 8,189,153,244,152,217,132, 42,149,134,210, 27, 42, 1, +148,249,251,235,239, 84,149,136,133,170,171, 37,245,229,186, 92, 39, 99,166, 45,245,223,157,157, 51,148, 57, 87,139,117, 53, 20, +123,168,171,251,111,113,139,192,192, 92,123,228,210,138, 77,107,252,248,241,184, 25, 92,185,114, 5, 47, 96,189, 57,126,252,120, + 22, 67,137, 68,210,212,212,212,179,103,207,209,163, 71,207,159, 63,255,245,215, 95, 7, 0,163,209,184,113,227,198,252,252,252, +115,231,206,253,252,243,207, 90,173,214, 94, 72, 58, 49, 49,209,229,115,254,225,135, 31,216, 63, 63, 92, 84, 36,189, 19,142,219, + 63, 60, 14,187, 77,229,216, 54, 68,102,173,221,218, 0,204, 34,133, 52,223,113,228, 62, 46,250, 72, 46,151,219,119, 1,236,190, +186,216, 91,183,182, 69, 8, 85, 31,126, 63, 44, 66,168,214, 34,132,128, 32, 64, 99, 64, 90, 3, 24, 77, 8, 0, 76, 20,162, 16, + 2,128, 75, 23,242, 21, 10, 5,128,216, 98,183,245, 85, 87,196, 33, 1, 33,254,254,245, 74,109,189, 74,121,234, 74, 85,185, 18, +121,122,106,162,187,170,181,234,154,190,221,141,189, 34,245,233, 91,243,139,138,138, 0, 60,128, 71,203, 36, 39, 65, 16, 89, 89, + 89,227,199,143,207,206,206,238,221,187,119, 82, 82,146, 67,222,196,212, 89, 93, 93,237,233,233, 57, 98,196,136,175,191,254, 90, + 36, 18,201,229,242, 31,127,252, 49, 63, 63,255,212,169, 83, 7, 15, 30,188,116,233, 82,112,112, 48,203, 28, 75,179,103,207,182, +231,176,127,255, 61, 91,161,233, 86,113,216,247,236,217,243, 96, 57,236,244, 43,230,172,252,108, 95,197, 75,173, 39,244,110,231, + 69,111,112,215,144,205,114, 93, 56,250,233,242,172, 78, 25,239,122, 89, 43, 80,159,171,243,111,232, 81,101, 61, 69, 16, 2, 47, + 29, 34, 8,194,100, 70, 58, 35,232, 12,160, 55,130,222, 8, 58, 3, 24, 77,205,170,231, 94,218,245,190,242,126,249,237,136,200, + 8,111,129,135,176, 86,171, 61,120,230, 86, 97, 89,121,109,157,122, 80, 95,179, 94, 99,210, 25,204, 90, 29,117,179, 12, 52, 90, +248,234,171,175,248,153, 13, 90, 46, 57,123,245,234, 21, 21, 21,165, 80, 40,178,179,179,177,240,116,200,155,216, 97,239,223,191, +191,135,135,199,143, 63,254, 56,107,214,172, 47,191,252, 18, 33,116,250,244,233,188,188,188,139, 23, 47,170, 84,170,238,221,187, + 55, 52, 52,176, 84, 49,122,238,185,231,172, 5, 53, 86,217,236,154,244,127,211, 97,111, 53,213,121,191,152,136,118,144,109, 86, +206, 98, 9, 74,222, 95,150,151,201,100,152, 61,109,202,103,123, 10,218, 38, 45,114,241,220, 95,254,182,169, 83,160,224,197, 97, + 98,189, 17,124, 61, 9, 33,129, 0,192, 96, 70,122, 35, 52,233, 81,147, 14,105, 12,200, 76,129,205, 78,227,151,191,109,234, 31, +167,232, 30, 83,247,123,222,157, 58,149,110,112,223,134,199,252,212, 34,177, 94,163,163,110, 85,160, 38, 29, 97, 54, 19,193,129, + 4, 16,124,141,135,214, 1,110,207, 76,247, 37, 59, 59,155, 73,106, 54, 35,158, 2,129, 96,209,162, 69, 36, 73,254,244,211, 79, + 27, 54,108,120,237,181,215,150, 46, 93, 74, 16, 68, 73, 73,137, 86,171, 77, 73, 73, 49,153, 76,201,201,201, 44,137, 1, 46,107, + 61,222, 97,127, 32, 85, 39, 51, 60,103, 77,145,246,232,233,190, 11, 79,102,136,147,121,146,185,185,185,184, 20, 98, 90, 90,154, +117, 58,174, 67,222,196, 61,236,214,182,102, 10, 52,122,164, 55,162,250, 38,164, 51, 34, 17, 9, 0, 96, 50,131,206, 0, 26, 3, +170,109, 68,213, 13,232,124,137, 9, 33, 72, 74, 74,210,222,187, 79, 51, 5,101, 21,134,162, 34,229,137,115, 74,132,136,107, 69, +212,244,137, 38, 18,161,202, 59,176,255, 40, 52,106, 16, 69,193,147,131, 9,169, 4,198, 37, 62,107,110,147,187,231, 26, 92,171, +226, 23, 24,216,118, 77,200,162, 1,167,165,165,197,199,199,159, 59,119, 46, 43, 43,139,185,222, 94,103,209,242,229,203,253,253, +253,177,112, 91,191,126,253,172, 89,179, 54,108,216,128, 57,119,249,242,229,245,245,245, 13, 13, 13, 26,141,134,229, 4,222,124, +243, 77,166,163,141, 37, 39,187,183,254, 63,235,176, 63,240,212,153,159,159,111,175, 95, 88,161, 80,112,201,106,106,149, 16,149, +205,101,123,239, 6, 86,157, 22, 4, 10,140,138,219, 54, 85,103, 75,138,160,165,165,165, 93,191,126,189,244,248, 55, 8, 81,132, + 6,196, 36, 1, 0, 6, 19, 50, 35,104,212, 32,189, 17, 76,102, 48,153, 97,226,115, 83,100, 50,153, 5,237, 98,219,146,227,171, +123, 71, 82, 71,206,155, 5, 2,168,172, 38,164, 30,176,239, 40,104, 52, 4,162, 32,190,151,168,244, 54, 53,242,201,196,177, 99, +199,230,156,168,104,203,176,140,187,109,237, 57,161,109, 3,220,171, 62,126,252,120,252,232,177, 11,181,104,209, 34,155, 27, 83, + 20,117,254,252,249,225,195,135,211,107,214,175, 95,143, 89,204,104, 52,154,205,230,235,215,175,135,132,132,176,143, 92,120,238, +185,231, 92,208,140,188,195,238, 70,234,204,207,207,119,135,215,140, 5, 90,106,106, 42,142, 15, 90,232, 77, 76, 64, 73, 73, 73, +110, 37, 77, 11,214,198,127,226, 72,130, 67,189, 76, 19, 40, 48,226,158, 92,108,237, 97,217,110,157, 61,219,152,152,152,245,235, +140, 99, 30, 17, 81, 0, 70, 19,229, 33, 34, 16,130, 70, 29,210,155,144,153,130,252, 98,179,137, 66,246,114,176, 99, 98, 98,126, +250,222, 52,178,191,240,197,241, 66,181, 22,169, 26,161,177,137,136,233,138, 76, 38,130, 0,143,218,122,170,188,210,240,108, 82, + 47,161, 80,216,198,186,204,169,111,137,107,182,247,107, 28,206,192,129, 3, 63,253,244, 83,166,192, 92,182,108,217,132, 9, 19, +236, 61, 35,131,193, 16, 23, 23,167,211,233,132, 66,161,167,167, 39, 0,236,220,185,115,242,228,201, 90,173, 86,167,211,233,245, +122,111,111,111,179,217,204,126, 57,174,245,179,243, 14,187,187,168,179,133,188,201, 98, 46,147,201, 48, 63,226,248, 32,157, 8, +197, 20,155, 54,187, 98,220,196,155, 76,238, 99,239,106,103,242, 38, 51,238,201,197,150,157, 55,237,217, 18, 4,241,229,242,117, +243,222, 73,150, 74,128,162,224,145, 8, 33, 65, 0, 66,119, 73,211,140,132,147, 38, 77, 98,177,253,108,217,186,249,115,147,205, + 20, 24, 76,200,108, 6, 2, 96,220,104, 80, 53, 18,127, 93,209,234,140,130,137, 19, 39,185, 59,169,243,127, 10,214,217,239,114, +185,124,252,248,241, 44,253, 69, 6,131, 65,171,213, 42, 20,138,126,253,250,153, 76, 38,145, 72,180,123,247,238,132,132, 4,157, + 78,167,209,104,174, 95,191, 30, 16, 16,192,146,156, 68,131, 14,127,113,113,213,121,135,221,141,212,233, 38,189,105,211, 17,179, +118,207,221,154, 21,239, 50,111,194,189,125, 65, 52,251, 3,183,180, 80,123, 17, 79, 46,182, 43,215,172,147,203,229, 4, 1,199, +174,153,112,150, 18, 0, 32, 4, 73, 73,147, 28,126, 99,150,126,181,230,221,119,255,129,173, 16,130, 35,103,160, 73, 67, 81, 20, + 76,156,152,248,212, 83, 79,241,124,215,138,176,224,205,228,228,100, 76,154, 89, 89, 89, 4, 65,216, 36, 80,131,193, 32, 16, 8, + 58,117,234,212,216,216,120,246,236,217, 1, 3, 6,152, 76, 38,149, 74,117,225,194,133,110,221,186, 5, 5, 5,105,181, 90,147, +201,228, 80, 68,227,220,120,167, 68, 40,239,176,183,136, 58,237,165,112,114, 33, 47,246,244, 79,135,123,192,163, 33, 45,118,226, +178,118,227, 8,123,231,204,229,184,204,225,234,116, 4,211,217,146, 74,114,185, 60,227, 93, 47,204,164,206, 86, 10,162,111, 23, +238, 23,138,138,138,226,114,175, 68, 34,209,154, 53,255,119,249,242,229,181,107,215, 2, 64,163, 26, 18, 19, 19,163,163,163,227, +226,226,220, 23, 16,108, 73,191, 80,139,250,148,238, 95,136, 19,238,237, 8, 82, 40, 20, 8,161,236,236,108,235,159, 44,168, 19, + 87, 34, 50, 24, 12, 17, 17, 17,245,245,245,159,124,242,137, 74,165,234,220,185,179, 90,173, 54, 24, 12, 56,226,233,240,208, 46, +248,236,149,149,149, 45,191,228, 86,217,201,131, 71,157,247,189,204, 89, 84, 84, 84, 91,102, 32,181,226,177, 90,242,122, 59,236, +112,103,185, 93,174, 5, 52, 72,146,236,215,175, 31,253,231,248,241,227,113, 10,119, 59,188,207,247,189, 77,186, 76,217, 22,165, +217,122,246,236,185,126,253,122,135,165,217,176,162,164, 40,202,104, 52,226,233, 63, 0,128,162,168, 54,152,254,131,135,115,143, +152, 79,126,230,193,131, 7, 15,103,193,207, 18,207,131, 7, 15, 30, 60,117,242,224,193,131, 7, 79,157, 60,120,240,224,193, 83, + 39, 15, 30, 60,120, 60, 12,176, 81,214,205, 98,250, 53,155,211,178, 61,196,101,161,152, 9, 82,244,181,243, 37,180,248,123,213, + 18, 91,123, 89,107,238,182,125, 88,239,179, 83,134,208,198,101,221,156,133, 51,227, 14,197,214,182,244,178,197,204, 73, 22, 63, +185,233, 3, 66,151, 39,106, 78,147,188, 91,141,160, 13,190, 93,133,133,133,203,151, 47,199,203,239,191,255,126, 92, 92, 92, 59, +255,216, 90,220,171,191,255,254, 27, 0,122,246,236,233,214,131,202,229,242,103,159,147,239,254, 53,205,162, 25,228,252,118,110, +247,175,105,246, 26,134, 92, 46,191,124,249,114,223, 62,143, 80, 8,240, 2, 0, 92,188,116,207, 26, 10,113,106, 87,184, 29,186, +214, 2,241, 24, 51,139,137, 14,184, 95, 56,184,185, 86,194,195,138,130,130, 2,183,190, 77,173, 57,253, 7,199,220,245, 43,229, + 54,190, 0, 22,108,197, 28,210,192, 78,100, 45,175,122,136,247,128,185,192, 58,225, 14,255,106, 51,133,139,121,232,206,221,186, + 0, 64,149, 78,103,210,234, 1, 0,234, 27,160,121,202, 78,246, 19,163,121, 19, 0, 86,172, 88,193,165,132,153,128, 0, 10, 1, +254, 23,192,246,194,218,117,105,110,162, 48,250, 94, 97,210,228,126,175, 92,126,249, 49,111,142,123, 38, 30, 64,190,251,215, 52, +167,118,133,233, 18, 0, 30,121,228, 17,122, 13,190,123,244, 26,119,127,105,232, 97,102, 28,199, 44, 88,220, 79,252, 46, 56,117, +213,214, 27,115, 55,119,193,182, 37,223, 21, 55,125, 24, 10, 10, 10, 86,174, 92,185,110,221,186, 7,131, 58, 93,254,180,222,195, +161, 46,152,180,160,234, 33, 93, 13, 9, 0,240,191, 22,191,114,154,116,199,223,247,162, 98,155, 20,194,205,112,252,206,127,206, + 93, 40,174,157,180,116,131,251,158,153,133,110, 2, 0, 11,109, 69,177,222, 15,246,250, 25, 44,101,191,240,189,122,245,213, 87, + 1, 0,255,107,249,254,224,161,157,182, 12,199,140,249, 77, 46,127,198,229, 55,100,220, 51,241,179,103,207, 6, 72,223,253,235, + 61,235,177, 14,101,193,199, 31,255,179,188,162, 70,171,169, 31, 52,104,208,197,139,151,127,250,241, 7,139, 53, 27, 55,254,224, + 86,234,100, 14, 87,115,106,206, 89,102,113, 89,103,217,211,122, 51,238,199,117,193, 22, 79,223,195,114,122, 14,105,193,166,173, +203,100,130,121,147,162,168,244,244,244,140,140,140, 25, 51,102,176,111,207,156, 31,158,123,158,187,128,249,121,196,224,184,204, +242,129,117,232,188,216,100, 55,204, 80,132, 21,217,113, 25,232,146,110, 31, 83,167, 78,101,121, 96, 73, 73, 73,214,140,249,193, + 7, 31, 16, 4,145,146,146,226,144,148, 59,119,235, 2,254,190,191, 36, 79, 14, 34,134, 86,252,103,141,119,109,189,187,121,211, + 66, 73, 81, 8, 40,116,143,146,162, 90, 54, 67,144, 61, 21,143,239,149, 53, 99,110,220,184,177,103,207,158,207, 12, 29, 0, 0, +224,227,229,166, 75,206,249,237, 92,122,122,122,206,111,231,156, 53, 44,187, 85,113,179,164,248,239,107,127,175, 88,177,188, 71, +143, 24, 10, 89,174,113,183,234, 76, 75,187, 27, 79,160, 23,156,229, 77,166, 62,224,232, 99,185, 92,155,192, 53, 91,153, 76,134, + 39, 54,195, 37,181, 45,222,113,122,242, 51, 22,230,181, 62, 10,182,114, 97,144, 30,205,155,243,231,207,207,200,200, 56,118,236, + 24,119,222, 4,103,202,108,144,214,238,182,197,140, 24, 54,215,219,116,186, 49,165, 90, 79,156,193, 52,204,204,204,180,230,117, +235,169, 97,219, 32,190,137,177,125,251,118, 11,210,196, 50,129,150,162,116,109, 78,155,184,165, 40,109,218,245,255,188,103,173, +238,220,173, 75,104,144, 84,177, 75, 49,105,233, 6,240,247,133,250, 6, 16,113,154,186,109,254,252,249,180,207, 62,127,254,124, + 46, 38, 20,130, 8, 47,248,118, 38,188,177, 17, 66, 60,225,239,122,203, 53, 87, 56,204, 5,236, 66,145,200,127,255,251,223, 22, +164,137,239,213,178, 87,199,175,249,253, 84, 88, 84,199,202,155, 85,246, 36, 39, 0,176, 8, 79,135,122,106,247,175,105,216, 91, +183,224, 83,135, 45, 68, 42, 21,201,100, 99, 16,136,126,220,184, 1, 79, 43, 99,189,198, 53, 18,113, 95,203,100,250,233,204, 71, +227, 80,123,226,159,232,240,168,189, 95, 89, 30,129,107,182,208, 60, 14, 56, 45, 77, 9,160,148,203, 3,184,243, 38,109,139,137, +146,158, 91, 18, 91, 57,123,147, 11, 10, 10, 86,172, 88,129,199,191, 14, 31, 62,252,232,209,163, 28,123, 44,102,167, 44, 5,128, +244,212, 15,238,143,195,158,153,153,137,163, 96, 22,228, 75,255,201, 62,127,176,189,206, 34,135,119,144, 69, 87,114, 7,125,139, +105,210,100, 58, 89,246,122,232,180, 80,170,126,254,113,228,179, 0,100,159,168, 97, 43,252,231, 28, 0,160,204, 5,162,151,215, +152, 76,156, 42, 85,196,198,198, 58,219, 62,238,172,135,127,173,131, 46,225, 80,149, 45,254,241, 7,195,171,219,108,172,105,121, +148,131, 5,116,167, 80,197,175, 75,125,122,123,120,119,159,187,125,233, 27,253, 30, 9,139, 27,255, 57,203,189, 98,121,238,236, +238, 60,110, 12, 52,111,166,165,165,225,222, 33, 46, 59,127,235,173, 57, 22,193, 13,235, 53,110, 10,113,186, 86,167,218, 66,111, + 90,196,139,216,217,147,150,183, 44,241, 74,150,155, 76,219, 50,107,142, 2, 0, 49, 85,201,110,203,226, 92,114,100, 64, 38,243, + 66,243,148,254,206,190, 23,115,230,204, 1, 0,138,162, 22, 44, 88,176,106,213, 42,204,155,120,142, 27,118,201,137,121, 19, 47, +164,167,126,144,189,249, 51, 46,110,123, 43,199, 58,163,162,162,112,224,131, 89,118, 2,223, 62, 46, 97, 11,235,206, 34,224,208, +211,221,242, 34,154, 88, 90, 90,144,166, 67,201, 9, 0,191,127,248,233,132, 47, 87,152,100, 67, 73, 0,239,147, 69, 7,138,107, + 1,192, 36,123,199,120, 41,152, 8,121,203, 5,231,136, 75,115,169,125,110,235, 59,175,149, 21, 38, 47,106, 58,104, 8, 11,182, +189,198, 5,213,201,145, 79, 55,110,220, 8, 0,179, 39,140, 56,117,251,142, 79, 63,159,242,125,197,224, 33,153,252,206,203,129, +225,227,193,109,176,238, 85,231,114,187,210,210,210,142, 31, 63,142,123,204, 88, 22,184, 28,212,169,158, 16,135, 82,203,230,172, +222, 54,219, 3, 75,239,104, 59,156,125,130,169, 55,211,210,148, 0,144,153,233,162, 60,119, 65,111, 34,132,232, 66,161,195,134, + 13, 59,122,244, 40, 59,111,182, 16, 36,151, 32,151,245, 74,150,199,134, 63,167, 56,196,139,163,159, 88,138,226,234,128,110,125, +169, 92, 6,206,182,177, 14,122, 58,140,235, 79, 90,183, 19, 77,236, 86,245, 68,124, 16, 12,149, 78, 94, 99,170,168, 6,127, 95, +178,118,107,246,170,124,224, 48,215,186,107,229, 34, 46,188, 63,125, 80,127,136,122,231,114,111,239,215, 10,186, 38,193,183,139, +172,215,184, 79,117,166,166,166, 14,127, 52, 78, 54, 52,118, 66,159, 69,203, 87,173,189,154, 95,158,252,228,160,202,221, 57, 42, +101,131, 11,207,194,194,157,183,215,174,108,202, 76, 46,217, 8,173,149,156,228, 90,176,216,222, 50, 52,207,244,106, 51,120, 69, +111,105,239, 25,181,164, 66,137,251, 96,179,196,161,107,197, 29, 92,176,194,177, 23,146, 36,231,205,155,119,246,236, 89,135, 33, +206,214,164, 78,123, 21,201,185,164,196, 51, 47,152, 41, 60, 49, 87, 70, 69, 69,209,105,128,214,229,198, 88,190,177, 92,226, 20, + 45, 79, 78,194,210,210,102,103,145,195,221, 22,127, 53, 91, 52,121,141,246,118, 33,121,114,141,113,231, 59,196,184,175,247,188, + 53,229,230,158, 27, 19,150,253, 4,164,187,234, 62, 45,202,132,125,203,118,245,190, 57, 22,106,154, 22, 38, 44,178,185,198, 29, +177, 78, 90,114,238,222,245,169,176,115, 47,111,136, 45,205, 75,111, 36,208,159,133,101,178,203,229,172,119,190,180, 57,180,146, + 70,115, 37, 0, 28, 60,248,140,197,175, 54,219,149, 61,247,156, 75,143,115,219, 39, 39,165,165,165,209,170,211,122, 70, 87,186, +197, 98,213,105, 93, 63,138,251, 81,220,145,230,221, 26,151,175,196,242,147,169, 64,185,139,214,204,204, 76, 23,120, 51, 35, 35, +227,200,145, 35,104,123, 0, 49, 85,185,114,229, 74,132,144, 64, 32,112,107,102, 18,184, 41,175, 19, 23,204,192, 13,200,154, 79, +237, 61,114,150,206,162, 22, 10, 40,118, 10,198,146,211,130, 52, 49,209, 59, 60,135, 11,197,181,198, 75,255,170,130,227, 97,227, +190, 6, 85, 67,113,250,130,232, 57, 43, 43, 55, 44, 0, 17, 9, 2,119, 13,114, 45,109,130,158, 29,158,103, 95,227, 38,213,153, +154,154, 58, 77,246,184, 31, 21,160, 1,209,206,149,239,124,151,253,215,194,167,135,189,186, 98,203,148, 37,155,220,212,109,130, +137,166, 57,175,211,185,239, 37,220,167,228, 36,153, 76, 22, 21, 21,197, 50,243, 55,247, 9,188, 45, 2,157,240,224,192,217,188, + 34,102, 37, 68,167,108,183,108,201, 56,124,248, 48,177, 35, 8, 0,246,127,236,243,212,231,141, 35, 70,140,112,152,144,212, 78, +169, 19,154, 83,189,152, 43, 57,182, 21,139,183,130,227, 11,201,146,141,200, 94,136,216, 66,114,114, 39,205,187, 14,251,210, 13, +191, 0, 60,253,101, 34,202, 92, 64, 76, 93,126,161,184,150, 8, 12, 40,186,213, 0, 36, 9,110, 43,142,102,157,197,233, 84, 94, +167,203,177, 78, 44, 57,223, 24,213,119,238,215,171, 63, 92,156, 18,226,219,225,202,213,210, 87,175,110,105,131,129, 46, 76,222, +100,122,172, 14,133,103,217,173,138,178,178,210,218,186, 59, 71,142,228,253,227, 31,111,227,228, 36,230, 26, 55,197,133, 88, 38, +237,118,250,118,201,182, 3, 0,228, 78,229,242,238,180, 74, 15,187,117,185,102,135, 61,236, 22,202,145, 46, 47,230,254,232,170, + 28,109, 15, 0,204,155, 23, 77, 27, 14, 25, 0,160, 13,120,243, 30,234,180, 87, 74,215,206,178,152, 11,141, 50,111, 52, 22,158, + 78, 9,162, 54, 24, 10, 73, 75, 78,102, 90,146, 66,161,160, 9,215,225, 7, 16,179,231,243, 95,174, 71, 59, 33,248,213,180,195, +115,167, 12, 75,205, 0,145,200,203, 67,236,166,115,166, 61, 77,139, 5,167,156, 80, 23, 36, 12,150,156,115,211,179, 22,191,254, + 84,167,176, 81,116,136,134,251,189,106,102,189,103,198,140,249,173,217, 91,119,130,179,152,121,157,244,184, 76,118,180, 36, 57, +169,117, 67,159, 45, 28,114,195,157,223, 91,222,195,238,172,173,181,114,108,155,226,128,114,185,156,250, 57, 96,255, 69, 19, 0, +108, 60,100,216,118,194,128, 16,106,179, 17,171,173,153,215,105, 65,157,214, 68,233,166, 27,218,242,228, 36,204,209,184,218, 15, +253,121,224, 62,108,110,210,210, 13,208,156, 6, 63,114,241,221, 8, 75,147, 59, 95,143,150, 95,172,107,120, 99, 84,223,132,220, +211, 51,254,249, 19,142,232, 49,159,108, 27,188, 45, 76,237,201, 49, 61,190,133,201, 73,246, 34, 3,220,159, 2, 29,229,199,203, +109, 21,112,108,211,209, 68,247, 23, 99, 63,111,116,249, 84,199,207,252, 36,123,243,103,233,169, 31, 48,243, 58, 57,166, 46,180, +166,195,110,221,206,108,166,104, 56, 60, 51,103,223,237, 22, 38, 39,225,110,116,230, 40, 8,142, 68,128,245,105,235,222,177, 54, +152,232,161, 37,251, 79,248,248,123,215,238,149,181,240,228,126, 26,246, 88,242,217,231,228,244,175, 22, 30, 61,125,160,150, 36, + 39,181, 86, 20, 11, 7,175,112,221, 61, 87, 62,111,205,174, 58,247,247,162,141,199,176,223,199,198, 41,152,166, 36, 8, 98,226, +179,179, 45,154,138,205,246,192, 22,241,115, 38, 25,190,149,169,147,251, 53,179,247, 12, 58,123,239, 90, 94,246,203,101, 34,104, +185,212,186, 79,223,115,212, 60,222,181,237,238, 85, 75, 46,220,217,215,160, 93,105,124,104,238, 53,229,222,245,209,242,131,222, + 95,213,217,182, 60,235, 74, 99,182, 22,158,220,133,221,127, 63,111,124, 89, 55, 30, 60,120,240,112, 22,252, 44,241, 60,120,240, +224,193, 83, 39, 15, 30, 60,120,184, 31,255, 31, 19, 50, 19, 5, 1,234,172,253, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, +}; diff --git a/source/blender/src/booleanops.c b/source/blender/src/booleanops.c new file mode 100644 index 00000000000..5c89dee1a46 --- /dev/null +++ b/source/blender/src/booleanops.c @@ -0,0 +1,795 @@ + +#include <string.h> +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * CSG operations. + */ + + + +#include "MEM_guardedalloc.h" + +#include "BLI_ghash.h" + +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "CSG_BooleanOps.h" + +#include "BKE_global.h" +#include "BKE_mesh.h" +#include "BKE_displist.h" +#include "BKE_object.h" +#include "BKE_booleanops.h" +#include "BKE_utildefines.h" +#include "BKE_library.h" +#include "BKE_material.h" + +#include <math.h> + +// TODO check to see how many of these includes are necessary + +#include "BLI_blenlib.h" +#include "BLI_editVert.h" +#include "BLI_arithb.h" +#include "BLI_linklist.h" +#include "BLI_memarena.h" + + +/** + * Here's the vertex iterator structure used to walk through + * the blender vertex structure. + */ + +typedef struct { + Object *ob; + Mesh *mesh; + int pos; +} VertexIt; + +/** + * Implementations of local vertex iterator functions. + * These describe a blender mesh to the CSG module. + */ + +static + void +VertexIt_Destruct( + CSG_VertexIteratorDescriptor * iterator +){ + if (iterator->it) { + // deallocate memory for iterator + MEM_freeN(iterator->it); + iterator->it = 0; + } + iterator->Done = NULL; + iterator->Fill = NULL; + iterator->Reset = NULL; + iterator->Step = NULL; + iterator->num_elements = 0; + +}; + +static + int +VertexIt_Done( + CSG_IteratorPtr it +){ + VertexIt * iterator = (VertexIt *)it; + return(iterator->pos >= iterator->mesh->totvert); +} + + +static + void +VertexIt_Fill( + CSG_IteratorPtr it, + CSG_IVertex *vert +){ + VertexIt * iterator = (VertexIt *)it; + MVert *verts = iterator->mesh->mvert; + + float global_pos[3]; + + VecMat4MulVecfl( + global_pos, + iterator->ob->obmat, + verts[iterator->pos].co + ); + + vert->position[0] = global_pos[0]; + vert->position[1] = global_pos[1]; + vert->position[2] = global_pos[2]; +} + +static + void +VertexIt_Step( + CSG_IteratorPtr it +){ + VertexIt * iterator = (VertexIt *)it; + iterator->pos ++; +} + +static + void +VertexIt_Reset( + CSG_IteratorPtr it +){ + VertexIt * iterator = (VertexIt *)it; + iterator->pos = 0; +} + +static + void +VertexIt_Construct( + CSG_VertexIteratorDescriptor * output, + Object *ob +){ + + VertexIt *it; + if (output == 0) return; + + // allocate some memory for blender iterator + it = (VertexIt *)(MEM_mallocN(sizeof(VertexIt),"Boolean_VIt")); + if (it == 0) { + return; + } + // assign blender specific variables + it->ob = ob; + it->mesh = ob->data; + + it->pos = 0; + + // assign iterator function pointers. + output->Step = VertexIt_Step; + output->Fill = VertexIt_Fill; + output->Done = VertexIt_Done; + output->Reset = VertexIt_Reset; + output->num_elements = it->mesh->totvert; + output->it = it; +} + +/** + * Blender Face iterator + */ + +typedef struct { + Object *ob; + Mesh *mesh; + int pos; +} FaceIt; + + +static + void +FaceIt_Destruct( + CSG_FaceIteratorDescriptor * iterator +) { + MEM_freeN(iterator->it); + iterator->Done = NULL; + iterator->Fill = NULL; + iterator->Reset = NULL; + iterator->Step = NULL; + iterator->num_elements = 0; +}; + + +static + int +FaceIt_Done( + CSG_IteratorPtr it +) { + // assume CSG_IteratorPtr is of the correct type. + FaceIt * iterator = (FaceIt *)it; + return(iterator->pos >= iterator->mesh->totface); +}; + +static + void +FaceIt_Fill( + CSG_IteratorPtr it, + CSG_IFace *face +){ + // assume CSG_IteratorPtr is of the correct type. + FaceIt * face_it = (FaceIt *)it; + Object *ob = face_it->ob; + MFace *mfaces = face_it->mesh->mface; + TFace *tfaces = face_it->mesh->tface; + int f_index = face_it->pos; + MFace *mface = &mfaces[f_index]; + FaceData *fdata = face->user_face_data; + + if (mface->v3) { + // ignore lines (faces with mface->v3==0) + face->vertex_index[0] = mface->v1; + face->vertex_index[1] = mface->v2; + face->vertex_index[2] = mface->v3; + if (mface->v4) { + face->vertex_index[3] = mface->v4; + face->vertex_number = 4; + } else { + face->vertex_number = 3; + } + } + + fdata->material = give_current_material(ob, mface->mat_nr+1); + + // pack rgba colors. + if (tfaces) { + TFace *tface= &tfaces[f_index]; + int i; + + fdata->tpage = tface->tpage; + fdata->flag = tface->flag; + fdata->transp = tface->transp; + fdata->mode = tface->mode; + fdata->tile = tface->tile; + + for (i=0; i<4; i++) { + FaceVertexData *fvdata= face->user_face_vertex_data[i]; + + fvdata->uv[0] = tface->uv[i][0]; + fvdata->uv[1] = tface->uv[i][1]; + fvdata->color[0] = (float) ((tface->col[i] >> 24) & 0xff); + fvdata->color[1] = (float) ((tface->col[i] >> 16) & 0xff); + fvdata->color[2] = (float) ((tface->col[i] >> 8) & 0xff); + fvdata->color[3] = (float) ((tface->col[i] >> 0) & 0xff); + } + } +}; + + +static + void +FaceIt_Step( + CSG_IteratorPtr it +) { + FaceIt * face_it = (FaceIt *)it; + face_it->pos ++; +}; + +static + void +FaceIt_Reset( + CSG_IteratorPtr it +) { + FaceIt * face_it = (FaceIt *)it; + face_it->pos = 0; +} + +static + void +FaceIt_Construct( + CSG_FaceIteratorDescriptor * output, + Object * ob +){ + + FaceIt *it; + if (output == 0) return; + + // allocate some memory for blender iterator + it = (FaceIt *)(MEM_mallocN(sizeof(FaceIt),"Boolean_FIt")); + if (it == 0) { + return ; + } + // assign blender specific variables + it->ob = ob; + it->mesh = ob->data; + it->pos = 0; + + // assign iterator function pointers. + output->Step = FaceIt_Step; + output->Fill = FaceIt_Fill; + output->Done = FaceIt_Done; + output->Reset = FaceIt_Reset; + output->num_elements = it->mesh->totface; + output->it = it; +}; + + +/** + * Interpolation functions for various user data types. + */ + + int +InterpNoUserData( + void *d1, + void *d2, + void *dnew, + float epsilon +) { + // nothing to do of course. + return 0; +} + + int +InterpFaceVertexData( + void *d1, + void *d2, + void *dnew, + float epsilon +) { + /* XXX, passed backwards, should be fixed inside + * BSP lib I guess. + */ + FaceVertexData *fv1 = d2; + FaceVertexData *fv2 = d1; + FaceVertexData *fvO = dnew; + + fvO->uv[0] = (fv2->uv[0] - fv1->uv[0]) * epsilon + fv1->uv[0]; + fvO->uv[1] = (fv2->uv[1] - fv1->uv[1]) * epsilon + fv1->uv[1]; + fvO->color[0] = (fv2->color[0] - fv1->color[0]) * epsilon + fv1->color[0]; + fvO->color[1] = (fv2->color[1] - fv1->color[1]) * epsilon + fv1->color[1]; + fvO->color[2] = (fv2->color[2] - fv1->color[2]) * epsilon + fv1->color[2]; + fvO->color[3] = (fv2->color[3] - fv1->color[3]) * epsilon + fv1->color[3]; + + return 0; +} + + + +/** + * Assumes mesh is valid and forms part of a fresh + * blender object. + */ + + + + int +NewBooleanMesh( + struct Base * base, + struct Base * base_select, + int int_op_type +){ + Mesh *me2 = get_mesh(base_select->object); + Mesh *me = get_mesh(base->object); + Mesh *me_new = NULL; + Object *ob; + int free_tface1,free_tface2; + + float inv_mat[4][4]; + int success = 0; + // build and fill new descriptors for these meshes + CSG_VertexIteratorDescriptor vd_1; + CSG_VertexIteratorDescriptor vd_2; + CSG_FaceIteratorDescriptor fd_1; + CSG_FaceIteratorDescriptor fd_2; + + CSG_MeshPropertyDescriptor mpd1,mpd2; + + // work out the operation they chose and pick the appropriate + // enum from the csg module. + + CSG_OperationType op_type; + + if (me == NULL || me2 == NULL) return 0; + + switch (int_op_type) { + case 1 : op_type = e_csg_intersection; break; + case 2 : op_type = e_csg_union; break; + case 3 : op_type = e_csg_difference; break; + case 4 : op_type = e_csg_classify; break; + default : op_type = e_csg_intersection; + } + + // Here is the section where we describe the properties of + // both meshes to the bsp module. + + if (me->mcol != NULL) { + // Then this mesh has vertex colors only + // well this is awkward because there is no equivalent + // test_index_mface just for vertex colors! + // as a temporary hack we can convert these vertex colors + // into tfaces do the operation and turn them back again. + + // create some memory for the tfaces. + me->tface = (TFace *)MEM_callocN(sizeof(TFace)*me->totface,"BooleanOps_TempTFace"); + mcol_to_tface(me,1); + free_tface1 = 1; + } else { + free_tface1 = 0; + } + + mpd1.user_face_vertex_data_size = 0; + mpd1.user_data_size = sizeof(FaceData); + + if (me->tface) { + mpd1.user_face_vertex_data_size = sizeof(FaceVertexData); + } + + // same for mesh2 + + if (me2->mcol != NULL) { + // create some memory for the tfaces. + me2->tface = (TFace *)MEM_callocN(sizeof(TFace)*me2->totface,"BooleanOps_TempTFace"); + mcol_to_tface(me2,1); + free_tface2 = 1; + } else { + free_tface2 = 0; + } + + mpd2.user_face_vertex_data_size = 0; + mpd2.user_data_size = sizeof(FaceData); + + if (me2->tface) { + mpd2.user_face_vertex_data_size = sizeof(FaceVertexData); + } + + ob = base->object; + + // we map the final object back into object 1's (ob) + // local coordinate space. For this we need to compute + // the inverse transform from global to local. + + Mat4Invert(inv_mat,ob->obmat); + + // make a boolean operation; + { + CSG_BooleanOperation * bool_op = CSG_NewBooleanFunction(); + CSG_MeshPropertyDescriptor output_mpd = CSG_DescibeOperands(bool_op,mpd1,mpd2); + // analyse the result and choose mesh descriptors accordingly + int output_type; + if (output_mpd.user_face_vertex_data_size) { + output_type = 1; + } else { + output_type = 0; + } + + BuildMeshDescriptors( + base->object, + &fd_1, + &vd_1 + ); + BuildMeshDescriptors( + base_select->object, + &fd_2, + &vd_2 + ); + + // perform the operation + + if (output_type == 0) { + + success = + CSG_PerformBooleanOperation( + bool_op, + op_type, + fd_1,vd_1,fd_2,vd_2, + InterpNoUserData + ); + } else { + success = + CSG_PerformBooleanOperation( + bool_op, + op_type, + fd_1,vd_1,fd_2,vd_2, + InterpFaceVertexData + ); + } + + if (success) { + // descriptions of the output; + CSG_VertexIteratorDescriptor vd_o; + CSG_FaceIteratorDescriptor fd_o; + + // Create a new blender mesh object - using 'base' as + // a template for the new object. + Object * ob_new= AddNewBlenderMesh(base); + + // get the output descriptors + + CSG_OutputFaceDescriptor(bool_op,&fd_o); + CSG_OutputVertexDescriptor(bool_op,&vd_o); + + me_new = ob_new->data; + // iterate through results of operation and insert into new object + // see subsurf.c + + ConvertCSGDescriptorsToMeshObject( + ob_new, + &output_mpd, + &fd_o, + &vd_o, + inv_mat + ); + + // initialize the object + tex_space_mesh(me_new); + + // free up the memory + + CSG_FreeVertexDescriptor(&vd_o); + CSG_FreeFaceDescriptor(&fd_o); + } + + CSG_FreeBooleanOperation(bool_op); + bool_op = NULL; + + } + + // We may need to map back the tfaces to mcols here. + if (free_tface1) { + tface_to_mcol(me); + MEM_freeN(me->tface); + me->tface = NULL; + } + if (free_tface2) { + tface_to_mcol(me2); + MEM_freeN(me2->tface); + me2->tface = NULL; + } + + if (free_tface1 && free_tface2) { + // then we need to map the output tfaces into mcols + if (me_new) { + tface_to_mcol(me_new); + MEM_freeN(me_new->tface); + me_new->tface = NULL; + } + } + + FreeMeshDescriptors(&fd_1,&vd_1); + FreeMeshDescriptors(&fd_2,&vd_2); + + return success; +} + + + Object * +AddNewBlenderMesh( + Base *base +){ + Mesh *old_me; + Base *basen; + Object *ob_new; + + // now create a new blender object. + // duplicating all the settings from the previous object + // to the new one. + ob_new= copy_object(base->object); + + // Ok we don't want to use the actual data from the + // last object, the above function incremented the + // number of users, so decrement it here. + old_me= ob_new->data; + old_me->id.us--; + + // Now create a new base to add into the linked list of + // vase objects. + + basen= MEM_mallocN(sizeof(Base), "duplibase"); + *basen= *base; + BLI_addhead(&G.scene->base, basen); /* addhead: anders oneindige lus */ + basen->object= ob_new; + basen->flag &= ~SELECT; + + // Initialize the mesh data associated with this object. + ob_new->data= add_mesh(); + G.totmesh++; + + // Finally assign the object type. + ob_new->type= OB_MESH; + + return ob_new; +}; + + + +/** + * + * External interface + * + * This function builds a blender mesh using the output information from + * the CSG module. It declares all the necessary blender cruft and + * fills in the vertex and face arrays. + */ + int +ConvertCSGDescriptorsToMeshObject( + Object *ob, + CSG_MeshPropertyDescriptor *props, + CSG_FaceIteratorDescriptor *face_it, + CSG_VertexIteratorDescriptor *vertex_it, + float parinv[][4] +){ + Mesh *me = ob->data; + FaceVertexData *user_face_vertex_data; + GHash *material_hash; + CSG_IVertex vert; + CSG_IFace face; + MVert *insert_pos; + MFace *mfaces; + TFace *tfaces; + int fi_insert_pos, nmaterials; + + // create some memory for the Iface according to output mesh props. + + if (face_it == NULL || vertex_it == NULL || props == NULL || me == NULL) { + return 0; + } + if (vertex_it->num_elements > 65000) return 0; + + // initialize the face structure for readback + + face.user_face_data = MEM_callocN(sizeof(FaceData),"BooleanOp_IFaceData"); + + if (props->user_face_vertex_data_size) { + user_face_vertex_data = MEM_callocN(sizeof(FaceVertexData)*4,"BooleanOp_IFaceData"); + face.user_face_vertex_data[0] = &user_face_vertex_data[0]; + face.user_face_vertex_data[1] = &user_face_vertex_data[1]; + face.user_face_vertex_data[2] = &user_face_vertex_data[2]; + face.user_face_vertex_data[3] = &user_face_vertex_data[3]; + } else { + user_face_vertex_data = NULL; + } + + // create memory for the vertex array. + + me->mvert = MEM_callocN(sizeof(MVert) * vertex_it->num_elements,"BooleanOp_VertexArray"); + me->mface = MEM_callocN(sizeof(MFace) * face_it->num_elements,"BooleanOp_FaceArray"); + + if (user_face_vertex_data) { + me->tface = MEM_callocN(sizeof(TFace) * face_it->num_elements,"BooleanOp_TFaceArray"); + if (me->tface == NULL) return 0; + } else { + me->tface = NULL; + } + + if (me->mvert == NULL || me->mface == NULL) return 0; + + insert_pos = me->mvert; + mfaces = me->mface; + tfaces = me->tface; + + fi_insert_pos = 0; + + // step through the iterators. + + while (!vertex_it->Done(vertex_it->it)) { + vertex_it->Fill(vertex_it->it,&vert); + + // map output vertex into insert_pos + // and transform at by parinv at the same time. + + VecMat4MulVecfl( + insert_pos->co, + parinv, + vert.position + ); + insert_pos ++; + vertex_it->Step(vertex_it->it); + } + + me->totvert = vertex_it->num_elements; + + // a hash table to remap materials to indices with + material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + nmaterials = 0; + + while (!face_it->Done(face_it->it)) { + MFace *mface = &mfaces[fi_insert_pos]; + FaceData *fdata; + + face_it->Fill(face_it->it,&face); + + // cheat CSG never dumps out quads. + + mface->v1 = face.vertex_index[0]; + mface->v2 = face.vertex_index[1]; + mface->v3 = face.vertex_index[2]; + mface->v4 = 0; + + mface->edcode = ME_V1V2|ME_V2V3|ME_V3V4|ME_V4V1; + mface->puno = 0; + mface->mat_nr = 0; + mface->flag = 0; + + /* HACK, perform material to index mapping using a general + * hash table, just tuck the int into a void *. + */ + + fdata = face.user_face_data; + if (!BLI_ghash_haskey(material_hash, fdata->material)) { + int matnr = nmaterials++; + BLI_ghash_insert(material_hash, fdata->material, (void*) matnr); + assign_material(ob, fdata->material, matnr+1); + } + mface->mat_nr = (int) BLI_ghash_lookup(material_hash, fdata->material); + + // grab the vertex colors and texture cos and dump them into the tface. + + if (tfaces) { + TFace *tface= &tfaces[fi_insert_pos]; + int i; + + // copy all the tface settings back + tface->tpage = fdata->tpage; + tface->flag = fdata->flag; + tface->transp = fdata->transp; + tface->mode = fdata->mode; + tface->tile = fdata->tile; + + for (i=0; i<4; i++) { + FaceVertexData *fvdata = face.user_face_vertex_data[i]; + float *color = fvdata->color; + + tface->uv[i][0] = fvdata->uv[0]; + tface->uv[i][1] = fvdata->uv[1]; + tface->col[i] = + ((((unsigned int)floor(color[0] + 0.5f)) & 0xff) << 24) | + ((((unsigned int)floor(color[1] + 0.5f)) & 0xff) << 16) | + ((((unsigned int)floor(color[2] + 0.5f)) & 0xff) << 8) | + ((((unsigned int)floor(color[3] + 0.5f)) & 0xff) << 0); + } + + test_index_face(mface, tface, 3); + } else { + test_index_mface(mface, 3); + } + + fi_insert_pos++; + face_it->Step(face_it->it); + } + + BLI_ghash_free(material_hash, NULL, NULL); + + me->totface = face_it->num_elements; + // thats it! + + if (user_face_vertex_data) { + MEM_freeN(user_face_vertex_data); + } + MEM_freeN(face.user_face_data); + + return 1; +} + + void +BuildMeshDescriptors( + struct Object *ob, + struct CSG_FaceIteratorDescriptor * face_it, + struct CSG_VertexIteratorDescriptor * vertex_it +){ + VertexIt_Construct(vertex_it,ob); + FaceIt_Construct(face_it,ob); +} + + void +FreeMeshDescriptors( + struct CSG_FaceIteratorDescriptor *face_it, + struct CSG_VertexIteratorDescriptor *vertex_it +){ + VertexIt_Destruct(vertex_it); + FaceIt_Destruct(face_it); +} + diff --git a/source/blender/src/booleanops_mesh.c b/source/blender/src/booleanops_mesh.c new file mode 100644 index 00000000000..8df36833a1d --- /dev/null +++ b/source/blender/src/booleanops_mesh.c @@ -0,0 +1,302 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#include "CSG_BooleanOps.h" + +#include "BKE_booleanops.h" +#include "BKE_booleanops_mesh.h" +#include "MEM_guardedalloc.h" + +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_global.h" +#include "BKE_mesh.h" +#include "BKE_displist.h" +#include "BKE_object.h" +#include "BKE_utildefines.h" +#include "BKE_library.h" +#include "BKE_material.h" + +#include "BLI_arithb.h" + +/** + * Implementation of boolean ops mesh interface. + */ + + void +CSG_DestroyMeshDescriptor( + CSG_MeshDescriptor *mesh +){ + // Call mesh descriptors destroy function.... + mesh->m_destroy_func(mesh); +} + +// Destroy function for blender mesh internals. + +static + void +CSG_DestroyBlenderMeshInternals( + CSG_MeshDescriptor *mesh +) { + // Free face and vertex iterators. + FreeMeshDescriptors(&(mesh->m_face_iterator),&(mesh->m_vertex_iterator)); +}; + + +static + void +CSG_DestroyCSGMeshInternals( + CSG_MeshDescriptor *mesh +){ + CSG_FreeVertexDescriptor(&(mesh->m_vertex_iterator)); + CSG_FreeFaceDescriptor(&(mesh->m_face_iterator)); +} + +static + int +MakeCSGMeshFromBlenderBase( + Base * base, + CSG_MeshDescriptor * output +) { + Mesh *me; + if (output == NULL || base == NULL) return 0; + + me = get_mesh(base->object); + + output->m_descriptor.user_face_vertex_data_size = 0; + output->m_descriptor.user_data_size = sizeof(FaceData); + + if (me->tface) { + output->m_descriptor.user_face_vertex_data_size = sizeof(FaceVertexData); + } + + output->base = base; + + BuildMeshDescriptors( + base->object, + &(output->m_face_iterator), + &(output->m_vertex_iterator) + ); + + output->m_destroy_func = CSG_DestroyBlenderMeshInternals; + + return 1; +} + + int +CSG_LoadBlenderMesh( + Object * obj, + CSG_MeshDescriptor *output +){ + + Mesh *me; + if (output == NULL || obj == NULL) return 0; + + me = get_mesh(obj); + + output->m_descriptor.user_face_vertex_data_size = 0; + output->m_descriptor.user_data_size = sizeof(FaceData); + + if (me->tface) { + output->m_descriptor.user_face_vertex_data_size = sizeof(FaceVertexData); + } + + output->base = NULL; + + BuildMeshDescriptors( + obj, + &(output->m_face_iterator), + &(output->m_vertex_iterator) + ); + + output->m_destroy_func = CSG_DestroyBlenderMeshInternals; + output->base = NULL; + + return 1; +} + + + + + int +CSG_AddMeshToBlender( + CSG_MeshDescriptor *mesh +){ + Mesh *me_new = NULL; + Object *ob_new = NULL; + float inv_mat[4][4]; + + if (mesh == NULL) return 0; + if (mesh->base == NULL) return 0; + + Mat4Invert(inv_mat,mesh->base->object->obmat); + + // Create a new blender mesh object - using 'base' as + // a template for the new object. + ob_new= AddNewBlenderMesh(mesh->base); + + me_new = ob_new->data; + + // make sure the iterators are reset. + mesh->m_face_iterator.Reset(mesh->m_face_iterator.it); + mesh->m_vertex_iterator.Reset(mesh->m_vertex_iterator.it); + + // iterate through results of operation and insert into new object + // see subsurf.c + + ConvertCSGDescriptorsToMeshObject( + ob_new, + &(mesh->m_descriptor), + &(mesh->m_face_iterator), + &(mesh->m_vertex_iterator), + inv_mat + ); + + // initialize the object + tex_space_mesh(me_new); + + return 1; +} + + int +CSG_PerformOp( + CSG_MeshDescriptor *mesh1, + CSG_MeshDescriptor *mesh2, + int int_op_type, + CSG_MeshDescriptor *output +){ + + CSG_OperationType op_type; + CSG_BooleanOperation * bool_op = CSG_NewBooleanFunction(); + int success = 0; + + if (bool_op == NULL) return 0; + + if ((mesh1 == NULL) || (mesh2 == NULL) || (output == NULL)) { + return 0; + } + if ((int_op_type < 1) || (int_op_type > 3)) return 0; + + switch (int_op_type) { + case 1 : op_type = e_csg_intersection; break; + case 2 : op_type = e_csg_union; break; + case 3 : op_type = e_csg_difference; break; + case 4 : op_type = e_csg_classify; break; + default : op_type = e_csg_intersection; + } + + output->m_descriptor = CSG_DescibeOperands(bool_op,mesh1->m_descriptor,mesh2->m_descriptor); + output->base = mesh1->base; + + if (output->m_descriptor.user_face_vertex_data_size) { + // Then use the only interp function supported + success = + CSG_PerformBooleanOperation( + bool_op, + op_type, + mesh1->m_face_iterator, + mesh1->m_vertex_iterator, + mesh2->m_face_iterator, + mesh2->m_vertex_iterator, + InterpFaceVertexData + ); + } else { + success = + CSG_PerformBooleanOperation( + bool_op, + op_type, + mesh1->m_face_iterator, + mesh1->m_vertex_iterator, + mesh2->m_face_iterator, + mesh2->m_vertex_iterator, + InterpNoUserData + ); + } + + if (!success) { + CSG_FreeBooleanOperation(bool_op); + bool_op = NULL; + return 0; + } + + // get the ouput mesh descriptors. + + CSG_OutputFaceDescriptor(bool_op,&(output->m_face_iterator)); + CSG_OutputVertexDescriptor(bool_op,&(output->m_vertex_iterator)); + output->m_destroy_func = CSG_DestroyCSGMeshInternals; + + return 1; +}; + + int +NewBooleanMeshTest( + struct Base * base, + struct Base * base_select, + int op_type +){ + + CSG_MeshDescriptor m1,m2,output; + CSG_MeshDescriptor output2,output3; + + if (!MakeCSGMeshFromBlenderBase(base,&m1)) { + return 0; + } + + if (!MakeCSGMeshFromBlenderBase(base_select,&m2)) { + return 0; + } + + CSG_PerformOp(&m1,&m2,1,&output); + CSG_PerformOp(&m1,&m2,2,&output2); + CSG_PerformOp(&m1,&m2,3,&output3); + + if (!CSG_AddMeshToBlender(&output)) { + return 0; + } + if (!CSG_AddMeshToBlender(&output2)) { + return 0; + } + if (!CSG_AddMeshToBlender(&output3)) { + return 0; + } + + + CSG_DestroyMeshDescriptor(&m1); + CSG_DestroyMeshDescriptor(&m2); + CSG_DestroyMeshDescriptor(&output); + CSG_DestroyMeshDescriptor(&output2); + CSG_DestroyMeshDescriptor(&output3); + + return 1; +}; diff --git a/source/blender/src/buttons.c b/source/blender/src/buttons.c new file mode 100644 index 00000000000..85aeb92d959 --- /dev/null +++ b/source/blender/src/buttons.c @@ -0,0 +1,7338 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * Everything for drawing buttons (and I do mean _everything_). + */ + + +/* System includes ----------------------------------------------------- */ + +#include <time.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> + +#ifdef _WIN32 +#include "BLI_winstuff.h" +#else +#include <unistd.h> +#endif +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_camera_types.h" +#include "DNA_constraint_types.h" +#include "DNA_curve_types.h" +#include "DNA_effect_types.h" +#include "DNA_group_types.h" +#include "DNA_ika_types.h" +#include "DNA_image_types.h" +#include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_lattice_types.h" +#include "DNA_material_types.h" +#include "DNA_meta_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_packedFile_types.h" +#include "DNA_radio_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_sound_types.h" +#include "DNA_space_types.h" +#include "DNA_texture_types.h" +#include "DNA_userdef_types.h" +#include "DNA_vfont_types.h" +#include "DNA_view3d_types.h" +#include "DNA_world_types.h" + +#include "BKE_anim.h" +#include "BKE_armature.h" +#include "BKE_constraint.h" +#include "BKE_curve.h" +#include "BKE_displist.h" +#include "BKE_effect.h" +#include "BKE_font.h" +#include "BKE_global.h" +#include "BKE_ika.h" +#include "BKE_image.h" +#include "BKE_ipo.h" +#include "BKE_lattice.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_mball.h" +#include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_packedFile.h" +#include "BKE_plugin_types.h" +#include "BKE_sound.h" +#include "BKE_texture.h" +#include "BKE_utildefines.h" +#include "BKE_writeavi.h" + +/* Everything from source (BIF, BDR, BSE) ------------------------------ */ + +#include "BDR_drawobject.h" +#include "BDR_editcurve.h" +#include "BDR_editface.h" +#include "BDR_editobject.h" +#include "BDR_isect.h" +#include "BDR_vpaint.h" + +#include "BSE_drawview.h" +#include "BSE_editipo.h" +#include "BSE_edit.h" +#include "BSE_filesel.h" +#include "BSE_headerbuttons.h" +#include "BSE_trans_types.h" +#include "BSE_view.h" +#include "BSE_buttons.h" + +#include "BIF_gl.h" +#include "BIF_editarmature.h" +#include "BIF_editconstraint.h" +#include "BIF_editdeform.h" +#include "BIF_editfont.h" +#include "BIF_editmesh.h" +#include "BIF_editsca.h" +#include "BIF_editsound.h" +#include "BIF_interface.h" +#include "BIF_mywindow.h" +#include "BIF_renderwin.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_scrarea.h" +#include "BIF_space.h" +#include "BIF_toets.h" +#include "BIF_toolbox.h" +#include "BIF_previewrender.h" +#include "BIF_writeimage.h" +#include "BIF_writeavicodec.h" + +#include "license_key.h" +extern int LICENSE_KEY_VALID; + +/* 'old' stuff": defines and types ------------------------------------- */ +#include "blendef.h" +#include "interface.h" + +/* old style modules --------------------------------------------------- */ + +#include "mydevice.h" + +#include "render.h" +#include "radio.h" +#include "nla.h" /* For __NLA: Do not remove! */ + +/* Decimation includes. See LOD_DependKludge.h for enabling Decimation */ +#include "LOD_DependKludge.h" +#ifdef NAN_DECIMATION + #include "LOD_decimation.h" +#endif + +/* own include --------------------------------------------------------- */ +#include "BSE_buttons.h" + +/* some dirt ... let the linker deal with it :( ------------------------ */ +extern ListBase editNurb; /* from editcurve */ +extern VPaint Gvp; /* from vpaint */ + +/* Local vars ---------------------------------------------------------- */ +short bgpicmode=0, near=1000, far=1000; +short degr= 90, step= 9, turn= 1, editbutflag= 1; +float hspeed=.1, prspeed=0.0, prlen=0.0, doublimit= 0.001; +int decim_faces=0; + +#ifdef __NLA +float editbutvweight=1; +#endif +float extr_offs= 1.0, editbutweight=1.0, editbutsize=0.1, cumapsize= 1.0; +MTex emptytex; +char texstr[15][8]= {"None" , "Clouds" , "Wood", + "Marble", "Magic" , "Blend", + "Stucci", "Noise" , "Image", + "Plugin", "EnvMap" , "", + "" , "" , ""}; + + +/* Local functions ----------------------------------------------------- */ + +/* event for buttons (ROW) to indicate the backbuffer isn't OK (ogl) */ +#define B_DIFF 1 + +/* *********************** */ +#define B_VIEWBUTS 1100 + +#define B_LOADBGPIC 1001 +#define B_BLENDBGPIC 1002 +#define B_BGPICBROWSE 1003 +#define B_BGPICTEX 1004 +#define B_BGPICCLEAR 1005 +#define B_BGPICTEXCLEAR 1006 + +/* *********************** */ +#define B_LAMPBUTS 1200 + +#define B_LAMPREDRAW 1101 +#define B_COLLAMP 1102 +#define B_TEXCLEARLAMP 1103 + +/* *********************** */ +#define B_MATBUTS 1300 + +#define B_MATCOL 1201 +#define B_SPECCOL 1202 +#define B_MIRCOL 1203 +#define B_ACTCOL 1204 +#define B_MATFROM 1205 +#define B_MATPRV 1206 +#define B_MTEXCOL 1207 +#define B_TEXCLEAR 1208 +#define B_MATPRV_DRAW 1209 +#define B_MTEXPASTE 1210 +#define B_MTEXCOPY 1211 +#define B_MATLAY 1212 + +/* *********************** */ +#define B_TEXBUTS 1400 + +#define B_TEXTYPE 1301 +#define B_DEFTEXVAR 1302 +#define B_LOADTEXIMA 1303 +#define B_NAMEIMA 1304 +#define B_TEXCHANNEL 1305 +#define B_TEXREDR_PRV 1306 +#define B_TEXIMABROWSE 1307 +#define B_IMAPTEST 1308 +#define B_RELOADIMA 1309 +#define B_LOADPLUGIN 1310 +#define B_NAMEPLUGIN 1311 +#define B_COLORBAND 1312 +#define B_ADDCOLORBAND 1313 +#define B_DELCOLORBAND 1314 +#define B_CALCCBAND 1315 +#define B_CALCCBAND2 1316 +#define B_DOCOLORBAND 1317 +#define B_REDRAWCBAND 1318 +#define B_BANDCOL 1319 +#define B_LOADTEXIMA1 1320 +#define B_PLUGBUT 1321 + +/* plugbut reserves 24 buttons at least! */ + +#define B_ENV_MAKE 1350 +#define B_ENV_FREE 1351 +#define B_ENV_DELETE 1352 +#define B_ENV_SAVE 1353 +#define B_ENV_OB 1354 + +#define B_PACKIMA 1355 + +/* *********************** */ +#define B_ANIMBUTS 1500 + +#define B_RECALCPATH 1401 +#define B_MUL_IPO 1402 +#define B_AUTOTIMEOFS 1403 +#define B_FRAMEMAP 1404 +#define B_NEWEFFECT 1405 +#define B_PREVEFFECT 1406 +#define B_NEXTEFFECT 1407 +#define B_CHANGEEFFECT 1408 +#define B_CALCEFFECT 1409 +#define B_DELEFFECT 1410 +#define B_RECALCAL 1411 +#define B_SETSPEED 1412 +#define B_PRINTSPEED 1413 +#define B_PRINTLEN 1414 +#define B_RELKEY 1415 + + /* heeft MAX_EFFECT standen! Volgende pas 1450... */ +#define B_SELEFFECT 1430 + + +/* *********************** */ +#define B_WORLDBUTS 1600 + +#define B_TEXCLEARWORLD 1501 + +/* *********************** */ +#define B_RENDERBUTS 1700 + +#define B_FS_PIC 1601 +#define B_FS_BACKBUF 1602 + +#define B_FS_FTYPE 1604 +#define B_DORENDER 1605 +#define B_DOANIM 1606 +#define B_PLAYANIM 1607 +#define B_PR_PAL 1608 +#define B_PR_FULL 1609 +#define B_PR_PRV 1610 +#define B_PR_CDI 1611 +#define B_PR_PAL169 1612 +#define B_PR_D2MAC 1613 +#define B_PR_MPEG 1614 +#define B_REDRAWDISP 1615 +#define B_SETBROWSE 1616 +#define B_CLEARSET 1617 +#define B_PR_PRESET 1618 +#define B_PR_PANO 1619 + +#define B_IS_FTYPE 1622 +#define B_IS_BACKBUF 1623 +#define B_PR_PC 1624 + +#define B_PR_PANO360 1627 +#define B_PR_HALFFIELDS 1628 +#define B_NEWRENDERPIPE 1629 +#define B_R_SCALE 1630 +#define B_G_SCALE 1631 +#define B_B_SCALE 1632 +#define B_USE_R_SCALE 1633 +#define B_USE_G_SCALE 1634 +#define B_USE_B_SCALE 1635 +#define B_EDGECOLSLI 1636 +#define B_GAMMASLI 1637 + +#define B_FILETYPEMENU 1638 +#define B_SELECTCODEC 1639 +#define B_RTCHANGED 1640 + +#ifdef __NLA +/* *********************** */ +enum { + B_ARMATUREBUTS = 1800, + B_POSE = 1701 +}; +#endif + +/* *********************** */ +#define B_COMMONEDITBUTS 2049 + +#define B_MATWICH 2003 +#define B_MATNEW 2004 +#define B_MATDEL 2005 +#define B_MATASS 2006 +#define B_MATSEL 2007 +#define B_MATDESEL 2008 +#define B_HIDE 2009 +#define B_REVEAL 2010 +#define B_SELSWAP 2011 +#define B_SETSMOOTH 2012 +#define B_SETSOLID 2013 +#define B_AUTOTEX 2014 +#define B_DOCENTRE 2015 +#define B_DOCENTRENEW 2016 +#define B_DOCENTRECURSOR 2017 + + /* 32 getallen! */ +#define B_OBLAY 2018 + +#define B_MESHBUTS 2100 + +#define B_FLIPNORM 2050 +#define B_SPIN 2051 +#define B_SPINDUP 2052 +#define B_EXTR 2053 +#define B_SCREW 2054 +#define B_EXTREP 2055 +#define B_SPLIT 2056 +#define B_REMDOUB 2057 +#define B_SUBDIV 2058 +#define B_FRACSUBDIV 2059 +#define B_XSORT 2060 +#define B_HASH 2061 +#define B_DELSTICKY 2062 +#define B_DELVERTCOL 2063 +#define B_MAKE_TFACES 2064 +#define B_TOSPHERE 2065 +#define B_DEL_TFACES 2066 +#define B_NEWVGROUP 2067 +#define B_DELVGROUP 2068 +#define B_ASSIGNVGROUP 2069 +#define B_REMOVEVGROUP 2070 +#define B_SELVGROUP 2071 +#define B_DESELVGROUP 2072 +#define B_DECIM_FACES 2073 +#define B_DECIM_CANCEL 2074 +#define B_DECIM_APPLY 2075 +#define B_AUTOVGROUP 2076 +#define B_SLOWERDRAW 2077 +#define B_FASTERDRAW 2078 +#define B_VERTEXNOISE 2079 +#define B_VERTEXSMOOTH 2080 +#define B_INTERSECTMESH 2081 +#define B_MAKESTICKY 2082 +#define B_MAKEVERTCOL 2083 + +/* *********************** */ +#define B_CURVEBUTS 2200 + +#define B_CONVERTPOLY 2101 +#define B_CONVERTBEZ 2102 +#define B_CONVERTBSPL 2103 +#define B_CONVERTCARD 2104 +#define B_CONVERTNURB 2105 +#define B_UNIFU 2106 +#define B_ENDPU 2107 +#define B_BEZU 2108 +#define B_UNIFV 2109 +#define B_ENDPV 2110 +#define B_BEZV 2111 +#define B_SETWEIGHT 2112 +#define B_SETW1 2113 +#define B_SETW2 2114 +#define B_SETW3 2115 +#define B_SETORDER 2116 +#define B_MAKEDISP 2117 +#define B_SUBDIVCURVE 2118 +#define B_SPINNURB 2119 +#define B_CU3D 2120 +#define B_SETRESOLU 2121 +#define B_SETW4 2122 + + +/* *********************** */ +#define B_FONTBUTS 2300 + +#define B_MAKEFONT 2201 +#define B_TOUPPER 2202 +#define B_SETFONT 2203 +#define B_LOADFONT 2204 +#define B_TEXTONCURVE 2205 +#define B_PACKFONT 2206 + +/* *********************** */ +#define B_IKABUTS 2400 + +#define B_IKASETREF 2301 +#define B_IKARECALC 2302 + +/* *********************** */ +#define B_CAMBUTS 2500 + +/* *********************** */ +#define B_MBALLBUTS 2600 + +#define B_RECALCMBALL 2501 + +/* *********************** */ +#define B_LATTBUTS 2700 + +#define B_RESIZELAT 2601 +#define B_DRAWLAT 2602 +#define B_LATTCHANGED 2603 + +/* *********************** */ +#define B_GAMEBUTS 2800 + +/* in editsca.c */ + +/* *********************** */ +#define B_FPAINTBUTS 2900 + +#define B_VPCOLSLI 2801 +#define B_VPGAMMA 2802 + +#define B_COPY_TF_MODE 2804 +#define B_COPY_TF_UV 2805 +#define B_COPY_TF_COL 2806 +#define B_REDR_3D_IMA 2807 +#define B_SET_VCOL 2808 + +#define B_COPY_TF_TEX 2814 +#define B_TFACE_HALO 2815 +#define B_TFACE_BILLB 2816 + +#define B_SHOWTEX 2832 +#define B_ASSIGNMESH 2833 + + +/* *********************** */ +#define B_RADIOBUTS 3000 + +#define B_RAD_GO 2901 +#define B_RAD_INIT 2902 +#define B_RAD_LIMITS 2903 +#define B_RAD_FAC 2904 +#define B_RAD_NODELIM 2905 +#define B_RAD_NODEFILT 2906 +#define B_RAD_FACEFILT 2907 +#define B_RAD_ADD 2908 +#define B_RAD_DELETE 2909 +#define B_RAD_COLLECT 2910 +#define B_RAD_SHOOTP 2911 +#define B_RAD_SHOOTE 2912 +#define B_RAD_REPLACE 2913 +#define B_RAD_DRAW 2914 +#define B_RAD_FREE 2915 +#define B_RAD_ADDMESH 2916 + +/* *********************** */ +#define B_SCRIPTBUTS 3100 + +#define B_SCRIPT_ADD 3001 +#define B_SCRIPT_DEL 3002 +#define B_SCRIPT_TYPE 3003 + +/* Scene script buttons */ +#define B_SSCRIPT_ADD 3004 +#define B_SSCRIPT_DEL 3005 +#define B_SSCRIPT_TYPE 3006 + +/* *********************** */ +#define B_SOUNDBUTS 3200 +enum B_SOUND_BUTTONS { + B_SOUND_CHANGED = 3101, + B_SOUND_REDRAW, + B_SOUND_VOLUME, + B_SOUND_PANNING, + B_SOUND_PITCH, + B_SOUND_LOAD_SAMPLE, + B_SOUND_MENU_SAMPLE, + B_SOUND_NAME_SAMPLE, + B_SOUND_UNLINK_SAMPLE, + B_SOUND_RELOAD_SAMPLE, + B_SOUND_UNPACK_SAMPLE, + B_SOUND_PLAY_SAMPLE, + B_SOUND_COPY_SOUND, + B_SOUND_LOOPSTART, + B_SOUND_LOOPEND, + B_SOUND_BIDIRECTIONAL +}; + +/* *********************** */ +#define B_CONSTRAINTBUTS 3300 +enum { + B_CONSTRAINT_REDRAW = 3201, + B_CONSTRAINT_ADD, + B_CONSTRAINT_DEL, + B_CONSTRAINT_TEST, + B_CONSTRAINT_CHANGETYPE, + B_CONSTRAINT_CHANGENAME, + B_CONSTRAINT_CHANGETARGET +}; + +/* *********************** */ +/* BUTTON BUT: > 4000 */ +/* BUTTON 4001-4032: layers */ + + +static char *physics_pup(void) +{ + /* the number needs to match defines in game.h */ + return "Physics %t|Sumo %x0|" + "ODE %x4 |None %x7|"; +} + + +static void draw_buttons_edge(int win, float x1) +{ + float asp, winmat[4][4]; + int w,h; + + bwin_getsinglematrix(win, winmat); + bwin_getsize(win, &w, &h); + asp= 2.0/(w*winmat[0][0]); + + glColor3ub(0,0,0); + fdrawline(x1, -1000, x1, 2000); + glColor3ub(255,255,255); + fdrawline(x1+asp, -1000, x1+asp, 2000); +} + +static int packdummy = 0; + +void test_scriptpoin_but(char *name, ID **idpp) +{ + ID *id; + + id= G.main->text.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + return; + } + id= id->next; + } + *idpp= 0; +} +#ifdef __NLA +void test_actionpoin_but(char *name, ID **idpp) +{ + ID *id; + + id= G.main->action.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + return; + } + id= id->next; + } + *idpp= 0; +} +#endif + +void test_obpoin_but(char *name, ID **idpp) +{ + ID *id; + + if(idpp == (ID **)&(emptytex.object)) { + error("Add texture first"); + *idpp= 0; + return; + } + + id= G.main->object.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + return; + } + id= id->next; + } + *idpp= 0; +} + +void test_obcurpoin_but(char *name, ID **idpp) +{ + ID *id; + + if(idpp == (ID **)&(emptytex.object)) { + error("Add texture first"); + *idpp= 0; + return; + } + + id= G.main->object.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + if (((Object *)id)->type != OB_CURVE) { + error ("Bevel object must be a Curve"); + break; + } + *idpp= id; + return; + } + id= id->next; + } + *idpp= 0; +} + +void test_meshpoin_but(char *name, ID **idpp) +{ + ID *id; + + if( *idpp ) (*idpp)->us--; + + id= G.main->mesh.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + id_us_plus(id); + return; + } + id= id->next; + } + *idpp= 0; +} + +void test_matpoin_but(char *name, ID **idpp) +{ + ID *id; + + if( *idpp ) (*idpp)->us--; + + id= G.main->mat.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + id_us_plus(id); + return; + } + id= id->next; + } + *idpp= 0; +} + +void test_scenepoin_but(char *name, ID **idpp) +{ + ID *id; + + if( *idpp ) (*idpp)->us--; + + id= G.main->scene.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + id_us_plus(id); + return; + } + id= id->next; + } + *idpp= 0; +} + + + +/* ************************************* */ + +static void do_common_editbuts(unsigned short event) +{ + EditVlak *evl; + Base *base; + Object *ob; + Mesh *me; + Nurb *nu; + Curve *cu; + MFace *mface; + BezTriple *bezt; + BPoint *bp; + unsigned int local; + int a, bit, index= -1; + + switch(event) { + + case B_MATWICH: + if(G.obedit && G.obedit->actcol>0) { + if(G.obedit->type == OB_MESH) { + evl= G.edvl.first; + while(evl) { + if( vlakselectedAND(evl, 1) ) { + if(index== -1) index= evl->mat_nr; + else if(index!=evl->mat_nr) { + error("Mixed colors"); + return; + } + } + evl= evl->next; + } + } + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + nu= editNurb.first; + while(nu) { + if( isNurbsel(nu) ) { + if(index== -1) index= nu->mat_nr; + else if(index!=nu->mat_nr) { + error("Mixed colors"); + return; + } + } + nu= nu->next; + } + } + if(index>=0) { + G.obedit->actcol= index+1; + scrarea_queue_winredraw(curarea); + } + } + break; + case B_MATNEW: + new_material_to_objectdata((G.scene->basact) ? (G.scene->basact->object) : 0); + scrarea_queue_winredraw(curarea); + allqueue(REDRAWVIEW3D_Z, 0); + break; + case B_MATDEL: + delete_material_index(); + scrarea_queue_winredraw(curarea); + allqueue(REDRAWVIEW3D_Z, 0); + break; + case B_MATASS: + if(G.obedit && G.obedit->actcol>0) { + if(G.obedit->type == OB_MESH) { + evl= G.edvl.first; + while(evl) { + if( vlakselectedAND(evl, 1) ) + evl->mat_nr= G.obedit->actcol-1; + evl= evl->next; + } + allqueue(REDRAWVIEW3D_Z, 0); + makeDispList(G.obedit); + } + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + nu= editNurb.first; + while(nu) { + if( isNurbsel(nu) ) + nu->mat_nr= G.obedit->actcol-1; + nu= nu->next; + } + } + } + break; + case B_MATSEL: + case B_MATDESEL: + if(G.obedit) { + if(G.obedit->type == OB_MESH) { + evl= G.edvl.first; + while(evl) { + if(evl->mat_nr== G.obedit->actcol-1) { + if(event==B_MATSEL) { + if(evl->v1->h==0) evl->v1->f |= 1; + if(evl->v2->h==0) evl->v2->f |= 1; + if(evl->v3->h==0) evl->v3->f |= 1; + if(evl->v4 && evl->v4->h==0) evl->v4->f |= 1; + } + else { + if(evl->v1->h==0) evl->v1->f &= ~1; + if(evl->v2->h==0) evl->v2->f &= ~1; + if(evl->v3->h==0) evl->v3->f &= ~1; + if(evl->v4 && evl->v4->h==0) evl->v4->f &= ~1; + } + } + evl= evl->next; + } + tekenvertices_ext( event==B_MATSEL ); + } + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + nu= editNurb.first; + while(nu) { + if(nu->mat_nr==G.obedit->actcol-1) { + if(nu->bezt) { + a= nu->pntsu; + bezt= nu->bezt; + while(a--) { + if(bezt->hide==0) { + if(event==B_MATSEL) { + bezt->f1 |= 1; + bezt->f2 |= 1; + bezt->f3 |= 1; + } + else { + bezt->f1 &= ~1; + bezt->f2 &= ~1; + bezt->f3 &= ~1; + } + } + bezt++; + } + } + else if(nu->bp) { + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a--) { + if(bp->hide==0) { + if(event==B_MATSEL) bp->f1 |= 1; + else bp->f1 &= ~1; + } + bp++; + } + } + } + nu= nu->next; + } + allqueue(REDRAWVIEW3D, 0); + } + } + break; + case B_HIDE: + if(G.obedit) { + if(G.obedit->type == OB_MESH) hide_mesh(0); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) hideNurb(0); + } + break; + case B_REVEAL: + if(G.obedit) { + if(G.obedit->type == OB_MESH) reveal_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) revealNurb(); + } + else if(G.f & G_FACESELECT) reveal_tface(); + + break; + case B_SELSWAP: + if(G.obedit) { + if(G.obedit->type == OB_MESH) selectswap_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) selectswapNurb(); + } + break; + case B_AUTOTEX: + ob= OBACT; + if(ob && G.obedit==0) { + if(ob->type==OB_MESH) tex_space_mesh(ob->data); + else if(ob->type==OB_MBALL) ; + else tex_space_curve(ob->data); + } + break; + case B_DOCENTRE: + docentre(); + break; + case B_DOCENTRENEW: + docentre_new(); + break; + case B_DOCENTRECURSOR: + docentre_cursor(); + break; + case B_SETSMOOTH: + case B_SETSOLID: + if(G.obedit) { + if(G.obedit->type == OB_MESH) { + evl= G.edvl.first; + while(evl) { + if( vlakselectedAND(evl, 1) ) { + if(event==B_SETSMOOTH) evl->flag |= ME_SMOOTH; + else evl->flag &= ~ME_SMOOTH; + } + evl= evl->next; + } + + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + } + else { + nu= editNurb.first; + while(nu) { + if(isNurbsel(nu)) { + if(event==B_SETSMOOTH) nu->flag |= ME_SMOOTH; + else nu->flag &= ~ME_SMOOTH; + } + nu= nu->next; + } + + } + } + else { + base= FIRSTBASE; + while(base) { + if(TESTBASELIB(base)) { + if(base->object->type==OB_MESH) { + me= base->object->data; + mface= me->mface; + for(a=0; a<me->totface; a++, mface++) { + if(event==B_SETSMOOTH) mface->flag |= ME_SMOOTH; + else mface->flag &= ~ME_SMOOTH; + } + + makeDispList(base->object); + } + else if ELEM(base->object->type, OB_SURF, OB_CURVE) { + cu= base->object->data; + nu= cu->nurb.first; + while(nu) { + if(event==B_SETSMOOTH) nu->flag |= ME_SMOOTH; + else nu->flag &= ~ME_SMOOTH; + nu= nu->next; + } + } + } + base= base->next; + } + allqueue(REDRAWVIEW3D, 0); + } + break; + + default: + if(event>=B_OBLAY && event<=B_OBLAY+31) { + local= BASACT->lay & 0xFF000000; + BASACT->lay -= local; + if(BASACT->lay==0 || (G.qual & LR_SHIFTKEY)==0) { + bit= event-B_OBLAY; + BASACT->lay= 1<<bit; + scrarea_queue_winredraw(curarea); + } + BASACT->lay += local; + /* optimale redraw */ + if( (OBACT->lay & G.vd->lay) && (BASACT->lay & G.vd->lay) ); + else if( (OBACT->lay & G.vd->lay)==0 && (BASACT->lay & G.vd->lay)==0 ); + else allqueue(REDRAWVIEW3D, 0); + + OBACT->lay= BASACT->lay; + } + } + +} + +void common_editbuts(void) +{ + Object *ob; + ID *id; + Material *ma; + uiBlock *block; + void *poin; + float min; + int xco, a, dx, dy; + char str[32]; + + ob= OBACT; + if(ob==0) return; + + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + /* LAYERS */ + xco= 291; + dx= 32; + dy= 30; + for(a=0; a<10; a++) { + /* the (a+10) evaluates correctly because of + precedence... brackets aren't a bad idea though */ + uiDefButI(block, TOG|BIT|(a+10), B_OBLAY+a+10, "", (short)(xco+a*(dx/2)), 180, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, ""); + uiDefButI(block, TOG|BIT|a, B_OBLAY+a, "",(short)(xco+a*(dx/2)), (short)(180+dy/2), (short)(dx/2), (short)(1+dy/2), &(BASACT->lay), 0, 0, 0, 0, ""); + if(a==4) xco+= 5; + } + + id= ob->data; + if(id && id->lib) uiSetButLock(1, "Can't edit library data"); + + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, LABEL, 0, "Drawtype", 28,200,100,18, 0, 0, 0, 0, 0, ""); + uiDefButC(block, MENU, REDRAWVIEW3D, "Drawtype%t|Bounds %x1|Wire %x2|Solid %x3|Shaded %x4", + 28,180,100,18, &ob->dt, 0, 0, 0, 0, "Drawtype menu"); + uiDefBut(block, LABEL, 0, "Draw Extra", 28,160,100,18, 0, 0, 0, 0, 0, ""); + uiDefButC(block, TOG|BIT|0, REDRAWVIEW3D, "Bounds", 28, 140, 100, 18, &ob->dtx, 0, 0, 0, 0, "Display bounding object"); + uiDefButS(block, MENU, REDRAWVIEW3D, "Bounding volume%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Polyheder", + 28, 120, 100, 18, &ob->boundtype, 0, 0, 0, 0, "Choose between bound objects"); + uiDefButC(block, TOG|BIT|1, REDRAWVIEW3D, "Axis", 28, 80, 100, 18, &ob->dtx, 0, 0, 0, 0, "Draw axis"); + uiDefButC(block, TOG|BIT|2, REDRAWVIEW3D, "TexSpace", 28, 60, 100, 18, &ob->dtx, 0, 0, 0, 0, "Display texture space"); + uiDefButC(block, TOG|BIT|3, REDRAWVIEW3D, "Name", 28, 40, 100, 18, &ob->dtx, 0, 0, 0, 0, "Print object name"); + + uiBlockSetCol(block, BUTGREY); + + /* material en select swap en hide */ + if ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL) { + + if(ob->type==OB_MESH) poin= &( ((Mesh *)ob->data)->texflag ); + else if(ob->type==OB_MBALL) poin= &( ((MetaBall *)ob->data)->texflag ); + else poin= &( ((Curve *)ob->data)->texflag ); + uiDefButI(block, TOG|BIT|0, B_AUTOTEX, "AutoTexSpace", 143,180,130,19, poin, 0, 0, 0, 0, "To switch automatic calculation of texture space"); + + sprintf(str,"%d Mat:", ob->totcol); + if(ob->totcol) min= 1.0; else min= 0.0; + ma= give_current_material(ob, ob->actcol); + + if(ma) { + uiDefButF(block, COL, 0, "", 291,123,24,30, &(ma->r), 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, ma->id.name+2, 318,146, 103, 30, 0, 0, 0, 0, 0, ""); + } + uiDefButC(block, NUM, B_REDR, str, 318,123,103,30, &ob->actcol, min, (float)(ob->totcol), 0, 0, "Total indices, active index"); + uiDefBut(block, BUT,B_MATWICH, "?", 423,123,31,30, 0, 0, 0, 0, 0, "In EditMode, sets the active material index from selected faces"); + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT,B_MATNEW, "New", 292,101,80,21, 0, 0, 0, 0, 0, "Add a new Material index"); + uiDefBut(block, BUT,B_MATDEL, "Delete", 374,101,80,21, 0, 0, 0, 0, 0, "Delete this Material index"); + uiDefBut(block, BUT,B_MATASS, "Assign", 291,47,162,26, 0, 0, 0, 0, 0, "In EditMode, assign the active index to selected faces"); + + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT,B_MATSEL, "Select", 292,76,79,22, 0, 0, 0, 0, 0, "In EditMode, select faces that have the active index"); + uiDefBut(block, BUT,B_MATDESEL, "Deselect", 373,76,79,21, 0, 0, 0, 0, 0, "Deselect everything with current indexnumber"); + + if(ob->type!=OB_FONT) { + uiDefBut(block, BUT,B_HIDE, "Hide", 1091,152,77,18, 0, 0, 0, 0, 0, "Hide selected faces"); + uiDefBut(block, BUT,B_REVEAL, "Reveal", 1171,152,86,18, 0, 0, 0, 0, 0, "Reveal selected faces"); + uiDefBut(block, BUT,B_SELSWAP, "Select Swap", 1091,129,166,18, 0, 0, 0, 0, 0, "Select not-selected, and deselect selected faces"); + } + uiDefBut(block, BUT,B_SETSMOOTH, "Set Smooth", 291,15,80,20, 0, 0, 0, 0, 0, "In EditMode: set 'smooth' rendering of selected faces"); + uiDefBut(block, BUT,B_SETSOLID, "Set Solid", 373,15,80,20, 0, 0, 0, 0, 0, "In EditMode: set 'solid' rendering of selected faces"); + + } + + if ELEM3(ob->type, OB_MESH, OB_SURF, OB_CURVE) { + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT,B_DOCENTRE, "Centre", 961, 115, 100, 19, 0, 0, 0, 0, 0, "Shift object data to be centered about object's origin"); + uiDefBut(block, BUT,B_DOCENTRENEW, "Centre New", 961, 95, 100, 19, 0, 0, 0, 0, 0, "Shift object's origin to center of object data"); + uiDefBut(block, BUT,B_DOCENTRECURSOR, "Centre Cursor", 961, 75, 100, 19, 0, 0, 0, 0, 0, "Shift object's origin to cursor location"); + } + + + uiDrawBlock(block); + +} + + + +/* *************************** MESH ******************************** */ + +#ifdef NAN_DECIMATION + +static int decimate_count_tria(Object *ob) +{ + int tottria; + MFace *mface; + Mesh *me; + int a; + + me= ob->data; + + /* count number of trias, since decimator doesnt allow quads */ + tottria= 0; + mface= me->mface; + for(a=0; a<me->totface; a++, mface++) { + if(mface->v4) tottria++; + if(mface->v3) tottria++; + } + + return tottria; +} + +static void decimate_faces(void) +{ + Object *ob; + Mesh *me; + MVert *mvert; + MFace *mface; + LOD_Decimation_Info lod; + float *vb=NULL; + float *vnb=NULL; + int *tib=NULL; + int a, tottria; + + /* we assume the active object being decimated */ + ob= OBACT; + if(ob==NULL || ob->type!=OB_MESH) return; + me= ob->data; + + /* add warning for vertex col and tfaces */ + if(me->tface || me->mcol) { + if(okee("This will remove UV coords and vertexcolors")==0) return; + if(me->tface) MEM_freeN(me->tface); + if(me->mcol) MEM_freeN(me->mcol); + me->tface= NULL; + me->mcol= NULL; + } + + /* count number of trias, since decimator doesnt allow quads */ + tottria= decimate_count_tria(ob); + + if(tottria<3) { + error("Need more input faces than just 3"); + return; + } + /* allocate and init */ + lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*me->totvert, "vertices"); + lod.vertex_normal_buffer= MEM_mallocN(3*sizeof(float)*me->totvert, "normals"); + lod.triangle_index_buffer= MEM_mallocN(3*sizeof(int)*tottria, "trias"); + lod.vertex_num= me->totvert; + lod.face_num= tottria; + + /* fill vertex buffer */ + vb= lod.vertex_buffer; + vnb= lod.vertex_normal_buffer; + mvert= me->mvert; + for(a=0; a<me->totvert; a++, mvert++, vb+=3, vnb+=3) { + VECCOPY(vb, mvert->co); + VECCOPY(vnb, mvert->no); + Normalise(vnb); + } + + /* fill index buffer */ + mface= me->mface; + tib= lod.triangle_index_buffer; + for(a=0; a<me->totface; a++, mface++) { + if(mface->v4) { + tib[0]= mface->v1; + tib[1]= mface->v3; + tib[2]= mface->v4; + tib+= 3; + } + if(mface->v3) { + tib[0]= mface->v1; + tib[1]= mface->v2; + tib[2]= mface->v3; + tib+= 3; + } + } + + if(LOD_LoadMesh(&lod) ) { + if( LOD_PreprocessMesh(&lod) ) { + DispList *dl; + DispListMesh *dlm; + MFaceInt *mfaceint; + + /* we assume the decim_faces tells how much to reduce */ + + while(lod.face_num > decim_faces) { + if( LOD_CollapseEdge(&lod)==0) break; + } + + /* ok, put back the stuff in a displist */ + freedisplist(&(ob->disp)); + dl= MEM_callocN(sizeof(DispList), "disp"); + BLI_addtail(&ob->disp, dl); + dl->type= DL_MESH; + dlm=dl->mesh= MEM_callocN(sizeof(DispListMesh), "dispmesh"); + dlm->mvert= MEM_callocN(lod.vertex_num*sizeof(MVert), "mvert"); + dlm->mface= MEM_callocN(lod.face_num*sizeof(MFaceInt), "mface"); + dlm->totvert= lod.vertex_num; + dlm->totface= lod.face_num; + + mvert= dlm->mvert; + vb= lod.vertex_buffer; + for(a=0; a<lod.vertex_num; a++, vb+=3, mvert++) { + VECCOPY(mvert->co, vb); + } + + mfaceint= dlm->mface; + tib= lod.triangle_index_buffer; + for(a=0; a<lod.face_num; a++, mfaceint++, tib+=3) { + mfaceint->v1= tib[0]; + mfaceint->v2= tib[1]; + mfaceint->v3= tib[2]; + } + } + else error("No memory"); + + LOD_FreeDecimationData(&lod); + } + else error("No manifold Mesh"); + + MEM_freeN(lod.vertex_buffer); + MEM_freeN(lod.vertex_normal_buffer); + MEM_freeN(lod.triangle_index_buffer); + + allqueue(REDRAWVIEW3D, 0); +} + + + +static void decimate_cancel(void) +{ + Object *ob; + + ob= OBACT; + if(ob) { + freedisplist(&ob->disp); + makeDispList(ob); + } + allqueue(REDRAWVIEW3D, 0); +} + +static void decimate_apply(void) +{ + Object *ob; + DispList *dl; + DispListMesh *dlm; + Mesh *me; + MFace *mface; + MFaceInt *mfaceint; + int a; + + if(G.obedit) return; + + ob= OBACT; + if(ob) { + dl= ob->disp.first; + if(dl && dl->mesh) { + dlm= dl->mesh; + me= ob->data; + + // vertices + if(me->mvert) MEM_freeN(me->mvert); + me->mvert= dlm->mvert; + dlm->mvert= NULL; + me->totvert= dlm->totvert; + + // faces + if(me->mface) MEM_freeN(me->mface); + me->mface= MEM_callocN(dlm->totface*sizeof(MFace), "mface"); + me->totface= dlm->totface; + mface= me->mface; + mfaceint= dlm->mface; + for(a=0; a<me->totface; a++, mface++, mfaceint++) { + mface->v1= mfaceint->v1; + mface->v2= mfaceint->v2; + mface->v3= mfaceint->v3; + test_index_mface(mface, 3); + } + + freedisplist(&ob->disp); + + G.obedit= ob; + make_editMesh(); + load_editMesh(); + free_editMesh(); + G.obedit= NULL; + tex_space_mesh(me); + } + else error("Not a decimated Mesh"); + } +} + +#endif + +void do_meshbuts(unsigned short event) +{ + Object *ob; + Mesh *me; + float fac; + short randfac; + + ob= OBACT; + if(ob && ob->type==OB_MESH) { + + me= get_mesh(ob); + if(me==0) return; + + switch(event) { +#ifdef __NLA + case B_AUTOVGROUP: + if (!get_armature(ob->parent)){ + error ("Mesh must be the child of an armature"); + break; + } + /* Verify that there are vertex groups for bones in armature */ + /* Remove selected vertices from all defgroups */ + /* Perform assignment for selected vertices */ + + allqueue (REDRAWVIEW3D, 1); + break; + case B_NEWVGROUP: + add_defgroup (G.obedit); + scrarea_queue_winredraw(curarea); + break; + case B_DELVGROUP: + del_defgroup (G.obedit); + allqueue (REDRAWVIEW3D, 1); + break; + case B_ASSIGNVGROUP: + assign_verts_defgroup (); + allqueue (REDRAWVIEW3D, 1); + break; + case B_REMOVEVGROUP: + remove_verts_defgroup (0); + allqueue (REDRAWVIEW3D, 1); + break; + case B_SELVGROUP: + sel_verts_defgroup(1); + allqueue (REDRAWVIEW3D, 1); + break; + case B_DESELVGROUP: + sel_verts_defgroup(0); + allqueue (REDRAWVIEW3D, 1); + break; +#endif + case B_DELSTICKY: + + if(me->msticky) MEM_freeN(me->msticky); + me->msticky= 0; + allqueue(REDRAWBUTSEDIT, 0); + break; + case B_MAKESTICKY: + make_sticky(); + break; + case B_MAKEVERTCOL: + make_vertexcol(); + break; + case B_DELVERTCOL: + if(me->mcol) MEM_freeN(me->mcol); + me->mcol= 0; + G.f &= ~G_VERTEXPAINT; + freedisplist(&(ob->disp)); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); + break; + + case B_MAKE_TFACES: + make_tfaces(me); + allqueue(REDRAWBUTSEDIT, 0); + break; + + case B_DEL_TFACES: + if(me->tface) MEM_freeN(me->tface); + me->tface= 0; + G.f &= ~G_FACESELECT; + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + break; + + case B_FLIPNORM: + if(G.obedit) { + flip_editnormals(); + } + else flipnorm_mesh( get_mesh(ob) ); + + allqueue(REDRAWVIEW3D, 0); + break; + + case B_DECIM_FACES: + decimate_faces(); + break; + case B_DECIM_CANCEL: + decimate_cancel(); + break; + case B_DECIM_APPLY: + decimate_apply(); + break; + + case B_SLOWERDRAW: + slowerdraw(); + break; + case B_FASTERDRAW: + fasterdraw(); + break; + } + } + + if(G.obedit==0 || (G.obedit->type!=OB_MESH)) return; + + switch(event) { + case B_SPIN: + if( select_area(SPACE_VIEW3D)) spin_mesh(step, degr, 0, 0); + break; + case B_SPINDUP: + if( select_area(SPACE_VIEW3D)) spin_mesh(step, degr, 0, 1); + break; + case B_EXTR: + G.f |= G_DISABLE_OK; + if( select_area(SPACE_VIEW3D)) extrude_mesh(); + G.f -= G_DISABLE_OK; + break; + case B_SCREW: + if( select_area(SPACE_VIEW3D)) screw_mesh(step, turn); + break; + case B_EXTREP: + if( select_area(SPACE_VIEW3D)) extrude_repeat_mesh(step, extr_offs); + break; + case B_SPLIT: + G.f |= G_DISABLE_OK; + split_mesh(); + G.f -= G_DISABLE_OK; + break; + case B_REMDOUB: + notice("Removed: %d", removedoublesflag(1, doublimit)); + allqueue(REDRAWVIEW3D, 0); + break; + case B_SUBDIV: + waitcursor(1); + subdivideflag(1, 0.0, editbutflag & B_BEAUTY); + countall(); + waitcursor(0); + allqueue(REDRAWVIEW3D, 0); + break; + case B_FRACSUBDIV: + randfac= 10; + if(button(&randfac, 1, 100, "Rand fac:")==0) return; + waitcursor(1); + fac= -( (float)randfac )/100; + subdivideflag(1, fac, editbutflag & B_BEAUTY); + countall(); + waitcursor(0); + allqueue(REDRAWVIEW3D, 0); + break; + case B_XSORT: + if( select_area(SPACE_VIEW3D)) xsortvert_flag(1); + break; + case B_HASH: + hashvert_flag(1); + break; + case B_TOSPHERE: + vertices_to_sphere(); + break; + case B_INTERSECTMESH: + intersect_mesh(); + break; + case B_VERTEXNOISE: + vertexnoise(); + break; + case B_VERTEXSMOOTH: + vertexsmooth(); + break; + } + /* LETOP: bovenstaande events alleen in editmode! */ +} + +static void verify_vertexgroup_name_func(void *datav, void *data2_unused) +{ + unique_vertexgroup_name((bDeformGroup*)datav, OBACT); +} + +void meshbuts(void) +{ + Object *ob; + Mesh *me; + uiBlock *block; + uiBut *but; + float val; + char str[64]; +#ifdef __NLA + int by; + float min; + int defCount; + bDeformGroup *defGroup; +#endif + + ob= OBACT; + if(ob==0) return; + + sprintf(str, "editbuttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + me= get_mesh(ob); + + if(me) { + uiDefButS(block, TOG|BIT|1, REDRAWVIEW3D, "No V.Normal Flip", 143,160,130,18, &me->flag, 0, 0, 0, 0, "Disable flipping of vertexnormals during render"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|5, REDRAWVIEW3D, "Auto Smooth", 143,140,130,18, &me->flag, 0, 0, 0, 0, "Automatic detection of smooth rendered faces during render"); + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, NUM, B_DIFF, "Degr:", 143, 120, 130, 18, &me->smoothresh, 1, 80, 0, 0, "Maximum angle (between face normals) that defines smooth rendering"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|7, B_MAKEDISP, "SubSurf", 143,100,130,18, &me->flag, 0, 0, 0, 0, "Catmull-Clark Subdivision Surface"); + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, NUM, B_MAKEDISP, "Subdiv:", 143, 80, 100, 18, &me->subdiv, 0, 12, 0, 0, "Level of subdivision for interactive display"); + uiDefButS(block, NUM, B_MAKEDISP, "", 243, 80, 30, 18, &me->subdivr, 0, 12, 0, 0, "Level of subdivision for rendering"); + uiDefButS(block, TOG|BIT|2, REDRAWVIEW3D, "Double Sided", 1090,184,164,19, &me->flag, 0, 0, 0, 0, "Make faces doublesided"); + + uiBlockSetCol(block, BUTSALMON); + + if(me->msticky) val= 1.0; else val= 0.0; + uiDefBut(block, LABEL, 0, "Sticky", 137,55,70,20, 0, val, 0, 0, 0, ""); + if(me->msticky==0) { + uiDefBut(block, BUT, B_MAKESTICKY, "Make", 210,58,63,19, 0, 0, 0, 0, 0, "Make sticky texture coords (projected from view)"); + } + else uiDefBut(block, BUT, B_DELSTICKY, "Delete", 210,58,63,19, 0, 0, 0, 0, 0, "Delete sticky texture coords"); + + if(me->mcol) val= 1.0; else val= 0.0; + uiDefBut(block, LABEL, 0, "VertCol", 140,33,70,20, 0, val, 0, 0, 0, ""); + if(me->mcol==0) { + uiDefBut(block, BUT, B_MAKEVERTCOL, "Make", 209,36,64,19, 0, 0, 0, 0, 0, "Enable vertex colours"); + } + else uiDefBut(block, BUT, B_DELVERTCOL, "Delete", 209,36,64,19, 0, 0, 0, 0, 0, ""); + + if(me->tface) val= 1.0; else val= 0.0; + uiDefBut(block, LABEL, 0, "TexFace", 142,13,70,20, 0, val, 0, 0, 0, ""); + if(me->tface==0) { + uiDefBut(block, BUT, B_MAKE_TFACES, "Make", 209,14,64,20, 0, 0, 0, 0, 0, "Enable texture face"); + } + else uiDefBut(block, BUT, B_DEL_TFACES, "Delete", 209,14,64,20, 0, 0, 0, 0, 0, "Delete texture face"); + + uiBlockSetCol(block, BUTGREY); + + uiDefIDPoinBut(block, test_meshpoin_but, 0, "TexMesh:", 477,185,249,19, &me->texcomesh, "Enter the name of a Meshblock"); + } + + + /* EDIT */ + + if(me) { +#ifdef NAN_DECIMATION + int tottria= decimate_count_tria(ob); + DispList *dl; + + // wacko, wait for new displist system (ton) + if( (dl=ob->disp.first) && dl->mesh); + else decim_faces= tottria; + + uiBlockSetCol(block, BUTPURPLE); + uiDefButI(block, NUMSLI,B_DECIM_FACES, "Decimator", 477,155,249,20, &decim_faces, 4.0, tottria, 10, 10, "The number of triangles to reduce to"); + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT,B_DECIM_CANCEL, "Cancel", 477,135,124,19, 0, 0, 0, 0, 0, "restore Mesh"); + uiDefBut(block, BUT,B_DECIM_APPLY, "Apply", 602,135,124,19, 0, 0, 0, 0, 0, "apply decimation to Mesh"); +#endif + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT,B_EXTR,"Extrude", 477,100,249,24, 0, 0, 0, 0, 0, "Convert selected edges to faces"); + uiDefBut(block, BUT,B_SPINDUP,"Spin Dup", 639,75,87,24, 0, 0, 0, 0, 0, "Use spin with duplication tool"); + uiDefBut(block, BUT,B_SPIN, "Spin", 558,75,78,24, 0, 0, 0, 0, 0, "Use spin tool"); + uiDefBut(block, BUT,B_SCREW,"Screw", 477,75,79,24, 0, 0, 0, 0, 0, "Use screw tool"); + uiDefBut(block, BUT,B_EXTREP, "ExtrudeRepeat",477,15,128,19, 0, 0, 0, 0, 0, "Create a repetitive extrude along a straight line"); + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, NUM, B_DIFF, "Degr:", 477,55,78,19, °r,10.0,360.0, 0, 0, "Specify the number of degrees the spin revolves"); + uiDefButS(block, NUM, B_DIFF, "Steps:", 558,55,78,19, &step,1.0,180.0, 0, 0, "Specify the total number of spin revolutions"); + uiDefButS(block, NUM, B_DIFF, "Turns:", 639,55,86,19, &turn,1.0,360.0, 0, 0, "Specify the number of revolutions the screw turns"); + uiDefButS(block, TOG|BIT|0, B_DIFF, "Clockwise", 639,35,86,19, &editbutflag, 0, 0, 0, 0, "Specify the direction for screw and spin"); + uiDefButS(block, TOG|BIT|1, B_DIFF, "Keep Original", 477,35,156,19, &editbutflag, 0, 0, 0, 0, "Seperate original and new vertices and faces"); + uiDefButF(block, NUM, B_DIFF, "Offset:", 608,15,117,19, &extr_offs, 0.01, 10.0, 100, 0, "Set the distance between each step of the extrude repeat"); + } + + by=206; + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|2, 0, "Beauty", 847,by-=20,94,19, &editbutflag, 0, 0, 0, 0, "Split face in halves"); + uiBlockSetCol(block, BUTSALMON); + + uiDefBut(block, BUT, B_INTERSECTMESH, "Intersect", 847,by-=19,94,18, 0, 0, 0, 0, 0, "Intersect selected faces"); + uiDefBut(block, BUT,B_SPLIT,"Split", 847,by-=19,94,18, 0, 0, 0, 0, 0, "Split msh without removing faces"); + uiDefBut(block, BUT,B_TOSPHERE,"To Sphere", 847,by-=19,94,18, 0, 0, 0, 0, 0, "Blow vertices up into spherical shape"); + uiDefBut(block, BUT,B_SUBDIV,"Subdivide", 847,by-=19,94,18, 0, 0, 0, 0, 0, "Split face in quarters"); + uiDefBut(block, BUT,B_FRACSUBDIV, "Fract Subd",847,by-=19,94,18, 0, 0, 0, 0, 0, "Split face with random factor"); + + uiDefBut(block, BUT,B_VERTEXNOISE,"Noise", 847,by-=19,94,18, 0, 0, 0, 0, 0, "Use vertex coordinate as texture coordinate"); + uiDefBut(block, BUT,B_VERTEXSMOOTH,"Smooth", 847,by-=19,94,18, 0, 0, 0, 0, 0, "Flatten angels"); + uiDefBut(block, BUT,B_XSORT,"Xsort", 847,by-=19,94,18, 0, 0, 0, 0, 0, "Sort vertices in the X direction"); + uiDefBut(block, BUT,B_HASH,"Hash", 847,by-=19,94,18, 0, 0, 0, 0, 0, "Randomize vertices sequence"); + + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_DIFF, "Limit:", 959,151,100,19, &doublimit, 0.0001, 1.0, 10, 0, "Specify the limit in distance to remove doubles"); + + uiBlockSetCol(block, BUTSALMON); + + uiDefBut(block, BUT,B_REMDOUB,"Rem Doubles", 958,173,101,32, 0, 0, 0, 0, 0, "Remove doubles"); + + uiDefBut(block, BUT,B_FLIPNORM,"Flip Normals", 961,55,100,19, 0, 0, 0, 0, 0, "Toggle the direction of the face normals"); + + uiDefBut(block, BUT, B_SLOWERDRAW,"SlowerDraw", 961,35,100,19, 0, 0, 0, 0, 0, "Draw slow but accurate"); + uiDefBut(block, BUT, B_FASTERDRAW,"FasterDraw", 961,15,100,19, 0, 0, 0, 0, 0, "Draw fast but less accurate"); + +#ifdef __NLA + + /* Draw Vertex grouping buttons if we're in editmode*/ + if (ob){ + char *s, *menustr; + bDeformGroup *dg; + int index; + + by = 210; + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, LABEL,0,"Vertex Groups", 740,by-=19,93,18, 0, 0, 0, 0, 0, ""); + + defCount=BLI_countlist(&ob->defbase); + + if (!defCount) + min=0; + else + min=1; + +#if 0 + sprintf (str, "%d Group:", defCount); + uiDefButS(block, NUM, REDRAWBUTSEDIT, str, 740, by-=22,93,18, &ob->actdef, min, defCount, 0, 0, ""); +#else + s= menustr = MEM_callocN((32 * defCount)+20, "menustr"); + + for (index = 1, dg = ob->defbase.first; dg; index++, dg=dg->next){ + int cnt= sprintf (s, "%s%%x%d|", dg->name, index); + + if (cnt>0) + s+= cnt; + } + + by-=22; + if (defCount) + uiDefButS(block, MENU, REDRAWBUTSEDIT, menustr, 740, by,18,18, &ob->actdef, min, defCount, 0, 0, "Active deformation group"); + MEM_freeN (menustr); +#endif + if (ob->actdef){ + defGroup = BLI_findlink(&ob->defbase, ob->actdef-1); + but= uiDefBut(block, TEX,REDRAWBUTSEDIT,"", 758,by,93-18,18, defGroup->name, 0, 32, 0, 0, "Change the current deformations group's name (and bone affiliation)"); + uiButSetFunc(but, verify_vertexgroup_name_func, defGroup, NULL); + } + uiDefButF(block, NUM, REDRAWVIEW3D, "Weight:", 740, by-=22, 93, 18, &editbutvweight, 0, 1, 10, 0, "Change the bone's deformation strength"); + + } + + if (G.obedit && G.obedit==ob){ + + uiBlockSetCol(block, BUTSALMON); +/* uiDefBut(block, BUT,B_AUTOVGROUP,"Auto Weight", 740,by-=22,93,18, 0, 0, 0, 0, 0, "Automatically assign deformation groups"); */ + uiDefBut(block, BUT,B_NEWVGROUP,"New", 740,by-=22,45,18, 0, 0, 0, 0, 0, "Create a new deformation group"); + uiDefBut(block, BUT,B_DELVGROUP,"Delete", 788,by,45,18, 0, 0, 0, 0, 0, "Remove the current deformation group"); + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT,B_ASSIGNVGROUP,"Assign", 740,by-=22,93,18, 0, 0, 0, 0, 0, "Assign selected vertices to the current deformation group"); + uiDefBut(block, BUT,B_REMOVEVGROUP,"Remove", 740,by-=22,93,18, 0, 0, 0, 0, 0, "Remove selected vertices from the current deformation group"); + + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT,B_SELVGROUP,"Select", 740,by-=22,93,18, 0, 0, 0, 0, 0, "Select vertices belonging to the current deformation group"); + uiDefBut(block, BUT,B_DESELVGROUP,"Deselect", 740,by-=22,93,18, 0, 0, 0, 0, 0, "Deselect vertices belonging to the current deformation group"); + +} +#endif + + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, REDRAWVIEW3D, "NSize:", 1090, 90, 164, 19, &editbutsize, 0.001, 2.0, 10, 0, "Set the length of the face normals"); + uiDefButI(block, TOG|BIT|6, REDRAWVIEW3D, "Draw Normals", 1090,70,164,19, &G.f, 0, 0, 0, 0, "Draw face normals"); + uiDefButI(block, TOG|BIT|7, REDRAWVIEW3D, "Draw Faces", 1090,50,164,19, &G.f, 0, 0, 0, 0, "Draw faces"); + uiDefButI(block, TOG|BIT|11, 0, "All edges", 1090,10,164,19, &G.f, 0, 0, 0, 0, "Draw edges normally, without optimisation"); + + uiDrawBlock(block); +} + +/* *************************** FONT ******************************** */ + +short give_vfontnr(VFont *vfont) +{ + VFont *vf; + short nr= 1; + + vf= G.main->vfont.first; + while(vf) { + if(vf==vfont) return nr; + nr++; + vf= vf->id.next; + } + return -1; +} + +VFont *give_vfontpointer(int nr) /* nr= button */ +{ + VFont *vf; + short tel= 1; + + vf= G.main->vfont.first; + while(vf) { + if(tel==nr) return vf; + tel++; + vf= vf->id.next; + } + return G.main->vfont.first; +} + +VFont *exist_vfont(char *str) +{ + VFont *vf; + + vf= G.main->vfont.first; + while(vf) { + if(strcmp(vf->name, str)==0) return vf; + vf= vf->id.next; + } + return 0; +} + +static char *give_vfontbutstr(void) +{ + VFont *vf; + int len= 0; + char *str, di[FILE_MAXDIR], fi[FILE_MAXFILE]; + + vf= G.main->vfont.first; + while(vf) { + strcpy(di, vf->name); + BLI_splitdirstring(di, fi); + len+= strlen(fi)+4; + vf= vf->id.next; + } + + str= MEM_callocN(len+21, "vfontbutstr"); + strcpy(str, "FONTS %t"); + vf= G.main->vfont.first; + while(vf) { + + if(vf->id.us==0) strcat(str, "|0 "); + else strcat(str, "| "); + + strcpy(di, vf->name); + BLI_splitdirstring(di, fi); + + strcat(str, fi); + vf= vf->id.next; + } + return str; +} + +void load_buts_vfont(char *name) +{ + VFont *vf; + Curve *cu; + + if(OBACT && OBACT->type==OB_FONT) cu= OBACT->data; + else return; + + vf= exist_vfont(name); + if(vf==0) { + vf= load_vfont(name); + if(vf==0) return; + } + else id_us_plus((ID *)vf); + + if(cu->vfont) cu->vfont->id.us--; + cu->vfont= vf; + + text_to_curve(OBACT, 0); + makeDispList(OBACT); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); +} + +void do_fontbuts(unsigned short event) +{ + Curve *cu; + VFont *vf; + Object *ob; + ScrArea *sa; + char str[80]; + + ob= OBACT; + + switch(event) { + case B_MAKEFONT: + text_to_curve(ob, 0); + makeDispList(ob); + allqueue(REDRAWVIEW3D, 0); + break; + case B_TOUPPER: + to_upper(); + break; + case B_LOADFONT: + vf= give_vfontpointer(G.buts->texnr); + if(vf && vf->id.prev!=vf->id.next) strcpy(str, vf->name); + else strcpy(str, U.fontdir); + + sa= closest_bigger_area(); + areawinset(sa->win); + + activate_fileselect(FILE_SPECIAL, "SELECT FONT", str, load_buts_vfont); + + break; + case B_PACKFONT: + if (ob) { + cu= ob->data; + if(cu && cu->vfont) { + if (cu->vfont->packedfile) { + if (G.fileflags & G_AUTOPACK) { + if (okee("Disable AutoPack ?")) { + G.fileflags &= ~G_AUTOPACK; + } + } + + if ((G.fileflags & G_AUTOPACK) == 0) { + if (unpackVFont(cu->vfont, PF_ASK) == RET_OK) { + text_to_curve(ob, 0); + makeDispList(ob); + allqueue(REDRAWVIEW3D, 0); + } + } + } else { + cu->vfont->packedfile = newPackedFile(cu->vfont->name); + } + } + } + allqueue(REDRAWHEADERS, 0); + allqueue(REDRAWBUTSEDIT, 0); + break; + + case B_SETFONT: + if(ob) { + cu= ob->data; + + vf= give_vfontpointer(G.buts->texnr); + if(vf) { + id_us_plus((ID *)vf); + cu->vfont->id.us--; + cu->vfont= vf; + text_to_curve(ob, 0); + makeDispList(ob); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + } + } + break; + case B_TEXTONCURVE: + if(ob) { + cu= ob->data; + if(cu->textoncurve && cu->textoncurve->type!=OB_CURVE) { + error("Only Curve Objects"); + cu->textoncurve= 0; + allqueue(REDRAWBUTSEDIT, 0); + } + text_to_curve(ob, 0); + makeDispList(ob); + } + } +} + + + +void fontbuts(void) +{ + Curve *cu; + uiBlock *block; + char *strp, str[64]; + + if(OBACT==0) return; + + sprintf(str, "editbuttonswin1 %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + cu= OBACT->data; + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW,B_MAKEFONT, "Left", 484,139,53,18, &cu->spacemode, 0.0,0.0, 0, 0, ""); + uiDefButS(block, ROW,B_MAKEFONT, "Middle", 604,139,61,18, &cu->spacemode, 0.0,1.0, 0, 0, ""); + uiDefButS(block, ROW,B_MAKEFONT, "Right", 540,139,62,18, &cu->spacemode, 0.0,2.0, 0, 0, ""); + uiDefButS(block, ROW,B_MAKEFONT, "Flush", 665,139,61,18, &cu->spacemode, 0.0,3.0, 0, 0, ""); + + uiBlockSetCol(block, BUTGREY); + + uiDefIDPoinBut(block, test_obpoin_but, B_TEXTONCURVE, "TextOnCurve:", 484,115,243,19, &cu->textoncurve, ""); + + uiDefButF(block, NUM,B_MAKEFONT, "Size:", 482,56,121,19, &cu->fsize, 0.1,10.0, 10, 0, ""); + uiDefButF(block, NUM,B_MAKEFONT, "Linedist:", 605,56,121,19, &cu->linedist, 0.0,10.0, 10, 0, ""); + uiDefButF(block, NUM,B_MAKEFONT, "Spacing:", 482,34,121,19, &cu->spacing, 0.0,10.0, 10, 0, ""); + uiDefButF(block, NUM,B_MAKEFONT, "Y offset:", 605,34,121,19, &cu->yof, -50.0,50.0, 10, 0, ""); + uiDefButF(block, NUM,B_MAKEFONT, "Shear:", 482,12,121,19, &cu->shear, -1.0,1.0, 10, 0, ""); + uiDefButF(block, NUM,B_MAKEFONT, "X offset:", 605,12,121,19, &cu->xof, -50.0,50.0, 10, 0, ""); + + uiDefBut(block, TEX,REDRAWVIEW3D, "Ob Family:", 752,192,164,19, cu->family, 0.0, 20.0, 0, 0, ""); + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_TOUPPER, "ToUpper", 623,163,103,23, 0, 0, 0, 0, 0, ""); + + uiBlockSetCol(block, BUTGREY); + + G.buts->texnr= give_vfontnr(cu->vfont); + + strp= give_vfontbutstr(); + + uiDefButS(block, MENU, B_SETFONT, strp, 484,191,220,20, &G.buts->texnr, 0, 0, 0, 0, ""); + + if (cu->vfont->packedfile) { + packdummy = 1; + } else { + packdummy = 0; + } + + uiBlockSetCol(block, BUTYELLOW); + uiDefIconButI(block, TOG|BIT|0, B_PACKFONT, ICON_PACKAGE, 706,191,20,20, &packdummy, 0, 0, 0, 0, "Pack/Unpack this Vectorfont"); + + MEM_freeN(strp); + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT,B_LOADFONT, "Load Font", 484,163,103,23, 0, 0, 0, 0, 0, ""); + + uiDrawBlock(block); +} + +/* *************************** CURVE ******************************** */ + + +void do_curvebuts(unsigned short event) +{ + extern Nurb *lastnu; + Object *ob; + Curve *cu; + Nurb *nu; + + ob= OBACT; + if(ob==0) return; + + switch(event) { + + case B_CONVERTPOLY: + case B_CONVERTBEZ: + case B_CONVERTBSPL: + case B_CONVERTCARD: + case B_CONVERTNURB: + if(G.obedit) { + setsplinetype(event-B_CONVERTPOLY); + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + } + break; + case B_UNIFU: + case B_ENDPU: + case B_BEZU: + case B_UNIFV: + case B_ENDPV: + case B_BEZV: + if(G.obedit) { + nu= editNurb.first; + while(nu) { + if(isNurbsel(nu)) { + if((nu->type & 7)==CU_NURBS) { + if(event<B_UNIFV) { + nu->flagu &= 1; + nu->flagu += ((event-B_UNIFU)<<1); + makeknots(nu, 1, nu->flagu>>1); + } + else if(nu->pntsv>1) { + nu->flagv &= 1; + nu->flagv += ((event-B_UNIFV)<<1); + makeknots(nu, 2, nu->flagv>>1); + } + } + } + nu= nu->next; + } + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + } + break; + case B_SETWEIGHT: + if(G.obedit) { + weightflagNurb(1, editbutweight, 0); + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + } + break; + case B_SETW1: + editbutweight= 1.0; + scrarea_queue_winredraw(curarea); + break; + case B_SETW2: + editbutweight= sqrt(2.0)/4.0; + scrarea_queue_winredraw(curarea); + break; + case B_SETW3: + editbutweight= 0.25; + scrarea_queue_winredraw(curarea); + break; + case B_SETW4: + editbutweight= sqrt(0.5); + scrarea_queue_winredraw(curarea); + break; + case B_SETORDER: + if(G.obedit) { + nu= lastnu; + if(nu && (nu->type & 7)==CU_NURBS ) { + if(nu->orderu>nu->pntsu) { + nu->orderu= nu->pntsu; + scrarea_queue_winredraw(curarea); + } + makeknots(nu, 1, nu->flagu>>1); + if(nu->orderv>nu->pntsv) { + nu->orderv= nu->pntsv; + scrarea_queue_winredraw(curarea); + } + makeknots(nu, 2, nu->flagv>>1); + } + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + } + break; + case B_MAKEDISP: + if(ob->type==OB_FONT) text_to_curve(ob, 0); + makeDispList(ob); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWINFO, 1); /* 1, want header->win==0! */ + break; + + case B_SUBDIVCURVE: + subdivideNurb(); + break; + case B_SPINNURB: + /* bad bad bad!!! use brackets!!! In case you wondered: + {==,!=} goes before & goes before || */ + if( (G.obedit==0) || + (G.obedit->type!=OB_SURF) || + ((G.obedit->lay & G.vd->lay) == 0) ) return; + spinNurb(0, 0); + countall(); + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + break; + case B_CU3D: /* allow 3D curve */ + if(G.obedit) { + cu= G.obedit->data; + nu= editNurb.first; + while(nu) { + nu->type &= ~CU_2D; + if((cu->flag & CU_3D)==0) nu->type |= CU_2D; + test2DNurb(nu); + nu= nu->next; + } + } + if(ob->type==OB_CURVE) { + cu= ob->data; + nu= cu->nurb.first; + while(nu) { + nu->type &= ~CU_2D; + if((cu->flag & CU_3D)==0) nu->type |= CU_2D; + test2DNurb(nu); + nu= nu->next; + } + } + break; + case B_SETRESOLU: + if(ob->type==OB_CURVE) { + cu= ob->data; + if(ob==G.obedit) nu= editNurb.first; + else nu= cu->nurb.first; + + while(nu) { + nu->resolu= cu->resolu; + nu= nu->next; + } + } + else if(ob->type==OB_FONT) text_to_curve(ob, 0); + + makeDispList(ob); + allqueue(REDRAWVIEW3D, 0); + + break; + } +} + +void curvebuts(void) +{ + Object *ob; + Curve *cu; + Nurb *nu; + extern Nurb *lastnu; + uiBlock *block; + short *sp; + char str[64]; + + ob= OBACT; + if(ob==0) return; + + sprintf(str, "editbuttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + cu= ob->data; + + if(ob->type==OB_CURVE || ob->type==OB_SURF) { + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, LABEL, 0, "Convert", 463,173,72, 18, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_CONVERTPOLY,"Poly", 467,152,72, 18, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_CONVERTBEZ,"Bezier", 467,132,72, 18, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_CONVERTBSPL,"Bspline", 467,112,72, 18, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_CONVERTCARD,"Cardinal", 467,92,72, 18, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_CONVERTNURB,"Nurb", 467,72,72, 18, 0, 0, 0, 0, 0, ""); + + uiDefBut(block, LABEL, 0, "Make Knots",562,173,102, 18, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_UNIFU,"Uniform U", 565,152,102, 18, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_ENDPU,"Endpoint U", 565,132,102, 18, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_BEZU,"Bezier U", 565,112,102, 18, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_UNIFV,"V", 670,152,50, 18, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_ENDPV,"V", 670,132,50, 18, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_BEZV,"V", 670,112,50, 18, 0, 0, 0, 0, 0, ""); + + uiDefBut(block, BUT,B_SETWEIGHT,"Set Weight", 465,11,95,49, 0, 0, 0, 0, 0, ""); + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM,0,"Weight:", 564,36,102,22, &editbutweight, 0.01, 10.0, 10, 0, ""); + uiDefBut(block, BUT,B_SETW1,"1.0", 669,36,50,22, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_SETW2,"sqrt(2)/4", 564,11,57,20, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_SETW3,"0.25", 621,11,43,20, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT,B_SETW4,"sqrt(0.5)", 664,11,57,20, 0, 0, 0, 0, 0, ""); + + if(ob==G.obedit) { + nu= lastnu; + if(nu==0) nu= editNurb.first; + if(nu) sp= &(nu->orderu); + else sp= 0; + uiDefButS(block, NUM, B_SETORDER, "Order U:", 565,91,102, 18, sp, 2.0, 6.0, 0, 0, ""); + if(nu) sp= &(nu->orderv); + else sp= 0; + uiDefButS(block, NUM, B_SETORDER, "V:", 670,91,50, 18, sp, 2.0, 6.0, 0, 0, ""); + if(nu) sp= &(nu->resolu); + else sp= 0; + uiDefButS(block, NUM, B_MAKEDISP, "Resol U:", 565,70,102, 18, sp, 1.0, 128.0, 0, 0, ""); + if(nu) sp= &(nu->resolv); + else sp= 0; + uiDefButS(block, NUM, B_MAKEDISP, "V:", 670,70,50, 18, sp, 1.0, 128.0, 0, 0, ""); + } + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_SUBDIVCURVE, "Subdivide", 1092,105,165,20, 0, 0, 0, 0, 0, ""); + } + + if(ob->type==OB_SURF) { + uiDefBut(block, BUT, B_SPINNURB, "Spin", 808,92,101,36, 0, 0, 0, 0, 0, ""); + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, TOG|BIT|5, 0, "UV Orco", 143,160,130,18, &cu->flag, 0, 0, 0, 0, ""); + uiDefButS(block, TOG|BIT|6, REDRAWVIEW3D, "No Puno Flip", 143,140,130,18, &cu->flag, 0, 0, 0, 0, ""); + } + else { + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, TOG|BIT|5, 0, "UV Orco", 143,160,130,18, &cu->flag, 0, 0, 0, 0, ""); + + uiDefButS(block, NUM, B_MAKEDISP, "DefResolU:", 752,163,132,21, &cu->resolu, 1.0, 128.0, 0, 0, ""); + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_SETRESOLU, "Set", 887,163,29,21, 0, 0, 0, 0, 0, ""); + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, NUM, B_MAKEDISP, "BevResol:", 753,30,163,18, &cu->bevresol, 0.0, 10.0, 0, 0, ""); + + uiDefIDPoinBut(block, test_obcurpoin_but, B_MAKEDISP, "BevOb:", 753,10,163,18, &cu->bevobj, ""); + uiDefButF(block, NUM, B_MAKEDISP, "Width:", 753,90,163,18, &cu->width, 0.0, 2.0, 1, 0, ""); + uiDefButF(block, NUM, B_MAKEDISP, "Ext1:", 753,70,163,18, &cu->ext1, 0.0, 5.0, 10, 0, ""); + uiDefButF(block, NUM, B_MAKEDISP, "Ext2:", 753,50,163,18, &cu->ext2, 0.0, 2.0, 1, 0, ""); + uiBlockSetCol(block, BUTBLUE); + if(ob->type==OB_FONT) { + uiDefButS(block, TOG|BIT|1, B_MAKEDISP, "Front", 833,130,79,18, &cu->flag, 0, 0, 0, 0, ""); + uiDefButS(block, TOG|BIT|2, B_MAKEDISP, "Back", 753,130,76,18, &cu->flag, 0, 0, 0, 0, ""); + } + else { + uiDefButS(block, TOG|BIT|0, B_CU3D, "3D", 867,130,47,18, &cu->flag, 0, 0, 0, 0, ""); + uiDefButS(block, TOG|BIT|1, B_MAKEDISP, "Front", 810,130,55,18, &cu->flag, 0, 0, 0, 0, ""); + uiDefButS(block, TOG|BIT|2, B_MAKEDISP, "Back", 753,130,53,18, &cu->flag, 0, 0, 0, 0, ""); + } + uiBlockSetCol(block, BUTGREY); + } + + uiDefButF(block, NUM, REDRAWVIEW3D, "NSize:", 1090, 80, 164, 19, &editbutsize, 0.001, 1.0, 10, 0, ""); + + uiDrawBlock(block); +} + + +/* *************************** CAMERA ******************************** */ + + +void camerabuts(void) +{ + Camera *cam; + Object *ob; + uiBlock *block; + float grid=0.0; + char str[64]; + + if(G.vd) grid= G.vd->grid; + if(grid<1.0) grid= 1.0; + + ob= OBACT; + if(ob==0) return; + + sprintf(str, "editbuttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + cam= ob->data; + uiDefButF(block, NUM,REDRAWVIEW3D, "Lens:", 470,178,160,20, &cam->lens, 1.0, 250.0, 100, 0, "Specify the lens of the camera"); + uiDefButF(block, NUM,REDRAWVIEW3D, "ClipSta:", 470,147,160,20, &cam->clipsta, 0.001*grid, 100.0*grid, 10, 0, "Specify the startvalue of the the field of view"); + uiDefButF(block, NUM,REDRAWVIEW3D, "ClipEnd:", 470,125,160,20, &cam->clipend, 1.0, 5000.0*grid, 100, 0, "Specify the endvalue of the the field of view"); + uiDefButF(block, NUM,REDRAWVIEW3D, "DrawSize:", 470,90,160,20, &cam->drawsize, 0.1*grid, 10.0, 10, 0, "Specify the drawsize of the camera"); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG, REDRAWVIEW3D, "Ortho", 470,49,61,40, &cam->type, 0, 0, 0, 0, "Render orthogonally"); + + uiDefButS(block, TOG|BIT|0,REDRAWVIEW3D, "ShowLimits", 533,69,97,20, &cam->flag, 0, 0, 0, 0, "Draw the field of view"); + uiDefButS(block, TOG|BIT|1,REDRAWVIEW3D, "Show Mist", 533,49,97,20, &cam->flag, 0, 0, 0, 0, "Draw a line that indicates the mist area"); + + if(G.special1 & G_HOLO) { + uiBlockSetCol(block, BUTGREY); + if(cam->netend==0.0) cam->netend= EFRA; + uiDefButF(block, NUM, REDRAWVIEW3D, "Anim len", 670,80,100,20, &cam->netend, 1.0, 2500.0, 0, 0, ""); + uiDefButF(block, NUM, REDRAWVIEW3D, "Path len:", 670,160,100,20, &cam->hololen, 0.1, 25.0, 10, 0, ""); + uiDefButF(block, NUM, REDRAWVIEW3D, "Shear fac:", 670,140,100,20, &cam->hololen1, 0.1, 5.0, 10, 0, ""); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|4, REDRAWVIEW3D, "Holo 1", 670,120,100,20, &cam->flag, 0.0, 0.0, 0, 0, ""); + uiDefButS(block, TOG|BIT|5, REDRAWVIEW3D, "Holo 2", 670,100,100,20, &cam->flag, 0.0, 0.0, 0, 0, ""); + + } + uiDrawBlock(block); +} + +/* *************************** FACE/PAINT *************************** */ + +void do_fpaintbuts(unsigned short event) +{ + Mesh *me; + Object *ob; + extern TFace *lasttface; /* caches info on tface bookkeeping ?*/ + + ob= OBACT; + if(ob==0) return; + + switch(event) { + + case B_VPGAMMA: + vpaint_dogamma(); + break; + case B_COPY_TF_MODE: + case B_COPY_TF_UV: + case B_COPY_TF_COL: + case B_COPY_TF_TEX: + me= get_mesh(ob); + if(me && me->tface) { +/* extern TFace *lasttface; */ + TFace *tface= me->tface; + int a= me->totface; + + set_lasttface(); + if(lasttface) { + + while(a--) { + if(tface!=lasttface && (tface->flag & TF_SELECT)) { + if(event==B_COPY_TF_MODE) { + tface->mode= lasttface->mode; + tface->transp= lasttface->transp; + } + else if(event==B_COPY_TF_UV) { + memcpy(tface->uv, lasttface->uv, sizeof(tface->uv)); + tface->tpage= lasttface->tpage; + tface->tile= lasttface->tile; + + if(lasttface->mode & TF_TILES) tface->mode |= TF_TILES; + else tface->mode &= ~TF_TILES; + + } + else if(event==B_COPY_TF_TEX) { + tface->tpage= lasttface->tpage; + tface->tile= lasttface->tile; + + if(lasttface->mode & TF_TILES) tface->mode |= TF_TILES; + else tface->mode &= ~TF_TILES; + } + else if(event==B_COPY_TF_COL) memcpy(tface->col, lasttface->col, sizeof(tface->col)); + } + tface++; + } + } + do_shared_vertexcol(me); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + } + break; + case B_SET_VCOL: + clear_vpaint_selectedfaces(); + break; + case B_REDR_3D_IMA: + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + break; + case B_ASSIGNMESH: + + test_object_materials(ob->data); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSGAME, 0); + break; + + case B_TFACE_HALO: + set_lasttface(); + if(lasttface) { + lasttface->mode &= ~TF_BILLBOARD2; + allqueue(REDRAWBUTSGAME, 0); + } + break; + + case B_TFACE_BILLB: + set_lasttface(); + if(lasttface) { + lasttface->mode &= ~TF_BILLBOARD; + allqueue(REDRAWBUTSGAME, 0); + } + break; + } +} + +void fpaintbuts(void) +{ +/* extern VPaint Gvp; already in the top of the file */ + Object *ob; + uiBlock *block; + char str[32]; + + ob= OBACT; + if(ob==0) return; + + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + /* VPAINT BUTTONS */ + uiBlockSetCol(block, BUTGREY); + + if (G.f & G_VERTEXPAINT) { + uiDefBut(block, LABEL, 0, "Vertex Paint", 1037,180,194,18, 0, 0, 0, 0, 0, ""); + } else if (G.f & G_TEXTUREPAINT) { + uiDefBut(block, LABEL, 0, "Texture Paint", 1037,180,194,18, 0, 0, 0, 0, 0, ""); + } + + uiDefButF(block, NUMSLI, 0, "R ", 979,160,194,19, &Gvp.r, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of red used for painting"); + uiDefButF(block, NUMSLI, 0, "G ", 979,140,194,19, &Gvp.g, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of green used for painting"); + uiDefButF(block, NUMSLI, 0, "B ", 979,120,194,19, &Gvp.b, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of blue used for painting"); + uiDefButF(block, NUMSLI, 0, "Opacity ", 979,100,194,19, &Gvp.a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush"); + uiDefButF(block, NUMSLI, 0, "Size ", 979,80,194,19, &Gvp.size, 2.0, 64.0, 0, 0, "The size of the brush"); + + uiDefButF(block, COL, B_VPCOLSLI, "", 1176,100,28,80, &(Gvp.r), 0, 0, 0, 0, ""); + + uiDefButS(block, ROW, B_DIFF, "Mix", 1212,160,63,19, &Gvp.mode, 1.0, 0.0, 0, 0, "Mix the vertex colours"); + uiDefButS(block, ROW, B_DIFF, "Add", 1212,140,63,19, &Gvp.mode, 1.0, 1.0, 0, 0, "Add the vertex colour"); + uiDefButS(block, ROW, B_DIFF, "Sub", 1212, 120,63,19, &Gvp.mode, 1.0, 2.0, 0, 0, "Subtract from the vertex colour"); + uiDefButS(block, ROW, B_DIFF, "Mul", 1212, 100,63,19, &Gvp.mode, 1.0, 3.0, 0, 0, "Multiply the vertex colour"); + uiDefButS(block, ROW, B_DIFF, "Filter", 1212, 80,63,19, &Gvp.mode, 1.0, 4.0, 0, 0, "Mix the colours with an alpha factor"); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|1, 0, "Area", 980,50,80,19, &Gvp.flag, 0, 0, 0, 0, "Set the area the brush covers"); + uiDefButS(block, TOG|BIT|2, 0, "Soft", 1061,50,112,19, &Gvp.flag, 0, 0, 0, 0, "Use a soft brush"); + uiDefButS(block, TOG|BIT|3, 0, "Normals", 1174,50,102,19, &Gvp.flag, 0, 0, 0, 0, "Use vertex normal for painting"); + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_VPGAMMA, "Set", 980,30,80,19, 0, 0, 0, 0, 0, "Apply Mul and Gamma to vertex colours"); + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_DIFF, "Mul:", 1061,30,112,19, &Gvp.mul, 0.1, 50.0, 10, 0, "Set the number to multiply vertex colours with"); + uiDefButF(block, NUM, B_DIFF, "Gamma:", 1174,30,102,19, &Gvp.gamma, 0.1, 5.0, 10, 0, "Change the clarity of the vertex colours"); + + uiDefBut(block, LABEL, 0, "Face Select", 600,180,194,18, 0, 0, 0, 0, 0, ""); + if(G.f & G_FACESELECT) { + extern TFace *lasttface; + + set_lasttface(); + if(lasttface) { + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|2, B_REDR_3D_IMA, "Tex", 600,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Render face with texture"); + uiDefButS(block, TOG|BIT|7, B_REDR_3D_IMA, "Tiles", 660,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Use tilemode for face"); + uiDefButS(block, TOG|BIT|4, REDRAWVIEW3D, "Light", 720,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Use light for face"); + uiDefButS(block, TOG|BIT|10, REDRAWVIEW3D, "Invisible",780,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Make face invisible"); + uiDefButS(block, TOG|BIT|0, REDRAWVIEW3D, "Collision", 840,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Use face for collision detection"); + + uiDefButS(block, TOG|BIT|6, REDRAWVIEW3D, "Shared", 600,140,60,19, &lasttface->mode, 0, 0, 0, 0, "Blend vertex colours across face when vertices are shared"); + uiDefButS(block, TOG|BIT|9, REDRAWVIEW3D, "Twoside", 660,140,60,19, &lasttface->mode, 0, 0, 0, 0, "Render face twosided"); + uiDefButS(block, TOG|BIT|11, REDRAWVIEW3D, "ObColor",720,140,60,19, &lasttface->mode, 0, 0, 0, 0, "Use ObColor instead of vertex colours"); + + uiDefButS(block, TOG|BIT|8, B_TFACE_HALO, "Halo", 600,120,60,19, &lasttface->mode, 0, 0, 0, 0, "Screen aligned billboard"); + uiDefButS(block, TOG|BIT|12, B_TFACE_BILLB, "Billboard",660,120,60,19, &lasttface->mode, 0, 0, 0, 0, "Billboard with Z-axis constraint"); + uiDefButS(block, TOG|BIT|13, REDRAWVIEW3D, "Shadow", 720,120,60,19, &lasttface->mode, 0, 0, 0, 0, "Face is used for shadow"); + uiDefButS(block, TOG|BIT|14, REDRAWVIEW3D, "Text", 780,120,60,19, &lasttface->mode, 0, 0, 0, 0, "Enable bitmap text on face"); + + uiBlockSetCol(block, BUTPURPLE); + uiDefButC(block, ROW, REDRAWVIEW3D, "Opaque", 600,100,60,19, &lasttface->transp, 2.0, 0.0, 0, 0, "Render colour of textured face as colour"); + uiDefButC(block, ROW, REDRAWVIEW3D, "Add", 660,100,60,19, &lasttface->transp, 2.0, 1.0, 0, 0, "Render face transparent and add colour of face"); + uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha", 720,100,60,19, &lasttface->transp, 2.0, 2.0, 0, 0, "Render polygon transparent, depending on alpha channel of the texture"); + /* uiDefButC(block, ROW, REDRAWVIEW3D, "Sub", 780,100,60,19, &lasttface->transp, 2.0, 3.0, 0, 0); ,""*/ + + } + } + uiBlockSetCol(block, BUTSALMON); + if(G.f & G_FACESELECT) { + uiDefBut(block, BUT, B_SET_VCOL, "Set VertCol", 859,37,103,28, 0, 0, 0, 0, 0, "Set Vertex colour of selection to current (Shift+K)"); + + } + uiDefBut(block, BUT, B_COPY_TF_MODE, "Copy DrawMode", 650,7,117,28, 0, 0, 0, 0, 0, "Copy the drawmode"); + uiDefBut(block, BUT, B_COPY_TF_UV, "Copy UV+tex", 771,7,85,28, 0, 0, 0, 0, 0, "Copy UV information and textures"); + uiDefBut(block, BUT, B_COPY_TF_COL, "Copy VertCol", 859,7,103,28, 0, 0, 0, 0, 0, "Copy vertex colours"); + + uiDrawBlock(block); +} + +/* *************************** RADIO ******************************** */ + +void do_radiobuts(short event) +{ + Radio *rad; + int phase; + + phase= rad_phase(); + rad= G.scene->radio; + + switch(event) { + case B_RAD_ADD: + add_radio(); + allqueue(REDRAWBUTSRADIO, 0); + allqueue(REDRAWVIEW3D, 0); + break; + case B_RAD_DELETE: + delete_radio(); + allqueue(REDRAWBUTSRADIO, 0); + allqueue(REDRAWVIEW3D, 0); + break; + case B_RAD_FREE: + freeAllRad(); + allqueue(REDRAWBUTSRADIO, 0); + allqueue(REDRAWVIEW3D, 0); + break; + case B_RAD_COLLECT: + rad_collect_meshes(); + allqueue(REDRAWBUTSRADIO, 0); + allqueue(REDRAWVIEW3D, 0); + break; + case B_RAD_INIT: + if(phase==RAD_PHASE_PATCHES) { + rad_limit_subdivide(); + allqueue(REDRAWBUTSRADIO, 0); + allqueue(REDRAWVIEW3D, 0); + } + break; + case B_RAD_SHOOTP: + if(phase==RAD_PHASE_PATCHES) { + waitcursor(1); + rad_subdivshootpatch(); + allqueue(REDRAWBUTSRADIO, 0); + allqueue(REDRAWVIEW3D, 0); + waitcursor(0); + } + break; + case B_RAD_SHOOTE: + if(phase==RAD_PHASE_PATCHES) { + waitcursor(1); + rad_subdivshootelem(); + allqueue(REDRAWBUTSRADIO, 0); + allqueue(REDRAWVIEW3D, 0); + waitcursor(0); + } + break; + case B_RAD_GO: + if(phase==RAD_PHASE_PATCHES) { + waitcursor(1); + rad_go(); + waitcursor(0); + allqueue(REDRAWBUTSRADIO, 0); + allqueue(REDRAWVIEW3D, 0); + } + break; + case B_RAD_LIMITS: + rad_setlimits(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSRADIO, 0); + break; + case B_RAD_FAC: + set_radglobal(); + if(phase & RAD_PHASE_FACES) make_face_tab(); + else make_node_display(); + allqueue(REDRAWVIEW3D, 0); + break; + case B_RAD_NODELIM: + if(phase & RAD_PHASE_FACES) { + set_radglobal(); + removeEqualNodes(rad->nodelim); + make_face_tab(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSRADIO, 0); + } + break; + case B_RAD_NODEFILT: + if(phase & RAD_PHASE_FACES) { + set_radglobal(); + filterNodes(); + make_face_tab(); + allqueue(REDRAWVIEW3D, 0); + } + break; + case B_RAD_FACEFILT: + if(phase & RAD_PHASE_FACES) { + filterFaces(); + allqueue(REDRAWVIEW3D, 0); + } + break; + case B_RAD_DRAW: + set_radglobal(); + allqueue(REDRAWVIEW3D, 0); + break; + case B_RAD_ADDMESH: + if(phase & RAD_PHASE_FACES) rad_addmesh(); + allqueue(REDRAWVIEW3D, 0); + break; + case B_RAD_REPLACE: + if(phase & RAD_PHASE_FACES) rad_replacemesh(); + allqueue(REDRAWVIEW3D, 0); + break; + } + +} + + +void radiobuts(void) +{ + Radio *rad; + uiBlock *block; + int flag; + char str[128]; + + rad= G.scene->radio; + if(rad==0) { + add_radio(); + rad= G.scene->radio; + } + + flag= rad_phase(); + + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + uiAutoBlock(block, 10, 30, 190, 100, UI_BLOCK_ROWS); + + if(flag == RAD_PHASE_PATCHES) uiBlockSetCol(block, BUTSALMON); + else uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_RAD_INIT, "Limit Subdivide", 0, 0, 10, 10, NULL, 0, 0, 0, 0, "Subdivide patches"); + if(flag & RAD_PHASE_PATCHES) uiBlockSetCol(block, BUTPURPLE); + else uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_RAD_COLLECT, "Collect Meshes", 1, 0, 10, 10, NULL, 0, 0, 0, 0, "Convert selected and visible meshes to patches"); + uiDrawBlock(block); + + sprintf(str, "buttonswin1 %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + uiAutoBlock(block, 210, 30, 230, 150, UI_BLOCK_ROWS); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW, B_RAD_DRAW, "Wire", 0, 0, 10, 10, &rad->drawtype, 0.0, 0.0, 0, 0, "Enable wireframe drawmode"); + uiDefButS(block, ROW, B_RAD_DRAW, "Solid", 0, 0, 10, 10, &rad->drawtype, 0.0, 1.0, 0, 0, "Enable solid drawmode"); + uiDefButS(block, ROW, B_RAD_DRAW, "Gour", 0, 0, 10, 10, &rad->drawtype, 0.0, 2.0, 0, 0, "Enable Gourad drawmode"); + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, TOG|BIT|0, B_RAD_DRAW, "ShowLim", 1, 0, 10, 10, &rad->flag, 0, 0, 0, 0, "Visualize patch and element limits"); + uiDefButS(block, TOG|BIT|1, B_RAD_DRAW, "Z", 1, 0, 3, 10, &rad->flag, 0, 0, 0, 0, "Draw limits different"); + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, NUM, B_RAD_LIMITS, "ElMax:", 2, 0, 10, 10, &rad->elma, 1.0, 500.0, 0, 0, "Set maximum size of an element"); + uiDefButS(block, NUM, B_RAD_LIMITS, "ElMin:", 2, 0, 10, 10, &rad->elmi, 1.0, 100.0, 0, 0, "Set minimum size of an element"); + uiDefButS(block, NUM, B_RAD_LIMITS, "PaMax:", 3, 0, 10, 10, &rad->pama, 10.0, 1000.0, 0, 0, "Set maximum size of a patch"); + uiDefButS(block, NUM, B_RAD_LIMITS, "PaMin:", 3, 0, 10, 10, &rad->pami, 10.0, 1000.0, 0, 0, "Set minimum size of a patch"); + uiDrawBlock(block); + + sprintf(str, "buttonswin2 %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + uiAutoBlock(block, 450, 30, 180, 150, UI_BLOCK_ROWS); + + if(flag == RAD_PHASE_PATCHES) uiBlockSetCol(block, BUTSALMON); + else uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_RAD_SHOOTE, "Subdiv Shoot Element", 0, 0, 12, 10, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_RAD_SHOOTP, "Subdiv Shoot Patch", 1, 0, 12, 10, NULL, 0, 0, 0, 0, "Detect high energy changes"); + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, NUM, 0, "Max Subdiv Shoot:", 2, 0, 10, 10, &rad->maxsublamp, 1.0, 250.0, 0, 0, "Set the maximum number of shoot patches that are evaluated"); + uiDefButI(block, NUM, 0, "MaxEl:", 3, 0, 10, 10, &rad->maxnode, 1.0, 250000.0, 0, 0, "Set the maximum allowed number of elements"); + uiDefButS(block, NUM, B_RAD_LIMITS, "Hemires:", 4, 0, 10, 10, &rad->hemires, 100.0, 1000.0, 100, 0, "Set the size of a hemicube"); + uiDrawBlock(block); + + sprintf(str, "buttonswin3 %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + uiAutoBlock(block, 640, 30, 200, 150, UI_BLOCK_ROWS); + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, NUM, 0, "Max Iterations:", 0, 0, 10, 10, &rad->maxiter, 0.0, 10000.0, 0, 0, "Maximum number of radiosity rounds"); + uiDefButF(block, NUM, 0, "Convergence:", 1, 0, 10, 10, &rad->convergence, 0.0, 1.0, 10, 0, "Set the lower threshold of unshot energy"); + uiDefButS(block, NUM, 0, "SubSh P:", 2, 0, 10, 10, &rad->subshootp, 0.0, 10.0, 0, 0, "Set the number of times the environment is tested to detect pathes"); + uiDefButS(block, NUM, 0, "SubSh E:", 2, 0, 10, 10, &rad->subshoote, 0.0, 10.0, 0, 0, "Set the number of times the environment is tested to detect elements"); + if(flag == RAD_PHASE_PATCHES) uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_RAD_GO, "GO", 3, 0, 10, 15, NULL, 0, 0, 0, 0, "Start the radiosity simulation"); + uiDrawBlock(block); + + sprintf(str, "buttonswin4 %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + uiAutoBlock(block, 850, 30, 200, 150, UI_BLOCK_ROWS); + + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_RAD_FAC, "Mult:", 0, 0, 50, 17, &rad->radfac, 0.001, 250.0, 100, 0, "Mulitply the energy values"); + uiDefButF(block, NUM, B_RAD_FAC, "Gamma:", 0, 0, 50, 17, &rad->gamma, 0.2, 10.0, 10, 0, "Change the contrast of the energy values"); + if(flag & RAD_PHASE_FACES) uiBlockSetCol(block, BUTSALMON); + else uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_RAD_FACEFILT, "FaceFilter", 1, 0, 10, 10, NULL, 0, 0, 0, 0, "Force an extra smoothing"); + if(flag & RAD_PHASE_FACES) uiBlockSetCol(block, BUTSALMON); + else uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_RAD_NODELIM, "RemoveDoubles", 2, 0, 30, 10, NULL, 0.0, 50.0, 0, 0, "Join elements which differ less than 'Lim'"); + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, NUM, 0, "Lim:", 2, 0, 10, 10, &rad->nodelim, 0.0, 50.0, 0, 0, "Set the range for removing doubles"); + if(flag & RAD_PHASE_FACES) uiBlockSetCol(block, BUTSALMON); + else uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_RAD_NODEFILT, "Element Filter", 3, 0, 10, 10, NULL, 0, 0, 0, 0, "Filter elements to remove aliasing artefacts"); + uiDrawBlock(block); + + sprintf(str, "buttonswin5 %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + uiAutoBlock(block, 1060, 30, 190, 150, UI_BLOCK_ROWS); + + if(flag & RAD_PHASE_PATCHES) uiBlockSetCol(block, BUTSALMON); + else uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_RAD_FREE, "Free Radio Data", 0, 0, 10, 10, NULL, 0, 0, 0, 0, "Release all memory used by Radiosity"); + if(flag & RAD_PHASE_FACES) uiBlockSetCol(block, BUTSALMON); + else uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_RAD_REPLACE, "Replace Meshes", 1, 0, 10, 10, NULL, 0, 0, 0, 0, "Convert meshes to Mesh objects with vertex colours, changing input-meshes"); + uiDefBut(block, BUT, B_RAD_ADDMESH, "Add new Meshes", 2, 0, 10, 10, NULL, 0, 0, 0, 0, "Convert meshes to Mesh objects with vertex colours, unchanging input-meshes"); + uiDrawBlock(block); + + rad_status_str(str); + cpack(0); + glRasterPos2i(210, 189); + BMF_DrawString(uiBlockGetCurFont(block), str); +} + + +/* *************************** MBALL ******************************** */ + +void do_mballbuts(unsigned short event) +{ + switch(event) { + case B_RECALCMBALL: + makeDispList(OBACT); + allqueue(REDRAWVIEW3D, 0); + break; + } +} + +void mballbuts(void) +{ + extern MetaElem *lastelem; + MetaBall *mb; + Object *ob; + uiBlock *block; + char str[64]; + + ob= OBACT; + if(ob==0) return; + + sprintf(str, "editbuttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + mb= ob->data; + if (ob==find_basis_mball(ob)) { + uiDefButF(block, NUMSLI, B_RECALCMBALL, "Wiresize:", 470,178,250,19, &mb->wiresize, 0.05, 1.0, 0, 0, ""); + uiDefButF(block, NUMSLI, 0, "Rendersize:", 470,158,250,19, &mb->rendersize, 0.05, 1.0, 0, 0, ""); + uiDefButF(block, NUMSLI, B_RECALCMBALL, "Threshold:", 470,138,250,19, &mb->thresh, 0.0001, 5.0, 0, 0, ""); + + uiBlockSetCol(block, BUTBLUE); + uiDefBut(block, LABEL, 0, "Update:", 471,108,120,19, 0, 0, 0, 0, 0, ""); + uiDefButS(block, ROW, B_DIFF, "Always", 471, 85, 120, 19, &mb->flag, 0.0, 0.0, 0, 0, ""); + uiDefButS(block, ROW, B_DIFF, "Half Res", 471, 65, 120, 19, &mb->flag, 0.0, 1.0, 0, 0, ""); + uiDefButS(block, ROW, B_DIFF, "Fast", 471, 45, 120, 19, &mb->flag, 0.0, 2.0, 0, 0, ""); + uiBlockSetCol(block, BUTGREY); + } + + if(ob==G.obedit && lastelem) { + uiDefButF(block, NUMSLI, B_RECALCMBALL, "Stiffness:", 750,178,250,19, &lastelem->s, 0.0, 10.0, 0, 0, ""); + uiDefButF(block, NUMSLI, B_RECALCMBALL, "Len:", 750,158,250,19, &lastelem->len, 0.0, 20.0, 0, 0, ""); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|1, B_RECALCMBALL, "Negative",752,116,60,19, &lastelem->flag, 0, 0, 0, 0, ""); + + uiDefButS(block, ROW, B_RECALCMBALL, "Ball", 753,83,60,19, &lastelem->type, 1.0, 0.0, 0, 0, ""); + uiDefButS(block, ROW, B_RECALCMBALL, "TubeX", 753,62,60,19, &lastelem->type, 1.0, 1.0, 0, 0, ""); + uiDefButS(block, ROW, B_RECALCMBALL, "TubeY", 814,62,60,19, &lastelem->type, 1.0, 2.0, 0, 0, ""); + uiDefButS(block, ROW, B_RECALCMBALL, "TubeZ", 876,62,60,19, &lastelem->type, 1.0, 3.0, 0, 0, ""); + + } + uiDrawBlock(block); +} + +/* *************************** SCRIPT ******************************** */ + +static void extend_scriptlink(ScriptLink *slink) +{ + void *stmp, *ftmp; + + if (!slink) return; + + stmp= slink->scripts; + slink->scripts= MEM_mallocN(sizeof(ID*)*(slink->totscript+1), "scriptlistL"); + + ftmp= slink->flag; + slink->flag= MEM_mallocN(sizeof(short*)*(slink->totscript+1), "scriptlistF"); + + if (slink->totscript) { + memcpy(slink->scripts, stmp, sizeof(ID*)*(slink->totscript)); + MEM_freeN(stmp); + + memcpy(slink->flag, ftmp, sizeof(short)*(slink->totscript)); + MEM_freeN(ftmp); + } + + slink->scripts[slink->totscript]= NULL; + slink->flag[slink->totscript]= SCRIPT_FRAMECHANGED; + + slink->totscript++; + + if(slink->actscript<1) slink->actscript=1; +} + +static void delete_scriptlink(ScriptLink *slink) +{ + int i; + + if (!slink) return; + + if (slink->totscript>0) { + for (i=slink->actscript-1; i<slink->totscript-1; i++) { + slink->flag[i]= slink->flag[i+1]; + slink->scripts[i]= slink->scripts[i+1]; + } + + slink->totscript--; + } + + CLAMP(slink->actscript, 1, slink->totscript); + + if (slink->totscript==0) { + if (slink->scripts) MEM_freeN(slink->scripts); + if (slink->flag) MEM_freeN(slink->flag); + + slink->scripts= NULL; + slink->flag= NULL; + slink->totscript= slink->actscript= 0; + } +} + +void do_scriptbuts(short event) +{ + Object *ob=NULL; + ScriptLink *script=NULL; + Material *ma; + + switch (event) { + case B_SSCRIPT_ADD: + extend_scriptlink(&G.scene->scriptlink); + break; + case B_SSCRIPT_DEL: + delete_scriptlink(&G.scene->scriptlink); + break; + + case B_SCRIPT_ADD: + case B_SCRIPT_DEL: + ob= OBACT; + + if (ob && G.buts->scriptblock==ID_OB) { + script= &ob->scriptlink; + + } else if (ob && G.buts->scriptblock==ID_MA) { + ma= give_current_material(ob, ob->actcol); + if (ma) script= &ma->scriptlink; + + } else if (ob && G.buts->scriptblock==ID_CA) { + if (ob->type==OB_CAMERA) + script= &((Camera *)ob->data)->scriptlink; + + } else if (ob && G.buts->scriptblock==ID_LA) { + if (ob->type==OB_LAMP) + script= &((Lamp *)ob->data)->scriptlink; + + } else if (G.buts->scriptblock==ID_WO) { + if (G.scene->world) + script= &(G.scene->world->scriptlink); + } + + if (event==B_SCRIPT_ADD) extend_scriptlink(script); + else delete_scriptlink(script); + + break; + default: + break; + } + + allqueue(REDRAWBUTSSCRIPT, 0); +} + +void draw_scriptlink(uiBlock *block, ScriptLink *script, int sx, int sy, int scene) +{ + char str[256]; + + uiBlockSetCol(block, BUTGREY); + + if (script->totscript) { + strcpy(str, "FrameChanged%x 1|"); + strcat(str, "Redraw%x 4|"); + if (scene) { + strcat(str, "OnLoad%x 2"); + } + + uiDefButS(block, MENU, 1, str, (short)sx, (short)sy, 148, 19, &script->flag[script->actscript-1], 0, 0, 0, 0, "Script links for the Frame changed event"); + + uiDefIDPoinBut(block, test_scriptpoin_but, 1, "", (short)(sx+150),(short)sy, 98, 19, &script->scripts[script->actscript-1], "Name of Script to link"); + } + + sprintf(str,"%d Scr:", script->totscript); + uiDefButS(block, NUM, REDRAWBUTSSCRIPT, str, (short)(sx+250), (short)sy,98,19, &script->actscript, 1, script->totscript, 0, 0, "Total / Active Script link (LeftMouse + Drag to change)"); + + uiBlockSetCol(block, BUTSALMON); + + if (scene) { + if (script->totscript<32767) + uiDefBut(block, BUT, B_SSCRIPT_ADD, "New", (short)(sx+350), (short)sy, 38, 19, 0, 0, 0, 0, 0, "Add a new Script link"); + if (script->totscript) + uiDefBut(block, BUT, B_SSCRIPT_DEL, "Del", (short)(sx+390), (short)sy, 38, 19, 0, 0, 0, 0, 0, "Delete the current Script link"); + } else { + if (script->totscript<32767) + uiDefBut(block, BUT, B_SCRIPT_ADD, "New", (short)(sx+350), (short)sy, 38, 19, 0, 0, 0, 0, 0, "Add a new Script link"); + if (script->totscript) + uiDefBut(block, BUT, B_SCRIPT_DEL, "Del", (short)(sx+390), (short)sy, 38, 19, 0, 0, 0, 0, 0, "Delete the current Script link"); + } +} + +void scriptbuts(void) +{ + Object *ob=NULL; + ScriptLink *script=NULL; + Material *ma; + uiBlock *block; + char str[64]; + + ob= OBACT; + + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + if (ob && G.buts->scriptblock==ID_OB) { + script= &ob->scriptlink; + + } else if (ob && G.buts->scriptblock==ID_MA) { + ma= give_current_material(ob, ob->actcol); + if (ma) script= &ma->scriptlink; + + } else if (ob && G.buts->scriptblock==ID_CA) { + if (ob->type==OB_CAMERA) + script= &((Camera *)ob->data)->scriptlink; + + } else if (ob && G.buts->scriptblock==ID_LA) { + if (ob->type==OB_LAMP) + script= &((Lamp *)ob->data)->scriptlink; + + } else if (G.buts->scriptblock==ID_WO) { + if (G.scene->world) + script= &(G.scene->world->scriptlink); + } + + if (script) draw_scriptlink(block, script, 25, 180, 0); + + /* EVENTS */ + draw_buttons_edge(curarea->win, 540); + + draw_scriptlink(block, &G.scene->scriptlink, 600, 180, 1); + + uiDrawBlock(block); +} + +/* *************************** IKA ******************************** */ +/* is this number used elsewhere? */ +/* static int ika_del_number; */ +void do_ikabuts(unsigned short event) +{ + Base *base; + Object *ob; + + ob= OBACT; + + switch(event) { + case B_IKASETREF: + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base->object->type==OB_IKA) init_defstate_ika(base->object); + } + base= base->next; + } + break; + case B_IKARECALC: + itterate_ika(ob); + break; + } +} + +void ikabuts(void) +{ + Ika *ika; + Object *ob; + Limb *li; + Deform *def; + uiBlock *block; + int nr, cury, nlimbs; + char str[32]; + + ob= OBACT; + if(ob==0) return; + + sprintf(str, "editbuttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + ika= ob->data; + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_IKASETREF, "Set Reference",470,180,200,20, 0, 0, 0, 0, 0, ""); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|1, B_DIFF, "Lock XY Plane", 470,140,200,20, &ika->flag, 0.0, 1.0, 0, 0, "New IK option: allows both X and Y axes to rotate"); + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_DIFF, "XY constraint ", 470,120,200,20, &ika->xyconstraint, 0.0, 1.0, 100, 0, "Constrain in radians"); + + uiDefButF(block, NUMSLI, B_DIFF, "Mem ", 470,80,200,20, &ika->mem, 0.0, 1.0, 0, 0, ""); + uiDefButS(block, NUM, B_DIFF, "Iter: ", 470,60,200,20, &ika->iter, 2.0, 16.0, 0, 0, ""); + + + uiBlockSetCol(block, BUTGREY); + + uiDefBut(block, LABEL, 0, "Limb Weight", 680, 200, 150, 19, 0, 0, 0, 0, 0, ""); + cury= 180; + li= ika->limbbase.first; + + nlimbs= BLI_countlist(&ika->limbbase); + + for (nr = 0; nr < nlimbs; nr++) { + sprintf(str, "Limb %d:", nr); + uiDefButF(block, NUM, B_DIFF, str, 680, (short)cury, 150, 19, &li->fac, 0.01, 1.0, 10, 0, ""); + cury-= 20; + li= li->next; + } + + + + uiDefBut(block, LABEL, 0, "Deform Max Dist", 955, 200, 140, 19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Deform Weight", 1095, 200, 140, 19, 0, 0, 0, 0, 0, ""); + + + cury= 180; + def= ika->def; + for (nr = 0; nr < ika->totdef; nr++) { + def = ika->def+nr; + if(def->ob) { + if(def->ob->type!=OB_IKA) sprintf(str, "%s :", def->ob->id.name+2); + else sprintf(str, "%s (%d):", def->ob->id.name+2, def->par1); + } + + uiDefBut(block, LABEL, 0, str, 855, (short)cury, 100, 19, 0, 0.01, 0.0, 0, 0, ""); + uiDefButF(block, NUM, B_DIFF, "", 955, (short)cury, 140, 19, &def->dist, 0.0, 40.0, 100, 0, "Beyond this distance the Limb doesn't influence deformation. '0.0' is global influence."); + uiDefButF(block, NUM, B_DIFF, "", 1095,(short)cury, 140, 19, &def->fac, 0.01, 10.0, 10, 0, ""); + + cury-= 20; + } + uiDrawBlock(block); +} + +/* *************************** LATTICE ******************************** */ + +void do_latticebuts(unsigned short event) +{ + Object *ob; + Lattice *lt; + + ob= OBACT; + + switch(event) { + case B_RESIZELAT: + if(ob) { + if(ob==G.obedit) resizelattice(editLatt); + else resizelattice(ob->data); + } + allqueue(REDRAWVIEW3D, 0); + break; + case B_DRAWLAT: + if(ob==G.obedit) calc_lattverts_ext(); + allqueue(REDRAWVIEW3D, 0); + break; + case B_LATTCHANGED: + + lt= ob->data; + if(lt->flag & LT_OUTSIDE) outside_lattice(lt); + + make_displists_by_parent(ob); + + allqueue(REDRAWVIEW3D, 0); + + break; + } +} + +void latticebuts(void) +{ + Lattice *lt; + Object *ob; + uiBlock *block; + char str[64]; + + ob= OBACT; + if(ob==0) return; + + sprintf(str, "editbuttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + if(ob==G.obedit) lt= editLatt; + else lt= ob->data; + + uiSetButLock(lt->key!=0, "Not with VertexKeys"); + uiSetButLock(ob==G.obedit, "Unable to perform function in EditMode"); + uiDefButS(block, NUM, B_RESIZELAT, "U:", 470,178,100,19, <->pntsu, 1.0, 64.0, 0, 0, ""); + uiDefButS(block, NUM, B_RESIZELAT, "V:", 470,158,100,19, <->pntsv, 1.0, 64.0, 0, 0, ""); + uiDefButS(block, NUM, B_RESIZELAT, "W:", 470,138,100,19, <->pntsw, 1.0, 64.0, 0, 0, ""); + uiClearButLock(); + + uiBlockSetCol(block, BUTGREEN); + uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 178, 40, 19, <->typeu, 1.0, (float)KEY_LINEAR, 0, 0, ""); + uiDefButC(block, ROW, B_LATTCHANGED, "Card", 612, 178, 40, 19, <->typeu, 1.0, (float)KEY_CARDINAL, 0, 0, ""); + uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 178, 40, 19, <->typeu, 1.0, (float)KEY_BSPLINE, 0, 0, ""); + + uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 158, 40, 19, <->typev, 2.0, (float)KEY_LINEAR, 0, 0, ""); + uiDefButC(block, ROW, B_LATTCHANGED, "Card", 612, 158, 40, 19, <->typev, 2.0, (float)KEY_CARDINAL, 0, 0, ""); + uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 158, 40, 19, <->typev, 2.0, (float)KEY_BSPLINE, 0, 0, ""); + + uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 138, 40, 19, <->typew, 3.0, (float)KEY_LINEAR, 0, 0, ""); + uiDefButC(block, ROW, B_LATTCHANGED, "Card", 612, 138, 40, 19, <->typew, 3.0, (float)KEY_CARDINAL, 0, 0, ""); + uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 138, 40, 19, <->typew, 3.0, (float)KEY_BSPLINE, 0, 0, ""); + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_RESIZELAT, "Make Regular", 470,101,99,32, 0, 0, 0, 0, 0, ""); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|1, B_LATTCHANGED, "Outside", 571,101,120,31, <->flag, 0, 0, 0, 0, ""); + + uiDrawBlock(block); +} + + +/* *************************** TEXTURE ******************************** */ + +Tex *cur_imatex=0; +int prv_win= 0; + +void load_tex_image(char *str) /* aangeroepen vanuit fileselect */ +{ + Image *ima=0; + Tex *tex; + + tex= cur_imatex; + if(tex->type==TEX_IMAGE || tex->type==TEX_ENVMAP) { + + ima= add_image(str); + if(ima) { + if(tex->ima) { + tex->ima->id.us--; + } + tex->ima= ima; + + free_image_buffers(ima); /* forceer opnieuw inlezen */ + ima->ok= 1; + } + + allqueue(REDRAWBUTSTEX, 0); + + BIF_preview_changed(G.buts); + } +} + +void load_plugin_tex(char *str) /* aangeroepen vanuit fileselect */ +{ + Tex *tex; + + tex= cur_imatex; + if(tex->type!=TEX_PLUGIN) return; + + if(tex->plugin) free_plugin_tex(tex->plugin); + + tex->stype= 0; + tex->plugin= add_plugin_tex(str); + + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); +} + +int vergcband(const void *a1, const void *a2) +{ + const CBData *x1=a1, *x2=a2; + + if( x1->pos > x2->pos ) return 1; + else if( x1->pos < x2->pos) return -1; + return 0; +} + + + +void save_env(char *name) +{ + Tex *tex; + char str[FILE_MAXFILE]; + + strcpy(str, name); + BLI_convertstringcode(str, G.sce, G.scene->r.cfra); + tex= G.buts->lockpoin; + + if(tex && GS(tex->id.name)==ID_TE) { + if(tex->env && tex->env->ok && saveover(str)) { + waitcursor(1); + BIF_save_envmap(tex->env, str); + strcpy(G.ima, name); + waitcursor(0); + } + } + +} + +void drawcolorband(ColorBand *coba, float x1, float y1, float sizex, float sizey) +{ + CBData *cbd; + float v3[2], v1[2], v2[2]; + int a; + + if(coba==0) return; + + /* outline */ + v1[0]= x1; v1[1]= y1; + glLineWidth((GLfloat)(3)); + cpack(0x0); + glBegin(GL_LINE_LOOP); + glVertex2fv(v1); + v1[0]+= sizex; + glVertex2fv(v1); + v1[1]+= sizey; + glVertex2fv(v1); + v1[0]-= sizex; + glVertex2fv(v1); + glEnd(); + glLineWidth((GLfloat)(1)); + + + glShadeModel(GL_SMOOTH); + cbd= coba->data; + + v1[0]= v2[0]= x1; + v1[1]= y1; + v2[1]= y1+sizey; + + glBegin(GL_QUAD_STRIP); + + glColor3fv( &cbd->r ); + glVertex2fv(v1); glVertex2fv(v2); + + for(a=0; a<coba->tot; a++, cbd++) { + + v1[0]=v2[0]= x1+ cbd->pos*sizex; + + glColor3fv( &cbd->r ); + glVertex2fv(v1); glVertex2fv(v2); + } + + v1[0]=v2[0]= x1+ sizex; + glVertex2fv(v1); glVertex2fv(v2); + + glEnd(); + glShadeModel(GL_FLAT); + + /* hulplijntjes */ + + v1[0]= v2[0]=v3[0]= x1; + v1[1]= y1; + v2[1]= y1+0.5*sizey; + v3[1]= y1+sizey; + + cbd= coba->data; + glBegin(GL_LINES); + for(a=0; a<coba->tot; a++, cbd++) { + v1[0]=v2[0]=v3[0]= x1+ cbd->pos*sizex; + + glColor3ub(0, 0, 0); + glVertex2fv(v1); + glVertex2fv(v2); + + if(a==coba->cur) { + glVertex2f(v1[0]-1, v1[1]); + glVertex2f(v2[0]-1, v2[1]); + glVertex2f(v1[0]+1, v1[1]); + glVertex2f(v2[0]+1, v2[1]); + } + + glColor3ub(255, 255, 255); + glVertex2fv(v2); + glVertex2fv(v3); + + if(a==coba->cur) { + glVertex2f(v2[0]-1, v2[1]); + glVertex2f(v3[0]-1, v3[1]); + glVertex2f(v2[0]+1, v2[1]); + glVertex2f(v3[0]+1, v3[1]); + } + } + glEnd(); + + glFlush(); +} + + + +void do_texbuts(unsigned short event) +{ + Tex *tex; + ImBuf *ibuf; + ScrArea *sa; + ID *id; + CBData *cbd; + float dx; + int a, nr; + short mvalo[2], mval[2]; + char *name, str[80]; + + tex= G.buts->lockpoin; + + switch(event) { + case B_TEXCHANNEL: + scrarea_queue_headredraw(curarea); + BIF_preview_changed(G.buts); + allqueue(REDRAWBUTSTEX, 0); + break; + case B_TEXTYPE: + if(tex==0) return; + tex->stype= 0; + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + break; + case B_DEFTEXVAR: + if(tex==0) return; + default_tex(tex); + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + break; + case B_LOADTEXIMA: + case B_LOADTEXIMA1: + if(tex==0) return; + /* globals: even onthouden: we maken andere area fileselect */ + cur_imatex= tex; + prv_win= curarea->win; + + sa= closest_bigger_area(); + areawinset(sa->win); + if(tex->ima) name= tex->ima->name; + else name= U.textudir; + + if(event==B_LOADTEXIMA) + activate_imageselect(FILE_SPECIAL, "SELECT IMAGE", name, load_tex_image); + else + activate_fileselect(FILE_SPECIAL, "SELECT IMAGE", name, load_tex_image); + + break; + case B_NAMEIMA: + if(tex==0) return; + if(tex->ima) { + cur_imatex= tex; + prv_win= curarea->win; + + /* naam in tex->ima is door button veranderd! */ + strcpy(str, tex->ima->name); + if(tex->ima->ibuf) strcpy(tex->ima->name, tex->ima->ibuf->name); + + load_tex_image(str); + } + break; + case B_TEXREDR_PRV: + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + break; + case B_TEXIMABROWSE: + if(tex) { + id= (ID*) tex->ima; + + if(G.buts->menunr== -2) { + activate_databrowse(id, ID_IM, 0, B_TEXIMABROWSE, &G.buts->menunr, do_texbuts); + } else if (G.buts->menunr>0) { + Image *newima= (Image*) BLI_findlink(&G.main->image, G.buts->menunr-1); + + if (newima && newima!=(Image*) id) { + tex->ima= newima; + id_us_plus((ID*) newima); + if(id) id->us--; + + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + } + } + } + break; + case B_IMAPTEST: + if(tex) { + if( (tex->imaflag & (TEX_FIELDS+TEX_MIPMAP))== TEX_FIELDS+TEX_MIPMAP ) { + error("Cannot combine fields and mipmap"); + tex->imaflag -= TEX_MIPMAP; + allqueue(REDRAWBUTSTEX, 0); + } + + if(tex->ima && tex->ima->ibuf) { + ibuf= tex->ima->ibuf; + nr= 0; + if( !(tex->imaflag & TEX_FIELDS) && (ibuf->flags & IB_fields) ) nr= 1; + if( (tex->imaflag & TEX_FIELDS) && !(ibuf->flags & IB_fields) ) nr= 1; + if(nr) { + IMB_freeImBuf(ibuf); + tex->ima->ibuf= 0; + tex->ima->ok= 1; + BIF_preview_changed(G.buts); + } + } + } + break; + case B_RELOADIMA: + if(tex && tex->ima) { + // check if there is a newer packedfile + + if (tex->ima->packedfile) { + PackedFile *pf; + pf = newPackedFile(tex->ima->name); + if (pf) { + freePackedFile(tex->ima->packedfile); + tex->ima->packedfile = pf; + } else { + error("Image not available. Keeping packed image."); + } + } + + IMB_freeImBuf(tex->ima->ibuf); + tex->ima->ibuf= 0; + tex->ima->ok= 1; + allqueue(REDRAWBUTSTEX, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + BIF_preview_changed(G.buts); + } + break; + + case B_PACKIMA: + if(tex && tex->ima) { + if (tex->ima->packedfile) { + if (G.fileflags & G_AUTOPACK) { + if (okee("Disable AutoPack ?")) { + G.fileflags &= ~G_AUTOPACK; + } + } + + if ((G.fileflags & G_AUTOPACK) == 0) { + unpackImage(tex->ima, PF_ASK); + } + } else { + if (tex->ima->ibuf && (tex->ima->ibuf->userflags & IB_BITMAPDIRTY)) { + error("Can't pack painted image. Save image from Image window first."); + } else { + tex->ima->packedfile = newPackedFile(tex->ima->name); + } + } + allqueue(REDRAWBUTSTEX, 0); + allqueue(REDRAWHEADERS, 0); + } + break; + case B_LOADPLUGIN: + if(tex==0) return; + + /* globals: even onthouden: we maken andere area fileselect */ + cur_imatex= tex; + prv_win= curarea->win; + + sa= closest_bigger_area(); + areawinset(sa->win); + if(tex->plugin) strcpy(str, tex->plugin->name); + else { + strcpy(str, U.plugtexdir); + } + activate_fileselect(FILE_SPECIAL, "SELECT PLUGIN", str, load_plugin_tex); + + break; + + case B_NAMEPLUGIN: + if(tex==0 || tex->plugin==0) return; + strcpy(str, tex->plugin->name); + free_plugin_tex(tex->plugin); + tex->stype= 0; + tex->plugin= add_plugin_tex(str); + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + break; + + case B_COLORBAND: + if(tex==0) return; + if(tex->coba==0) tex->coba= add_colorband(); + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + break; + + case B_ADDCOLORBAND: + if(tex==0 || tex->coba==0) return; + + if(tex->coba->tot < MAXCOLORBAND-1) tex->coba->tot++; + tex->coba->cur= tex->coba->tot-1; + + do_texbuts(B_CALCCBAND); + + break; + + case B_DELCOLORBAND: + if(tex==0 || tex->coba==0 || tex->coba->tot<2) return; + + for(a=tex->coba->cur; a<tex->coba->tot; a++) { + tex->coba->data[a]= tex->coba->data[a+1]; + } + if(tex->coba->cur) tex->coba->cur--; + tex->coba->tot--; + + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + break; + + case B_CALCCBAND: + case B_CALCCBAND2: + if(tex==0 || tex->coba==0 || tex->coba->tot<2) return; + + for(a=0; a<tex->coba->tot; a++) tex->coba->data[a].cur= a; + qsort(tex->coba->data, tex->coba->tot, sizeof(CBData), vergcband); + for(a=0; a<tex->coba->tot; a++) { + if(tex->coba->data[a].cur==tex->coba->cur) { + if(tex->coba->cur!=a) addqueue(curarea->win, REDRAW, 0); /* button cur */ + tex->coba->cur= a; + break; + } + } + if(event==B_CALCCBAND2) return; + + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + + break; + + case B_DOCOLORBAND: + if(tex==0 || tex->coba==0) return; + + cbd= tex->coba->data + tex->coba->cur; + uiGetMouse(mywinget(), mvalo); + + while(get_mbut() & L_MOUSE) { + uiGetMouse(mywinget(), mval); + if(mval[0]!=mvalo[0]) { + dx= mval[0]-mvalo[0]; + dx/= 345.0; + cbd->pos+= dx; + CLAMP(cbd->pos, 0.0, 1.0); + + glDrawBuffer(GL_FRONT); + drawcolorband(tex->coba, 923,81,345,20); + /* uiSetButs(B_CALCCBAND, B_CALCCBAND); */ + glDrawBuffer(GL_BACK); + + do_texbuts(B_CALCCBAND2); + cbd= tex->coba->data + tex->coba->cur; /* ivm qsort */ + + mvalo[0]= mval[0]; + } + BIF_wait_for_statechange(); + } + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + + break; + + case B_REDRAWCBAND: + glDrawBuffer(GL_FRONT); + drawcolorband(tex->coba, 923,81,345,20); + glDrawBuffer(GL_BACK); + BIF_preview_changed(G.buts); + break; + + case B_ENV_DELETE: + if(tex->env) { + RE_free_envmap(tex->env); + tex->env= 0; + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + } + break; + case B_ENV_FREE: + if(tex->env) { + RE_free_envmapdata(tex->env); + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + } + break; + case B_ENV_SAVE: + if(tex->env && tex->env->ok) { + sa= closest_bigger_area(); + areawinset(sa->win); + save_image_filesel_str(str); + activate_fileselect(FILE_SPECIAL, str, G.ima, save_env); + } + break; + case B_ENV_OB: + if(tex->env && tex->env->object) { + BIF_preview_changed(G.buts); + if ELEM(tex->env->object->type, OB_CAMERA, OB_LAMP) { + error("Camera or Lamp not allowed"); + tex->env->object= 0; + } + } + break; + + default: + if(event>=B_PLUGBUT && event<=B_PLUGBUT+23) { + PluginTex *pit= tex->plugin; + if(pit && pit->callback) { + pit->callback(event - B_PLUGBUT); + BIF_preview_changed(G.buts); + } + } + } +} + +static void test_idbutton_cb(void *namev, void *arg2_unused) +{ + char *name= namev; + test_idbutton(name+2); +} + +void texbuts(void) +{ + Object *ob; + Material *ma=0; + World *wrld=0; + Lamp *la=0; + ID *id = NULL; + MTex *mtex = NULL; + Tex *tex; + VarStruct *varstr; + PluginTex *pit; + CBData *cbd; + EnvMap *env; + uiBlock *block; + uiBut *but; + int a, xco, yco, loos, dx, dy, ok; + char str[30], *strp; + + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + uiBlockSetCol(block, BUTSALMON); + + uiDefButC(block, ROW, B_TEXREDR_PRV, "Mat", 200,172,40,20, &G.buts->texfrom, 3.0, 0.0, 0, 0, "Display the texture of the active material"); + uiDefButC(block, ROW, B_TEXREDR_PRV, "World", 240,172,52,20, &G.buts->texfrom, 3.0, 1.0, 0, 0, "Display the texture of the world block"); + uiDefButC(block, ROW, B_TEXREDR_PRV, "Lamp", 292,172,46,20, &G.buts->texfrom, 3.0, 2.0, 0, 0, "Display the texture of the lamp"); + uiBlockSetCol(block, BUTGREY); + + ok= 0; + + if(G.buts->texfrom==0) { + ob= OBACT; + if(ob) { + id= ob->data; + if(id) { + ma= give_current_material(ob, ob->actcol); + if(ma) ok= 1; + } + } + + } + else if(G.buts->texfrom==1) { + wrld= G.scene->world; + if(wrld) { + id= (ID *)wrld; + ok= 1; + } + } + else if(G.buts->texfrom==2) { + ob= OBACT; + if(ob) { + if(ob->type==OB_LAMP) { + la= ob->data; + id= (ID *)la; + ok= 1; + } + } + } + + if(ok==0) { + uiDrawBlock(block); + return; + } + + uiSetButLock(id->lib!=0, "Can't edit library data"); + + /* CHANNELS */ + yco= 140; + for(a= 0; a<8; a++) { + if(G.buts->texfrom==0) mtex= ma->mtex[a]; + else if(G.buts->texfrom==1) mtex= wrld->mtex[a]; + else if(G.buts->texfrom==2) mtex= la->mtex[a]; + + if(mtex && mtex->tex) splitIDname(mtex->tex->id.name+2, str, &loos); + else strcpy(str, ""); + str[14]= 0; + if(G.buts->texfrom==0) { + uiDefButC(block, ROW, B_TEXCHANNEL, str, 200,(short)yco,140,18, &(ma->texact), 0.0, (float)a, 0, 0, "Linked channel"); + } + else if(G.buts->texfrom==1) { + uiDefButS(block, ROW, B_TEXCHANNEL, str, 200,(short)yco,140,18, &(wrld->texact), 0.0, (float)a, 0, 0, ""); + if(a==5) break; + } + else if(G.buts->texfrom==2) { + uiDefButS(block, ROW, B_TEXCHANNEL, str, 200,(short)yco,140,18, &(la->texact), 0.0, (float)a, 0, 0, ""); + if(a==5) break; + } + yco-= 19; + } + + if(G.buts->texfrom==0) { + but= uiDefBut(block, TEX, B_IDNAME, "MA:", 200,195,140,20, ma->id.name+2, 0.0, 18.0, 0, 0, "Name of the datablock"); + uiButSetFunc(but, test_idbutton_cb, ma->id.name, NULL); + mtex= ma->mtex[ ma->texact ]; + } + else if(G.buts->texfrom==1) { + but= uiDefBut(block, TEX, B_IDNAME, "WO:", 200,195,140,20, wrld->id.name+2, 0.0, 18.0, 0, 0, "Name of the datablock"); + uiButSetFunc(but, test_idbutton_cb, wrld->id.name, NULL); + mtex= wrld->mtex[ wrld->texact ]; + } + else if(G.buts->texfrom==2) { + but= uiDefBut(block, TEX, B_IDNAME, "LA:", 200,195,140,20, la->id.name+2, 0.0, 18.0, 0, 0, "Name of the datablock"); + uiButSetFunc(but, test_idbutton_cb, la->id.name, NULL); + mtex= la->mtex[ la->texact ]; + } + + if(mtex && mtex->tex) { + tex= mtex->tex; + + uiSetButLock(tex->id.lib!=0, "Can't edit library data"); + xco= 275; + uiDefButS(block, ROW, B_TEXTYPE, texstr[0], (short)(xco+=75), 195, 75, 20, &tex->type, 1.0, 0.0, 0, 0, "Default"); + uiDefButS(block, ROW, B_TEXTYPE, texstr[TEX_IMAGE],(short)(xco+=75), 195, 75, 20, &tex->type, 1.0, (float)TEX_IMAGE, 0, 0, "Use image texture"); + uiDefButS(block, ROW, B_TEXTYPE, texstr[TEX_ENVMAP], (short)(xco+=75), 195, 75, 20, &tex->type, 1.0, (float)TEX_ENVMAP, 0, 0, "Use environment maps"); + if(tex->plugin && tex->plugin->doit) strp= tex->plugin->pname; else strp= texstr[TEX_PLUGIN]; + uiDefButS(block, ROW, B_TEXTYPE, strp, (short)(xco+=75), 195, 75, 20, &tex->type, 1.0, (float)TEX_PLUGIN, 0, 0, "Use plugin"); + uiDefButS(block, ROW, B_TEXTYPE, texstr[TEX_CLOUDS], (short)(xco+=75), 195, 75, 20, &tex->type, 1.0, (float)TEX_CLOUDS, 0, 0, "Use clouds texture"); + uiDefButS(block, ROW, B_TEXTYPE, texstr[TEX_WOOD], (short)(xco+=75), 195, 75, 20, &tex->type, 1.0, (float)TEX_WOOD, 0, 0, "Use wood texture"); + uiDefButS(block, ROW, B_TEXTYPE, texstr[TEX_MARBLE], (short)(xco+=75), 195, 75, 20, &tex->type, 1.0, (float)TEX_MARBLE, 0, 0, "Use marble texture"); + uiDefButS(block, ROW, B_TEXTYPE, texstr[TEX_MAGIC], (short)(xco+=75), 195, 75, 20, &tex->type, 1.0, (float)TEX_MAGIC, 0, 0, "Use magic texture"); + uiDefButS(block, ROW, B_TEXTYPE, texstr[TEX_BLEND], (short)(xco+=75), 195, 75, 20, &tex->type, 1.0, (float)TEX_BLEND, 0, 0, "Use blend texture"); + uiDefButS(block, ROW, B_TEXTYPE, texstr[TEX_STUCCI], (short)(xco+=75), 195, 75, 20, &tex->type, 1.0, (float)TEX_STUCCI, 0, 0, "Use strucci texture"); + uiDefButS(block, ROW, B_TEXTYPE, texstr[TEX_NOISE], (short)(xco+=75), 195, 75, 20, &tex->type, 1.0, (float)TEX_NOISE, 0, 0, "Use noise texture"); + + /* TYPES */ + uiBlockSetCol(block, BUTGREEN); + switch(tex->type) { + case TEX_CLOUDS: + uiDefButS(block, ROW, B_MATPRV, "Default", 350, 170, 75, 18, &tex->stype, 2.0, 0.0, 0, 0, "Use standard noise"); + uiDefButS(block, ROW, B_MATPRV, "Color", 425, 170, 75, 18, &tex->stype, 2.0, 1.0, 0, 0, "Let Noise give RGB value"); + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_MATPRV, "NoiseSize :", 350, 110, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Set the dimension of the noise table"); + uiDefButS(block, NUM, B_MATPRV, "NoiseDepth:", 350, 90, 150, 19, &tex->noisedepth, 0.0, 6.0, 0, 0, "Set the depth of the cloud calculation"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW, B_MATPRV, "Soft noise", 350, 40, 100, 19, &tex->noisetype, 12.0, 0.0, 0, 0, "Use soft noise"); + uiDefButS(block, ROW, B_MATPRV, "Hard noise", 450, 40, 100, 19, &tex->noisetype, 12.0, 1.0, 0, 0, "Use hard noise"); + break; + + case TEX_WOOD: + uiDefButS(block, ROW, B_MATPRV, "Bands", 350, 170, 75, 18, &tex->stype, 2.0, 0.0, 0, 0, "Use standard wood texture"); + uiDefButS(block, ROW, B_MATPRV, "Rings", 425, 170, 75, 18, &tex->stype, 2.0, 1.0, 0, 0, "Use wood rings"); + uiDefButS(block, ROW, B_MATPRV, "BandNoise", 500, 170, 75, 18, &tex->stype, 2.0, 2.0, 0, 0, "Add noise to standard wood"); + uiDefButS(block, ROW, B_MATPRV, "RingNoise", 575, 170, 75, 18, &tex->stype, 2.0, 3.0, 0, 0, "Add noise to rings"); + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_MATPRV, "NoiseSize :", 350, 110, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Set the dimension of the noise table"); + uiDefButF(block, NUM, B_MATPRV, "Turbulence:", 350, 90, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Set the turbulence of the bandnoise and ringnoise types"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW, B_MATPRV, "Soft noise", 350, 40, 100, 19, &tex->noisetype, 12.0, 0.0, 0, 0, "Use soft noise"); + uiDefButS(block, ROW, B_MATPRV, "Hard noise", 450, 40, 100, 19, &tex->noisetype, 12.0, 1.0, 0, 0, "Use hard noise"); + break; + + case TEX_MARBLE: + uiDefButS(block, ROW, B_MATPRV, "Soft", 350, 170, 75, 18, &tex->stype, 2.0, 0.0, 0, 0, "Use soft marble"); + uiDefButS(block, ROW, B_MATPRV, "Sharp", 425, 170, 75, 18, &tex->stype, 2.0, 1.0, 0, 0, "Use more clearly defined marble"); + uiDefButS(block, ROW, B_MATPRV, "Sharper", 500, 170, 75, 18, &tex->stype, 2.0, 2.0, 0, 0, "Use very clear defined marble"); + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_MATPRV, "NoiseSize :", 350, 110, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Set the dimension of the noise table"); + uiDefButS(block, NUM, B_MATPRV, "NoiseDepth:", 350, 90, 150, 19, &tex->noisedepth, 0.0, 6.0, 0, 0, "Set the depth of the marble calculation"); + uiDefButF(block, NUM, B_MATPRV, "Turbulence:", 350, 70, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Set the turbulence of the sine bands"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW, B_MATPRV, "Soft noise", 350, 40, 100, 19, &tex->noisetype, 12.0, 0.0, 0, 0, "Use soft noise"); + uiDefButS(block, ROW, B_MATPRV, "Hard noise", 450, 40, 100, 19, &tex->noisetype, 12.0, 1.0, 0, 0, "Use hard noise"); + break; + + case TEX_MAGIC: + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_MATPRV, "Size :", 350, 110, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Set the dimension of the pattern"); + uiDefButS(block, NUM, B_MATPRV, "Depth:", 350, 90, 150, 19, &tex->noisedepth, 0.0, 10.0, 0, 0, "Set the depth of the pattern"); + uiDefButF(block, NUM, B_MATPRV, "Turbulence:", 350, 70, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Set the strength of the pattern"); + break; + + case TEX_BLEND: + uiDefButS(block, ROW, B_MATPRV, "Lin", 350, 170, 75, 18, &tex->stype, 2.0, 0.0, 0, 0, "Use a linear progresion"); + uiDefButS(block, ROW, B_MATPRV, "Quad", 425, 170, 75, 18, &tex->stype, 2.0, 1.0, 0, 0, "Use a quadratic progression"); + uiDefButS(block, ROW, B_MATPRV, "Ease", 500, 170, 75, 18, &tex->stype, 2.0, 2.0, 0, 0, ""); + uiDefButS(block, ROW, B_MATPRV, "Diag", 575, 170, 75, 18, &tex->stype, 2.0, 3.0, 0, 0, "Use a diagonal progression"); + uiDefButS(block, ROW, B_MATPRV, "Sphere", 650, 170, 75, 18, &tex->stype, 2.0, 4.0, 0, 0, "Use progression with the shape of a sphere"); + uiDefButS(block, ROW, B_MATPRV, "Halo", 725, 170, 75, 18, &tex->stype, 2.0, 5.0, 0, 0, "Use a quadratic progression with the shape of a sphere"); + + uiDefButS(block, TOG|BIT|1, B_MATPRV, "Flip XY", 350, 130, 75, 18, &tex->flag, 0, 0, 0, 0, "Flip the direction of the progression a quarter turn"); + break; + + case TEX_STUCCI: + uiDefButS(block, ROW, B_MATPRV, "Plastic", 350, 170, 75, 18, &tex->stype, 2.0, 0.0, 0, 0, "Use standard stucci"); + uiDefButS(block, ROW, B_MATPRV, "Wall In", 425, 170, 75, 18, &tex->stype, 2.0, 1.0, 0, 0, "Set start value"); + uiDefButS(block, ROW, B_MATPRV, "Wall Out", 500, 170, 75, 18, &tex->stype, 2.0, 2.0, 0, 0, "Set end value"); + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_MATPRV, "NoiseSize :", 350, 110, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Set the dimension of the noise table"); + uiDefButF(block, NUM, B_MATPRV, "Turbulence:", 350, 90, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Set the depth of the stucci"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW, B_MATPRV, "Soft noise", 350, 40, 100, 19, &tex->noisetype, 12.0, 0.0, 0, 0, "Use soft noise"); + uiDefButS(block, ROW, B_MATPRV, "Hard noise", 450, 40, 100, 19, &tex->noisetype, 12.0, 1.0, 0, 0, "Use hard noise"); + + break; + + case TEX_NOISE: + break; + + case TEX_IMAGE: + + break; + } + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_DEFTEXVAR, "Default Vars", 1180,169,93,47, 0, 0, 0, 0, 0, "Return to standard values"); + + uiBlockSetCol(block, BUTGREY); + /* SPECIFIC */ + if(tex->type==TEX_IMAGE) { + uiDefButF(block, NUM, B_REDR, "MinX ", 350,30,140,19, &tex->cropxmin, -10.0, 10.0, 10, 0, "Set minimum X value for cropping"); + uiDefButF(block, NUM, B_REDR, "MaxX ", 350,10,140,19, &tex->cropxmax, -10.0, 10.0, 10, 0, "Set maximum X value for cropping"); + uiDefButF(block, NUM, B_REDR, "MinY ", 494,30,140,19, &tex->cropymin, -10.0, 10.0, 10, 0, "Set minimum Y value for cropping"); + uiDefButF(block, NUM, B_REDR, "MaxY ", 494,10,140,19, &tex->cropymax, -10.0, 10.0, 10, 0, "Set maximum Y value for cropping"); + + + uiDefButS(block, ROW, 0, "Extend", 350,85,69,19, &tex->extend, 4.0, 1.0, 0, 0, "Extend the colour of the edge"); + uiDefButS(block, ROW, 0, "Clip", 421,85,59,19, &tex->extend, 4.0, 2.0, 0, 0, "Return alpha 0.0 outside image"); + uiDefButS(block, ROW, 0, "Repeat", 565,85,68,19, &tex->extend, 4.0, 3.0, 0, 0, "Repeat image horizontally and vertically"); + uiDefButS(block, ROW, 0, "ClipCube", 482,85,82,19, &tex->extend, 4.0, 4.0, 0, 0, "Return alpha 0.0 outside cubeshaped area around image"); + + uiDefButF(block, NUM, B_MATPRV, "Filter :", 352,109,135,19, &tex->filtersize, 0.1, 25.0, 0, 0, "Set the filter size used by mipmap and interpol"); + + uiDefButS(block, NUM, B_MATPRV, "Xrepeat:", 350,60,140,19, &tex->xrepeat, 1.0, 512.0, 0, 0, "Set the degree of repetition in the X direction"); + uiDefButS(block, NUM, B_MATPRV, "Yrepeat:", 494,60,140,19, &tex->yrepeat, 1.0, 512.0, 0, 0, "Set the degree of repetition in the Y direction"); + + uiDefButS(block, NUM, B_MATPRV, "Frames :", 642,110,150,19, &tex->frames, 0.0, 18000.0, 0, 0, "Activate animation option"); + uiDefButS(block, NUM, B_MATPRV, "Offset :", 642,90,150,19, &tex->offset, -9000.0, 9000.0, 0, 0, "Set the number of the first picture of the animation"); + uiDefButS(block, NUM, B_MATPRV, "Fie/Ima:", 642,60,98,19, &tex->fie_ima, 1.0, 200.0, 0, 0, "Set the number of fields per rendered frame"); + uiDefButS(block, NUM, B_MATPRV, "StartFr:", 642,30,150,19, &tex->sfra, 1.0, 9000.0, 0, 0, "Set the start frame of the animation"); + uiDefButS(block, NUM, B_MATPRV, "Len:", 642,10,150,19, &tex->len, 0.0, 9000.0, 0, 0, "Set the length of the animation"); + + uiDefButS(block, NUM, B_MATPRV, "Fra:", 802,70,73,19, &(tex->fradur[0][0]), 0.0, 18000.0, 0, 0, "Montage mode: frame start"); + uiDefButS(block, NUM, B_MATPRV, "", 879,70,37,19, &(tex->fradur[0][1]), 0.0, 250.0, 0, 0, "Montage mode: amount of displayed frames"); + uiDefButS(block, NUM, B_MATPRV, "Fra:", 802,50,73,19, &(tex->fradur[1][0]), 0.0, 18000.0, 0, 0, "Montage mode: frame start"); + uiDefButS(block, NUM, B_MATPRV, "", 879,50,37,19, &(tex->fradur[1][1]), 0.0, 250.0, 0, 0, "Montage mode: amount of displayed frames"); + uiDefButS(block, NUM, B_MATPRV, "Fra:", 802,30,73,19, &(tex->fradur[2][0]), 0.0, 18000.0, 0, 0, "Montage mode: frame start"); + uiDefButS(block, NUM, B_MATPRV, "", 879,30,37,19, &(tex->fradur[2][1]), 0.0, 250.0, 0, 0, "Montage mode: amount of displayed frames"); + uiDefButS(block, NUM, B_MATPRV, "Fra:", 802,10,73,19, &(tex->fradur[3][0]), 0.0, 18000.0, 0, 0, "Montage mode: frame start"); + uiDefButS(block, NUM, B_MATPRV, "", 879,10,37,19, &(tex->fradur[3][1]), 0.0, 250.0, 0, 0, "Montage mode: amount of displayed frames"); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|6, 0, "Cyclic", 743,60,48,19, &tex->imaflag, 0, 0, 0, 0, "Repeat animation image"); + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_LOADTEXIMA, "Load Image", 350,137,132,24, 0, 0, 0, 0, 0, "Load image - thumbnail view"); + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_LOADTEXIMA1, "", 485,137,10,24, 0, 0, 0, 0, 0, "Load image - file view"); + + id= (ID *)tex->ima; + IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), id, &(G.buts->menunr)); + if(strp[0]) + uiDefButS(block, MENU, B_TEXIMABROWSE, strp, 496,137,23,24, &(G.buts->menunr), 0, 0, 0, 0, "Browse"); + MEM_freeN(strp); + + if(tex->ima) { + uiDefBut(block, TEX, B_NAMEIMA, "", 520,137,412,24, tex->ima->name, 0.0, 79.0, 0, 0, "Texture name"); + sprintf(str, "%d", tex->ima->id.us); + uiDefBut(block, BUT, 0, str, 934,137,23,24, 0, 0, 0, 0, 0, "Number of users"); + uiDefBut(block, BUT, B_RELOADIMA, "Reload", 986,137,68,24, 0, 0, 0, 0, 0, "Reload"); + + if (tex->ima->packedfile) { + packdummy = 1; + } else { + packdummy = 0; + } + uiDefIconButI(block, TOG|BIT|0, B_PACKIMA, ICON_PACKAGE, 960,137,24,24, &packdummy, 0, 0, 0, 0, "Pack/Unpack this Image"); + } + + uiBlockSetCol(block, BUTGREEN); + + uiDefButS(block, TOG|BIT|0, 0, "InterPol", 350, 170, 75, 18, &tex->imaflag, 0, 0, 0, 0, "Interpolate pixels of the image"); + uiDefButS(block, TOG|BIT|1, B_MATPRV, "UseAlpha", 425, 170, 75, 18, &tex->imaflag, 0, 0, 0, 0, "Use the alpha layer"); + uiDefButS(block, TOG|BIT|5, B_MATPRV, "CalcAlpha", 500, 170, 75, 18, &tex->imaflag, 0, 0, 0, 0, "Calculate an alpha based on the RGB"); + uiDefButS(block, TOG|BIT|2, B_MATPRV, "NegAlpha", 575, 170, 75, 18, &tex->flag, 0, 0, 0, 0, "Reverse the alpha value"); + uiDefButS(block, TOG|BIT|2, B_IMAPTEST, "MipMap", 650, 170, 75, 18, &tex->imaflag, 0, 0, 0, 0, "Generate a series of pictures used for mipmapping"); + uiDefButS(block, TOG|BIT|3, B_IMAPTEST, "Fields", 725, 170, 75, 18, &tex->imaflag, 0, 0, 0, 0, "Work with field images"); + uiDefButS(block, TOG|BIT|4, B_MATPRV, "Rot90", 800, 170, 50, 18, &tex->imaflag, 0, 0, 0, 0, "Rotate image 90 degrees when rendered"); + uiDefButS(block, TOG|BIT|7, B_RELOADIMA, "Movie", 850, 170, 50, 18, &tex->imaflag, 0, 0, 0, 0, "Use a movie for an image"); + uiDefButS(block, TOG|BIT|8, 0, "Anti", 900, 170, 50, 18, &tex->imaflag, 0, 0, 0, 0, "Use anti-aliasing"); + uiDefButS(block, TOG|BIT|10, 0, "StField", 950, 170, 50, 18, &tex->imaflag, 0, 0, 0, 0, ""); + + uiBlockSetCol(block, BUTGREY); + + /* printen aantal frames anim */ + if(tex->ima && tex->ima->anim) { + sprintf(str, "%d frs ", IMB_anim_get_duration(tex->ima->anim)); + uiDefBut(block, LABEL, 0, str, 834, 110, 90, 18, 0, 0, 0, 0, 0, ""); + sprintf(str, "%d cur ", tex->ima->lastframe); + uiDefBut(block, LABEL, 0, str, 834, 90, 90, 18, 0, 0, 0, 0, 0, ""); + } + + + } + else if(tex->type==TEX_PLUGIN) { + if(tex->plugin && tex->plugin->doit) { + + pit= tex->plugin; + + uiBlockSetCol(block, BUTGREEN); + for(a=0; a<pit->stypes; a++) { + uiDefButS(block, ROW, B_MATPRV, pit->stnames+16*a, (short)(350+75*a), 170, 75, 18, &tex->stype, 2.0, (float)a, 0, 0, ""); + } + + uiBlockSetCol(block, BUTGREY); + varstr= pit->varstr; + if(varstr) { + for(a=0; a<pit->vars; a++, varstr++) { + xco= 350 + 140*(a/6); + yco= 110 - 20*(a % 6); + uiDefBut(block, varstr->type, B_PLUGBUT+a, varstr->name, (short)xco,(short)yco,137,19, &(pit->data[a]), varstr->min, varstr->max, 100, 0, varstr->tip); + } + } + uiDefBut(block, TEX, B_NAMEPLUGIN, "", 520,137,412,24, pit->name, 0.0, 79.0, 0, 0, "Browse"); + } + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_LOADPLUGIN, "Load Plugin", 350,137,137,24, 0, 0, 0, 0, 0, ""); + + } + else if(tex->type==TEX_ENVMAP) { + + if(tex->env==0) tex->env= RE_add_envmap(); + + if(tex->env) { + env= tex->env; + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW, B_REDR, "Static", 350, 170, 75, 18, &env->stype, 2.0, 0.0, 0, 0, "Calculate map only once"); + uiDefButS(block, ROW, B_REDR, "Anim", 425, 170, 75, 18, &env->stype, 2.0, 1.0, 0, 0, "Calculate map each rendering"); + uiDefButS(block, ROW, B_ENV_FREE, "Load", 500, 170, 75, 18, &env->stype, 2.0, 2.0, 0, 0, "Load map from disk"); + + if(env->stype==ENV_LOAD) { + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_LOADTEXIMA, "Load Image", 350,137,132,24, 0, 0, 0, 0, 0, "Load image - thumbnail view"); + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_LOADTEXIMA1, "", 485,137,10,24, 0, 0, 0, 0, 0, "Load image - file view"); + + id= (ID *)tex->ima; + IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), id, &(G.buts->menunr)); + if(strp[0]) + uiDefButS(block, MENU, B_TEXIMABROWSE, strp, 496,137,23,24, &(G.buts->menunr), 0, 0, 0, 0, ""); + MEM_freeN(strp); + + if(tex->ima) { + uiDefBut(block, TEX, B_NAMEIMA, "", 520,137,412,24, tex->ima->name, 0.0, 79.0, 0, 0, ""); + sprintf(str, "%d", tex->ima->id.us); + uiDefBut(block, BUT, 0, str, 934,137,23,24, 0, 0, 0, 0, 0, ""); + if (tex->ima->packedfile) { + packdummy = 1; + } else { + packdummy = 0; + } + uiDefIconButI(block, TOG|BIT|0, B_PACKIMA, ICON_PACKAGE, 960,137,24,24, &packdummy, 0, 0, 0, 0, "Pack/Unpack this Image"); + uiDefBut(block, BUT, B_RELOADIMA, "Reload", 986,137,68,24, 0, 0, 0, 0, 0, ""); + } + } + else { + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_ENV_FREE, "Free Data", 350,137,107,24, 0, 0, 0, 0, 0, "Release all images associated with environment map"); + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_ENV_SAVE, "Save EnvMap", 461,137,115,24, 0, 0, 0, 0, 0, "Save environment map"); + } + uiBlockSetCol(block, BUTGREY); + uiDefIDPoinBut(block, test_obpoin_but, B_ENV_OB, "Ob:", 350,95,206,24, &(env->object), "Object name"); + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, REDRAWVIEW3D, "ClipSta", 350,68,122,24, &env->clipsta, 0.01, 50.0, 100, 0, "Set start value for clipping"); + uiDefButF(block, NUM, 0, "ClipEnd", 475,68,142,24, &env->clipend, 0.1, 5000.0, 1000, 0, "Set end value for clipping"); + if(env->stype!=ENV_LOAD) uiDefButI(block, NUM, B_ENV_FREE, "CubeRes", 620,68,140,24, &env->cuberes, 50, 1000.0, 0, 0, "Set the resolution in pixels"); + + uiDefButF(block, NUM, B_MATPRV, "Filter :", 558,95,201,24, &tex->filtersize, 0.1, 25.0, 0, 0, "Adjust sharpness or blurriness of the reflection"), + + uiDefBut(block, LABEL, 0, "Don't render layer:", 772,100,140,22, 0, 0.0, 0.0, 0, 0, ""); + xco= 772; + dx= 28; + dy= 26; + for(a=0; a<10; a++) { + uiDefButI(block, TOG|BIT|(a+10), 0, "",(short)(xco+a*(dx/2)), 68, (short)(dx/2), (short)(dy/2), &env->notlay, 0, 0, 0, 0, "Render this layer"); + uiDefButI(block, TOG|BIT|a, 0, "", (short)(xco+a*(dx/2)), (short)(68+dy/2), (short)(dx/2), (short)(1+dy/2), &env->notlay, 0, 0, 0, 0, "Render this layer"); + if(a==4) xco+= 5; + } + + } + } + + /* COLORBAND */ + uiBlockSetCol(block, BUTSALMON); + uiDefButS(block, TOG|BIT|0, B_COLORBAND, "Colorband", 923,103,102,20, &tex->flag, 0, 0, 0, 0, "Use colorband"); + if(tex->flag & TEX_COLORBAND) { + uiDefBut(block, BUT, B_ADDCOLORBAND, "Add", 1029,103,50,20, 0, 0, 0, 0, 0, "Add new colour to the colorband"); + uiDefBut(block, BUT, B_DELCOLORBAND, "Del", 1218,104,50,20, 0, 0, 0, 0, 0, "Delete the active colour"); + uiBlockSetCol(block, BUTPURPLE); + uiDefButS(block, NUM, B_REDR, "Cur:", 1082,104,132,20, &tex->coba->cur, 0.0, (float)(tex->coba->tot-1), 0, 0, "The active colour from the colorband"); + + uiDefBut(block, LABEL, B_DOCOLORBAND, "", 923,81,345,20, 0, 0, 0, 0, 0, "Colorband"); /* alleen voor event! */ + + drawcolorband(tex->coba, 923,81,345,20); + cbd= tex->coba->data + tex->coba->cur; + + uiDefButF(block, NUM, B_CALCCBAND, "Pos", 923,59,89,20, &cbd->pos, 0.0, 1.0, 10, 0, "Set the position of the active colour"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW, B_REDRAWCBAND, "E", 1013,59,20,20, &tex->coba->ipotype, 5.0, 1.0, 0, 0, "Interpolation type Ease"); + uiDefButS(block, ROW, B_REDRAWCBAND, "L", 1033,59,20,20, &tex->coba->ipotype, 5.0, 0.0, 0, 0, "Interpolation type Linear"); + uiDefButS(block, ROW, B_REDRAWCBAND, "S", 1053,59,20,20, &tex->coba->ipotype, 5.0, 2.0, 0, 0, "Interpolation type Spline"); + uiBlockSetCol(block, BUTPURPLE); + uiDefButF(block, COL, B_BANDCOL, "", 1076,59,28,20, &(cbd->r), 0, 0, 0, 0, ""); + uiDefButF(block, NUMSLI, B_REDRAWCBAND, "A ", 1107,58,163,20, &cbd->a, 0.0, 1.0, 0, 0, "Set the alpha value"); + + uiDefButF(block, NUMSLI, B_REDRAWCBAND, "R ", 923,37,116,20, &cbd->r, 0.0, 1.0, B_BANDCOL, 0, "Set the red value"); + uiDefButF(block, NUMSLI, B_REDRAWCBAND, "G ", 1042,37,111,20, &cbd->g, 0.0, 1.0, B_BANDCOL, 0, "Set the green value"); + uiDefButF(block, NUMSLI, B_REDRAWCBAND, "B ", 1156,36,115,20, &cbd->b, 0.0, 1.0, B_BANDCOL, 0, "Set the blue value"); + + } + + + /* RGB-BRICON */ + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUMSLI, B_MATPRV, "Bright", 923,11,166,20, &tex->bright, 0.0, 2.0, 0, 0, "Set the brightness of the colour or intensity of a texture"); + + uiDefButF(block, NUMSLI, B_MATPRV, "Contr", 1093,11,180,20, &tex->contrast, 0.01, 2.0, 0, 0, "Set the contrast of the colour or intensity of a texture"); + + if((tex->flag & TEX_COLORBAND)==0) { + uiDefButF(block, NUMSLI, B_MATPRV, "R ", 923,37,116,20, &tex->rfac, 0.0, 2.0, 0, 0, "Set the red value"); + uiDefButF(block, NUMSLI, B_MATPRV, "G ", 1042,37,111,20, &tex->gfac, 0.0, 2.0, 0, 0, "Set the green value"); + uiDefButF(block, NUMSLI, B_MATPRV, "B ", 1156,36,115,20, &tex->bfac, 0.0, 2.0, 0, 0, "Set the blue value"); + } + } + + /* PREVIEW RENDER */ + + BIF_previewdraw(G.buts); + + uiDrawBlock(block); +} + +/* ****************************** MATERIAL ************************ */ +MTex mtexcopybuf; + + +void do_matbuts(unsigned short event) +{ + static short mtexcopied=0; + Material *ma; + MTex *mtex; + + switch(event) { + case B_ACTCOL: + scrarea_queue_headredraw(curarea); + allqueue(REDRAWBUTSMAT, 0); + allqueue(REDRAWIPO, 0); + BIF_previewdraw(G.buts); + break; + case B_MATFROM: + + scrarea_queue_headredraw(curarea); + allqueue(REDRAWBUTSMAT, 0); + BIF_previewdraw(G.buts); + break; + case B_MATPRV: + /* dit event wordt ook door lamp, tex en sky gebruikt */ + BIF_preview_changed(G.buts); + break; + case B_MATPRV_DRAW: + BIF_preview_changed(G.buts); + allqueue(REDRAWBUTSMAT, 0); + break; + case B_TEXCLEAR: + ma= G.buts->lockpoin; + mtex= ma->mtex[(int) ma->texact ]; + if(mtex) { + if(mtex->tex) mtex->tex->id.us--; + MEM_freeN(mtex); + ma->mtex[ (int) ma->texact ]= 0; + allqueue(REDRAWBUTSMAT, 0); + allqueue(REDRAWOOPS, 0); + BIF_preview_changed(G.buts); + } + break; + case B_MTEXCOPY: + ma= G.buts->lockpoin; + if(ma && ma->mtex[(int)ma->texact] ) { + mtex= ma->mtex[(int)ma->texact]; + if(mtex->tex==0) { + error("No texture available"); + } + else { + memcpy(&mtexcopybuf, ma->mtex[(int)ma->texact], sizeof(MTex)); + notice("copied!"); + mtexcopied= 1; + } + } + break; + case B_MTEXPASTE: + ma= G.buts->lockpoin; + if(ma && mtexcopied && mtexcopybuf.tex) { + if(ma->mtex[(int)ma->texact]==0 ) ma->mtex[(int)ma->texact]= MEM_mallocN(sizeof(MTex), "mtex"); + memcpy(ma->mtex[(int)ma->texact], &mtexcopybuf, sizeof(MTex)); + + id_us_plus((ID *)mtexcopybuf.tex); + notice("pasted!"); + BIF_preview_changed(G.buts); + scrarea_queue_winredraw(curarea); + } + break; + case B_MATLAY: + ma= G.buts->lockpoin; + if(ma && ma->lay==0) { + ma->lay= 1; + scrarea_queue_winredraw(curarea); + } + } +} + +void matbuts(void) +{ + Object *ob; + Material *ma; + ID *id, *idn; + MTex *mtex; + uiBlock *block; + uiBut *but; + float *colpoin = NULL, min; + int rgbsel = 0, a, loos; + char str[30], *strp; + short xco; + + ob= OBACT; + if(ob==0 || ob->data==0) return; + + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + if(ob->actcol==0) ob->actcol= 1; /* ivm TOG|BIT button */ + + /* aangeven waar het materiaal aan hangt */ + uiBlockSetCol(block, BUTSALMON); + uiDefButS(block, TOG|BIT|(ob->actcol-1), B_MATFROM, "OB", 342, 195, 33, 20, &ob->colbits, 0, 0, 0, 0, "Link material to object"); + idn= ob->data; + strncpy(str, idn->name, 2); + str[2]= 0; + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOGN|BIT|(ob->actcol-1), B_MATFROM, str, 380, 195, 33, 20, &ob->colbits, 0, 0, 0, 0, "Show the block the material is linked to"); + uiBlockSetCol(block, BUTGREY); + + /* id is het blok waarvan materiaal wordt gepakt */ + if( BTST(ob->colbits, ob->actcol-1) ) id= (ID *)ob; + else id= ob->data; + + sprintf(str, "%d Mat", ob->totcol); + if(ob->totcol) min= 1.0; else min= 0.0; + uiDefButC(block, NUM, B_ACTCOL, str, 415,195,140,20, &(ob->actcol), min, (float)ob->totcol, 0, 0, "Number of materials on object / Active material"); + + uiSetButLock(id->lib!=0, "Can't edit library data"); + + strncpy(str, id->name, 2); + str[2]= ':'; str[3]= 0; + but= uiDefBut(block, TEX, B_IDNAME, str, 200,195,140,20, id->name+2, 0.0, 18.0, 0, 0, "Show the block the material is linked to"); + uiButSetFunc(but, test_idbutton_cb, id->name, NULL); + + if(ob->totcol==0) { + uiDrawBlock(block); + return; + } + + ma= give_current_material(ob, ob->actcol); + + if(ma==0) { + uiDrawBlock(block); + return; + } + uiSetButLock(ma->id.lib!=0, "Can't edit library data"); + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, ROW, REDRAWBUTSMAT, "RGB", 200,166,44,22, &(ma->colormodel), 1.0, (float)MA_RGB, 0, 0, "Create colour by red, green and blue"); + uiDefButS(block, ROW, REDRAWBUTSMAT, "HSV", 200,143,44,22, &(ma->colormodel), 1.0, (float)MA_HSV, 0, 0, "Mix colour with hue, saturation and value"); + uiDefButS(block, TOG|BIT|0, REDRAWBUTSMAT, "DYN", 200,120,44,22, &(ma->dynamode), 0.0, 0.0, 0, 0, "Adjust parameters for dynamics options"); + + if((ma->mode & MA_HALO)==0) + uiDefButF(block, NUM, 0, "Zoffset:", 200,91,174,19, &(ma->zoffs), 0.0, 10.0, 0, 0, "Give face an artificial offset"); + + if(ma->dynamode & MA_DRAW_DYNABUTS) { + uiDefButF(block, NUMSLI, 0, "Restitut ", 380,168,175,21, &ma->reflect, 0.0, 1.0, 0, 0, "Elasticity of collisions"); + uiDefButF(block, NUMSLI, 0, "Friction ", + 380,144,175,21, &ma->friction, 0.0, 100.0, 0, 0, + "Coulomb friction coefficient"); +/**/ + uiDefButF(block, NUMSLI, 0, "Fh Force ", 380,120,175,21, &ma->fh, 0.0, 1.0, 0, 0, "Upward spring force within the Fh area"); + uiDefButF(block, NUM, 0, "Fh Damp ", 260,144,120,21, &ma->xyfrict, 0.0, 1.0, 10, 0, "Damping of the Fh spring force"); + uiDefButF(block, NUM, 0, "Fh Dist ", 260,120,120,21, &ma->fhdist, 0.0, 20.0, 10, 0, "Height of the Fh area"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|1, 0, "Fh Norm", 260,168,120,21, &ma->dynamode, 0.0, 0.0, 0, 0, "Add a horizontal spring force on slopes"); + uiBlockSetCol(block, BUTGREY); + } + else { + uiDefButF(block, COL, B_MIRCOL, "", 246,143,37,45, &(ma->mirr), 0, 0, 0, 0, ""); + uiDefButF(block, COL, B_SPECCOL, "", 287,143,37,45, &(ma->specr), 0, 0, 0, 0, ""); + uiDefButF(block, COL, B_MATCOL, "", 326,143,47,45, &(ma->r), 0, 0, 0, 0, ""); + + if(ma->mode & MA_HALO) { + uiDefButC(block, ROW, REDRAWBUTSMAT, "Ring", 246,120,37,22, &(ma->rgbsel), 2.0, 2.0, 0, 0, "Mix the colour of the rings with the RGB sliders"); + uiDefButC(block, ROW, REDRAWBUTSMAT, "Line", 287,120,37,22, &(ma->rgbsel), 2.0, 1.0, 0, 0, "Mix the colour of the lines with the RGB sliders"); + uiDefButC(block, ROW, REDRAWBUTSMAT, "Halo", 326,120,47,22, &(ma->rgbsel), 2.0, 0.0, 0, 0, "Mix the colour of the halo with the RGB sliders"); + } + else { + uiDefButC(block, ROW, REDRAWBUTSMAT, "Mir", 246,120,37,22, &(ma->rgbsel), 2.0, 2.0, 0, 0, "Use mirror colour"); + uiDefButC(block, ROW, REDRAWBUTSMAT, "Spec", 287,120,37,22, &(ma->rgbsel), 2.0, 1.0, 0, 0, "Set the colour of the specularity"); + uiDefButC(block, ROW, REDRAWBUTSMAT, "Color", 326,120,47,22, &(ma->rgbsel), 2.0, 0.0, 0, 0, "Set the basic colour of the material"); + } + if(ma->rgbsel==0) {colpoin= &(ma->r); rgbsel= B_MATCOL;} + else if(ma->rgbsel==1) {colpoin= &(ma->specr); rgbsel= B_SPECCOL;} + else if(ma->rgbsel==2) {colpoin= &(ma->mirr); rgbsel= B_MIRCOL;} + + if(ma->rgbsel==0 && (ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE) && !(ma->mode & MA_HALO))); + else if(ma->colormodel==MA_HSV) { + uiBlockSetCol(block, BUTPURPLE); + uiDefButF(block, HSVSLI, B_MATPRV, "H ", 380,168,175,21, colpoin, 0.0, 0.9999, rgbsel, 0, ""); + uiBlockSetCol(block, BUTPURPLE); + uiDefButF(block, HSVSLI, B_MATPRV, "S ", 380,144,175,21, colpoin, 0.0001, 1.0, rgbsel, 0, ""); + uiBlockSetCol(block, BUTPURPLE); + uiDefButF(block, HSVSLI, B_MATPRV, "V ", 380,120,175,21, colpoin, 0.0001, 1.0, rgbsel, 0, ""); + uiBlockSetCol(block, BUTGREY); + } + else { + uiDefButF(block, NUMSLI, B_MATPRV, "R ", 380,168,175,21, colpoin, 0.0, 1.0, rgbsel, 0, ""); + uiDefButF(block, NUMSLI, B_MATPRV, "G ", 380,144,175,21, colpoin+1, 0.0, 1.0, rgbsel, 0, ""); + uiDefButF(block, NUMSLI, B_MATPRV, "B ", 380,120,175,21, colpoin+2, 0.0, 1.0, rgbsel, 0, ""); + } + } + if(ma->mode & MA_HALO) { + uiDefButF(block, NUM, B_MATPRV, "HaloSize: ", 200,70,175,18, &(ma->hasize), 0.0, 100.0, 10, 0, "Set the dimension of the halo"); + uiDefButF(block, NUMSLI, B_MATPRV, "Alpha ", 200,50,175,18, &(ma->alpha), 0.0, 1.0, 0, 0, "Set the degree of coverage"); + uiDefButS(block, NUMSLI, B_MATPRV, "Hard ", 200,30,175,18, &(ma->har), 1.0, 127.0, 0, 0, "Set the hardness of the halo"); + uiDefButF(block, NUMSLI, B_MATPRV, "Add ", 200,10,175,18, &(ma->add), 0.0, 1.0, 0, 0, "Strength of the add effect"); + + uiDefButS(block, NUM, B_MATPRV, "Rings: ", 380,90,85,18, &(ma->ringc), 0.0, 24.0, 0, 0, "Set the number of rings rendered over the basic halo"); + uiDefButS(block, NUM, B_MATPRV, "Lines: ", 465,90,90,18, &(ma->linec), 0.0, 250.0, 0, 0, "Set the number of star shaped lines rendered over the halo"); + uiDefButS(block, NUM, B_MATPRV, "Star: ", 380,70,85,18, &(ma->starc), 3.0, 50.0, 0, 0, "Set the number of points on the star shaped halo"); + uiDefButC(block, NUM, B_MATPRV, "Seed: ", 465,70,90,18, &(ma->seed1), 0.0, 255.0, 0, 0, "Use random values for ring dimension and line location"); + + uiDefButF(block, NUM, B_MATPRV, "FlareSize: ", 380,50,85,18, &(ma->flaresize), 0.1, 25.0, 10, 0, "Set the factor the flare is larger than the halo"); + uiDefButF(block, NUM, B_MATPRV, "Sub Size: ", 465,50,90,18, &(ma->subsize), 0.1, 25.0, 10, 0, "Set the dimension of the subflares, dots and circles"); + uiDefButF(block, NUM, B_MATPRV, "FlareBoost: ", 380,30,175,18, &(ma->flareboost), 0.1, 10.0, 10, 0, "Give the flare extra strength"); + uiDefButC(block, NUM, B_MATPRV, "Fl.seed: ", 380,10,85,18, &(ma->seed2), 0.0, 255.0, 0, 0, "Specify an offset in the seed table"); + uiDefButS(block, NUM, B_MATPRV, "Flares: ", 465,10,90,18, &(ma->flarec), 1.0, 32.0, 0, 0, "Set the nuber of subflares"); + + uiBlockSetCol(block, BUTBLUE); + + uiDefButI(block, TOG|BIT|15, B_MATPRV, "Flare", 571, 181, 77, 36, &(ma->mode), 0, 0, 0, 0, "Render halo as a lensflare"); + uiDefButI(block, TOG|BIT|8, B_MATPRV, "Rings", 571, 143, 77, 18, &(ma->mode), 0, 0, 0, 0, "Render rings over basic halo"); + uiDefButI(block, TOG|BIT|9, B_MATPRV, "Lines", 571, 124, 77, 18, &(ma->mode), 0, 0, 0, 0, "Render star shaped lines over the basic halo"); + uiDefButI(block, TOG|BIT|11, B_MATPRV, "Star", 571, 105, 77, 18, &(ma->mode), 0, 0, 0, 0, "Render halo as a star"); + uiDefButI(block, TOG|BIT|5, B_MATPRV_DRAW, "Halo", 571, 86, 77, 18, &(ma->mode), 0, 0, 0, 0, "Render as a halo"); + + uiDefButI(block, TOG|BIT|12, B_MATPRV, "HaloTex", 571, 67, 77, 18, &(ma->mode), 0, 0, 0, 0, "Give halo a texture"); + uiDefButI(block, TOG|BIT|13, B_MATPRV, "HaloPuno", 571, 48, 77, 18, &(ma->mode), 0, 0, 0, 0, "Use the vertex normal to specify the dimension of the halo"); + uiDefButI(block, TOG|BIT|10, B_MATPRV, "X Alpha", 571, 28, 77, 18, &(ma->mode), 0, 0, 0, 0, "Use extreme alpha"); + uiDefButI(block, TOG|BIT|14, B_MATPRV, "Shaded", 571, 10, 77, 18, &(ma->mode), 0, 0, 0, 0, "Let halo receive light"); + } + else { + uiDefButF(block, NUMSLI, B_MATPRV, "Spec ", 200,70,175,18, &(ma->spec), 0.0, 2.0, 0, 0, "Set the degree of specularity"); + uiDefButS(block, NUMSLI, B_MATPRV, "Hard ", 200,50,175,18, &(ma->har), 1.0, 255.0, 0, 0, "Set the hardness of the specularity"); + uiDefButF(block, NUMSLI, B_MATPRV, "SpTr ", 200,30,175,18, &(ma->spectra), 0.0, 1.0, 0, 0, "Make sheen areas opaque"); + uiDefButF(block, NUMSLI, B_MATPRV, "Add ", 200,10,175,18, &(ma->add), 0.0, 1.0, 0, 0, "Glow factor"); + + uiDefButF(block, NUMSLI, B_MATPRV, "Ref ", 380,70,175,18, &(ma->ref), 0.0, 1.0, 0, 0, "Set the amount of reflection"); + uiDefButF(block, NUMSLI, B_MATPRV, "Alpha ", 380,50,175,18, &(ma->alpha), 0.0, 1.0, 0, 0, "Set the amount of coverage, to make materials transparent"); + uiDefButF(block, NUMSLI, B_MATPRV, "Emit ", 380,30,175,18, &(ma->emit), 0.0, 1.0, 0, 0, "Set the amount of emitting light"); + uiDefButF(block, NUMSLI, B_MATPRV, "Amb ", 380,10,175,18, &(ma->amb), 0.0, 1.0, 0, 0, "Set the amount of global ambient color"); + /* transparent solids : exponential dropoff */ +/* uiDefButF(block, NUMSLI, B_MATPRV, "K ", 380,-10,175,18, &(ma->kfac), 0.0, 10.0, 0, 0, ""); */ + + uiBlockSetCol(block, BUTBLUE); + + uiDefButI(block, TOG|BIT|0, 0, "Traceable", 571,200,77,18, &(ma->mode), 0, 0, 0, 0, "Make material visible for shadow lamps"); + uiDefButI(block, TOG|BIT|1, 0, "Shadow", 571,181,77,18, &(ma->mode), 0, 0, 0, 0, "Enable material for shadows"); + uiDefButI(block, TOG|BIT|2, B_MATPRV, "Shadeless", 571, 162, 77, 18, &(ma->mode), 0, 0, 0, 0, "Make material insensitive to light or shadow"); + uiDefButI(block, TOG|BIT|3, 0, "Wire", 571, 143, 77, 18, &(ma->mode), 0, 0, 0, 0, "Render only the edges of faces"); + uiDefButI(block, TOG|BIT|4, B_REDR, "VCol Light", 571, 124, 77, 18, &(ma->mode), 0, 0, 0, 0, "Add vertex colours as extra light"); + uiDefButI(block, TOG|BIT|7, B_REDR, "VCol Paint", 571,105, 77, 18, &(ma->mode), 0, 0, 0, 0, "Replace basic colours with vertex colours"); + uiDefButI(block, TOG|BIT|5, B_MATPRV_DRAW, "Halo",571, 86, 77, 18, &(ma->mode), 0, 0, 0, 0, "Render as a halo"); + uiDefButI(block, TOG|BIT|6, 0, "ZTransp", 571, 67, 77, 18, &(ma->mode), 0, 0, 0, 0, "Z-Buffer transparent faces"); + uiDefButI(block, TOG|BIT|8, 0, "ZInvert", 571, 48, 77, 18, &(ma->mode), 0, 0, 0, 0, "Render with inverted Z Buffer"); + uiDefButI(block, TOG|BIT|9, 0, "Env", 571, 29, 77, 18, &(ma->mode), 0, 0, 0, 0, "Do not render material"); + uiDefButI(block, TOG|BIT|10, 0, "OnlyShadow", 571, 10, 77, 18, &(ma->mode), 0, 0, 0, 0, "Let alpha be determined on the degree of shadow"); + /* transparent solids */ +/* uiDefButI(block, TOG|BIT|0, 0, "Transp", 571,-10, 77, 18, &(ma->mode2), 0, 0, 0, 0, ""); */ + + uiDefButI(block, TOG|BIT|14, 0, "No Mist", 477,95,77,18, &(ma->mode), 0, 0, 0, 0, "Set the material insensitive to mist"); + uiDefButI(block, TOG|BIT|11, B_REDR, "TexFace", 398,95,77,18, &(ma->mode), 0, 0, 0, 0, "UV-Editor assigned texture gives color and texture info for the faces"); + } + /* PREVIEW RENDER */ + + BIF_previewdraw(G.buts); + + uiDefIconButC(block, ROW, B_MATPRV, ICON_MATPLANE, 10,195,25,20, &(ma->pr_type), 10, 0, 0, 0, ""); + uiDefIconButC(block, ROW, B_MATPRV, ICON_MATSPHERE, 35,195,25,20, &(ma->pr_type), 10, 1, 0, 0, ""); + uiDefIconButC(block, ROW, B_MATPRV, ICON_MATCUBE, 60,195,25,20, &(ma->pr_type), 10, 2, 0, 0, ""); + + uiDefIconButS(block, ICONTOG|BIT|0, B_MATPRV, ICON_TRANSP_HLT, 95,195,25,20, &(ma->pr_back), 0, 0, 0, 0, ""); + + uiDefIconBut(block, BUT, B_MATPRV, ICON_EYE, 159,195,30,20, 0, 0, 0, 0, 0, ""); + + /* TEX CHANNELS */ + uiBlockSetCol(block, BUTGREY); + xco= 665; + for(a= 0; a<8; a++) { + mtex= ma->mtex[a]; + if(mtex && mtex->tex) splitIDname(mtex->tex->id.name+2, str, &loos); + else strcpy(str, ""); + str[10]= 0; + uiDefButC(block, ROW, B_MATPRV_DRAW, str, xco, 195, 63, 20, &(ma->texact), 3.0, (float)a, 0, 0, ""); + xco+= 65; + } + + uiDefIconBut(block, BUT, B_MTEXCOPY, ICON_COPYUP, (short)xco,195,20,21, 0, 0, 0, 0, 0, "Copy the material settings to the buffer"); + uiDefIconBut(block, BUT, B_MTEXPASTE, ICON_PASTEUP, (short)(xco+20),195,20,21, 0, 0, 0, 0, 0, "Paste the material settings from the buffer"); + + + uiBlockSetCol(block, BUTGREEN); + uiDefButC(block, TOG, B_MATPRV, "SepT", (short)(xco+40), 195, 40, 20, &(ma->septex), 0, 0, 0, 0, "Render only use active texture channel"); + uiBlockSetCol(block, BUTGREY); + + mtex= ma->mtex[ ma->texact ]; + if(mtex==0) { + mtex= &emptytex; + default_mtex(mtex); + } + + /* TEXCO */ + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW, B_MATPRV, "Object", 694,166,49,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Use linked object's coordinates for texture coordinates"); + uiDefIDPoinBut(block, test_obpoin_but, B_MATPRV, "", 745,166,133,18, &(mtex->object), ""); + uiDefButS(block, ROW, B_MATPRV, "UV", 664,166,29,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Use UV coordinates for texture coordinates"); + + uiDefButS(block, ROW, B_MATPRV, "Glob", 665,146,35,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Use global coordinates for the texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Orco", 701,146,38,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Use the original coordinates of the mesh"); + uiDefButS(block, ROW, B_MATPRV, "Stick", 739,146,38,18, &(mtex->texco), 4.0, (float)TEXCO_STICKY, 0, 0, "Use mesh sticky coordaintes for the texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Win", 779,146,31,18, &(mtex->texco), 4.0, (float)TEXCO_WINDOW, 0, 0, "Use screen coordinates as texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Nor", 811,146,32,18, &(mtex->texco), 4.0, (float)TEXCO_NORM, 0, 0, "Use normal vector as texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Refl", 844,146,33,18, &(mtex->texco), 4.0, (float)TEXCO_REFL, 0, 0, "Use reflection vector as texture coordinates"); + + uiBlockSetCol(block, BUTGREY); + + /* COORDS */ + uiDefButC(block, ROW, B_MATPRV, "Flat", 666,114,48,18, &(mtex->mapping), 5.0, (float)MTEX_FLAT, 0, 0, "Map X and Y coordinates directly"); + uiDefButC(block, ROW, B_MATPRV, "Cube", 717,114,50,18, &(mtex->mapping), 5.0, (float)MTEX_CUBE, 0, 0, "Map using the normal vector"); + uiDefButC(block, ROW, B_MATPRV, "Tube", 666,94,48,18, &(mtex->mapping), 5.0, (float)MTEX_TUBE, 0, 0, "Map with Z as central axis (tube-like)"); + uiDefButC(block, ROW, B_MATPRV, "Sphe", 716,94,50,18, &(mtex->mapping), 5.0, (float)MTEX_SPHERE, 0, 0, "Map with Z as central axis (sphere-like)"); + + xco= 665; + for(a=0; a<4; a++) { + if(a==0) strcpy(str, ""); + else if(a==1) strcpy(str, "X"); + else if(a==2) strcpy(str, "Y"); + else strcpy(str, "Z"); + + uiDefButC(block, ROW, B_MATPRV, str, (short)xco, 50, 24, 18, &(mtex->projx), 6.0, (float)a, 0, 0, ""); + uiDefButC(block, ROW, B_MATPRV, str, (short)xco, 30, 24, 18, &(mtex->projy), 7.0, (float)a, 0, 0, ""); + uiDefButC(block, ROW, B_MATPRV, str, (short)xco, 10, 24, 18, &(mtex->projz), 8.0, (float)a, 0, 0, ""); + xco+= 26; + } + + uiDefButF(block, NUM, B_MATPRV, "ofsX", 778,114,100,18, mtex->ofs, -10.0, 10.0, 10, 0, "Fine tune X coordinate"); + uiDefButF(block, NUM, B_MATPRV, "ofsY", 778,94,100,18, mtex->ofs+1, -10.0, 10.0, 10, 0, "Fine tune Y coordinate"); + uiDefButF(block, NUM, B_MATPRV, "ofsZ", 778,74,100,18, mtex->ofs+2, -10.0, 10.0, 10, 0, "Fine tune Z coordinate"); + uiDefButF(block, NUM, B_MATPRV, "sizeX", 778,50,100,18, mtex->size, -100.0, 100.0, 10, 0, "Set an extra scaling for the texture coordinate"); + uiDefButF(block, NUM, B_MATPRV, "sizeY", 778,30,100,18, mtex->size+1, -100.0, 100.0, 10, 0, "Set an extra scaling for the texture coordinate"); + uiDefButF(block, NUM, B_MATPRV, "sizeZ", 778,10,100,18, mtex->size+2, -100.0, 100.0, 10, 0, "Set an extra scaling for the texture coordinate"); + + /* TEXTUREBLOK SELECT */ + if(G.main->tex.first==0) + id= NULL; + else + id= (ID*) mtex->tex; + IDnames_to_pupstring(&strp, NULL, "ADD NEW %x32767", &(G.main->tex), id, &(G.buts->texnr)); + uiDefButS(block, MENU, B_EXTEXBROWSE, strp, 900,146,20,19, &(G.buts->texnr), 0, 0, 0, 0, "The name of the texture"); + MEM_freeN(strp); + + if(id) { + uiDefBut(block, TEX, B_IDNAME, "TE:", 900,166,163,19, id->name+2, 0.0, 18.0, 0, 0, "The name of the texture block"); + sprintf(str, "%d", id->us); + uiDefBut(block, BUT, 0, str, 996,146,21,19, 0, 0, 0, 0, 0, ""); + uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 1041,146,21,19, 0, 0, 0, 0, 0, "Auto-assign name to texture"); + if(id->lib) { + if(ma->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB, 1019,146,21,19, 0, 0, 0, 0, 0, ""); + else uiDefIconBut(block, BUT, 0, ICON_PARLIB, 1019,146,21,19, 0, 0, 0, 0, 0, ""); + } + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_TEXCLEAR, "Clear", 922, 146, 72, 19, 0, 0, 0, 0, 0, "Erase link to datablock"); + uiBlockSetCol(block, BUTGREY); + } + + /* TEXTURE OUTPUT */ + uiDefButS(block, TOG|BIT|1, B_MATPRV, "Stencil", 900,114,52,18, &(mtex->texflag), 0, 0, 0, 0, "Set the mapping to stencil mode"); + uiDefButS(block, TOG|BIT|2, B_MATPRV, "Neg", 954,114,38,18, &(mtex->texflag), 0, 0, 0, 0, "Reverse the effect of the texture"); + uiDefButS(block, TOG|BIT|0, B_MATPRV, "No RGB", 994,114,69,18, &(mtex->texflag), 0, 0, 0, 0, "Use an RGB texture as an intensity texture"); + + uiDefButF(block, COL, B_MTEXCOL, "", 900,100,163,12, &(mtex->r), 0, 0, 0, 0, "Browse datablocks"); + + if(ma->colormodel==MA_HSV) { + uiBlockSetCol(block, BUTPURPLE); + uiDefButF(block, HSVSLI, B_MATPRV, "H ", 900,80,163,18, &(mtex->r), 0.0, 0.9999, B_MTEXCOL, 0, ""); + uiBlockSetCol(block, BUTPURPLE); + uiDefButF(block, HSVSLI, B_MATPRV, "S ", 900,60,163,18, &(mtex->r), 0.0001, 1.0, B_MTEXCOL, 0, ""); + uiBlockSetCol(block, BUTPURPLE); + uiDefButF(block, HSVSLI, B_MATPRV, "V ", 900,40,163,18, &(mtex->r), 0.0001, 1.0, B_MTEXCOL, 0, ""); + uiBlockSetCol(block, BUTGREY); + } + else { + uiDefButF(block, NUMSLI, B_MATPRV, "R ", 900,80,163,18, &(mtex->r), 0.0, 1.0, B_MTEXCOL, 0, "Set the amount of red the intensity texture blends with"); + uiDefButF(block, NUMSLI, B_MATPRV, "G ", 900,60,163,18, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "Set the amount of green the intensity texture blends with"); + uiDefButF(block, NUMSLI, B_MATPRV, "B ", 900,40,163,18, &(mtex->b), 0.0, 1.0, B_MTEXCOL, 0, "Set the amount of blue the intensity texture blends with"); + } + + uiDefButF(block, NUMSLI, B_MATPRV, "DVar ", 900,10,163,18, &(mtex->def_var), 0.0, 1.0, 0, 0, "Set the value the texture blends with the current value"); + + /* MAP TO */ + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|0, B_MATPRV, "Col", 1087,166,35,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture affect basic colour of the material"); + uiDefButS(block, TOG3|BIT|1, B_MATPRV, "Nor", 1126,166,31,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture affect the rendered normal"); + uiDefButS(block, TOG|BIT|2, B_MATPRV, "Csp", 1160,166,34,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture affect the specularity colour"); + uiDefButS(block, TOG|BIT|3, B_MATPRV, "Cmir", 1196,166,35,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture affext the mirror colour"); + uiDefButS(block, TOG3|BIT|4, B_MATPRV, "Ref", 1234,166,31,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture affect the value of the materials reflectivity"); + uiDefButS(block, TOG3|BIT|5, B_MATPRV, "Spec", 1087,146,36,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture affect the value of specularity"); + uiDefButS(block, TOG3|BIT|8, B_MATPRV, "Hard", 1126,146,44,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture affect the hardness value"); + uiDefButS(block, TOG3|BIT|7, B_MATPRV, "Alpha", 1172,146,45,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture affect the alpha value"); + uiDefButS(block, TOG3|BIT|6, B_MATPRV, "Emit", 1220,146,45,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture affect the emit value"); + +/* uiDefButS(block, TOG|BIT|3, B_MATPRV, "Alpha Mix",1087,114,100,18, &(mtex->texflag), 0, 0, 0, 0); ,""*/ + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, ROW, B_MATPRV, "Mix", 1087,94,48,18, &(mtex->blendtype), 9.0, (float)MTEX_BLEND, 0, 0, "The texture blends the values or colour"); + uiDefButS(block, ROW, B_MATPRV, "Mul", 1136,94,44,18, &(mtex->blendtype), 9.0, (float)MTEX_MUL, 0, 0, "The texture multiplies the values or colour"); + uiDefButS(block, ROW, B_MATPRV, "Add", 1182,94,41,18, &(mtex->blendtype), 9.0, (float)MTEX_ADD, 0, 0, "The texture adds the values or colour"); + uiDefButS(block, ROW, B_MATPRV, "Sub", 1226,94,40,18, &(mtex->blendtype), 9.0, (float)MTEX_SUB, 0, 0, "The texture subtracts the values or colour"); + + uiDefButF(block, NUMSLI, B_MATPRV, "Col ", 1087,50,179,18, &(mtex->colfac), 0.0, 1.0, 0, 0, "Set the amount the texture affects colour"); + uiDefButF(block, NUMSLI, B_MATPRV, "Nor ", 1087,30,179,18, &(mtex->norfac), 0.0, 5.0, 0, 0, "Set the amount the texture affects the normal"); + uiDefButF(block, NUMSLI, B_MATPRV, "Var ", 1087,10,179,18, &(mtex->varfac), 0.0, 1.0, 0, 0, "Set the amount the texture affects a value"); + + uiDrawBlock(block); +} + + +/* ************************ SOUND *************************** */ +static void load_new_sample(char *str) /* called from fileselect */ +{ + char name[FILE_MAXDIR+FILE_MAXFILE]; + bSound *sound; + bSample *sample, *newsample; + + sound = G.buts->lockpoin; + + if (sound) { + // save values + sample = sound->sample; + strcpy(name, sound->sample->name); + + strcpy(sound->name, str); + sound_set_sample(sound, NULL); + sound_initialize_sample(sound); + + if (sound->sample->type == SAMPLE_INVALID) { + error("Not a valid sample: %s", str); + + newsample = sound->sample; + + // restore values + strcpy(sound->name, name); + sound_set_sample(sound, sample); + + // remove invalid sample + + sound_free_sample(newsample); + BLI_remlink(samples, newsample); + MEM_freeN(newsample); + } + } + + allqueue(REDRAWBUTSSOUND, 0); + if (curarea) BIF_preview_changed(G.buts); +} + + +void do_soundbuts(unsigned short event) +{ + char name[FILE_MAXDIR+FILE_MAXFILE]; + bSound *sound; + bSample *sample; + bSound* tempsound; + ID *id; + + sound = G.buts->lockpoin; + + switch(event) + { + case B_SOUND_REDRAW: + { + allqueue(REDRAWBUTSSOUND, 0); + break; + } + case B_SOUND_LOAD_SAMPLE: + { + if (sound) strcpy(name, sound->name); + else strcpy(name, U.sounddir); + + activate_fileselect(FILE_SPECIAL, "SELECT WAV FILE", name, load_new_sample); + break; + } + case B_SOUND_PLAY_SAMPLE: + { + if (sound) + { + if (sound->sample->type != SAMPLE_INVALID) + { + sound_play_sound(sound); + allqueue(REDRAWBUTSSOUND, 0); + } + } + break; + } + case B_SOUND_MENU_SAMPLE: + { + if (G.buts->menunr == -2) { + if (sound) { + activate_databrowse((ID *)sound->sample, ID_SAMPLE, 0, B_SOUND_MENU_SAMPLE, &G.buts->menunr, do_soundbuts); + } + } else if (G.buts->menunr > 0) { + sample = BLI_findlink(samples, G.buts->menunr - 1); + if (sample && sound) { + BLI_strncpy(sound->name, sample->name, sizeof(sound->name)); + sound_set_sample(sound, sample); + do_soundbuts(B_SOUND_REDRAW); + } + } + + break; + } + case B_SOUND_NAME_SAMPLE: + { + load_new_sample(sound->name); + break; + } + case B_SOUND_UNPACK_SAMPLE: + if(sound && sound->sample) { + sample = sound->sample; + + if (sample->packedfile) { + if (G.fileflags & G_AUTOPACK) { + if (okee("Disable AutoPack ?")) { + G.fileflags &= ~G_AUTOPACK; + } + } + + if ((G.fileflags & G_AUTOPACK) == 0) { + unpackSample(sample, PF_ASK); + } + } else { + sound_set_packedfile(sample, newPackedFile(sample->name)); + } + allqueue(REDRAWHEADERS, 0); + do_soundbuts(B_SOUND_REDRAW); + } + break; + case B_SOUND_COPY_SOUND: + { + if (sound) + { + tempsound = sound_make_copy(sound); + sound = tempsound; + id = &sound->id; + G.buts->lockpoin = (bSound*)id; + do_soundbuts(B_SOUND_REDRAW); + } + break; + } + case B_SOUND_LOOPSTART: + { +#ifdef SOUND_UNDER_DEVELOPMENT +/* if (sound->loopstart > sound->loopend) + sound->loopstart = sound->loopend;*/ +#endif + allqueue(REDRAWBUTSSOUND, 0); + BIF_preview_changed(G.buts); + break; + } + case B_SOUND_LOOPEND: + { +#ifdef SOUND_UNDER_DEVELOPMENT +/* if (sound->loopend < sound->loopstart) + sound->loopend = sound->loopstart;*/ +#endif + allqueue(REDRAWBUTSSOUND, 0); + BIF_preview_changed(G.buts); + break; + } + + default: + { + if (G.f & G_DEBUG) + { + printf("do_soundbuts: unhandled event %d\n", event); + } + break; + } + } +} + + +void soundbuts(void) +{ + short xco, yco, xcostart = 20; + bSound *sound; + bSample *sample; + uiBlock *block; + char *strp, str[32]; + ID *id; + char ch[20]; + char sampleinfo[200]; + char mixrateinfo[50]; + int mixrate; + + sound = G.buts->lockpoin; + yco = 195; + + if (sound) + { + sound_initialize_sample(sound); + + sample = sound->sample; + + xco = xcostart; + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + uiSetButLock(sound->id.lib!=0, "Can't edit library data"); + + /* sound settings ------------------------------------------------------------------ */ + + uiDefBut(block, LABEL, 0, "Sound settings:",xco,yco,195,20, 0, 0, 0, 0, 0, ""); + + yco -= 30; + uiBlockSetCol(block, BUTGREEN); + uiDefBut(block, BUT, B_SOUND_PLAY_SAMPLE, "Play", xco, yco, 195, 24, 0, 0.0, 0, 0, 0, + "Playback sample using settings below"); + + uiBlockSetCol(block, BUTGREY); + xco += 225; + + if (sound->sample && sound->sample->len) + { + if (sound->sample->channels == 1) + strcpy(ch, "Mono"); + else if (sound->sample->channels == 2) + strcpy(ch, "Stereo"); + else + strcpy(ch, "Unknown"); + + uiDefBut(block, LABEL, 0, "Sample: ",xco,yco,195,20, 0, 0, 0, 0, 0, ""); + xco +=55; + sprintf(sampleinfo, "%s, %d bit, %d Hz, %d samples", ch, sound->sample->bits, sound->sample->rate, sound->sample->len); + uiDefBut(block, LABEL, 0, sampleinfo,xco,yco,295,20, 0, 0, 0, 0, 0, ""); + } + else + { + uiDefBut(block, LABEL, 0, "No sample info available.",xco,yco,195,20, 0, 0, 0, 0, 0, ""); + xco +=55; + } + + xco += 314; + uiDefBut(block, BUT, B_SOUND_COPY_SOUND, "Copy sound", + xco,yco,95,24, 0, 0, 0, 0, 0, "Make a copy of the current sound"); + /* + xco += 25; + if (sample->channels > 1) + { + xco += 100; + uiDefButC(block, ROW, B_SOUND_REDRAW, "Left", xco, yco, 95, 20, &sound->channels, 1.0, (float)SOUND_CHANNELS_LEFT, 0, 0, ""); + xco += 100; + uiDefButC(block, ROW, B_SOUND_REDRAW, "Stereo", xco, yco, 95, 20, &sound->channels, 1.0, (float)SOUND_CHANNELS_STEREO, 0, 0, ""); + xco += 100; + uiDefButC(block, ROW, B_SOUND_REDRAW, "Right", xco, yco, 95, 20, &sound->channels, 1.0, (float)SOUND_CHANNELS_RIGHT, 0, 0, ""); + } + */ + + xco = xcostart; + yco -= 30; + uiDefBut(block, BUT, B_SOUND_LOAD_SAMPLE, "Load sample", + xco, yco,195,24, 0, 0, 0, 0, 0, "Load a different sample"); + + uiBlockSetCol(block, BUTGREY); + + id= (ID *)sound->sample; + IDnames_to_pupstring(&strp, NULL, NULL, samples, id, &(G.buts->menunr)); + if (strp[0]) { + xco += 200; + uiDefButS(block, MENU, B_SOUND_MENU_SAMPLE, strp,xco,yco,23,24, &(G.buts->menunr), 0, 0, 0, 0, "Select another loaded sample"); + } + MEM_freeN(strp); + + xco += 25; + uiDefBut(block, TEX, B_SOUND_NAME_SAMPLE, "",xco,yco,412,24, sound->name, 0.0, 79.0, 0, 0, "The sample used by this sound"); + + sprintf(str, "1"); + // sprintf(str, "%d", tex->ima->id.us); + xco += 415; + uiDefBut(block, BUT, B_SOUND_UNLINK_SAMPLE, str,xco,yco,23,24, 0, 0, 0, 0, 0, "The number of users"); + + if (sound->sample->packedfile) + packdummy = 1; + else + packdummy = 0; + + xco += 25; + uiDefIconButI(block, TOG|BIT|0, B_SOUND_UNPACK_SAMPLE, ICON_PACKAGE, + xco, yco,24,24, &packdummy, 0, 0, 0, 0,"Pack/Unpack this sample"); + /* + xco += 25; + uiDefBut(block, BUT, B_SOUND_RELOAD_SAMPLE, "Reload",xco, yco,68,24, 0, 0, 0, 0, 0, ""); + */ + /* parameters settings ------------------------------------------------------------------ */ + + xco = xcostart; + yco -= 45; + uiDefBut(block, LABEL, 0, "Parameter settings:",xco,yco,195,20, 0, 0, 0, 0, 0, ""); + + yco -= 30; + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Volume: ", + xco,yco,195,24,&sound->volume, 0.0, 1.0, 0, 0, "Set the volume of this sound"); + + xco += 200; + uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Pitch: ", + xco,yco,195,24,&sound->pitch, -12.0, 12.0, 0, 0, "Set the pitch of this sound"); + + xco = xcostart; + yco -= 30; + uiBlockSetCol(block, BUTSALMON); + uiDefButI(block, TOG|BIT|SOUND_FLAGS_LOOP_BIT, B_SOUND_REDRAW, "Loop", + xco, yco, 95, 24, &sound->flags, 0.0, 0.0, 0, 0,"Toggle between looping on/off"); + + if (sound->flags & SOUND_FLAGS_LOOP && LICENSE_KEY_VALID) + { + xco += 100; + uiDefButI(block, TOG|BIT|SOUND_FLAGS_BIDIRECTIONAL_LOOP_BIT, B_SOUND_REDRAW, "Ping Pong", + xco, yco, 95, 24, &sound->flags, 0.0, 0.0, 0, 0,"Toggle between A->B and A->B->A looping"); + +#ifdef SOUND_UNDER_DEVELOPMENT +/* uiBlockSetCol(block, REDALERT); + xco += 100; + uiDefButI(block, NUM, B_SOUND_LOOPSTART, "loopstart: ", xco,yco,195,24, + &sound->loopstart, 0, sound->sample->len, 0, 0, "Set the startpoint for the loop of this sound"); + + xco += 200; + uiDefButI(block, NUM, B_SOUND_LOOPEND, "loopend: ",xco,yco,195,24, + &sound->loopend, 0, sound->sample->len, 0, 0, "Set the endpoint for the loop of this sound"); +*/ +#endif + } + +#ifdef SOUND_UNDER_DEVELOPMENT + xco = xcostart; + yco -= 30; + uiDefButI(block, TOG|BIT|SOUND_FLAGS_PRIORITY_BIT, B_SOUND_REDRAW, "Priority", + xco, yco, 95, 24, &sound->flags, 0.0, 0.0, 0, 0,"Toggle between high and low priority"); +#endif + + /* 2D & 3D settings ------------------------------------------------------------------ */ + + uiBlockSetCol(block, BUTGREY); + if (sound->sample->channels == 1) + { + xco = xcostart; + yco -= 30; + uiDefButI(block, TOG|BIT|SOUND_FLAGS_3D_BIT, B_SOUND_REDRAW, "3D Sound", + xco, yco, 95, 24, &sound->flags, 0, 0, 0, 0, "Turns 3D sound on"); + + if (sound->flags & SOUND_FLAGS_3D) + { + xco = xcostart; + yco -= 30; + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, LABEL, 0, "3D surround settings:",xco,yco,195,20, 0, 0, 0, 0, 0, ""); + uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Scale: ", + xco,(short)(yco-=30),195,24,&sound->attenuation, 0.0, 5.0, 1.0, 0, "Sets the world-scaling factor for this sound"); + + /* + xco += 200; + uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Distance: ", + xco,yco,195,20,&sound->distance, 0.0, 100.0, 1.0, 0, "Reference distance: sets the distance at which the listener will experience gain"); + xco -= 200; + yco -= 30; + uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Minvol: ", + xco,yco,195,20,&sound->min_gain, 0.0, 1.0, 1.0, 0, "Minimal volume: sets the lower threshold for the gain of this sound"); + xco += 200; + uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Maxvol: ", + xco,yco,195,20,&sound->max_gain, 0.0, 10.0, 1.0, 0, "Maximal volume: sets the upper threshold for the gain of this sound"); + */ + } + } + + /* listener settings ------------------------------------------------------------------ */ + + draw_buttons_edge(curarea->win, 740); + + xco = xcostart + 750; + yco = 195; + uiBlockSetCol(block, BUTGREY); + mixrate = sound_get_mixrate(); + sprintf(mixrateinfo, "Mixrate: %d Hz", mixrate); + uiDefBut(block, LABEL, 0, mixrateinfo, xco,yco,295,20, 0, 0, 0, 0, 0, ""); + + yco -= 30; + + uiDefBut(block, LABEL, 0, "Listener settings:",xco,yco,195,20, 0, 0, 0, 0, 0, ""); + + yco -= 30; + uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Volume: ", + xco,yco,195,24,&G.listener->gain, 0.0, 1.0, 1.0, 0, "Sets the maximum volume for the overall sound"); + + yco -= 30; + uiDefBut(block, LABEL, 0, "Doppler effect settings:",xco,yco,195,20, 0, 0, 0, 0, 0, ""); + /* + yco -= 30; + uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Scale: ", + xco,yco,195,20,&G.listener->dopplerfactor, 0.0, 10.0, 1.0, 0, "Doppler scaling: sets the scaling factor for doppler effect"); + */ + yco -= 30; + uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Doppler: ", + xco,yco,195,24,&G.listener->dopplervelocity, 0.0, 10.0, 1.0, 0, "Use this for scaling the doppler effect"); + /* + if (sound->channels != SOUND_CHANNELS_STEREO || sample->channels == 1) + { + uiBlockSetCol(block, BUTGREEN); + uiDefButI(block, TOGN|BIT|SOUND_FLAGS_FIXED_PANNING_BIT, B_SOUND_REDRAW, "3D pan", + xco, yco, 95, 20, &sound->flags, 0, 0, 0, 0, ""); + + uiBlockSetCol(block, BUTSALMON); + xco += 100; + uiDefButI(block, TOG|BIT|SOUND_FLAGS_FIXED_PANNING_BIT, B_SOUND_REDRAW, "Fixed", + xco, yco, 95, 20, &sound->flags, 0, 0, 0, 0, ""); + + uiBlockSetCol(block, BUTGREY); + if (sound->flags & SOUND_FLAGS_FIXED_PANNING) + { + xco += 100; + uiDefButF(block, NUMSLI, B_SOUND_CHANGED, "Pann: ", + xco,yco,195,20,&sound->panning, -1.0, 1.0, 0, 0, ""); + } + } + */ + uiDrawBlock(block); + } +} + +/* ************************ LAMP *************************** */ + +void do_lampbuts(unsigned short event) +{ + Lamp *la; + MTex *mtex; + + switch(event) { + case B_LAMPREDRAW: + BIF_preview_changed(G.buts); + allqueue(REDRAWVIEW3D, 0); + break; + case B_TEXCLEARLAMP: + la= G.buts->lockpoin; + mtex= la->mtex[ la->texact ]; + if(mtex) { + if(mtex->tex) mtex->tex->id.us--; + MEM_freeN(mtex); + la->mtex[ la->texact ]= 0; + allqueue(REDRAWBUTSLAMP, 0); + allqueue(REDRAWOOPS, 0); + BIF_preview_changed(G.buts); + } + break; + } + + if(event) freefastshade(); +} + + +void lampbuts(void) +{ + Object *ob; + Lamp *la; + MTex *mtex; + ID *id; + uiBlock *block; + float grid=0.0; + int loos, a; + char *strp, str[32]; + short xco; + + if(G.vd) grid= G.vd->grid; + if(grid<1.0) grid= 1.0; + + ob= OBACT; + if(ob==0) return; + if(ob->type!=OB_LAMP) return; + + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + la= ob->data; + uiSetButLock(la->id.lib!=0, "Can't edit library data"); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW,B_LAMPREDRAW,"Lamp", 317,190,61,25,&la->type,1.0,(float)LA_LOCAL, 0, 0, "Use a point light source"); + uiDefButS(block, ROW,B_LAMPREDRAW,"Spot", 379,190,59,25,&la->type,1.0,(float)LA_SPOT, 0, 0, "Restrict lamp to conical space"); + uiDefButS(block, ROW,B_LAMPREDRAW,"Sun", 439,190,58,25,&la->type,1.0,(float)LA_SUN, 0, 0, "Light shines from constant direction"); + uiDefButS(block, ROW,B_LAMPREDRAW,"Hemi", 499,190,55,25,&la->type,1.0,(float)LA_HEMI, 0, 0, "Light shines as half a sphere"); + + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM,B_LAMPREDRAW,"Dist:",611,190,104,25,&la->dist, 0.01, 5000.0, 100, 0, "Set the distance value"); + + uiBlockSetCol(block, BUTBLUE); + uiDefButS(block, TOG|BIT|3, B_MATPRV,"Quad", 203,196,100,19,&la->mode, 0, 0, 0, 0, "Use inverse quadratic proportion"); + uiDefButS(block, TOG|BIT|6, REDRAWVIEW3D,"Sphere",203,176,100,19,&la->mode, 0, 0, 0, 0, "Lamp only shines inside a sphere"); + uiDefButS(block, TOG|BIT|0, REDRAWVIEW3D, "Shadows", 203,156,100,19,&la->mode, 0, 0, 0, 0, "Let lamp produce shadows"); + uiDefButS(block, TOG|BIT|1, 0,"Halo", 203,136,100,19,&la->mode, 0, 0, 0, 0, "Render spotlights with a volumetric halo"); + uiDefButS(block, TOG|BIT|2, 0,"Layer", 203,116,100,19,&la->mode, 0, 0, 0, 0, "Illuminate objects in the same layer only"); + uiDefButS(block, TOG|BIT|4, B_MATPRV,"Negative", 203,96,100,19,&la->mode, 0, 0, 0, 0, "Cast negative light"); + uiDefButS(block, TOG|BIT|5, 0,"OnlyShadow", 203,76,100,19,&la->mode, 0, 0, 0, 0, "Render shadow only"); + uiDefButS(block, TOG|BIT|7, B_LAMPREDRAW,"Square", 203,56,100,19,&la->mode, 0, 0, 0, 0, "Use square spotbundles"); +#ifdef __SHADOW_EXP + /* move this elsewhere */ + uiDefButS(block, TOG|BIT|10, 0,"DeepShadow", 203,216,100,19,&la->mode, 0, 0, 0, 0, ""); +#endif + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, ROW,B_DIFF,"BufSi 512", 203,30,89,19, &la->bufsize,2.0,512.0, 0, 0, "Set the size of the shadow buffer"); + uiDefButS(block, ROW,B_DIFF,"768", 293,30,48,19, &la->bufsize,2.0,768.0, 0, 0, "Set the size of the shadow buffer"); + uiDefButS(block, ROW,B_DIFF,"1024", 203,10,43,19, &la->bufsize,2.0,1024.0, 0, 0, "Set the size of the shadow buffer"); + uiDefButS(block, ROW,B_DIFF,"1536", 248,10,45,19, &la->bufsize,2.0,1536.0, 0, 0, "Set the size of the shadow buffer"); + uiDefButS(block, ROW,B_DIFF,"2560", 293,10,48,19, &la->bufsize,2.0,2560.0, 0, 0, "Set the size of the shadow buffer"); + uiDefButF(block, NUM,REDRAWVIEW3D,"ClipSta:", 346,30,146,19, &la->clipsta, 0.1*grid,1000.0*grid, 10, 0, "Set the shadow map clip start"); + uiDefButF(block, NUM,REDRAWVIEW3D,"ClipEnd:", 346,9,146,19,&la->clipend, 1.0, 5000.0*grid, 100, 0, "Set the shadow map clip end"); + + uiDefButS(block, NUM,0,"Samples:", 496,30,105,19, &la->samp,1.0,16.0, 0, 0, "Number of shadow map samples"); + uiDefButS(block, NUM,0,"Halo step:", 496,10,105,19, &la->shadhalostep, 0.0, 12.0, 0, 0, "Volumetric halo sampling frequency"); + uiDefButF(block, NUM,0,"Bias:", 605,30,108,19, &la->bias, 0.01, 5.0, 1, 0, "Shadow map sampling bias"); + uiDefButF(block, NUM,0,"Soft:", 605,10,108,19, &la->soft,1.0,100.0, 100, 0, "Set the size of the shadow sample area"); + + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUMSLI,B_MATPRV,"Energy ", 520,156,195,20, &(la->energy), 0.0, 10.0, 0, 0, "Set the intensity of the light"); + + uiDefButF(block, NUMSLI,B_MATPRV,"R ", 520,128,194,20,&la->r, 0.0, 1.0, B_COLLAMP, 0, "Set the red component of the light"); + uiDefButF(block, NUMSLI,B_MATPRV,"G ", 520,108,194,20,&la->g, 0.0, 1.0, B_COLLAMP, 0, "Set the green component of the light"); + uiDefButF(block, NUMSLI,B_MATPRV,"B ", 520,88,194,20,&la->b, 0.0, 1.0, B_COLLAMP, 0, "Set the blue component of the light"); + + uiDefButF(block, COL, B_COLLAMP, "", 520,64,193,23, &la->r, 0, 0, 0, 0, ""); + + uiDefButF(block, NUMSLI,B_LAMPREDRAW,"SpotSi ",317,157,192,19,&la->spotsize, 1.0, 180.0, 0, 0, "Set the angle of the spot beam in degrees"); + uiDefButF(block, NUMSLI,B_MATPRV,"SpotBl ", 316,136,192,19,&la->spotblend, 0.0, 1.0, 0, 0, "Set the softness of the spot edge"); + uiDefButF(block, NUMSLI,B_MATPRV,"Quad1 ", 316,106,192,19,&la->att1, 0.0, 1.0, 0, 0, "Set the light intensity value 1 for a quad lamp"); + uiDefButF(block, NUMSLI,B_MATPRV,"Quad2 ", 317,86,191,19,&la->att2, 0.0, 1.0, 0, 0, "Set the light intensity value 2 for a quad lamp"); + uiDefButF(block, NUMSLI,0,"HaloInt ", 316,64,193,19,&la->haint, 0.0, 5.0, 0, 0, "Set the intensity of the spot halo"); + + + /* TEX CHANNELS */ + uiBlockSetCol(block, BUTGREY); + xco= 745; + for(a= 0; a<6; a++) { + mtex= la->mtex[a]; + if(mtex && mtex->tex) splitIDname(mtex->tex->id.name+2, str, &loos); + else strcpy(str, ""); + str[10]= 0; + uiDefButS(block, ROW, B_REDR, str, xco, 195, 83, 20, &(la->texact), 3.0, (float)a, 0, 0, ""); + xco+= 85; + } + + mtex= la->mtex[ la->texact ]; + if(mtex==0) { + mtex= &emptytex; + default_mtex(mtex); + mtex->texco= TEXCO_VIEW; + } + + /* TEXCO */ + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW, B_MATPRV, "Object", 745,146,49,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Use linked object's coordinates for texture coordinates"); + uiDefIDPoinBut(block, test_obpoin_but, B_MATPRV, "", 745,166,133,18, &(mtex->object), ""); + uiDefButS(block, ROW, B_MATPRV, "Glob", 795,146,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Generate texture coordinates from global coordinates"); + uiDefButS(block, ROW, B_MATPRV, "View", 839,146,39,18, &(mtex->texco), 4.0, (float)TEXCO_VIEW, 0, 0, "Generate texture coordinates from view coordinates"); + + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_MATPRV, "dX", 745,114,133,18, mtex->ofs, -20.0, 20.0, 10, 0, "Set the extra translation of the texture coordinate"); + uiDefButF(block, NUM, B_MATPRV, "dY", 745,94,133,18, mtex->ofs+1, -20.0, 20.0, 10, 0, "Set the extra translation of the texture coordinate"); + uiDefButF(block, NUM, B_MATPRV, "dZ", 745,74,133,18, mtex->ofs+2, -20.0, 20.0, 10, 0, "Set the extra translation of the texture coordinate"); + uiDefButF(block, NUM, B_MATPRV, "sizeX", 745,50,133,18, mtex->size, -10.0, 10.0, 10, 0, "Set the extra scaling of the texture coordinate"); + uiDefButF(block, NUM, B_MATPRV, "sizeY", 745,30,133,18, mtex->size+1, -10.0, 10.0, 10, 0, "Set the extra scaling of the texture coordinate"); + uiDefButF(block, NUM, B_MATPRV, "sizeZ", 745,10,133,18, mtex->size+2, -10.0, 10.0, 10, 0, "Set the extra scaling of the texture coordinate"); + + /* TEXTUREBLOK SELECT */ + id= (ID *)mtex->tex; + IDnames_to_pupstring(&strp, NULL, "ADD NEW %x 32767", &(G.main->tex), id, &(G.buts->texnr)); + + /* werkt niet omdat lockpoin op lamp staat, niet op texture */ + uiDefButS(block, MENU, B_LTEXBROWSE, strp, 900,146,20,19, &(G.buts->texnr), 0, 0, 0, 0, "Select an existing texture, or create new"); + MEM_freeN(strp); + + if(id) { + uiDefBut(block, TEX, B_IDNAME, "TE:", 900,166,163,19, id->name+2, 0.0, 18.0, 0, 0, "Name of the texture block"); + sprintf(str, "%d", id->us); + uiDefBut(block, BUT, 0, str, 996,146,21,19, 0, 0, 0, 0, 0, "Select an existing texture, or create new"); + uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 1041,146,21,19, 0, 0, 0, 0, 0, "Auto assign a name to the texture"); + if(id->lib) { + if(la->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB, 1019,146,21,19, 0, 0, 0, 0, 0, ""); + else uiDefIconBut(block, BUT, 0, ICON_PARLIB, 1019,146,21,19, 0, 0, 0, 0, 0, ""); + } + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_TEXCLEARLAMP, "Clear", 922, 146, 72, 19, 0, 0, 0, 0, 0, "Erase link to texture"); + uiBlockSetCol(block, BUTGREY); + } + + /* TEXTURE OUTPUT */ + uiDefButS(block, TOG|BIT|1, B_MATPRV, "Stencil", 900,114,52,18, &(mtex->texflag), 0, 0, 0, 0, "Set the mapping to stencil mode"); + uiDefButS(block, TOG|BIT|2, B_MATPRV, "Neg", 954,114,38,18, &(mtex->texflag), 0, 0, 0, 0, "Apply the inverse of the texture"); + uiDefButS(block, TOG|BIT|0, B_MATPRV, "RGBtoInt", 994,114,69,18, &(mtex->texflag), 0, 0, 0, 0, "Use an RGB texture as an intensity texture"); + + uiDefButF(block, COL, B_MTEXCOL, "", 900,100,163,12, &(mtex->r), 0, 0, 0, 0, ""); + uiDefButF(block, NUMSLI, B_MATPRV, "R ", 900,80,163,18, &(mtex->r), 0.0, 1.0, B_MTEXCOL, 0, "Set the red component of the intensity texture to blend with"); + uiDefButF(block, NUMSLI, B_MATPRV, "G ", 900,60,163,18, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "Set the green component of the intensity texture to blend with"); + uiDefButF(block, NUMSLI, B_MATPRV, "B ", 900,40,163,18, &(mtex->b), 0.0, 1.0, B_MTEXCOL, 0, "Set the blue component of the intensity texture to blend with"); + uiDefButF(block, NUMSLI, B_MATPRV, "DVar ", 900,10,163,18, &(mtex->def_var), 0.0, 1.0, 0, 0, "Set the value the texture blends with"); + + /* MAP TO */ + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|0, B_MATPRV, "Col", 1087,166,81,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture affect the colour of the lamp"); + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, ROW, B_MATPRV, "Blend", 1087,114,48,18, &(mtex->blendtype), 9.0, (float)MTEX_BLEND, 0, 0, "Mix the values"); + uiDefButS(block, ROW, B_MATPRV, "Mul", 1136,114,44,18, &(mtex->blendtype), 9.0, (float)MTEX_MUL, 0, 0, "Multiply the values"); + uiDefButS(block, ROW, B_MATPRV, "Add", 1182,114,41,18, &(mtex->blendtype), 9.0, (float)MTEX_ADD, 0, 0, "Add the values"); + uiDefButS(block, ROW, B_MATPRV, "Sub", 1226,114,40,18, &(mtex->blendtype), 9.0, (float)MTEX_SUB, 0, 0, "Subtract the values"); + + uiDefButF(block, NUMSLI, B_MATPRV, "Col ", 1087,50,179,18, &(mtex->colfac), 0.0, 1.0, 0, 0, "Set the amount the texture affects the colour"); + uiDefButF(block, NUMSLI, B_MATPRV, "Nor ", 1087,30,179,18, &(mtex->norfac), 0.0, 1.0, 0, 0, "Set the amount the texture affects the normal"); + uiDefButF(block, NUMSLI, B_MATPRV, "Var ", 1087,10,179,18, &(mtex->varfac), 0.0, 1.0, 0, 0, "Set the amount the texture affects the value"); + + + BIF_previewdraw(G.buts); + + uiDrawBlock(block); +} + +/* ***************************** ANIM ************************** */ + +void do_animbuts(unsigned short event) +{ + Object *ob; + Base *base; + Effect *eff, *effn; + int type; + + ob= OBACT; + + switch(event) { + + case B_RECALCPATH: + calc_curvepath(OBACT); + allqueue(REDRAWVIEW3D, 0); + break; + case B_MUL_IPO: + scale_editipo(); + allqueue(REDRAWBUTSANIM, 0); + break; + case B_AUTOTIMEOFS: + auto_timeoffs(); + break; + case B_FRAMEMAP: + G.scene->r.framelen= G.scene->r.framapto; + G.scene->r.framelen/= G.scene->r.images; + break; + case B_NEWEFFECT: + if(ob) { + if (BLI_countlist(&ob->effect)==MAX_EFFECT) + error("Unable to add: effect limit reached"); + else + copy_act_effect(ob); + } + allqueue(REDRAWBUTSANIM, 0); + break; + case B_DELEFFECT: + if(ob==0 || ob->type!=OB_MESH) break; + eff= ob->effect.first; + while(eff) { + effn= eff->next; + if(eff->flag & SELECT) { + BLI_remlink(&ob->effect, eff); + free_effect(eff); + break; + } + eff= effn; + } + allqueue(REDRAWBUTSANIM, 0); + allqueue(REDRAWVIEW3D, 0); + break; + case B_NEXTEFFECT: + if(ob==0 || ob->type!=OB_MESH) break; + eff= ob->effect.first; + while(eff) { + if(eff->flag & SELECT) { + if(eff->next) { + eff->flag &= ~SELECT; + eff->next->flag |= SELECT; + } + break; + } + eff= eff->next; + } + allqueue(REDRAWBUTSANIM, 0); + break; + case B_PREVEFFECT: + if(ob==0 || ob->type!=OB_MESH) break; + eff= ob->effect.first; + while(eff) { + if(eff->flag & SELECT) { + if(eff->prev) { + eff->flag &= ~SELECT; + eff->prev->flag |= SELECT; + } + break; + } + eff= eff->next; + } + allqueue(REDRAWBUTSANIM, 0); + break; + case B_CHANGEEFFECT: + if(ob==0 || ob->type!=OB_MESH) break; + eff= ob->effect.first; + while(eff) { + if(eff->flag & SELECT) { + if(eff->type!=eff->buttype) { + BLI_remlink(&ob->effect, eff); + type= eff->buttype; + free_effect(eff); + eff= add_effect(type); + BLI_addtail(&ob->effect, eff); + } + break; + } + eff= eff->next; + } + allqueue(REDRAWBUTSANIM, 0); + allqueue(REDRAWVIEW3D, 0); + break; + case B_CALCEFFECT: + if(ob==0 || ob->type!=OB_MESH) break; + eff= ob->effect.first; + while(eff) { + if(eff->flag & SELECT) { + if(eff->type==EFF_PARTICLE) build_particle_system(ob); + else if(eff->type==EFF_WAVE) object_wave(ob); + } + eff= eff->next; + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSANIM, 0); + break; + case B_RECALCAL: + base= FIRSTBASE; + while(base) { + if(base->lay & G.vd->lay) { + ob= base->object; + eff= ob->effect.first; + while(eff) { + if(eff->flag & SELECT) { + if(eff->type==EFF_PARTICLE) build_particle_system(ob); + } + eff= eff->next; + } + } + base= base->next; + } + allqueue(REDRAWVIEW3D, 0); + break; + case B_SETSPEED: + set_speed_editipo(hspeed); + break; + case B_PRINTSPEED: + ob= OBACT; + if(ob) { + float vec[3]; + CFRA++; + do_ob_ipo(ob); + where_is_object(ob); + VECCOPY(vec, ob->obmat[3]); + CFRA--; + do_ob_ipo(ob); + where_is_object(ob); + VecSubf(vec, vec, ob->obmat[3]); + prspeed= Normalise(vec); + scrarea_queue_winredraw(curarea); + } + break; + case B_PRINTLEN: + ob= OBACT; + if(ob && ob->type==OB_CURVE) { + Curve *cu=ob->data; + + if(cu->path) prlen= cu->path->totdist; else prlen= -1.0; + scrarea_queue_winredraw(curarea); + } + break; + case B_RELKEY: + allspace(REMAKEIPO, 0); + allqueue(REDRAWBUTSANIM, 0); + allqueue(REDRAWIPO, 0); + break; + + default: + if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) { + ob= OBACT; + if(ob) { + int a=B_SELEFFECT; + + eff= ob->effect.first; + while(eff) { + if(event==a) eff->flag |= SELECT; + else eff->flag &= ~SELECT; + + a++; + eff= eff->next; + } + allqueue(REDRAWBUTSANIM, 0); + } + } + } +} + +void animbuts(void) +{ + Object *ob; + Mesh *me; + Lattice *lt; + Effect *eff; + Curve *cu; + ScrArea *sa; + uiBlock *block; + int a, ok; + char str[32]; + short x, y; + + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + uiDefButS(block, NUM,REDRAWSEQ,"Sta:", 320,17,93,27,&G.scene->r.sfra,1.0,18000.0, 0, 0, "Specify the start frame of the animation"); + uiDefButS(block, NUM,REDRAWSEQ,"End:", 416,17,95,27,&G.scene->r.efra,1.0,18000.0, 0, 0, "Specify the end frame of the animation"); + + uiDefButS(block, NUM,B_FRAMEMAP,"Map Old:", 320,69,93,22,&G.scene->r.framapto,1.0,900.0, 0, 0, "Specify old map value in frames"); + uiDefButS(block, NUM,B_FRAMEMAP,"Map New:", 416,69,95,22,&G.scene->r.images,1.0,900.0, 0, 0, "Specify new map value in frames"); + + uiDefButS(block, NUM, 0, "AnimSpeed:", 320,47,192,19, &G.animspeed, 1.0, 9.0, 0, 0, "Set the maximum speed of the animation"); + + ob= OBACT; + if(ob) { + + uiBlockSetCol(block, BUTGREEN); +/* uiDefButC(block, TOG|BIT|1, REDRAWVIEW3D, "Quaternions", 320,190,192,19, &ob->transflag, 0.0, 0.0, 0, 0, "Use quaternions for rotation"); */ + uiBlockSetCol(block, BUTGREY); + + uiDefButF(block, NUM, REDRAWALL, "TimeOffset:", 23,18,114,30, &ob->sf, -9000.0, 9000.0, 100, 0, "Specify an offset in frames"); + + uiBlockSetCol(block, BUTGREEN); + uiDefButC(block, TOG|BIT|0, REDRAWVIEW3D, "Draw Key", 25,144,84,19, &ob->ipoflag, 0, 0, 0, 0, "Draw object as key position"); + uiDefButC(block, TOG|BIT|1, REDRAWVIEW3D, "Draw Key Sel", 25,123,84,19, &ob->ipoflag, 0, 0, 0, 0, "Limit the drawing of object keys"); + + uiDefButC(block, TOG|BIT|2, REDRAWALL, "Offs Ob", 25,64,60,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on its own objectipo"); + uiDefButC(block, TOG|BIT|6, REDRAWALL, "Offs Par", 85,64,60,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the parent"); + uiDefButC(block, TOG|BIT|7, REDRAWALL, "Offs Parti", 145,64,60,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the particle effect"); + + uiDefButS(block, TOG|BIT|4, 0, "SlowPar", 205,64,60,20, &ob->partype, 0, 0, 0, 0, "Create a delay in the parent relationship"); + + /* uiDefButC(block, TOG|BIT|5, REDRAWALL, "Offs Path", 85,64,60,20, &ob->ipoflag, 0, 0, 0, 0); ,""*/ + /* uiDefButC(block, TOG|BIT|3, REDRAWALL, "Offs Mat", 145,64,60,20, &ob->ipoflag, 0, 0, 0, 0); ,""*/ + /* uiDefButC(block, TOG|BIT|4, REDRAWALL, "Offs VertKey", 205,64,60,20, &ob->ipoflag, 0, 0, 0, 0); ,""*/ + + + uiBlockSetCol(block, BUTGREY); + uiDefButC(block, TOG|BIT|3, REDRAWVIEW3D, "DupliFrames", 112,144,106,19, &ob->transflag, 0, 0, 0, 0, "Make copy of object for every frame"); + uiDefButC(block, TOG|BIT|4, REDRAWVIEW3D, "DupliVerts", 112,123,80,19, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all vertices"); + uiBlockSetCol(block, BUTGREEN); + uiDefButC(block, TOG|BIT|5, REDRAWVIEW3D, "Rot", 194,123,24,19, &ob->transflag, 0, 0, 0, 0, "Rotate dupli according to facenormal"); + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, NUM, REDRAWVIEW3D, "DupSta:", 220,144,93,19, &ob->dupsta, 1.0, 1500.0, 0, 0, "Specify startframe for Dupliframes"); + uiDefButS(block, NUM, REDRAWVIEW3D, "DupEnd", 315,144,93,19, &ob->dupend, 1.0, 2500.0, 0, 0, "Specify endframe for Dupliframes"); + uiDefButS(block, NUM, REDRAWVIEW3D, "DupOn:", 220,123,93,19, &ob->dupon, 1.0, 1500.0, 0, 0, ""); + uiDefButS(block, NUM, REDRAWVIEW3D, "DupOff", 315,123,93,19, &ob->dupoff, 0.0, 1500.0, 0, 0, ""); + uiBlockSetCol(block, BUTGREEN); + uiDefButC(block, TOG|BIT|6, REDRAWVIEW3D, "No Speed", 410,144,93,19, &ob->transflag, 0, 0, 0, 0, "Set dupliframes to still, regardless of frame"); + uiDefButC(block, TOG|BIT|7, REDRAWVIEW3D, "Powertrack", 410,123,93,19, &ob->transflag, 0, 0, 0, 0, "Switch objects rotation off"); + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_AUTOTIMEOFS, "Automatic Time", 140,18,104,31, 0, 0, 0, 0, 0, "Generate automatic timeoffset values for all selected frames"); + uiBlockSetCol(block, BUTGREY); + sprintf(str, "%.4f", prspeed); + uiDefBut(block, LABEL, 0, str, 247,40,63,31, 0, 1.0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_PRINTSPEED, "PrSpeed", 247,18,63,31, 0, 0, 0, 0, 0, "Print objectspeed"); + + if(ob->type==OB_MESH) { + me= ob->data; + if(me->key) { + uiDefButS(block, NUM, B_DIFF, "Slurph:", 125,101,93,19, &(me->key->slurph), -500.0, 500.0, 0, 0, ""); + uiDefButS(block, TOG, B_RELKEY, "Relative Keys", 220,100,93,19, &me->key->type, 0, 0, 0, 0, ""); + } + } + if(ob->type==OB_CURVE) { + cu= ob->data; + uiDefButS(block, NUM, B_RECALCPATH, "PathLen:", 34,100,90,19, &cu->pathlen, 1.0, 9000.0, 0, 0, ""); + /* if(cu->key==0) { */ + uiDefButS(block, TOG|BIT|3, B_RECALCPATH, "CurvePath", 125,100,90,19 , &cu->flag, 0, 0, 0, 0, ""); + uiDefButS(block, TOG|BIT|4, REDRAWVIEW3D, "CurveFollow", 216,100,90,19, &cu->flag, 0, 0, 0, 0, ""); + /* } */ + sprintf(str, "%.4f", prlen); + uiDefBut(block, LABEL, 0, str, 396,100,90,19, 0, 1.0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_PRINTLEN, "PrintLen", 306,100,90,19, 0, 0, 0, 0, 0, ""); + } + if(ob->type==OB_SURF) { + cu= ob->data; + + if(cu->key) { + /* uiDefButS(block, NUM, B_DIFF, "Slurph:", 124,100,93,19, &(cu->key->slurph), -500.0, 500.0,0,0); ,""*/ + uiDefButS(block, TOG, B_RELKEY, "Relative Keys", 220,100,93,19, &cu->key->type, 0, 0, 0, 0, ""); + } + } + if(ob->type==OB_LATTICE) { + lt= ob->data; + if(lt->key) { + uiDefButS(block, NUM, B_DIFF, "Slurph:", 124,100,93,19, &(lt->key->slurph), -500.0, 500.0, 0, 0, ""); + uiDefButS(block, TOG, B_RELKEY, "Relative Keys", 370,190,133,19, <->key->type, 0, 0, 0, 0, ""); + } + } + + uiBlockSetCol(block, BUTGREEN); + uiDefButC(block, ROW,REDRAWVIEW3D,"TrackX", 27,190,58,17, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object"); + uiDefButC(block, ROW,REDRAWVIEW3D,"Y", 85,190,19,17, &ob->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object"); + uiDefButC(block, ROW,REDRAWVIEW3D,"Z", 104,190,19,17, &ob->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object"); + uiDefButC(block, ROW,REDRAWVIEW3D,"-X", 123,190,24,17, &ob->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object"); + uiDefButC(block, ROW,REDRAWVIEW3D,"-Y", 147,190,24,17, &ob->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object"); + uiDefButC(block, ROW,REDRAWVIEW3D,"-Z", 171,190,24,17, &ob->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object"); + uiDefButC(block, ROW,REDRAWVIEW3D,"UpX", 205,190,40,17, &ob->upflag, 13.0, 0.0, 0, 0, "Specify the axis that points up"); + uiDefButC(block, ROW,REDRAWVIEW3D,"Y", 245,190,20,17, &ob->upflag, 13.0, 1.0, 0, 0, "Specify the axis that points up"); + uiDefButC(block, ROW,REDRAWVIEW3D,"Z", 265,190,19,17, &ob->upflag, 13.0, 2.0, 0, 0, "Specify the axis that points up"); + + uiBlockSetCol(block, BUTSALMON); + + /* EFFECTS */ + + draw_buttons_edge(curarea->win, 540); + draw_buttons_edge(curarea->win, 1010); + + if (ob->type == OB_MESH) { + uiDefBut(block, BUT, B_NEWEFFECT, "NEW Effect", 550,187,124,27, 0, 0, 0, 0, 0, "Create a new effect"); + uiDefBut(block, BUT, B_DELEFFECT, "Delete", 676,187,62,27, 0, 0, 0, 0, 0, "Delete the effect"); + } + + uiBlockSetCol(block, BUTGREY); + + /* select effs */ + eff= ob->effect.first; + a= 0; + while(eff) { + + x= 15 * a + 550; + y= 172; // - 12*( abs(a/10) ) ; + uiDefButS(block, TOG|BIT|0, B_SELEFFECT+a, "", x, y, 15, 12, &eff->flag, 0, 0, 0, 0, ""); + + a++; + if(a==MAX_EFFECT) break; + eff= eff->next; + } + + eff= ob->effect.first; + while(eff) { + if(eff->flag & SELECT) break; + eff= eff->next; + } + + if(eff) { + uiDefButS(block, MENU, B_CHANGEEFFECT, "Build %x0|Particles %x1|Wave %x2", 895,187,107,27, &eff->buttype, 0, 0, 0, 0, "Start building the effect"); + + if(eff->type==EFF_BUILD) { + BuildEff *bld; + + bld= (BuildEff *)eff; + + uiDefButF(block, NUM, 0, "Len:", 649,138,95,21, &bld->len, 1.0, 9000.0, 100, 0, "Specify the total time the building requires"); + uiDefButF(block, NUM, 0, "Sfra:", 746,138,94,22, &bld->sfra, 1.0, 9000.0, 100, 0, "Specify the startframe of the effect"); + } + else if(eff->type==EFF_WAVE) { + WaveEff *wav; + + wav= (WaveEff *)eff; + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|1, B_CALCEFFECT, "X", 782,135,54,23, &wav->flag, 0, 0, 0, 0, "Enable X axis"); + uiDefButS(block, TOG|BIT|2, B_CALCEFFECT, "Y", 840,135,47,23, &wav->flag, 0, 0, 0, 0, "Enable Y axis"); + uiDefButS(block, TOG|BIT|3, B_CALCEFFECT, "Cycl", 890,135,111,23, &wav->flag, 0, 0, 0, 0, "Enable cyclic wave efefct"); + + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_CALCEFFECT, "Sta x:", 550,135,113,24, &wav->startx, -100.0, 100.0, 100, 0, "Starting position for the X axis"); + uiDefButF(block, NUM, B_CALCEFFECT, "Sta y:", 665,135,104,24, &wav->starty, -100.0, 100.0, 100, 0, "Starting position for the Y axis"); + + uiDefButF(block, NUMSLI, B_CALCEFFECT, "Speed:", 550,100,216,20, &wav->speed, -2.0, 2.0, 0, 0, "Specify the wave speed"); + uiDefButF(block, NUMSLI, B_CALCEFFECT, "Heigth:", 550,80,216,20, &wav->height, -2.0, 2.0, 0, 0, "Specify the amplitude of the wave"); + uiDefButF(block, NUMSLI, B_CALCEFFECT, "Width:", 550,60,216,20, &wav->width, 0.0, 5.0, 0, 0, "Specify the width of the wave"); + uiDefButF(block, NUMSLI, B_CALCEFFECT, "Narrow:", 550,40,216,20, &wav->narrow, 0.0, 10.0, 0, 0, "Specify how narrow the wave follows"); + + uiDefButF(block, NUM, B_CALCEFFECT, "Time sta:", 780,100,219,20, &wav->timeoffs, -1000.0, 1000.0, 100, 0, "Specify startingframe of the wave"); + + uiDefButF(block, NUM, B_CALCEFFECT, "Lifetime:", 780,80,219,20, &wav->lifetime, -1000.0, 1000.0, 100, 0, "Specify the lifespan of the wave"); + uiDefButF(block, NUM, B_CALCEFFECT, "Damptime:", 780,60,219,20, &wav->damp, -1000.0, 1000.0, 100, 0, "Specify the dampingtime of the wave"); + + } + else if(eff->type==EFF_PARTICLE) { + PartEff *paf; + + paf= (PartEff *)eff; + + uiDefBut(block, BUT, B_RECALCAL, "RecalcAll", 741,187,67,27, 0, 0, 0, 0, 0, "Update the particle system"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|2, B_CALCEFFECT, "Static", 825,187,67,27, &paf->flag, 0, 0, 0, 0, "Make static particles"); + uiBlockSetCol(block, BUTGREY); + + uiDefButI(block, NUM, B_CALCEFFECT, "Tot:", 550,146,91,20, &paf->totpart, 1.0, 100000.0, 0, 0, "Set the total number of particles"); + if(paf->flag & PAF_STATIC) { + uiDefButS(block, NUM, REDRAWVIEW3D, "Step:", 644,146,84,20, &paf->staticstep, 1.0, 100.0, 10, 0, ""); + } + else { + uiDefButF(block, NUM, B_CALCEFFECT, "Sta:", 644,146,84,20, &paf->sta, -250.0, 9000.0, 100, 0, "Specify the startframe"); + uiDefButF(block, NUM, B_CALCEFFECT, "End:", 731,146,97,20, &paf->end, 1.0, 9000.0, 100, 0, "Specify the endframe"); + } + uiDefButF(block, NUM, B_CALCEFFECT, "Life:", 831,146,88,20, &paf->lifetime, 1.0, 9000.0, 100, 0, "Specify the life span of the particles"); + uiDefButI(block, NUM, B_CALCEFFECT, "Keys:", 922,146,80,20, &paf->totkey, 1.0, 32.0, 0, 0, "Specify the number of key positions"); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, NUM, B_REDR, "CurMul:", 550,124,91,20, &paf->curmult, 0.0, 3.0, 0, 0, "Multiply the particles"); + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, NUM, B_CALCEFFECT, "Mat:", 644,124,84,20, paf->mat+paf->curmult, 1.0, 8.0, 0, 0, "Specify the material used for the particles"); + uiDefButF(block, NUM, B_CALCEFFECT, "Mult:", 730,124,98,20, paf->mult+paf->curmult, 0.0, 1.0, 10, 0, "Switch particle multiplication on/off"); + uiDefButS(block, NUM, B_CALCEFFECT, "Child:", 922,124,80,20, paf->child+paf->curmult, 1.0, 600.0, 100, 0, "Specify the number of children of a particle that multiply itself"); + uiDefButF(block, NUM, B_CALCEFFECT, "Life:", 831,124,89,20, paf->life+paf->curmult, 1.0, 600.0, 100, 0, "Specify the lifespan of the next generation particles"); + + uiDefButF(block, NUM, B_CALCEFFECT, "Randlife:", 550,96,96,20, &paf->randlife, 0.0, 2.0, 10, 0, "Give the particlelife a random variation"); + uiDefButI(block, NUM, B_CALCEFFECT, "Seed:", 652,96,80,20, &paf->seed, 0.0, 255.0, 0, 0, "Set an offset in the random table"); + + uiDefButF(block, NUM, B_DIFF, "VectSize", 885,96,116,20, &paf->vectsize, 0.0, 1.0, 10, 0, "Set the speed for Vect"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|3, B_CALCEFFECT, "Face", 735,96,46,20, &paf->flag, 0, 0, 0, 0, "Emit particles also from faces"); + uiDefButS(block, TOG|BIT|1, B_CALCEFFECT, "Bspline", 782,96,54,20, &paf->flag, 0, 0, 0, 0, "Use B spline formula for particle interpolation"); + uiDefButS(block, TOG, REDRAWVIEW3D, "Vect", 837,96,45,20, &paf->stype, 0, 0, 0, 0, "Give the particles a rotation direction"); + + uiBlockSetCol(block, BUTPURPLE); + uiDefButF(block, NUM, B_CALCEFFECT, "Norm:", 550,67,96,20, &paf->normfac, -2.0, 2.0, 10, 0, "Let the mesh give the particle a starting speed"); + uiDefButF(block, NUM, B_CALCEFFECT, "Ob:", 649,67,86,20, &paf->obfac, -1.0, 1.0, 10, 0, "Let the object give the particle a starting speed"); + uiDefButF(block, NUM, B_CALCEFFECT, "Rand:", 738,67,86,20, &paf->randfac, 0.0, 2.0, 10, 0, "Give the startingspeed a random variation"); + uiDefButF(block, NUM, B_CALCEFFECT, "Tex:", 826,67,85,20, &paf->texfac, 0.0, 2.0, 10, 0, "Let the texture give the particle a starting speed"); + uiDefButF(block, NUM, B_CALCEFFECT, "Damp:", 913,67,89,20, &paf->damp, 0.0, 1.0, 10, 0, "Specify the damping factor"); + + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_CALCEFFECT, "X:", 550,31,72,20, paf->force, -1.0, 1.0, 1, 0, "Specify the X axis of a continues force"); + uiDefButF(block, NUM, B_CALCEFFECT, "Y:", 624,31,78,20, paf->force+1,-1.0, 1.0, 1, 0, "Specify the Y axis of a continues force"); + uiDefBut(block, LABEL, 0, "Force:", 550,9,72,20, 0, 1.0, 0, 0, 0, ""); + uiDefButF(block, NUM, B_CALCEFFECT, "Z:", 623,9,79,20, paf->force+2, -1.0, 1.0, 1, 0, "Specify the Z axis of a continues force"); + + uiDefBut(block, LABEL, 0, "Texture:", 722,9,74,20, 0, 1.0, 0, 0, 0, ""); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW, B_CALCEFFECT, "Int", 875,9,32,43, &paf->texmap, 14.0, 0.0, 0, 0, "Use texture intensity as a factor for texture force"); + uiDefButS(block, ROW, B_CALCEFFECT, "RGB", 911,31,45,20, &paf->texmap, 14.0, 1.0, 0, 0, "Use RGB values as a factor for particle speed"); + uiDefButS(block, ROW, B_CALCEFFECT, "Grad", 958,31,44,20, &paf->texmap, 14.0, 2.0, 0, 0, "Use texture gradient as a factor for particle speed"); + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_CALCEFFECT, "Nabla:", 911,9,91,20, &paf->nabla, 0.0001, 1.0, 1, 0, "Specify the dimension of the area for gradient calculation"); + uiDefButF(block, NUM, B_CALCEFFECT, "X:", 722,31,74,20, paf->defvec, -1.0, 1.0, 1, 0, "Specify the X axis of a force, determined by the texture"); + uiDefButF(block, NUM, B_CALCEFFECT, "Y:", 798,31,74,20, paf->defvec+1,-1.0, 1.0, 1, 0, "Specify the Y axis of a force, determined by the texture"); + uiDefButF(block, NUM, B_CALCEFFECT, "Z:", 797,9,75,20, paf->defvec+2, -1.0, 1.0, 1, 0, "Specify the Z axis of a force, determined by the texture"); + + } + } + } + + /* IPO BUTTONS ALS LAATSTE */ + ok= 0; + if(G.sipo) { + /* bestaat deze? */ + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==SPACE_IPO && sa->spacedata.first==G.sipo) break; + sa= sa->next; + } + if(sa) { + if(G.sipo->ipo && G.sipo->ipo->curve.first) ok= 1; + } + } + + uiBlockSetCol(block, BUTGREEN); + // RMGRP uiDefButC(block, ROW, B_REDR, "Ipo settings", 1020, 180, 100, 19, &G.buts->showgroup, 15.0, 0.0, 0, 0, ""); + // RMGRP uiDefButC(block, ROW, B_REDR, "Group settings", 1120, 180, 100, 19, &G.buts->showgroup, 15.0, 1.0, 0, 0, ""); + uiBlockSetCol(block, BUTGREY); + + if(ok && G.buts->showgroup==0) { + sprintf(str, "%.3f", G.sipo->v2d.tot.xmin); + uiDefBut(block, LABEL, 0, str, 1020, 140, 100, 19, 0, 0, 0, 0, 0, ""); + sprintf(str, "%.3f", G.sipo->v2d.tot.xmax); + uiDefBut(block, LABEL, 0, str, 1120, 140, 100, 19, 0, 0, 0, 0, 0, ""); + + uiDefButF(block, NUM, B_DIFF, "Xmin:", 1020, 120, 100, 19, &G.sipo->tot.xmin, -G.sipo->v2d.max[0], G.sipo->v2d.max[0], 100, 0, ""); + uiDefButF(block, NUM, B_DIFF, "Xmax:", 1120, 120, 100, 19, &G.sipo->tot.xmax, -G.sipo->v2d.max[0], G.sipo->v2d.max[0], 100, 0, ""); + + sprintf(str, "%.3f", G.sipo->v2d.tot.ymin); + uiDefBut(block, LABEL, 0, str, 1020, 100, 100, 19, 0, 0, 0, 0, 0, ""); + sprintf(str, "%.3f", G.sipo->v2d.tot.ymax); + uiDefBut(block, LABEL, 0, str, 1120, 100, 100, 19, 0, 0, 0, 0, 0, ""); + + uiDefButF(block, NUM, B_DIFF, "Ymin:", 1020, 80, 100, 19, &G.sipo->tot.ymin, -G.sipo->v2d.max[1], G.sipo->v2d.max[1], 100, 0, ""); + uiDefButF(block, NUM, B_DIFF, "Ymax:", 1120, 80, 100, 19, &G.sipo->tot.ymax, -G.sipo->v2d.max[1], G.sipo->v2d.max[1], 100, 0, ""); + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_MUL_IPO, "SET", 1220,79,50,62, 0, 0, 0, 0, 0, ""); + + + /* SPEED BUTTON */ + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_DIFF, "Speed:", 1020,23,164,28, &hspeed, 0.0, 180.0, 1, 0, ""); + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_SETSPEED, "SET", 1185,23,83,29, 0, 0, 0, 0, 0, ""); + } + + if(G.buts->showgroup && G.scene->group) { + GroupKey *gk; + short yco= 140; + + gk= G.scene->group->gkey.first; + while(gk) { + if(gk==G.scene->group->active) uiBlockSetCol(block, BUTPURPLE); + else uiBlockSetCol(block, BUTGREY); + uiDefBut(block, TEX, B_DIFF, "Name:", 1020, yco, 140, 19, &gk->name, 0.0, 31.0, 10, 0, ""); + uiDefButS(block, NUM, B_DIFF, "Sta:", 1160, yco, 60, 19, &gk->sfra, 0.0, 5000.0, 10, 0, ""); + uiDefButS(block, NUM, B_DIFF, "End:", 1220, yco, 50, 19, &gk->efra, 0.0, 5000.0, 10, 0, ""); + yco-= 20; + gk= gk->next; + } + } + + uiDrawBlock(block); +} + + + + +/* ***************************** WORLD ************************** */ + +void do_worldbuts(unsigned short event) +{ + World *wrld; + MTex *mtex; + + switch(event) { + case B_TEXCLEARWORLD: + wrld= G.buts->lockpoin; + mtex= wrld->mtex[ wrld->texact ]; + if(mtex) { + if(mtex->tex) mtex->tex->id.us--; + MEM_freeN(mtex); + wrld->mtex[ wrld->texact ]= 0; + allqueue(REDRAWBUTSWORLD, 0); + allqueue(REDRAWOOPS, 0); + BIF_preview_changed(G.buts); + } + break; + } +} + +void worldbuts(void) +{ + World *wrld; + MTex *mtex; + ID *id; + uiBlock *block; + int a, loos; + char str[30], *strp; + short xco; + + wrld= G.scene->world; + if(wrld==0) return; + + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + uiSetButLock(wrld->id.lib!=0, "Can't edit library data"); + uiBlockSetCol(block, BUTGREEN); + + uiDefButS(block, TOG|BIT|1,B_MATPRV,"Real", 286,190,71,19, &wrld->skytype, 0, 0, 0, 0, "Render background with real horizon"); + uiDefButS(block, TOG|BIT|0,B_MATPRV,"Blend", 208,190,74,19, &wrld->skytype, 0, 0, 0, 0, "Render background with natural progression"); + uiDefButS(block, TOG|BIT|2,B_MATPRV,"Paper", 361,190,71,19, &wrld->skytype, 0, 0, 0, 0, "Flatten blend or texture coordinates"); + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUMSLI,B_MATPRV,"HoR ", 200,55,175,18, &(wrld->horr), 0.0, 1.0, 0,0, "The amount of red of the horizon colour"); + uiDefButF(block, NUMSLI,B_MATPRV,"HoG ", 200,34,175,18, &(wrld->horg), 0.0, 1.0, 0,0, "The amount of green of the horizon colour"); + uiDefButF(block, NUMSLI,B_MATPRV,"HoB ", 200,13,175,18, &(wrld->horb), 0.0, 1.0, 0,0, "The amount of blue of the horizon colour"); + uiDefButF(block, NUMSLI,B_MATPRV,"ZeR ", 200,136,175,18, &(wrld->zenr), 0.0, 1.0, 0,0, "The amount of red of the zenith colour"); + uiDefButF(block, NUMSLI,B_MATPRV,"ZeG ", 200,116,175,18, &(wrld->zeng), 0.0, 1.0, 0,0, "The amount of green of the zenith colour"); + uiDefButF(block, NUMSLI,B_MATPRV,"ZeB ", 200,96,175,18, &(wrld->zenb), 0.0, 1.0, 0,0, "The amount of blue of the zenith colour"); + uiDefButF(block, NUMSLI,B_MATPRV,"AmbR ", 380,55,175,18, &(wrld->ambr), 0.0, 1.0 ,0,0, "The amount of red of the ambient colour"); + uiDefButF(block, NUMSLI,B_MATPRV,"AmbG ", 380,34,175,18, &(wrld->ambg), 0.0, 1.0 ,0,0, "The amount of red of the ambient colour"); + uiDefButF(block, NUMSLI,B_MATPRV,"AmbB ", 380,13,175,18, &(wrld->ambb), 0.0, 1.0 ,0,0, "The amount of red of the ambient colour"); + + uiDefBut(block, MENU|SHO, 1, physics_pup(), + 380,152,175,18, &wrld->pad1, 0, 0, 0, 0, "Physics Engine"); + + + /* Activity bubble */ + // uiDefButS(block, TOG|BIT|3,B_DIFF, "Do activity culling", + // 380,152,175,18, &wrld->mode, 0, 0, 0, 0, + // "Disable logic and physics for far away objects."); +/* if (wrld->mode & WO_ACTIVITY_CULLING) { */ + // uiDefButF(block, NUM,0, "Active R ", + // 380,132,175,18, &(wrld->activityBoxRadius), 0.5, 10000.0, 100.0, 0, + // "Radius for activity culling (in Manhattan length)."); +/* } */ + + /* Gravitation for the game worlds */ + uiDefButF(block, NUMSLI,0, "Grav ", + 380,112,175,18, &(wrld->gravity), 0.0, 25.0, 0, 0, + "Gravitation constant of the game world."); + + uiDefButF(block, NUMSLI,0, "Expos ", 380,92,175,18, &(wrld->exposure), 0.2, 5.0, 0, 0, "Set the lighting time, exposure"); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|0,REDRAWVIEW3D,"Mist", 571,190,100,19, &wrld->mode, 0, 0, 0, 0, "Enable mist"); + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, ROW, B_DIFF, "Qua", 571, 170, 33, 19, &wrld->mistype, 1.0, 0.0, 0, 0, "Use quadratic progression"); + uiDefButS(block, ROW, B_DIFF, "Lin", 604, 170, 33, 19, &wrld->mistype, 1.0, 1.0, 0, 0, "Use linear progression"); + uiDefButS(block, ROW, B_DIFF, "Sqr", 637, 170, 33, 19, &wrld->mistype, 1.0, 2.0, 0, 0, "Use inverse quadratic progression"); + + uiDefButF(block, NUM,REDRAWVIEW3D, "Sta:", 571,150,100,19, &wrld->miststa, 0.0, 1000.0, 10, 0, "Specify the starting distance of the mist"); + uiDefButF(block, NUM,REDRAWVIEW3D, "Di:", 571,130,100,19, &wrld->mistdist, 0.0,1000.0, 10, 00, "Specify the depth of the mist"); + uiDefButF(block, NUM,B_DIFF,"Hi:", 571,110,100,19, &wrld->misthi,0.0,100.0, 10, 0, "Specify the factor for a less dense mist with increasing height"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|1,B_DIFF, "Stars",571,90,100,19, &wrld->mode, 0, 0, 0, 0, "Enable stars"); + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM,B_DIFF,"StarDist:", 571,70,100,19, &(wrld->stardist), 2.0, 1000.0, 100, 0, "Specify the average distance between two stars"); + uiDefButF(block, NUM,B_DIFF,"MinDist:", 571,50,100,19, &(wrld->starmindist), 0.0, 1000.0, 100, 0, "Specify the minimum distance to the camera"); + uiDefButF(block, NUM,B_DIFF,"Size:", 571,30,100,19, &(wrld->starsize), 0.0, 10.0, 10, 0, "Specify the average screen dimension"); + uiDefButF(block, NUM,B_DIFF,"Colnoise:", 571,10,100,19, &(wrld->starcolnoise), 0.0, 1.0, 100, 0, "Randomize starcolour"); + + + /* TEX CHANNELS */ + uiBlockSetCol(block, BUTGREY); + xco= 745; + for(a= 0; a<6; a++) { + mtex= wrld->mtex[a]; + if(mtex && mtex->tex) splitIDname(mtex->tex->id.name+2, str, &loos); + else strcpy(str, ""); + str[10]= 0; + uiDefButS(block, ROW, REDRAWBUTSWORLD, str, xco, 195, 83, 20, &(wrld->texact), 3.0, (float)a, 0, 0, "Texture channel"); + xco+= 85; + } + + mtex= wrld->mtex[ wrld->texact ]; + if(mtex==0) { + mtex= &emptytex; + default_mtex(mtex); + mtex->texco= TEXCO_VIEW; + } + + /* TEXCO */ + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, ROW, B_MATPRV, "Object", 745,146,49,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "The name of the object used as a source for texture coordinates"); + uiDefIDPoinBut(block, test_obpoin_but, B_MATPRV, "", 745,166,133,18, &(mtex->object), ""); + uiDefButS(block, ROW, B_MATPRV, "View", 839,146,39,18, &(mtex->texco), 4.0, (float)TEXCO_VIEW, 0, 0, "Pass camera view vector on to the texture"); + + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM, B_MATPRV, "dX", 745,114,133,18, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tune X coordinate"); + uiDefButF(block, NUM, B_MATPRV, "dY", 745,94,133,18, mtex->ofs+1, -20.0, 20.0, 10, 0, "Fine tune Y coordinate"); + uiDefButF(block, NUM, B_MATPRV, "dZ", 745,74,133,18, mtex->ofs+2, -20.0, 20.0, 10, 0, "Fine tune Z coordinate"); + uiDefButF(block, NUM, B_MATPRV, "sizeX", 745,50,133,18, mtex->size, -20.0, 20.0, 10, 0, "Set an extra scaling for the texture coordinate"); + uiDefButF(block, NUM, B_MATPRV, "sizeY", 745,30,133,18, mtex->size+1, -20.0, 20.0, 10, 0, "Set an extra scaling for the texture coordinate"); + uiDefButF(block, NUM, B_MATPRV, "sizeZ", 745,10,133,18, mtex->size+2, -20.0, 20.0, 10, 0, "Set an extra scaling for the texture coordinate"); + + /* TEXTUREBLOK SELECT */ + id= (ID *)mtex->tex; + IDnames_to_pupstring(&strp, NULL, "ADD NEW %x 32767", &(G.main->tex), id, &(G.buts->texnr)); + uiDefButS(block, MENU, B_WTEXBROWSE, strp, 900,146,20,19, &(G.buts->texnr), 0, 0, 0, 0, "Browse"); + MEM_freeN(strp); + + if(id) { + uiDefBut(block, TEX, B_IDNAME, "TE:", 900,166,163,19, id->name+2, 0.0, 18.0, 0, 0, "Specify the texture name"); + sprintf(str, "%d", id->us); + uiDefBut(block, BUT, 0, str, 996,146,21,19, 0, 0, 0, 0, 0, "Number of users"); + uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 1041,146,21,19, 0, 0, 0, 0, 0, "Auto assign name to texture"); + if(id->lib) { + if(wrld->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB, 1019,146,21,19, 0, 0, 0, 0, 0, ""); + else uiDefIconBut(block, BUT, 0, ICON_PARLIB, 1019,146,21,19, 0, 0, 0, 0, 0, ""); + } + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_TEXCLEARWORLD, "Clear", 922, 146, 72, 19, 0, 0, 0, 0, 0, "Erase link to texture"); + uiBlockSetCol(block, BUTGREY); + } + + /* TEXTURE OUTPUT */ + uiDefButS(block, TOG|BIT|1, B_MATPRV, "Stencil", 900,114,52,18, &(mtex->texflag), 0, 0, 0, 0, "Use stencil mode"); + uiDefButS(block, TOG|BIT|2, B_MATPRV, "Neg", 954,114,38,18, &(mtex->texflag), 0, 0, 0, 0, "Inverse texture operation"); + uiDefButS(block, TOG|BIT|0, B_MATPRV, "RGBtoInt", 994,114,69,18, &(mtex->texflag), 0, 0, 0, 0, "Use RGB values for intensity texure"); + + uiDefButF(block, COL, B_MTEXCOL, "", 900,100,163,12, &(mtex->r), 0, 0, 0, 0, ""); + uiDefButF(block, NUMSLI, B_MATPRV, "R ", 900,80,163,18, &(mtex->r), 0.0, 1.0, B_MTEXCOL, 0, "The amount of red that blends with the intensity colour"); + uiDefButF(block, NUMSLI, B_MATPRV, "G ", 900,60,163,18, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "The amount of green that blends with the intensity colour"); + uiDefButF(block, NUMSLI, B_MATPRV, "B ", 900,40,163,18, &(mtex->b), 0.0, 1.0, B_MTEXCOL, 0, "The amount of blue that blends with the intensity colour"); + uiDefButF(block, NUMSLI, B_MATPRV, "DVar ", 900,10,163,18, &(mtex->def_var), 0.0, 1.0, 0, 0, "The value that an intensity texture blends with the current value"); + + /* MAP TO */ + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|0, B_MATPRV, "Blend", 1087,166,81,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture work on the colour progression in the sky"); + uiDefButS(block, TOG|BIT|1, B_MATPRV, "Hori", 1172,166,81,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture work on the colour of the horizon"); + uiDefButS(block, TOG|BIT|2, B_MATPRV, "ZenUp", 1087,147,81,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture work on the colour of the zenith above"); + uiDefButS(block, TOG|BIT|3, B_MATPRV, "ZenDo", 1172,147,81,18, &(mtex->mapto), 0, 0, 0, 0, "Let the texture work on the colour of the zenith below"); + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, ROW, B_MATPRV, "Blend", 1087,114,48,18, &(mtex->blendtype), 9.0, (float)MTEX_BLEND, 0, 0, "The texture blends the values"); + uiDefButS(block, ROW, B_MATPRV, "Mul", 1136,114,44,18, &(mtex->blendtype), 9.0, (float)MTEX_MUL, 0, 0, "The texture multiplies the values"); + uiDefButS(block, ROW, B_MATPRV, "Add", 1182,114,41,18, &(mtex->blendtype), 9.0, (float)MTEX_ADD, 0, 0, "The texture adds the values"); + uiDefButS(block, ROW, B_MATPRV, "Sub", 1226,114,40,18, &(mtex->blendtype), 9.0, (float)MTEX_SUB, 0, 0, "The texture subtracts the values"); + + uiDefButF(block, NUMSLI, B_MATPRV, "Col ", 1087,50,179,18, &(mtex->colfac), 0.0, 1.0, 0, 0, "Specify the extent to which the texture works on colour"); + uiDefButF(block, NUMSLI, B_MATPRV, "Nor ", 1087,30,179,18, &(mtex->norfac), 0.0, 1.0, 0, 0, "Specify the extent to which the texture works on the normal"); + uiDefButF(block, NUMSLI, B_MATPRV, "Var ", 1087,10,179,18, &(mtex->varfac), 0.0, 1.0, 0, 0, "Specify the extent to which the texture works on a value"); + + + BIF_previewdraw(G.buts); + + uiDrawBlock(block); +} + + +/* **************************** VIEW ************************ */ + +static void view3d_change_bgpic_ima(View3D *v3d, Image *newima) { + if (v3d->bgpic && v3d->bgpic->ima!=newima) { + if (newima) + id_us_plus((ID*) newima); + if (v3d->bgpic->ima) + v3d->bgpic->ima->id.us--; + v3d->bgpic->ima= newima; + + if(v3d->bgpic->rect) MEM_freeN(v3d->bgpic->rect); + v3d->bgpic->rect= NULL; + + allqueue(REDRAWBUTSVIEW, 0); + } +} +static void view3d_change_bgpic_tex(View3D *v3d, Tex *newtex) { + if (v3d->bgpic && v3d->bgpic->tex!=newtex) { + if (newtex) + id_us_plus((ID*) newtex); + if (v3d->bgpic->tex) + v3d->bgpic->tex->id.us--; + v3d->bgpic->tex= newtex; + + allqueue(REDRAWBUTSVIEW, 0); + } +} + +static void load_bgpic_image(char *name) +{ + Image *ima; + View3D *vd; + + vd= scrarea_find_space_of_type(curarea, SPACE_VIEW3D); + if(vd==0 || vd->bgpic==0) return; + + ima= add_image(name); + if(ima) { + if(vd->bgpic->ima) { + vd->bgpic->ima->id.us--; + } + vd->bgpic->ima= ima; + + free_image_buffers(ima); /* forceer opnieuw inlezen */ + ima->ok= 1; + } + allqueue(REDRAWBUTSVIEW, 0); + +} + +void do_viewbuts(unsigned short event) +{ + View3D *vd; + char *name; + + vd= scrarea_find_space_of_type(curarea, SPACE_VIEW3D); + if(vd==0) return; + + switch(event) { + case B_LOADBGPIC: + if(vd->bgpic && vd->bgpic->ima) name= vd->bgpic->ima->name; + else name= G.ima; + + activate_imageselect(FILE_SPECIAL, "SELECT IMAGE", name, load_bgpic_image); + break; + case B_BLENDBGPIC: + if(vd->bgpic && vd->bgpic->rect) setalpha_bgpic(vd->bgpic); + break; + case B_BGPICBROWSE: + if(vd->bgpic) { + if (G.buts->menunr==-2) { + activate_databrowse((ID*) vd->bgpic->ima, ID_IM, 0, B_BGPICBROWSE, &G.buts->menunr, do_viewbuts); + } else if (G.buts->menunr>0) { + Image *newima= (Image*) BLI_findlink(&G.main->image, G.buts->menunr-1); + + if (newima) + view3d_change_bgpic_ima(vd, newima); + } + } + break; + case B_BGPICCLEAR: + if (vd->bgpic) + view3d_change_bgpic_ima(vd, NULL); + break; + case B_BGPICTEX: + if (vd->bgpic) { + if (G.buts->texnr==-2) { + activate_databrowse((ID*) vd->bgpic->tex, ID_TE, 0, B_BGPICTEX, &G.buts->texnr, do_viewbuts); + } else if (G.buts->texnr>0) { + Tex *newtex= (Tex*) BLI_findlink(&G.main->tex, G.buts->texnr-1); + + if (newtex) + view3d_change_bgpic_tex(vd, newtex); + } + } + break; + case B_BGPICTEXCLEAR: + if (vd->bgpic) + view3d_change_bgpic_tex(vd, NULL); + break; + } +} + +void viewbuts(void) +{ + View3D *vd; + ID *id; + uiBlock *block; + char *strp, str[64]; + + /* op zoek naar spacedata */ + vd= scrarea_find_space_of_type(curarea, SPACE_VIEW3D); + if(vd==0) return; + + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + if(vd->flag & V3D_DISPBGPIC) { + if(vd->bgpic==0) { + vd->bgpic= MEM_callocN(sizeof(BGpic), "bgpic"); + vd->bgpic->size= 5.0; + vd->bgpic->blend= 0.5; + } + } + + uiDefButS(block, TOG|BIT|1, REDRAWBUTSVIEW, "BackGroundPic", 347,160,127,29 , + &vd->flag, 0, 0, 0, 0, "Display a picture in the 3D background"); + if(vd->bgpic) { + uiDefButF(block, NUM, B_DIFF, "Size:", + 478,160,82,29, &vd->bgpic->size, 0.1, + 250.0, 100, 0, "Set the size for the width of the BackGroundPic"); + + id= (ID *)vd->bgpic->ima; + IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), id, &(G.buts->menunr)); + if(strp[0]) + uiDefButS(block, MENU, B_BGPICBROWSE, strp, 347,112,20,19, &(G.buts->menunr), 0, 0, 0, 0, "Browse"); + MEM_freeN(strp); + + uiDefBut(block, BUT, B_LOADBGPIC, "LOAD", 370,112,189,19, 0, 0, 0, 0, 0, "Specify the BackGroundPic"); + uiDefButF(block, NUMSLI, B_BLENDBGPIC, "Blend:", 347,84,213,19,&vd->bgpic->blend, 0.0,1.0, 0, 0, "Set the BackGroundPic transparency"); + + if(vd->bgpic->ima) { + uiDefBut(block, TEX, 0,"BGpic: ", 347,136,211,19,&vd->bgpic->ima->name,0.0,100.0, 0, 0, "The Selected BackGroundPic"); + uiDefIconBut(block, BUT, B_BGPICCLEAR, ICON_X, 347+211,112,20,19, 0, 0, 0, 0, 0, "Remove background image link"); + } + + /* There is a bug here ... (what bug? where? what is this? - zr) */ + /* textureblok: */ + id= (ID *)vd->bgpic->tex; + IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->tex), id, &(G.buts->texnr)); + if (strp[0]) + uiDefButS(block, MENU, B_BGPICTEX, strp, 347, 20, 20,19, &(G.buts->texnr), 0, 0, 0, 0, "Browse"); + MEM_freeN(strp); + + uiDefBut(block, LABEL, 0, "Select texture for animated backgroundimage", 370, 20, 300,19, 0, 0, 0, 0, 0, ""); + + if (id) { + uiDefBut(block, TEX, B_IDNAME, "TE:", 347,0,211,19, id->name+2, 0.0, 18.0, 0, 0, ""); + uiDefIconBut(block, BUT, B_BGPICTEXCLEAR, ICON_X, 347+211,0,20,19, 0, 0, 0, 0, 0, "Remove background texture link"); + } + } + + uiDefButF(block, NUM, B_DIFF, "Grid:", 347, 60, 105, 19, &vd->grid, 0.001, 1000.0, 100, 0, "Set the distance between gridlines"); + uiDefButS(block, NUM, B_DIFF, "GridLines:", 452, 60, 105, 19, &vd->gridlines, 0.0, 100.0, 100, 0, "Set the number of gridlines"); + uiDefButF(block, NUM, B_DIFF, "Lens:", 557, 60, 105, 19, &vd->lens, 10.0, 120.0, 100, 0, "Set the lens for the perspective view"); + + uiDefButF(block, NUM, B_DIFF, "ClipStart:", 347, 40, 105, 19, &vd->near, 0.1*vd->grid, 100.0, 100, 0, "Set startvalue in perspective view mode"); + uiDefButF(block, NUM, B_DIFF, "ClipEnd:", 452, 40, 105, 19, &vd->far, 1.0, 1000.0*vd->grid, 100, 0, "Set endvalue in perspective view mode"); + + /* for(b=0; b<8; b++) { */ + /* for(a=0; a<8; a++) { */ + /* uiDefButC(block, TOG|BIT|(7-a), 0, "", 100+12*a, 100-12*b, 12, 12, &(arr[b]),0,0,0,0); ,""*/ + /* } */ + /* } */ + /* DefBut(BUT, 1001, "print", 50,100,50,20, 0, 0, 0, 0,0); */ + + uiDrawBlock(block); +} + +void output_pic(char *name) +{ + strcpy(G.scene->r.pic, name); + allqueue(REDRAWBUTSRENDER, 0); +} + +void backbuf_pic(char *name) +{ + Image *ima; + + strcpy(G.scene->r.backbuf, name); + allqueue(REDRAWBUTSRENDER, 0); + + ima= add_image(name); + if(ima) { + free_image_buffers(ima); /* forceer opnieuw inlezen */ + ima->ok= 1; + } +} + +void ftype_pic(char *name) +{ + strcpy(G.scene->r.ftype, name); + allqueue(REDRAWBUTSRENDER, 0); +} + + +/* **************************** VIEW ************************ */ + + +static void scene_change_set(Scene *sc, Scene *set) { + if (sc->set!=set) { + sc->set= set; + + allqueue(REDRAWBUTSRENDER, 0); + allqueue(REDRAWVIEW3D, 0); + } +} + +static void run_playanim(char *file) { + extern char bprogname[]; /* usiblender.c */ + char str[FILE_MAXDIR+FILE_MAXFILE]; + int pos[2], size[2]; + + calc_renderwin_rectangle(R.winpos, pos, size); + + sprintf(str, "%s -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file); + system(str); +} + +void do_renderbuts(unsigned short event) +{ + ScrArea *sa; + ID *id; + char file[FILE_MAXDIR+FILE_MAXFILE]; + + switch(event) { + + case B_DORENDER: + BIF_do_render(0); + break; + case B_RTCHANGED: + allqueue(REDRAWALL, 0); + break; + case B_PLAYANIM: + makeavistring(file); + if(BLI_exist(file)) { + run_playanim(file); + } + else { + makepicstring(file, G.scene->r.sfra); + if(BLI_exist(file)) { + run_playanim(file); + } + else error("Can't find image: %s", file); + } + break; + + case B_DOANIM: + BIF_do_render(1); + break; + + case B_FS_PIC: + sa= closest_bigger_area(); + areawinset(sa->win); + activate_fileselect(FILE_SPECIAL, "SELECT OUTPUT PICTURES", G.scene->r.pic, output_pic); + break; + case B_FS_BACKBUF: + sa= closest_bigger_area(); + areawinset(sa->win); + activate_fileselect(FILE_SPECIAL, "SELECT BACKBUF PICTURE", G.scene->r.backbuf, backbuf_pic); + break; + case B_IS_BACKBUF: + sa= closest_bigger_area(); + areawinset(sa->win); + activate_imageselect(FILE_SPECIAL, "SELECT BACKBUF PICTURE", G.scene->r.backbuf, backbuf_pic); + break; + case B_FS_FTYPE: + sa= closest_bigger_area(); + areawinset(sa->win); + activate_fileselect(FILE_SPECIAL, "SELECT FTYPE", G.scene->r.ftype, ftype_pic); + break; + case B_IS_FTYPE: + sa= closest_bigger_area(); + areawinset(sa->win); + activate_imageselect(FILE_SPECIAL, "SELECT FTYPE", G.scene->r.ftype, ftype_pic); + break; + + case B_PR_PAL: + G.scene->r.xsch= 720; + G.scene->r.ysch= 576; + G.scene->r.xasp= 54; + G.scene->r.yasp= 51; + G.scene->r.size= 100; + G.scene->r.mode &= ~R_PANORAMA; + G.scene->r.xparts= G.scene->r.yparts= 1; + + BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); + allqueue(REDRAWBUTSRENDER, 0); + allqueue(REDRAWVIEWCAM, 0); + break; +#ifdef _WIN32 + case B_FILETYPEMENU: + allqueue(REDRAWBUTSRENDER, 0); + // fall through to codec settings if this is the first + // time R_AVICODEC is selected for this scene. + if ((G.scene->r.imtype != R_AVICODEC) || (G.scene->r.avicodecdata)) { + break; + } + case B_SELECTCODEC: + get_codec_settings(); + break; +#endif + case B_PR_FULL: + G.scene->r.xsch= 1280; + G.scene->r.ysch= 1024; + G.scene->r.xasp= 1; + G.scene->r.yasp= 1; + G.scene->r.size= 100; + G.scene->r.mode &= ~R_PANORAMA; + G.scene->r.xparts= G.scene->r.yparts= 1; + + BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); + allqueue(REDRAWBUTSRENDER, 0); + allqueue(REDRAWVIEWCAM, 0); + break; + case B_PR_PRV: + G.scene->r.xsch= 640; + G.scene->r.ysch= 512; + G.scene->r.xasp= 1; + G.scene->r.yasp= 1; + G.scene->r.size= 50; + G.scene->r.mode &= ~R_PANORAMA; + G.scene->r.xparts= G.scene->r.yparts= 1; + + BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); + allqueue(REDRAWVIEWCAM, 0); + allqueue(REDRAWBUTSRENDER, 0); + break; + case B_PR_CDI: + G.scene->r.xsch= 384; + G.scene->r.ysch= 280; + G.scene->r.xasp= 1; + G.scene->r.yasp= 1; + G.scene->r.size= 100; + G.scene->r.mode &= ~R_PANORAMA; + G.scene->r.xparts= G.scene->r.yparts= 1; + + BLI_init_rctf(&G.scene->r.safety, 0.15, 0.85, 0.15, 0.85); + allqueue(REDRAWVIEWCAM, 0); + allqueue(REDRAWBUTSRENDER, 0); + break; + case B_PR_PAL169: + G.scene->r.xsch= 720; + G.scene->r.ysch= 576; + G.scene->r.xasp= 64; + G.scene->r.yasp= 45; + G.scene->r.size= 100; + G.scene->r.mode &= ~R_PANORAMA; + G.scene->r.xparts= G.scene->r.yparts= 1; + + BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); + allqueue(REDRAWVIEWCAM, 0); + allqueue(REDRAWBUTSRENDER, 0); + break; + case B_PR_D2MAC: + G.scene->r.xsch= 1024; + G.scene->r.ysch= 576; + G.scene->r.xasp= 1; + G.scene->r.yasp= 1; + G.scene->r.size= 50; + G.scene->r.mode &= ~R_PANORAMA; + G.scene->r.xparts= G.scene->r.yparts= 1; + + BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); + allqueue(REDRAWVIEWCAM, 0); + allqueue(REDRAWBUTSRENDER, 0); + break; + case B_PR_MPEG: + G.scene->r.xsch= 368; + G.scene->r.ysch= 272; + G.scene->r.xasp= 105; + G.scene->r.yasp= 100; + G.scene->r.size= 100; + G.scene->r.mode &= ~R_PANORAMA; + G.scene->r.xparts= G.scene->r.yparts= 1; + + BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); + allqueue(REDRAWVIEWCAM, 0); + allqueue(REDRAWBUTSRENDER, 0); + break; + case B_PR_PC: + G.scene->r.xsch= 640; + G.scene->r.ysch= 480; + G.scene->r.xasp= 100; + G.scene->r.yasp= 100; + G.scene->r.size= 100; + G.scene->r.mode &= ~R_PANORAMA; + G.scene->r.xparts= G.scene->r.yparts= 1; + + BLI_init_rctf(&G.scene->r.safety, 0.0, 1.0, 0.0, 1.0); + allqueue(REDRAWVIEWCAM, 0); + allqueue(REDRAWBUTSRENDER, 0); + break; + case B_PR_PRESET: + G.scene->r.xsch= 720; + G.scene->r.ysch= 576; + G.scene->r.xasp= 54; + G.scene->r.yasp= 51; + G.scene->r.size= 100; + G.scene->r.mode= R_OSA+R_SHADOW+R_FIELDS; + G.scene->r.imtype= R_TARGA; + G.scene->r.xparts= G.scene->r.yparts= 1; + + BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); + allqueue(REDRAWVIEWCAM, 0); + allqueue(REDRAWBUTSRENDER, 0); + break; + case B_PR_PANO: + G.scene->r.xsch= 36; + G.scene->r.ysch= 176; + G.scene->r.xasp= 115; + G.scene->r.yasp= 100; + G.scene->r.size= 100; + G.scene->r.mode |= R_PANORAMA; + G.scene->r.xparts= 16; + G.scene->r.yparts= 1; + + BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); + allqueue(REDRAWVIEWCAM, 0); + allqueue(REDRAWBUTSRENDER, 0); + break; + + case B_SETBROWSE: + id= (ID*) G.scene->set; + + if (G.buts->menunr==-2) { + activate_databrowse(id, ID_SCE, 0, B_SETBROWSE, &G.buts->menunr, do_renderbuts); + } else if (G.buts->menunr>0) { + Scene *newset= (Scene*) BLI_findlink(&G.main->scene, G.buts->menunr-1); + + if (newset==G.scene) + error("Not allowed"); + else if (newset) + scene_change_set(G.scene, newset); + } + break; + case B_CLEARSET: + scene_change_set(G.scene, NULL); + break; + } +} + +uiBlock *edge_render_menu(void *arg_unused) +{ + uiBlock *block; + + block= uiNewBlock(&curarea->uiblocks, + "edge render", UI_EMBOSSX, UI_HELV, + curarea->win); + + /* use this for a fake extra empy space around the buttons */ + uiDefBut(block, LABEL, 0, "", +/* 285, -20, 230, 100, NULL, */ + 285, -20, 230, 120, NULL, + 0, 0, 0, 0, ""); + + uiDefButS(block, NUM, 0,"Eint:", + 295,50,70,19, + &G.scene->r.edgeint, 0.0, 255.0, 0, 0, + "Sets edge intensity for Toon shading"); + uiBlockSetCol(block, BUTGREEN); + uiDefButI(block, TOG, 0,"Shift", + 365,50,70,19, + &G.compat, 0, 0, 0, 0, + "For unified renderer: use old offsets for edges"); + uiDefButI(block, TOG, 0,"All", 435,50,70,19, + &G.notonlysolid, 0, 0, 0, 0, + "For unified renderer: also consider transparent " + "faces for toon shading"); + + /* colour settings for the toon shading */ + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, COL, B_EDGECOLSLI, "", + 295,-10,30,60, + &(G.scene->r.edgeR), 0, 0, 0, 0, + ""); + + uiDefButF(block, NUMSLI, 0, "R ", + 325, 30, 180,19, + &G.scene->r.edgeR, 0.0, 1.0, B_EDGECOLSLI, 0, + "For unified renderer: Colour for edges in toon shading mode."); + uiDefButF(block, NUMSLI, 0, "G ", + 325, 10, 180,19, + &G.scene->r.edgeG, 0.0, 1.0, B_EDGECOLSLI, 0, + "For unified renderer: Colour for edges in toon shading mode."); + uiDefButF(block, NUMSLI, 0, "B ", + 325, -10, 180,19, + &G.scene->r.edgeB, 0.0, 1.0, B_EDGECOLSLI, 0, + "For unified renderer: Colour for edges in toon shading mode."); + + uiDefButI(block, NUM, 0,"AntiShift", + 365,70,140,19, + &(G.scene->r.same_mat_redux), 0, 255.0, 0, 0, + "For unified renderer: reduce intensity on boundaries " + "with identical materials with this number."); + + uiBlockSetDirection(block, UI_TOP); + + return block; +} + +static uiBlock *post_render_menu(void *arg_unused) +{ + uiBlock *block; + + block= uiNewBlock(&curarea->uiblocks, "post render", UI_EMBOSSX, UI_HELV, curarea->win); + + /* use this for a fake extra empy space around the buttons */ + uiDefBut(block, LABEL, 0, "", -10, 10, 200, 80, NULL, 0, 0, 0, 0, ""); + + uiDefButF(block, NUMSLI, 0,"Add:", 0,60,180,19, + &G.scene->r.postadd, -1.0, 1.0, 0, 0, ""); + uiDefButF(block, NUMSLI, 0,"Mul:", 0,40,180,19, + &G.scene->r.postmul, 0.01, 4.0, 0, 0, ""); + uiDefButF(block, NUMSLI, 0,"Gamma:", 0,20,180,19, + &G.scene->r.postgamma, 0.2, 2.0, 0, 0, ""); + + uiBlockSetDirection(block, UI_TOP); + + return block; +} + + +static uiBlock *framing_render_menu(void *arg_unused) +{ + uiBlock *block; + short yco = 60, xco = 0; + int randomcolorindex = 1234; + + block= uiNewBlock(&curarea->uiblocks, "framing_options", UI_EMBOSSX, UI_HELV, curarea->win); + + /* use this for a fake extra empy space around the buttons */ + uiDefBut(block, LABEL, 0, "", -10, -10, 300, 100, NULL, 0, 0, 0, 0, ""); + + uiDefBut(block, LABEL, B_NOP, "Framing:", xco, yco, 68,19, 0, 0, 0, 0, 0, ""); + uiDefButC(block, ROW, 0, "Stretch", xco += 70, yco, 68, 19, &G.scene->framing.type, 1.0, SCE_GAMEFRAMING_SCALE , 0, 0, "Stretch or squeeze the viewport to fill the display window"); + uiDefButC(block, ROW, 0, "Expose", xco += 70, yco, 68, 19, &G.scene->framing.type, 1.0, SCE_GAMEFRAMING_EXTEND, 0, 0, "Show the entire viewport in the display window, viewing more horizontally or vertically"); + uiDefButC(block, ROW, 0, "Bars", xco += 70, yco, 68, 19, &G.scene->framing.type, 1.0, SCE_GAMEFRAMING_BARS , 0, 0, "Show the entire viewport in the display window, using bar horizontally or vertically"); + + yco -= 20; + xco = 35; + + uiDefButF(block, COL, randomcolorindex, "", 0, yco - 58 + 18, 33, 58, &G.scene->framing.col[0], 0, 0, 0, 0, ""); + + uiDefButF(block, NUMSLI, 0, "R ", xco,yco,243,18, &G.scene->framing.col[0], 0.0, 1.0, randomcolorindex, 0, "Set the red component of the bars"); + yco -= 20; + uiDefButF(block, NUMSLI, 0, "G ", xco,yco,243,18, &G.scene->framing.col[1], 0.0, 1.0, randomcolorindex, 0, "Set the green component of the bars"); + yco -= 20; + uiDefButF(block, NUMSLI, 0, "B ", xco,yco,243,18, &G.scene->framing.col[2], 0.0, 1.0, randomcolorindex, 0, "Set the blue component of the bars"); + + uiBlockSetDirection(block, UI_TOP); + + return block; +} + + +static char *imagetype_pup(void) +{ + static char string[1024]; + char formatstring[1024]; + + strcpy(formatstring, "Save image as: %%t|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d"); + +#ifdef __sgi + strcat(formatstring, "|%s %%x%d"); // add space for Movie +#endif + + if (LICENSE_KEY_VALID) { + strcat(formatstring, "|%s %%x%d"); // add space for PNG + +#ifdef _WIN32 + strcat(formatstring, "|%s %%x%d"); // add space for AVI Codec +#endif + + sprintf(string, formatstring, + "AVI Raw", R_AVIRAW, + "AVI Jpeg", R_AVIJPEG, +#ifdef _WIN32 + "AVI Codec", R_AVICODEC, +#endif + "Targa", R_TARGA, + "Targa Raw", R_RAWTGA, + "PNG", R_PNG, + "Jpeg", R_JPEG90, + "HamX", R_HAMX, + "Iris", R_IRIS, + "Iris + Zbuffer", R_IRIZ, + "Ftype", R_FTYPE, + "Movie", R_MOVIE + ); + } else { + sprintf(string, formatstring, + "AVI Raw", R_AVIRAW, + "AVI Jpeg", R_AVIJPEG, + "Targa", R_TARGA, + "Targa Raw", R_RAWTGA, + "Jpeg", R_JPEG90, + "HamX", R_HAMX, + "Iris", R_IRIS, + "Iris + Zbuffer", R_IRIZ, + "Ftype", R_FTYPE, + "Movie", R_MOVIE + ); + } + + return (string); +} + + +void renderbuts(void) +{ + ID *id; + int a,b; + uiBlock *block; + char *strp; + char str[64]; + int yofs; + + sprintf(str, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + uiDefBut(block, TEX,0,"", 34,172,257,19,G.scene->r.pic, 0.0,79.0, 0, 0, "Directory/name to save rendered Pics to"); + uiDefBut(block, BUT,B_FS_PIC," ", 10,172,22,19, 0, 0, 0, 0, 0, "Open Fileselect to get Pics dir/name"); + uiDefBut(block, TEX,0,"", 34,149,257,19,G.scene->r.backbuf, 0.0,79.0, 0, 0, "Image to use as background for rendering"); + uiDefBut(block, BUT,B_FS_BACKBUF," ", 21,149,11,19, 0, 0, 0, 0, 0, "Open Fileselect to get Backbuf image"); + uiDefBut(block, TEX,0,"", 34,126,257,19,G.scene->r.ftype,0.0,79.0, 0, 0, "Image to use with FTYPE Image type"); + uiDefBut(block, BUT,B_FS_FTYPE," ", 21,126,11,19, 0, 0, 0, 0, 0, "Open Fileselect to get Ftype image"); + uiDefIconBut(block, BUT, B_CLEARSET, ICON_X, 267,102,24,21, 0, 0, 0, 0, 0, "Remove Set link"); + + /* SET BUTTON */ + id= (ID *)G.scene->set; + IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->scene), id, &(G.buts->menunr)); + if(strp[0]) + uiDefButS(block, MENU, B_SETBROWSE, strp, 10,103,22,19, &(G.buts->menunr), 0, 0, 0, 0, "Scene to link as a Set"); + MEM_freeN(strp); + + uiDefBut(block, LABEL, 0, "Set", 295,103,63,19, 0, 0, 0, 0, 0, ""); + + uiBlockSetCol(block, BUTBLUE); + + if(G.scene->set) { + uiSetButLock(1, NULL); + uiDefIDPoinBut(block, test_scenepoin_but, 0, "", 34,103,231,19, &(G.scene->set), "Name of the Set"); + uiClearButLock(); + } + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT,B_IS_BACKBUF," ", 10,149,11,19, 0, 0, 0, 0, 0, "Open Imageselect to get Backbuf image"); + uiDefBut(block, BUT,B_IS_FTYPE," ", 10,126,11,19, 0, 0, 0, 0, 0, "Open Imageselect to get Ftype image"); + uiBlockSetCol(block, BUTGREY); + + uiDefBut(block, LABEL,0,"Pics", 295,172,63,19, 0, 0, 0, 0, 0, ""); + uiDefButS(block, TOG|BIT|0, 0,"Backbuf", 295,149,63,19, &G.scene->r.bufflag, 0, 0, 0, 0, "Enable/Disable use of Backbuf image"); + uiDefBut(block, LABEL,0,"Ftype", 295,126,63,19, 0, 0, 0, 0, 0, ""); + + uiBlockSetCol(block, BUTGREY); + + for(b=0; b<3; b++) + for(a=0; a<3; a++) + uiDefButS(block, TOG|BIT|(3*b+a),800,"", (short)(34+18*a),(short)(11+12*b),16,10, &R.winpos, 0, 0, 0, 0, "Render window placement on screen"); + + uiDefButS(block, ROW, B_REDR, "DispView", 99,28,77,18, &R.displaymode, 0.0, (float)R_DISPLAYVIEW, 0, 0, "Sets render output to display in 3D view"); + uiDefButS(block, ROW, B_REDR, "DispWin", 99,10,78,18, &R.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output to display in a seperate window"); + + uiDefButS(block, TOG|BIT|4, 0, "Extensions", 190,10,95,18, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds extensions to the output when rendering animations"); + + uiBlockSetCol(block, BUTSALMON); + + uiDefBut(block, BUT,B_DORENDER,"RENDER", 369,142,192,47, 0, 0, 0, 0, 0, "Start the rendering"); + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, TOG|BIT|1,0,"Shadows", 565,167,122,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable shadow calculation"); + uiDefButS(block, TOG|BIT|10,0,"Panorama",565,142,122,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable panorama rendering (output width is multiplied by Xparts)"); + + uiDefButS(block, ROW,B_DIFF,"100%", 565,114,121,20,&G.scene->r.size,1.0,100.0, 0, 0, "Set render size to defined size"); + uiDefButS(block, ROW,B_DIFF,"75%", 565,90,36,20,&G.scene->r.size,1.0,75.0, 0, 0, "Set render size to 3/4 of defined size"); + uiDefButS(block, ROW,B_DIFF,"50%", 604,90,40,20,&G.scene->r.size,1.0,50.0, 0, 0, "Set render size to 1/2 of defined size"); + uiDefButS(block, ROW,B_DIFF,"25%", 647,90,39,20,&G.scene->r.size,1.0,25.0, 0, 0, "Set render size to 1/4 of defined size"); + + uiDefButS(block, TOG|BIT|0, 0, "OSA", 369,114,124,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)"); + uiDefButF(block, NUM,B_DIFF,"Bf:", 495,90,65,20,&G.scene->r.blurfac, 0.01, 5.0, 10, 0, "Sets motion blur factor"); + uiDefButS(block, TOG|BIT|14, 0, "MBLUR", 495,114,66,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Motion Blur calculation"); + + uiDefButS(block, ROW,B_DIFF,"5", 369,90,29,20,&G.scene->r.osa,2.0,5.0, 0, 0, "Sets oversample level to 5"); + uiDefButS(block, ROW,B_DIFF,"8", 400,90,29,20,&G.scene->r.osa,2.0,8.0, 0, 0, "Sets oversample level to 8 (Recommended)"); + uiDefButS(block, ROW,B_DIFF,"11", 431,90,33,20,&G.scene->r.osa,2.0,11.0, 0, 0, "Sets oversample level to 11"); + uiDefButS(block, ROW,B_DIFF,"16", 466,90,28,20,&G.scene->r.osa,2.0,16.0, 0, 0, "Sets oversample level to 16"); + + uiDefButS(block, NUM,B_DIFF,"Xparts:", 369,42,99,31,&G.scene->r.xparts,1.0, 64.0, 0, 0, "Sets the number of horizontal parts to render image in (For panorama sets number of camera slices)"); + uiDefButS(block, NUM,B_DIFF,"Yparts:", 472,42,86,31,&G.scene->r.yparts,1.0, 64.0, 0, 0, "Sets the number of vertical parts to render image in"); + + uiDefButS(block, TOG|BIT|6,0,"Fields",564,42,90,31,&G.scene->r.mode, 0, 0, 0, 0, "Enables field rendering"); + + uiDefButS(block, TOG|BIT|13,0,"Odd", 655,57,30,16,&G.scene->r.mode, 0, 0, 0, 0, "Enables Odd field first rendering (Default: Even field)"); + uiDefButS(block, TOG|BIT|7,0,"x", 655,42,30,15,&G.scene->r.mode, 0, 0, 0, 0, "Disables time difference in field calculations"); + + uiDefButS(block, ROW,800,"Sky", 369,11,38,24,&G.scene->r.alphamode,3.0,0.0, 0, 0, "Fill background with sky"); + uiDefButS(block, ROW,800,"Premul", 410,11,54,24,&G.scene->r.alphamode,3.0,1.0, 0, 0, "Multiply alpha in advance"); + uiDefButS(block, ROW,800,"Key", 467,11,44,24,&G.scene->r.alphamode,3.0,2.0, 0, 0, "Alpha and colour values remain unchanged"); + + /* Toon shading buttons */ + uiDefButS(block, TOG|BIT|5, 0,"Edge", 295,70,70,19, + &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon shading"); + uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings |>> ", 155, 70, 138, 19, "Display edge settings"); + + /* unified render buttons */ + if(G.scene->r.mode & R_UNIFIED) { + uiDefBlockBut(block, post_render_menu, NULL, "Post process |>> ", 15, 70, 138, 19, "Only for unified render"); + if (G.scene->r.mode & R_GAMMA) { + uiDefButF(block, NUMSLI, 0,"Gamma:", 15, 50, 280, 19, + &(G.scene->r.gamma), 0.2, 5.0, B_GAMMASLI, 0, + "The gamma value for blending oversampled images (1.0 = no correction)."); + } + } + + + uiDefButS(block, TOG|BIT|9,REDRAWVIEWCAM, "Border", 565,11,58,24, &G.scene->r.mode, 0, 0, 0, 0, "Render a small cut-out of the image"); + uiDefButS(block, TOG|BIT|2,0, "Gamma", 626,11,58,24, &G.scene->r.mode, 0, 0, 0, 0, "Enable gamma correction"); + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT,B_DOANIM,"ANIM", 692,142,192,47, 0, 0, 0, 0, 0, "Start rendering a sequence"); + + uiBlockSetCol(block, BUTBLUE); + + uiDefButS(block, TOG|BIT|0, 0, "Do Sequence", 692,114,192,20, &G.scene->r.scemode, 0, 0, 0, 0, "Enables sequence output rendering (Default: 3D rendering)"); + uiDefButS(block, TOG|BIT|1, 0, "Render Daemon", 692,90,192,20, &G.scene->r.scemode, 0, 0, 0, 0, "Let external network render current scene"); + + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT,B_PLAYANIM, "PLAY", 692,40,94,33, 0, 0, 0, 0, 0, "Play animation of rendered images/avi (searches Pics: field)"); + + uiDefButS(block, NUM, B_RTCHANGED, "rt:", 790,40,95,33, &G.rt, 0.0, 256.0, 0, 0, "General testing/debug button"); + + uiDefButS(block, ROW,B_DIFF,"BW", 892, 10,74,20, &G.scene->r.planes, 5.0,(float)R_PLANESBW, 0, 0, "Images are saved with BW (grayscale) data"); + uiDefButS(block, ROW,B_DIFF,"RGB", 968, 10,74,20, &G.scene->r.planes, 5.0,(float)R_PLANES24, 0, 0, "Images are saved with RGB (color) data"); + uiDefButS(block, ROW,B_DIFF,"RGBA", 1044, 10,75,20, &G.scene->r.planes, 5.0,(float)R_PLANES32, 0, 0, "Images are saved with RGB and Alpha data (if supported)"); + + yofs = 54; + +#ifdef __sgi + yofs = 76; + uiDefButS(block, NUM,B_DIFF,"MaxSize:", 892,32,165,20, &G.scene->r.maximsize, 0.0, 500.0, 0, 0, "Maximum size per frame to save in an SGI movie"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|12,0,"Cosmo", 1059,32,60,20, &G.scene->r.mode, 0, 0, 0, 0, "Attempt to save SGI movies using Cosmo hardware"); + uiBlockSetCol(block, BUTGREY); +#endif + + uiDefButS(block, MENU,B_FILETYPEMENU,imagetype_pup(), 892,yofs,174,20, &G.scene->r.imtype, 0, 0, 0, 0, "Images are saved in this file format"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|11,0, "Crop", 1068,yofs,51,20, &G.scene->r.mode, 0, 0, 0, 0, "Exclude border rendering from total image"); + uiBlockSetCol(block, BUTGREY); + + yofs -= 22; + + if(G.scene->r.quality==0) G.scene->r.quality= 90; + +#ifdef _WIN32 + if (G.scene->r.imtype == R_AVICODEC) { +#else + if (0) { +#endif + uiDefBut(block, BUT,B_SELECTCODEC, "Select Codec", 892,yofs,112,20, 0, 0, 0, 0, 0, "Set codec settings for AVI Codec"); + } else { + uiDefButS(block, NUM,0, "Quality:", 892,yofs,112,20, &G.scene->r.quality, 10.0, 100.0, 0, 0, "Quality setting for JPEG images, AVI Jpeg and SGI movies"); + } + uiDefButS(block, NUM,REDRAWSEQ,"Frs/sec:", 1007,yofs,112,20, &G.scene->r.frs_sec, 1.0, 120.0, 0, 0, "Frames per second, for AVI and Sequence window grid"); + + uiDefButS(block, NUM,REDRAWSEQ,"Sta:", 692,10,94,24, &G.scene->r.sfra,1.0,18000.0, 0, 0, "The start frame of the animation"); + uiDefButS(block, NUM,REDRAWSEQ,"End:", 790,10,95,24, &G.scene->r.efra,1.0,18000.0, 0, 0, "The end frame of the animation"); + + uiDefBlockBut(block, framing_render_menu, NULL, "Game framing settings |>> ", 892, 169, 227, 20, "Display game framing settings"); + + uiDefButS(block, NUM,REDRAWVIEWCAM,"SizeX:", 892 ,136,112,27, &G.scene->r.xsch, 4.0, 10000.0, 0, 0, "The image width in pixels"); + uiDefButS(block, NUM,REDRAWVIEWCAM,"SizeY:", 1007,136,112,27, &G.scene->r.ysch, 4.0,10000.0, 0, 0, "The image height in scanlines"); + uiDefButS(block, NUM,REDRAWVIEWCAM,"AspX:", 892 ,114,112,20, &G.scene->r.xasp, 1.0,200.0, 0, 0, "The horizontal aspect ratio"); + uiDefButS(block, NUM,REDRAWVIEWCAM,"AspY:", 1007,114,112,20, &G.scene->r.yasp, 1.0,200.0, 0, 0, "The vertical aspect ratio"); + + uiDefBut(block, BUT,B_PR_PAL, "PAL", 1146,170,133,18, 0, 0, 0, 0, 0, "Size preset: Image size - 720x576, Aspect ratio - 54x51"); + uiDefBut(block, BUT,B_PR_PRESET, "Default", 1146,149,133,18, 0, 0, 0, 0, 0, "Same as PAL, with render settings (OSA, Shadows, Fields)"); + uiDefBut(block, BUT,B_PR_PRV, "Preview", 1146,115,133,18, 0, 0, 0, 0, 0, "Size preset: Image size - 640x512, Render size 50%"); + uiDefBut(block, BUT,B_PR_PC, "PC", 1146,94,133,18, 0, 0, 0, 0, 0, "Size preset: Image size - 640x480, Aspect ratio - 100x100"); + uiDefBut(block, BUT,B_PR_PAL169, "PAL 16:9", 1146,73,133,18, 0, 0, 0, 0, 0, "Size preset: Image size - 720x576, Aspect ratio - 64x45"); + uiDefBut(block, BUT,B_PR_PANO, "PANO", 1146,52,133,18, 0, 0, 0, 0, 0, "Standard panorama settings"); + uiDefBut(block, BUT,B_PR_FULL, "FULL", 1146,31,133,18, 0, 0, 0, 0, 0, "Size preset: Image size - 1280x1024, Aspect ratio - 1x1"); + uiDefButS(block, TOG|BIT|15, B_REDR, "Unified Renderer", 1146,10,133,18, + &G.scene->r.mode, 0, 0, 0, 0, + "Use the unified renderer."); + + uiDrawBlock(block); +} + +/* ********************* CONSTRAINT ***************************** */ + +static void activate_constraint_ipo_func (void *arg1v, void *unused) +{ + + bConstraint *con = arg1v; + bConstraintChannel *chan; + ListBase *conbase; + Ipo *ipo = NULL; + + get_constraint_client(NULL, NULL, NULL); + + conbase = get_constraint_client_channels(1); + + if (!conbase) + return; + + /* See if this list already has an appropriate channel */ + chan = find_constraint_channel(conbase, con->name); + + if (!chan){ + /* Add a new constraint channel */ + chan = add_new_constraint_channel(con->name); + BLI_addtail(conbase, chan); + } + + /* Ensure there is an ipo to display */ + if (!chan->ipo){ + chan->ipo = add_ipo(con->name, IPO_CO); + } + + /* Make this the active channel */ + OBACT->activecon = chan; + + allqueue(REDRAWIPO, 0); + allqueue(REDRAWNLA, 0); + +} + +static void del_constraint_func (void *arg1v, void *arg2v) +{ + bConstraint *con= arg1v; + Object *ob; + + ListBase *lb= arg2v; + + ob=OBACT; + + if (ob->activecon && !strcmp(ob->activecon->name, con->name)) + ob->activecon = NULL; + + free_constraint_data (con); + + BLI_freelinkN(lb, con); + + allqueue(REDRAWBUTSCONSTRAINT, 0); + allqueue(REDRAWIPO, 0); + +} + +static void verify_constraint_name_func (void *data, void *data2_unused) +{ + ListBase *conlist; + bConstraint *con; + char ownerstr[64]; + short type; + + con = (bConstraint*) data; + if (!con) + return; + + conlist = get_constraint_client(ownerstr, &type, NULL); + unique_constraint_name (con, conlist); +} + +static void constraint_changed_func (void *data, void *data2_unused) +{ + bConstraint *con = (bConstraint*) data; + + if (con->type == con->otype) + return; + + free_constraint_data (con); + con->data = new_constraint_data(con->type); + +} + +static void move_constraint_func (void *datav, void *data2_unused) +{ + bConstraint *constraint_to_move= datav; + int val; + ListBase *conlist; + char ownerstr[64]; + short type; + bConstraint *curCon, *con, *neighbour; + + val= pupmenu("Move up%x1|Move down %x2"); + + con = constraint_to_move; + + if(val>0) { + conlist = get_constraint_client(ownerstr, &type, NULL); + for (curCon = conlist->first; curCon; curCon = curCon->next){ + if (curCon == con){ + /* Move up */ + if (val == 1 && con->prev){ + neighbour = con->prev; + BLI_remlink(conlist, neighbour); + BLI_insertlink(conlist, con, neighbour); + } + /* Move down */ + else if (val == 2 && con->next){ + neighbour = con->next; + BLI_remlink (conlist, con); + BLI_insertlink(conlist, neighbour, con); + } + break; + } + } + } +} + +static void get_constraint_typestring (char *str, bConstraint *con) +{ + switch (con->type){ + case CONSTRAINT_TYPE_CHILDOF: + strcpy (str, "Child Of"); + return; + case CONSTRAINT_TYPE_NULL: + strcpy (str, "Null"); + return; + case CONSTRAINT_TYPE_TRACKTO: + strcpy (str, "Track To"); + return; + case CONSTRAINT_TYPE_KINEMATIC: + strcpy (str, "IK Solver"); + return; + case CONSTRAINT_TYPE_ROTLIKE: + strcpy (str, "Copy Rotation"); + return; + case CONSTRAINT_TYPE_LOCLIKE: + strcpy (str, "Copy Location"); + return; + case CONSTRAINT_TYPE_ACTION: + strcpy (str, "Action"); + return; + default: + strcpy (str, "Unknown"); + return; + } +} + +static BIFColorID get_constraint_col(bConstraint *con) +{ + switch (con->type) { + case CONSTRAINT_TYPE_NULL: + return BUTWHITE; + case CONSTRAINT_TYPE_KINEMATIC: + return BUTPURPLE; + case CONSTRAINT_TYPE_TRACKTO: + return BUTGREEN; + case CONSTRAINT_TYPE_ROTLIKE: + return BUTBLUE; + case CONSTRAINT_TYPE_LOCLIKE: + return BUTYELLOW; + case CONSTRAINT_TYPE_ACTION: + return BUTPINK; + default: + return REDALERT; + } +} + +static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, short *xco, short *yco, short type) +{ + uiBut *but; + char typestr[64]; + short height, width = 268; + BIFColorID curCol; + + uiBlockSetEmboss(block, UI_EMBOSSW); + + get_constraint_typestring (typestr, con); + + curCol = get_constraint_col(con); + /* Draw constraint header */ + uiBlockSetCol(block, BUTSALMON); + + but = uiDefIconBut(block, BUT, B_CONSTRAINT_REDRAW, ICON_X, *xco, *yco, 20, 20, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint"); + + uiButSetFunc(but, del_constraint_func, con, list); + + if (con->flag & CONSTRAINT_EXPAND){ + uiBlockSetCol(block, BUTYELLOW); + + if (con->flag & CONSTRAINT_DISABLE) + uiBlockSetCol(block, REDALERT); + + if (type==TARGET_BONE) + but = uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Bone Constraint%t|Track To%x2|IK Solver%x3|Copy Rotation%x8|Copy Location%x9|Action%x12|Null%x0", *xco+20, *yco, 100, 20, &con->type, 0.0, 0.0, 0.0, 0.0, "Constraint type"); + else + but = uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Object Constraint%t|Track To%x2|Copy Rotation%x8|Copy Location%x9|Null%x0", *xco+20, *yco, 100, 20, &con->type, 0.0, 0.0, 0.0, 0.0, "Constraint type"); + + uiButSetFunc(but, constraint_changed_func, con, NULL); + con->otype = con->type; + + but = uiDefBut(block, TEX, B_CONSTRAINT_REDRAW, "", *xco+120, *yco, 128, 20, con->name, 0.0, 32.0, 0.0, 0.0, "Constraint name"); + uiButSetFunc(but, verify_constraint_name_func, con, NULL); + } + else{ + uiBlockSetEmboss(block, UI_EMBOSSP); + uiBlockSetCol(block, BUTGREY); + + if (con->flag & CONSTRAINT_DISABLE){ + uiBlockSetCol(block, REDALERT); + BIF_set_color(REDALERT, COLORSHADE_MEDIUM); + } + else + BIF_set_color(curCol, COLORSHADE_MEDIUM); + + glRects(*xco+20, *yco, *xco+248, *yco+20); + + but = uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+20, *yco, 100, 20, NULL, 0.0, 0.0, 0.0, 0.0, ""); + uiButSetFunc(but, move_constraint_func, con, NULL); + but = uiDefBut(block, LABEL, B_CONSTRAINT_TEST, con->name, *xco+120, *yco, 128, 20, NULL, 0.0, 0.0, 0.0, 0.0, ""); + uiButSetFunc(but, move_constraint_func, con, NULL); + } + + uiBlockSetCol(block, BUTGREY); + + uiBlockSetEmboss(block, UI_EMBOSSW); + uiDefIconButS(block, ICONTOG|BIT|CONSTRAINT_EXPAND_BIT, B_CONSTRAINT_REDRAW, ICON_RIGHTARROW, *xco+248, *yco, 20, 20, &con->flag, 0.0, 0.0, 0.0, 0.0, "Collapse"); + + + /* Draw constraint data*/ +#ifdef __CON_IPO + if (con->type!=CONSTRAINT_TYPE_NULL) + { + uiDefBut(block, NUMSLI|FLO, B_CONSTRAINT_REDRAW, "Influence:", *xco+280, *yco, 196, 20, &con->enforce, 0.0, 1.0, 0.0, 0.0, "Amount of influence this constraint will have on the final solution"); + but = uiDefBut(block, BUT, B_CONSTRAINT_REDRAW, "Edit Ipo", *xco+480, *yco, 64, 20, 0, 0.0, 1.0, 0.0, 0.0, "Show this constraint's ipo in the object's Ipo window"); + /* If this is on an object, add the constraint to the object */ + uiButSetFunc (but, activate_constraint_ipo_func, con, NULL); + /* If this is on a bone, add the constraint to the action (if any) */ + } +#endif + + if (!(con->flag & CONSTRAINT_EXPAND)){ + (*yco)-=21; + return; + } + + switch (con->type){ + case CONSTRAINT_TYPE_ACTION: + { + bActionConstraint *data = con->data; + bArmature *arm; + + height = 86; + BIF_set_color(curCol, COLORSHADE_GREY); + glRects(*xco, *yco-height, *xco+width, *yco); + uiEmboss((float)*xco, (float)*yco-height, (float)*xco+width, (float)*yco, 1); + + /* Draw target parameters */ + uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object"); + + arm = get_armature(data->tar); + if (arm){ + but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone"); + } + else + strcpy (data->subtarget, ""); + + /* Draw action button */ + uiDefIDPoinBut(block, test_actionpoin_but, B_CONSTRAINT_CHANGETARGET, "AC:", *xco+((width/2)-120), *yco-60, 80, 18, &data->act, "Action containing the keyed motion for this bone"); + + uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "Start:", *xco+((width/2)-40), *yco-60, 80, 18, &data->start, 1, 18000, 0.0, 0.0, "Starting frame of the keyed motion"); + uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "End:", *xco+((width/2)+40), *yco-60, 80, 18, &data->end, 1, 18000, 0.0, 0.0, "Ending frame of the keyed motion"); + + /* Draw XYZ toggles */ + uiDefButI(block, MENU, B_CONSTRAINT_REDRAW, "Key on%t|X Rot%x0|Y Rot%x1|Z Rot%x2", *xco+((width/2)-120), *yco-80, 80, 18, &data->type, 0, 24, 0, 0, "Specify which transformation channel from the target is used to key the action"); + uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Min:", *xco+((width/2)-40), *yco-80, 80, 18, &data->min, -180, 180, 0, 0, "Minimum value for target channel range"); + uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Max:", *xco+((width/2)+40), *yco-80, 80, 18, &data->max, -180, 180, 0, 0, "Maximum value for target channel range"); + + } + break; + case CONSTRAINT_TYPE_LOCLIKE: + { + bLocateLikeConstraint *data = con->data; + bArmature *arm; + height = 66; + BIF_set_color(curCol, COLORSHADE_GREY); + glRects(*xco, *yco-height, *xco+width, *yco); + uiEmboss((float)*xco, (float)*yco-height, (float)*xco+width, (float)*yco, 1); + + /* Draw target parameters */ + uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object"); + + arm = get_armature(data->tar); + if (arm){ + but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone"); + } + else + strcpy (data->subtarget, ""); + + /* Draw XYZ toggles */ + but=uiDefButI(block, TOG|BIT|0, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component"); + but=uiDefButI(block, TOG|BIT|1, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component"); + but=uiDefButI(block, TOG|BIT|2, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component"); + } + break; + case CONSTRAINT_TYPE_ROTLIKE: + { + bRotateLikeConstraint *data = con->data; + bArmature *arm; + height = 46; + BIF_set_color(curCol, COLORSHADE_GREY); + glRects(*xco, *yco-height, *xco+width, *yco); + uiEmboss((float)*xco, (float)*yco-height, (float)*xco+width, (float)*yco, 1); + + uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object"); + + arm = get_armature(data->tar); + if (arm){ + but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone"); + } + else + strcpy (data->subtarget, ""); + + } + break; + case CONSTRAINT_TYPE_KINEMATIC: + { + bKinematicConstraint *data = con->data; + bArmature *arm; + + height = 66; + BIF_set_color(curCol, COLORSHADE_GREY); + glRects(*xco, *yco-height, *xco+width, *yco); + uiEmboss((float)*xco, (float)*yco-height, (float)*xco+width, (float)*yco, 1); + + uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Tolerance:", *xco+((width/2)-96), *yco-20, 96, 18, &data->tolerance, 0.0001, 1.0, 0.0, 0.0, "Maximum distance to target after solving"); + uiDefButI(block, NUM, B_CONSTRAINT_REDRAW, "Iterations:", *xco+((width/2)), *yco-20, 96, 18, &data->iterations, 1, 10000, 0.0, 0.0, "Maximum number of solving iterations"); + + uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-40, 96, 18, &data->tar, "Target Object"); + + arm = get_armature(data->tar); + if (arm){ + but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-60,96,18, &data->subtarget, 0, 24, 0, 0, "Bone"); + } + else + strcpy (data->subtarget, ""); + + } + break; + case CONSTRAINT_TYPE_NULL: + { + height = 20; + BIF_set_color(curCol, COLORSHADE_GREY); + glRects(*xco, *yco-height, *xco+width, *yco); + uiEmboss((float)*xco, (float)*yco-height, (float)*xco+width, (float)*yco, 1); + } + break; + case CONSTRAINT_TYPE_TRACKTO: + { + bTrackToConstraint *data = con->data; + bArmature *arm; + + height = 46; + BIF_set_color(curCol, COLORSHADE_GREY); + glRects(*xco, *yco-height, *xco+width, *yco); + uiEmboss((float)*xco, (float)*yco-height, (float)*xco+width, (float)*yco, 1); + + uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object"); + + arm = get_armature(data->tar); + if (arm){ + but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone"); + } + else + strcpy (data->subtarget, ""); + } + break; + default: + height = 0; + break; + } + + (*yco)-=(24+height); + +} + +static void constraintbuts(void) +{ + short xco, yco, type; + uiBlock *block; + char str[32]; + ListBase *conlist; + char ownerstr[64]; + bConstraint *curcon; + + xco = 320; + yco = 195; + + sprintf(str, "buttonswin %d", curarea->win); + + block= uiNewBlock(&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + conlist = get_constraint_client(ownerstr, &type, NULL); + + if (conlist){ + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_CONSTRAINT_ADD, "Add", xco, yco, 95, 20, 0, 0.0, 0, 0, 0,"Add new constraint"); + + /* Go through the list of constraints and draw them */ + xco = 465; + yco = 195; + + for (curcon = conlist->first; curcon; curcon=curcon->next) + { + /* Draw default constraint header */ + draw_constraint(block, conlist, curcon, &xco, &yco, type); + } + + } + + uiDrawBlock(block); + +} + +static void do_constraintbuts(unsigned short event) +{ + ListBase *list; + short type; + + switch(event) { + case B_CONSTRAINT_CHANGENAME: + break; + case B_CONSTRAINT_TEST: + test_scene_constraints(); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWBUTSCONSTRAINT, 0); + break; + case B_CONSTRAINT_REDRAW: + test_scene_constraints(); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWBUTSCONSTRAINT, 0); + break; + case B_CONSTRAINT_CHANGETARGET: + test_scene_constraints(); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWBUTSCONSTRAINT, 0); + break; + case B_CONSTRAINT_CHANGETYPE: + test_scene_constraints(); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWBUTSCONSTRAINT, 0); + break; + case B_CONSTRAINT_ADD: + { + bConstraint *con; + // ListBase *chanbase; + // bConstraintChannel *chan; + + Object *ob = OBACT; + list = get_constraint_client(NULL, &type, NULL); + // chanbase= get_constraint_client_channels(0); + if (list){ + con = add_new_constraint(); + unique_constraint_name(con, list); + // chan = add_new_constraint_channel(con->name); + // ob->activecon = chan; + // BLI_addtail(chanbase, chan); + BLI_addtail(list, con); + } + test_scene_constraints(); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWBUTSCONSTRAINT, 0); + } + break; + case B_CONSTRAINT_DEL: + test_scene_constraints(); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWBUTSCONSTRAINT, 0); + break; + default: + break; + } +} + +/* ********************* GAME ***************************** */ + +/* in editsca.c */ + +/* ***************************<>******************************** */ + +void drawbutspace(void) +{ + SpaceButs *sbuts= curarea->spacedata.first; + View2D *v2d= &sbuts->v2d; + ID *id; + Object *ob; + float vec[2]; + + if(curarea->headertype==0) { + ID *id, *idfrom; + + buttons_active_id(&id, &idfrom); + G.buts->lockpoin= id; + } + + ob= OBACT; + + myortho2(v2d->cur.xmin, v2d->cur.xmax, v2d->cur.ymin, v2d->cur.ymax); + + glShadeModel(GL_SMOOTH); + glBegin(GL_QUADS); + cpack(0x909090); + vec[0]= v2d->cur.xmin; + vec[1]= v2d->cur.ymax-15; + glVertex2fv(vec); + vec[0]= v2d->cur.xmax; + glVertex2fv(vec); + cpack(0x646464); + vec[1]= v2d->cur.ymax; + glVertex2fv(vec); + vec[0]= v2d->cur.xmin; + glVertex2fv(vec); + glEnd(); + glShadeModel(GL_FLAT); + + cpack(0x909090); + glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax-15); + + uiSetButLock(G.scene->id.lib!=0, "Can't edit library data"); + uiFreeBlocksWin(&curarea->uiblocks, curarea->win); + + switch(G.buts->mainb) { + case BUTS_VIEW: + viewbuts(); + break; + case BUTS_LAMP: + lampbuts(); + break; + case BUTS_MAT: + if(ob==0) return; + if(ob->type>=OB_LAMP) return; + + matbuts(); + break; + case BUTS_TEX: + texbuts(); + break; + case BUTS_ANIM: + animbuts(); + break; + case BUTS_WORLD: + worldbuts(); + break; + case BUTS_RENDER: + renderbuts(); + break; + case BUTS_GAME: + gamebuts(); + break; + case BUTS_FPAINT: + fpaintbuts(); + break; + case BUTS_RADIO: + radiobuts(); + break; + case BUTS_SOUND: + soundbuts(); + break; + case BUTS_CONSTRAINT: + constraintbuts(); + break; + case BUTS_SCRIPT: + scriptbuts(); + break; + case BUTS_EDIT: + if(ob==0) return; + + common_editbuts(); + + id= ob->data; + if(id && id->lib) uiSetButLock(1, "Can't edit library data"); + + if(ob->type==OB_MESH) meshbuts(); + else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) { + curvebuts(); + if(ob->type==OB_FONT) fontbuts(); + } + else if(ob->type==OB_CAMERA) camerabuts(); + else if(ob->type==OB_MBALL) mballbuts(); + else if(ob->type==OB_LATTICE) latticebuts(); + else if(ob->type==OB_IKA) ikabuts(); +#ifdef __NLA + else if(ob->type==OB_ARMATURE) armaturebuts(); +#endif + + break; + } + + uiClearButLock(); + + test_butspace(); + + curarea->win_swap= WIN_BACK_OK; +} + +void do_blenderbuttons(unsigned short event) +{ + SpaceButs *buts; + + /* teken ook de soortgelijke windows? */ + buts= curarea->spacedata.first; + if(buts->mainb==BUTS_VIEW) allqueue(REDRAWBUTSVIEW, curarea->win); + else if(buts->mainb==BUTS_LAMP) allqueue(REDRAWBUTSLAMP, curarea->win); + else if(buts->mainb==BUTS_MAT || buts->mainb==BUTS_TEX) { + allqueue(REDRAWBUTSMAT, curarea->win); + allqueue(REDRAWBUTSTEX, curarea->win); + } + else if(buts->mainb==BUTS_WORLD) allqueue(REDRAWBUTSWORLD, curarea->win); + else if(buts->mainb==BUTS_ANIM) allqueue(REDRAWBUTSANIM, curarea->win); + else if(buts->mainb==BUTS_RENDER) allqueue(REDRAWBUTSRENDER, curarea->win); + else if(buts->mainb==BUTS_EDIT) allqueue(REDRAWBUTSEDIT, curarea->win); + else if(buts->mainb==BUTS_FPAINT) allqueue(REDRAWBUTSGAME, curarea->win); + else if(buts->mainb==BUTS_RADIO) allqueue(REDRAWBUTSRADIO, curarea->win); + else if(buts->mainb==BUTS_SCRIPT) allqueue(REDRAWBUTSSCRIPT, curarea->win); + else if(buts->mainb==BUTS_SOUND) allqueue(REDRAWBUTSSOUND, curarea->win); + else if(buts->mainb==BUTS_CONSTRAINT) allqueue(REDRAWBUTSCONSTRAINT, curarea->win); + + if(event<=100) { + do_global_buttons(event); + } + else if(event<=B_VIEWBUTS) { + do_viewbuts(event); + } + else if(event<=B_LAMPBUTS) { + do_lampbuts(event); + } + else if(event<=B_MATBUTS) { + do_matbuts(event); + } + else if(event<=B_TEXBUTS) { + do_texbuts(event); + } + else if(event<=B_ANIMBUTS) { + do_animbuts(event); + } + else if(event<=B_WORLDBUTS) { + do_worldbuts(event); + } + else if(event<=B_RENDERBUTS) { + do_renderbuts(event); + } + else if(event<=B_COMMONEDITBUTS) { + do_common_editbuts(event); + } + else if(event<=B_MESHBUTS) { + do_meshbuts(event); + } + else if(event<=B_CURVEBUTS) { + do_curvebuts(event); + } + else if(event<=B_FONTBUTS) { + do_fontbuts(event); + } + else if(event<=B_IKABUTS) { + do_ikabuts(event); + } + else if(event<=B_CAMBUTS) { + ; + } + else if(event<=B_MBALLBUTS) { + do_mballbuts(event); + } + else if(event<=B_LATTBUTS) { + do_latticebuts(event); + } + else if(event<=B_GAMEBUTS) { + do_gamebuts(event); + } + else if(event<=B_FPAINTBUTS) { + do_fpaintbuts(event); + } + else if(event<=B_RADIOBUTS) { + do_radiobuts(event); + } + else if(event<=B_SCRIPTBUTS) { + do_scriptbuts(event); + } + else if(event<=B_SOUNDBUTS) { + do_soundbuts(event); + } + else if(event<=B_CONSTRAINTBUTS) { + do_constraintbuts(event); + } + else if(event>=REDRAWVIEW3D) allqueue(event, 0); +} + + +void redraw_test_buttons(Base *new) +{ + ScrArea *sa; + SpaceButs *buts; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + + if(buts->mainb==BUTS_LAMP) { + allqueue(REDRAWBUTSLAMP, 0); + BIF_preview_changed(buts); + } + else if(buts->mainb==BUTS_MAT) { + allqueue(REDRAWBUTSMAT, 0); + BIF_preview_changed(buts); + } + else if(buts->mainb==BUTS_TEX) { + allqueue(REDRAWBUTSTEX, 0); + if(new && new->object->type==OB_LAMP) buts->texfrom= 2; + else buts->texfrom= 0; + BIF_preview_changed(buts); + } + else if(buts->mainb==BUTS_ANIM) { + allqueue(REDRAWBUTSANIM, 0); + } + else if(buts->mainb==BUTS_EDIT) { + allqueue(REDRAWBUTSEDIT, 0); + } + else if(buts->mainb==BUTS_GAME) { + allqueue(REDRAWBUTSGAME, 0); + } + else if(buts->mainb==BUTS_FPAINT) { + allqueue(REDRAWBUTSGAME, 0); + } + else if(buts->mainb==BUTS_SCRIPT) { + allqueue(REDRAWBUTSSCRIPT, 0); + } + else if(buts->mainb==BUTS_SOUND) { + allqueue(REDRAWBUTSSOUND, 0); + } + else if(buts->mainb==BUTS_CONSTRAINT) { + allqueue(REDRAWBUTSCONSTRAINT, 0); + } + } + sa= sa->next; + } +} + +void clever_numbuts_buts() +{ + Material *ma; + Lamp *la; + World *wo; + static char hexrgb[8]; /* Uh... */ + static char hexspec[8]; /* Uh... */ + static char hexmir[8]; /* Uh... */ + static char hexho[8]; + static char hexze[8]; + int rgb[3]; + + switch (G.buts->mainb){ + case BUTS_FPAINT: + + sprintf(hexrgb, "%02X%02X%02X", (int)(Gvp.r*255), (int)(Gvp.g*255), (int)(Gvp.b*255)); + + add_numbut(0, TEX, "RGB:", 0, 6, hexrgb, "HTML Hex value for the RGB color"); + do_clever_numbuts("Vertex Paint RGB Hex Value", 1, REDRAW); + + /* Assign the new hex value */ + sscanf(hexrgb, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); + Gvp.r= (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; + Gvp.g = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; + Gvp.b = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; + + break; + case BUTS_LAMP: + la= G.buts->lockpoin; + if (la){ + sprintf(hexrgb, "%02X%02X%02X", (int)(la->r*255), (int)(la->g*255), (int)(la->b*255)); + add_numbut(0, TEX, "RGB:", 0, 6, hexrgb, "HTML Hex value for the lamp color"); + do_clever_numbuts("Lamp RGB Hex Values", 1, REDRAW); + sscanf(hexrgb, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); + la->r = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; + la->g = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; + la->b = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; + BIF_preview_changed(G.buts); + } + break; + case BUTS_WORLD: + wo= G.buts->lockpoin; + if (wo){ + sprintf(hexho, "%02X%02X%02X", (int)(wo->horr*255), (int)(wo->horg*255), (int)(wo->horb*255)); + sprintf(hexze, "%02X%02X%02X", (int)(wo->zenr*255), (int)(wo->zeng*255), (int)(wo->zenb*255)); + add_numbut(0, TEX, "Zen:", 0, 6, hexze, "HTML Hex value for the Zenith color"); + add_numbut(1, TEX, "Hor:", 0, 6, hexho, "HTML Hex value for the Horizon color"); + do_clever_numbuts("World RGB Hex Values", 2, REDRAW); + + sscanf(hexho, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); + wo->horr = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; + wo->horg = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; + wo->horb = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; + sscanf(hexze, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); + wo->zenr = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; + wo->zeng = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; + wo->zenb = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; + BIF_preview_changed(G.buts); + + } + break; + case BUTS_MAT: + + ma= G.buts->lockpoin; + + /* Build a hex value */ + if (ma){ + sprintf(hexrgb, "%02X%02X%02X", (int)(ma->r*255), (int)(ma->g*255), (int)(ma->b*255)); + sprintf(hexspec, "%02X%02X%02X", (int)(ma->specr*255), (int)(ma->specg*255), (int)(ma->specb*255)); + sprintf(hexmir, "%02X%02X%02X", (int)(ma->mirr*255), (int)(ma->mirg*255), (int)(ma->mirb*255)); + + add_numbut(0, TEX, "Col:", 0, 6, hexrgb, "HTML Hex value for the RGB color"); + add_numbut(1, TEX, "Spec:", 0, 6, hexspec, "HTML Hex value for the Spec color"); + add_numbut(2, TEX, "Mir:", 0, 6, hexmir, "HTML Hex value for the Mir color"); + do_clever_numbuts("Material RGB Hex Values", 3, REDRAW); + + /* Assign the new hex value */ + sscanf(hexrgb, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); + ma->r = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; + ma->g = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; + ma->b = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; + sscanf(hexspec, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); + ma->specr = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; + ma->specg = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; + ma->specb = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; + sscanf(hexmir, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); + ma->mirr = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; + ma->mirg = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; + ma->mirb = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; + + BIF_preview_changed(G.buts); + } + break; + } +} diff --git a/source/blender/src/cmap.tga.c b/source/blender/src/cmap.tga.c new file mode 100644 index 00000000000..8c76d8be460 --- /dev/null +++ b/source/blender/src/cmap.tga.c @@ -0,0 +1,88 @@ +/* DataToC output of file <cmap_tga> */ +/* + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +int datatoc_cmap_tga_size= 13400; +char datatoc_cmap_tga[]= {"\x00\x01\x01\x00\x00\x00\x01\x18\x00\x00\x00\x00\x9a\x00\x50\x00\x08\x08\xf3\xf3\xf3\xdb\xdb\xdb\xc4\xc4\xc4\xad\xad\xad\x96\x96\x96\x7f\x7f\x7f\x67\x67\x67\x50\x50\x50\x39\x39\x39\x22\x22\x22\x0b\x0b\x0b\xf4\xf4\xf4\xe6\xc8\xec\xe6\xa4\xec\xe6\x7f\xec\xe6\x5b\xec\xe6\x36\xec\xe6\x12\xec\xb3\xec\xec\xb3\xc8\xec\xb3\xa4\xec\xb3\x7f\xec\xb3\x5b\xec" \ +"\xb3\x36\xec\xb3\x12\xec\x80\xec\xec\x80\xc8\xec\x80\xa4\xec\x80\x7f\xec\x80\x5b\xec\x80\x36\xec\x80\x12\xec\x4d\xec\xec\x4d\xc8\xec\x4d\xa4\xec\x4d\x7f\xec\x4d\x5b\xec\x4d\x36\xec\x4d\x12\xec\x1a\xec\xec\x1a\xc8\xec\x1a\xa4\xec\x1a\x7f\xec\x1a\x5b\xec\x1a\x36\xec\x1a\x12\xec\xe6\xec\xc8\xe6\xc8\xc8\xe6\xa4\xc8\xe6\x7f\xc8\xe6\x5b\xc8\xe6\x36\xc8\xe6\x12\xc8\xb3\xec\xc8\xb3\xc8\xc8\xb3\xa4\xc8\xb3\x7f\xc8\xb3\x5b\xc8\xb3\x36\xc8\xb3\x12\xc8\x80\xec\xc8\x80\xc8\xc8\x80\xa4\xc8\x80\x7f\xc8\x80\x5b\xc8\x80\x36\xc8\x80\x12\xc8\x4d\xec\xc8\x4d\xc8\xc8\x4d\xa4\xc8\x4d\x7f\xc8\x4d\x5b\xc8\x4d\x36\xc8\x4d\x12\xc8\x1a\xec\xc8\x1a\xc8\xc8\x1a\xa4\xc8\x1a\x7f\xc8\x1a\x5b\xc8\x1a\x36\xc8\x1a\x12\xc8\xe6\xec\xa4\xe6\xc8\xa4\xe6\xa4\xa4\xe6\x7f\xa4\xe6\x5b\xa4\xe6\x36\xa4\xe6\x12\xa4\xb3\xec\xa4\xb3\xc8\xa4\xb3\xa4\xa4\xb3\x7f\xa4\xb3\x5b\xa4\xb3\x36\xa4\xb3\x12\xa4\x80\xec\xa4\x80\xc8\xa4\x80\xa4\xa4\x80\x7f\xa4\x80\x5b\xa4\x80\x36\xa4\x80\x12\xa4\x4d\xec\xa4\x4d\xc8\xa4\x4d\xa4\xa4\x4d\x7f\xa4\x4d\x5b\xa4\x4d\x36\xa4\x4d" \ +"\x12\xa4\x1a\xec\xa4\x1a\xc8\xa4\x1a\xa4\xa4\x1a\x7f\xa4\x1a\x5b\xa4\x1a\x36\xa4\x1a\x12\xa4\xe6\xec\x7f\xe6\xc8\x7f\xe6\xa4\x7f\xe6\x7f\x7f\xe6\x5b\x7f\xe6\x36\x7f\xe6\x12\x7f\xb3\xec\x7f\xb3\xc8\x7f\xb3\xa4\x7f\xb3\x7f\x7f\xb3\x5b\x7f\xb3\x36\x7f\xb3\x12\x7f\x80\xec\x7f\x80\xc8\x7f\x80\xa4\x7f\x80\x7f\x7f\x80\x5b\x7f\x80\x36\x7f\x80\x12\x7f\x4d\xec\x7f\x4d\xc8\x7f\x4d\xa4\x7f\x4d\x7f\x7f\x4d\x5b\x7f\x4d\x36\x7f\x4d\x12\x7f\x1a\xec\x7f\x1a\xc8\x7f\x1a\xa4\x7f\x1a\x7f\x7f\x1a\x5b\x7f\x1a\x36\x7f\x1a\x12\x7f\xe6\xec\x5b\xe6\xc8\x5b\xe6\xa4\x5b\xe6\x7f\x5b\xe6\x5b\x5b\xe6\x36\x5b\xe6\x12\x5b\xb3\xec\x5b\xb3\xc8\x5b\xb3\xa4\x5b\xb3\x7f\x5b\xb3\x5b\x5b\xb3\x36\x5b\xb3\x12\x5b\x80\xec\x5b\x80\xc8\x5b\x80\xa4\x5b\x80\x7f\x5b\x80\x5b\x5b\x80\x36\x5b\x80\x12\x5b\x4d\xec\x5b\x4d\xc8\x5b\x4d\xa4\x5b\x4d\x7f\x5b\x4d\x5b\x5b\x4d\x36\x5b\x4d\x12\x5b\x1a\xec\x5b\x1a\xc8\x5b\x1a\xa4\x5b\x1a\x7f\x5b\x1a\x5b\x5b\x1a\x36\x5b\x1a\x12\x5b\xe6\xec\x36\xe6\xc8\x36\xe6\xa4\x36\xe6\x7f\x36\xe6\x5b\x36\xe6\x36\x36\xe6\x12\x36\xb3\xec" \ +"\x36\xb3\xc8\x36\xb3\xa4\x36\xb3\x7f\x36\xb3\x5b\x36\xb3\x36\x36\xb3\x12\x36\x80\xec\x36\x80\xc8\x36\x80\xa4\x36\x80\x7f\x36\x80\x5b\x36\x80\x36\x36\x80\x12\x36\x4d\xec\x36\x4d\xc8\x36\x4d\xa4\x36\x4d\x7f\x36\x4d\x5b\x36\x4d\x36\x36\x4d\x12\x36\x1a\xec\x36\x1a\xc8\x36\x1a\xa4\x36\x1a\x7f\x36\x1a\x5b\x36\x1a\x36\x36\x1a\x12\x36\xe6\xec\x12\xe6\xc8\x12\xe6\xa4\x12\xe6\x7f\x12\xe6\x5b\x12\xe6\x36\x12\xe6\x12\x12\xb3\xec\x12\xb3\xc8\x12\xb3\xa4\x12\xb3\x7f\x12\xb3\x5b\x12\xb3\x36\x12\xb3\x12\x12\x80\xec\x12\x80\xc8\x12\x80\xa4\x12\x80\x7f\x12\x80\x5b\x12\x80\x36\x12\x80\x12\x12\x4d\xec\x12\x4d\xc8\x12\x4d\xa4\x12\x4d\x7f\x12\x4d\x5b\x12\x4d\x36\x12\x4d\x12\x12\x1a\xec\x12\x1a\xc8\x12\x1a\xa4\x12\x1a\x7f\x12\x1a\x5b\x12\x1a\x36\x12\x1a\x12\x12\x03\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02" \ +"\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x04\x07\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x04\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a" \ +"\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x04\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a" \ +"\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x04\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x04\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a" \ +"\x0a\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x04\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\xff\xff\xff\xff\xff\x09\x09\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x09\x09\x09\xff\xff\xff\xff\xff\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x04\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\xdc\xdc\xdc\xdc\xdc" \ +"\xdc\xdc\xdc\xdc\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x09\x09\x09\x09\x09\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x09\x09\x09\x09\x09\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x04\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02\x07\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\x09\x09\x09\x09\xdb\xdb\xdb\xdb\xdb\xdb\x09\x09\x09\x09\x09\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x09\x09\x09\x09\x09\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x09\x09\x09\x09\xdc\xdc\xdc\xdc" \ +"\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x02\x04\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02\x07\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x09\x09\x09\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x09\x09\x09\x09\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\x02\x04\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02\x07\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe" \ +"\xfe\xfe\xfe\xfe\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\x02\x04\x07\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x02\x07\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\xdc\x02\x04\x07\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x02\x07\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9" \ +"\xb9\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb7\xb7\xda\xda\xda\xda\xda\xda\xda\xda\xda\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xf6\xf6\xf6\xf6\xf6\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xb2\xb2\xb2\xb2\xb2\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\x02\x04\x07\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x02\x07\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb7\xb7\xb7\xb7\xda\xda\xda\xda\xda\xda\xda\xda\xda\xda\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xb2" \ +"\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\x02\x04\x07\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x02\x07\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xda\xda\xda\xda\xda\xda\xda\xda\xda\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\x02\x04\x07\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x02\x07\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xda\xda\xda\xda\xda\xda\xda\xda\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xf6" \ +"\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\x02\x04\x07\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\x02\x07\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb8\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xda\xda\xda\xda\xda\xda\xda\xda\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf7\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\x02\x04\x07\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\x02\x07\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb8" \ +"\xb8\xb8\xb8\xb8\xb8\xb8\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xda\xda\xda\xda\xda\xda\xda\xda\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xf6\xef\xef\xef\xef\xef\xef\xef\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xce\xce\xce\xce\xce\xce\xce\xab\xab\xab\xab\xab\xab\xab\xab\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb2\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\xb9\x02\x04\x07\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\xdb\x02\x07\x96\x96\x96\x96\x96\x96\x96\x96\x95\x95\x95\x95\x95\x95\x95\x94\x94\x94\x94\x94\x94\x94\x94\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xee\xef\xef\xef\xef\xef\xef\xef\xef\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xce\xce\xce\xce\xce\xce\xce\xab\xab\xab\xab\xab" \ +"\xab\xab\xab\x88\x88\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x02\x04\x07\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x02\x07\x96\x96\x96\x96\x96\x96\x96\x96\x95\x95\x95\x95\x95\x95\x94\x94\x94\x94\x94\x94\x94\x94\x93\x93\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xee\xee\xee\xef\xef\xef\xef\xef\xef\xef\xef\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xce\xce\xce\xce\xce\xce\xab\xab\xab\xab\xab\xab\xab\xab\x88\x88\x88\x88\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x02\x04\x07\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x02\x07\x96\x96\x96\x96\x96\x96\x96\x95\x95\x95\x95\x95\x95\x95\x94\x94\x94\x94\x94\x94\x94\x93\x93\x93\x93\x93\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xd9\xd9\xd9\xd9\xd9\xd9\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xf5\xf5\xf5" \ +"\xf5\xf5\xf5\xf5\xf5\xf5\xee\xee\xee\xee\xee\xef\xef\xef\xef\xef\xef\xef\xef\xf0\xf0\xf0\xf0\xf0\xf0\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xce\xce\xce\xce\xce\xce\xce\xab\xab\xab\xab\xab\xab\xab\x88\x88\x88\x88\x88\x88\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x02\x04\x07\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x02\x07\x96\x96\x96\x96\x96\x96\x96\x95\x95\x95\x95\x95\x95\x94\x94\x94\x94\x94\x94\x94\x93\x93\x93\x93\x93\x93\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xd9\xd9\xd9\xd9\xd9\xd9\xd9\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xee\xee\xee\xee\xee\xee\xee\xef\xef\xef\xef\xef\xef\xef\xef\xf0\xf0\xf0\xf0\xf0\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xce\xce\xce\xce\xce\xce\xab\xab\xab\xab\xab\xab\xab\x88\x88\x88\x88\x88\x88\x88\x88\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x96\x96\x96\x96\x96\x96\x96\x96\x96\x02\x04\x07\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x02\x07\x96\x96\x96\x96\x96\x96\x95\x95" \ +"\x95\x95\x95\x95\x94\x94\x94\x94\x94\x94\x94\x93\x93\x93\x93\x93\x93\x93\x93\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xd9\xd9\xd9\xd9\xd9\xd9\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xee\xee\xee\xee\xee\xee\xee\xee\xee\xef\xef\xef\xef\xef\xef\xef\xf0\xf0\xf0\xf0\xf0\xf0\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xce\xce\xce\xce\xce\xce\xab\xab\xab\xab\xab\xab\xab\x88\x88\x88\x88\x88\x88\x88\x88\x88\x88\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x96\x96\x96\x96\x96\x96\x96\x96\x96\x02\x04\x07\x08\x08\x08\x08\x08\x08\x08\x08\x08\x07\x07\x02\x07\x73\x73\x73\x73\x73\x73\x72\x72\x72\x72\x72\x71\x71\x71\x71\x71\x71\x71\x70\x70\x70\x70\x70\x92\x92\x92\x92\x92\xb5\xb5\xb5\xb5\xb5\xb5\xb5\xd8\xd8\xd8\xd8\xd8\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xed\xed\xed\xed\xed\xed\xed\xee\xee\xee\xee\xef\xef\xef\xef\xef\xef\xef\xf0\xf0\xf0\xf0\xf0\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xce\xce\xce\xce\xce\xce\xab\xab\xab\xab\xab\xab" \ +"\x88\x88\x88\x88\x88\x65\x65\x65\x65\x65\x65\x65\x6c\x6c\x6c\x6c\x6c\x6c\x6c\x6c\x73\x73\x73\x73\x73\x73\x73\x73\x02\x04\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x02\x07\x73\x73\x73\x73\x73\x73\x72\x72\x72\x72\x72\x71\x71\x71\x71\x71\x71\x71\x70\x70\x70\x70\x6f\x6f\x92\x92\x92\x92\x92\xb5\xb5\xb5\xb5\xb5\xb5\xb5\xd8\xd8\xd8\xd8\xd8\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xed\xed\xed\xed\xed\xed\xed\xee\xee\xee\xee\xee\xef\xef\xef\xef\xef\xef\xf0\xf0\xf0\xf0\xf0\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xce\xce\xce\xce\xce\xab\xab\xab\xab\xab\xab\xab\x88\x88\x88\x88\x65\x65\x65\x65\x65\x65\x65\x65\x6c\x6c\x6c\x6c\x6c\x6c\x6c\x6c\x73\x73\x73\x73\x73\x73\x73\x73\x02\x04\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x02\x07\x73\x73\x73\x73\x73\x73\x72\x72\x72\x72\x72\x71\x71\x71\x71\x71\x71\x70\x70\x70\x70\x6f\x6f\x6f\x6f\x92\x92\x92\x92\x92\xb5\xb5\xb5\xb5\xb5\xb5\xd8\xd8\xd8\xd8\xd8\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xf4\xf4\xf4\xf4" \ +"\xf4\xf4\xf4\xf4\xed\xed\xed\xed\xed\xed\xed\xed\xed\xee\xee\xee\xee\xef\xef\xef\xef\xef\xef\xef\xf0\xf0\xf0\xf0\xf0\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xf1\xce\xce\xce\xce\xab\xab\xab\xab\xab\xab\xab\x88\x88\x88\x88\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x6c\x6c\x6c\x6c\x6c\x6c\x6c\x6c\x73\x73\x73\x73\x73\x73\x73\x02\x04\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x02\x07\x73\x73\x73\x73\x73\x72\x72\x72\x72\x72\x71\x71\x71\x71\x71\x71\x70\x70\x70\x70\x70\x6f\x6f\x6f\x6f\x6f\x92\x92\x92\x92\xb5\xb5\xb5\xb5\xb5\xb5\xd8\xd8\xd8\xd8\xd8\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xed\xed\xed\xed\xed\xed\xed\xed\xe6\xe6\xe6\xe7\xe7\xe7\xe7\xe8\xe8\xe8\xe8\xe8\xe8\xe9\xe9\xe9\xe9\xe9\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xc7\xc7\xc7\xc7\xc7\xa4\xa4\xa4\xa4\xa4\xa4\x81\x81\x81\x81\x5e\x5e\x5e\x5e\x65\x65\x65\x65\x65\x65\x65\x65\x6c\x6c\x6c\x6c\x6c\x6c\x6c\x73\x73\x73\x73\x73\x73\x73\x02\x04\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x02\x07\x73\x73\x73\x73\x73\x72" \ +"\x72\x72\x72\x71\x71\x71\x71\x71\x71\x70\x70\x70\x70\x70\x6f\x6f\x6f\x6f\x6f\x6f\x6f\x92\x92\x92\x92\xb5\xb5\xb5\xb5\xb5\xb5\xd8\xd8\xd8\xd8\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xed\xed\xed\xed\xed\xed\xed\xe6\xe6\xe6\xe6\xe7\xe7\xe7\xe7\xe7\xe8\xe8\xe8\xe8\xe8\xe8\xe9\xe9\xe9\xe9\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xc7\xc7\xc7\xc7\xc7\xa4\xa4\xa4\xa4\xa4\x81\x81\x81\x81\x81\x5e\x5e\x5e\x5e\x5e\x65\x65\x65\x65\x65\x65\x65\x6c\x6c\x6c\x6c\x6c\x6c\x6c\x73\x73\x73\x73\x73\x73\x73\x02\x04\x07\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\x02\x07\x73\x73\x73\x73\x73\x72\x72\x72\x72\x71\x71\x71\x71\x71\x71\x70\x70\x70\x70\x6f\x6f\x6f\x6f\x6f\x6f\x6f\x6f\x92\x92\x92\x92\xb5\xb5\xb5\xb5\xb5\xb5\xd8\xd8\xd8\xd8\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xfb\xf4\xf4\xf4\xf4\xf4\xf4\xf4\xed\xed\xed\xed\xed\xed\xed\xe6\xe6\xe6\xe6\xe6\xe6\xe7\xe7\xe7\xe7\xe8\xe8\xe8\xe8\xe8\xe8\xe9\xe9\xe9\xe9\xea\xea\xea\xea\xea\xea\xea\xea\xea\xea\xc7\xc7\xc7\xc7\xa4\xa4\xa4\xa4\xa4\xa4\x81" \ +"\x81\x81\x81\x5e\x5e\x5e\x5e\x5e\x5e\x65\x65\x65\x65\x65\x65\x65\x65\x6c\x6c\x6c\x6c\x6c\x6c\x6c\x73\x73\x73\x73\x73\x73\x02\x04\x07\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\x02\x07\x50\x50\x50\x50\x50\x4f\x4f\x4f\x4f\x4e\x4e\x4e\x4e\x4e\x4d\x4d\x4d\x4d\x4d\x4c\x4c\x4c\x4c\x6e\x6e\x6e\x6e\x6e\x91\x91\x91\x91\xb4\xb4\xb4\xb4\xb4\xb4\xd7\xd7\xd7\xd7\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xec\xec\xec\xec\xec\xec\xec\xe5\xe5\xe5\xe6\xe6\xe6\xe6\xe7\xe7\xe7\xe7\xe8\xe8\xe8\xe8\xe8\xe9\xe9\xe9\xe9\xe9\xea\xea\xea\xea\xea\xea\xea\xea\xea\xc7\xc7\xc7\xc7\xa4\xa4\xa4\xa4\xa4\xa4\x81\x81\x81\x81\x5e\x5e\x5e\x5e\x3b\x3b\x3b\x42\x42\x42\x42\x42\x42\x42\x49\x49\x49\x49\x49\x49\x49\x50\x50\x50\x50\x50\x50\x02\x04\x07\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\x02\x07\x50\x50\x50\x50\x4f\x4f\x4f\x4f\x4f\x4e\x4e\x4e\x4e\x4e\x4d\x4d\x4d\x4d\x4c\x4c\x4c\x4c\x4b\x4b\x6e\x6e\x6e\x6e\x6e\x91\x91\x91\x91\xb4\xb4\xb4\xb4\xb4\xd7\xd7\xd7\xd7\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xf3\xf3\xf3" \ +"\xf3\xf3\xf3\xec\xec\xec\xec\xec\xec\xec\xe5\xe5\xe5\xe5\xe6\xe6\xe6\xe6\xe6\xe7\xe7\xe7\xe8\xe8\xe8\xe8\xe8\xe8\xe9\xe9\xe9\xe9\xea\xea\xea\xea\xea\xea\xea\xea\xea\xc7\xc7\xc7\xc7\xa4\xa4\xa4\xa4\xa4\x81\x81\x81\x81\x5e\x5e\x5e\x5e\x3b\x3b\x3b\x3b\x3b\x42\x42\x42\x42\x42\x42\x42\x49\x49\x49\x49\x49\x49\x50\x50\x50\x50\x50\x50\x02\x04\x07\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x02\x07\x50\x50\x50\x50\x4f\x4f\x4f\x4f\x4e\x4e\x4e\x4e\x4e\x4d\x4d\x4d\x4d\x4c\x4c\x4c\x4c\x4c\x4b\x4b\x4b\x6e\x6e\x6e\x6e\x91\x91\x91\x91\xb4\xb4\xb4\xb4\xb4\xd7\xd7\xd7\xd7\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xf3\xf3\xf3\xf3\xf3\xec\xec\xec\xec\xec\xec\xec\xec\xe5\xe5\xe5\xe5\xe5\xe6\xe6\xe6\xe6\xe7\xe7\xe7\xe7\xe8\xe8\xe8\xe8\xe8\xe9\xe9\xe9\xe9\xea\xea\xea\xea\xea\xea\xea\xea\xea\xc7\xc7\xc7\xa4\xa4\xa4\xa4\xa4\x81\x81\x81\x81\x5e\x5e\x5e\x5e\x5e\x3b\x3b\x3b\x3b\x3b\x42\x42\x42\x42\x42\x42\x42\x42\x49\x49\x49\x49\x49\x50\x50\x50\x50\x50\x50\x02\x04\x07\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x02\x07\x50\x50\x50\x50" \ +"\x4f\x4f\x4f\x4f\x4e\x4e\x4e\x4e\x4e\x4d\x4d\x4d\x4d\x4c\x4c\x4c\x4c\x4b\x4b\x4b\x4b\x4b\x6e\x6e\x6e\x6e\x91\x91\x91\xb4\xb4\xb4\xb4\xb4\xb4\xd7\xd7\xd7\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xf3\xf3\xf3\xf3\xf3\xf3\xec\xec\xec\xec\xec\xec\xec\xe5\xe5\xe5\xe5\xe5\xe5\xe6\xe6\xe6\xe6\xe7\xe7\xe7\xe7\xe8\xe8\xe8\xe8\xe8\xe9\xe9\xe9\xe9\xea\xea\xea\xea\xea\xea\xea\xea\xc7\xc7\xc7\xc7\xa4\xa4\xa4\xa4\xa4\x81\x81\x81\x81\x5e\x5e\x5e\x5e\x3b\x3b\x3b\x3b\x3b\x3b\x3b\x42\x42\x42\x42\x42\x42\x42\x49\x49\x49\x49\x49\x50\x50\x50\x50\x50\x50\x02\x04\x07\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x02\x07\x50\x50\x50\x50\x4f\x4f\x4f\x4f\x4e\x4e\x4e\x4e\x4d\x4d\x4d\x4d\x4c\x4c\x4c\x4c\x4c\x4b\x4b\x4b\x4b\x4b\x6e\x6e\x6e\x6e\x91\x91\x91\x91\xb4\xb4\xb4\xb4\xb4\xd7\xd7\xd7\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xf3\xf3\xf3\xf3\xf3\xf3\xec\xec\xec\xec\xec\xec\xe5\xe5\xe5\xe5\xe5\xde\xde\xde\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe2\xe2\xe2\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xc0\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x9d\x7a" \ +"\x7a\x7a\x57\x57\x57\x57\x34\x34\x34\x34\x3b\x3b\x3b\x3b\x42\x42\x42\x42\x42\x42\x42\x49\x49\x49\x49\x49\x49\x50\x50\x50\x50\x50\x02\x04\x07\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x02\x07\x50\x50\x50\x50\x4f\x4f\x4f\x4e\x4e\x4e\x4e\x4e\x4d\x4d\x4d\x4d\x4c\x4c\x4c\x4c\x4b\x4b\x4b\x4b\x4b\x4b\x6e\x6e\x6e\x6e\x6e\x91\x91\x91\xb4\xb4\xb4\xb4\xb4\xd7\xd7\xd7\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xf3\xf3\xf3\xf3\xf3\xf3\xec\xec\xec\xec\xec\xec\xe5\xe5\xe5\xe5\xe5\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe2\xe2\xe2\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xc0\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x7a\x7a\x7a\x7a\x57\x57\x57\x57\x34\x34\x34\x34\x3b\x3b\x3b\x3b\x3b\x42\x42\x42\x42\x42\x42\x49\x49\x49\x49\x49\x49\x50\x50\x50\x50\x50\x02\x04\x07\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x02\x07\x2d\x2d\x2d\x2d\x2c\x2c\x2c\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x2a\x29\x29\x29\x29\x28\x28\x28\x28\x4a\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x90\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xd6\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf2\xf2" \ +"\xf2\xf2\xf2\xeb\xeb\xeb\xeb\xeb\xeb\xe4\xe4\xe4\xe4\xe4\xdd\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe2\xe2\xe2\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x9d\x7a\x7a\x7a\x57\x57\x57\x57\x57\x34\x34\x34\x11\x11\x18\x18\x18\x18\x18\x1f\x1f\x1f\x1f\x1f\x1f\x26\x26\x26\x26\x26\x2d\x2d\x2d\x2d\x2d\x02\x04\x07\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x02\x07\x2d\x2d\x2d\x2d\x2c\x2c\x2c\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x2a\x29\x29\x29\x29\x28\x28\x28\x28\x27\x4a\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xd6\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf2\xf2\xf2\xf2\xf2\xeb\xeb\xeb\xeb\xeb\xeb\xe4\xe4\xe4\xe4\xdd\xdd\xdd\xde\xde\xde\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe2\xe2\xe2\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x7a\x7a\x7a\x7a\x57\x57\x57\x57\x34\x34\x34\x34\x11\x11\x18\x18\x18\x18\x18\x1f\x1f\x1f\x1f\x1f\x1f\x26\x26\x26\x26\x26\x2d\x2d\x2d\x2d\x2d\x02\x04\x07\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x02\x07\x2d\x2d" \ +"\x2d\x2d\x2c\x2c\x2c\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x29\x29\x29\x29\x28\x28\x28\x28\x27\x27\x4a\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x90\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf2\xf2\xf2\xf2\xf2\xeb\xeb\xeb\xeb\xeb\xeb\xe4\xe4\xe4\xe4\xe4\xdd\xdd\xdd\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe2\xe2\xe2\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x7a\x7a\x7a\x7a\x57\x57\x57\x34\x34\x34\x34\x11\x11\x11\x11\x18\x18\x18\x18\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x26\x26\x26\x26\x2d\x2d\x2d\x2d\x2d\x02\x04\x07\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x02\x07\x2d\x2d\x2d\x2d\x2c\x2c\x2c\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x29\x29\x29\x29\x28\x28\x28\x28\x27\x27\x27\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x6d\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf2\xf2\xf2\xf2\xf2\xeb\xeb\xeb\xeb\xeb\xeb\xe4\xe4\xe4\xe4\xdd\xdd\xdd\xdd\xdd\xde\xde\xde\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe2\xe2\xe2\xe2\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x7a" \ +"\x7a\x7a\x57\x57\x57\x57\x34\x34\x34\x34\x11\x11\x11\x11\x11\x18\x18\x18\x18\x1f\x1f\x1f\x1f\x1f\x1f\x26\x26\x26\x26\x26\x2d\x2d\x2d\x2d\x02\x04\x07\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x02\x07\x2d\x2d\x2d\x2d\x2c\x2c\x2b\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x29\x29\x29\x28\x28\x28\x28\x27\x27\x27\x27\x27\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf2\xf2\xf2\xf2\xf2\xeb\xeb\xeb\xeb\xeb\xe4\xe4\xe4\xe4\xe4\xdd\xdd\xdd\xdd\xdd\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe2\xe2\xe2\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xc0\xc0\x9d\x9d\x9d\x9d\x7a\x7a\x7a\x7a\x57\x57\x57\x57\x34\x34\x34\x11\x11\x11\x11\x11\x11\x18\x18\x18\x18\x18\x1f\x1f\x1f\x1f\x1f\x26\x26\x26\x26\x26\x2d\x2d\x2d\x2d\x02\x04\x07\x05\x05\x05\x05\x85\x85\x85\x85\x85\x85\x85\x02\x07\x2d\x2d\x2d\x2c\x2c\x2c\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x29\x29\x29\x29\x28\x28\x28\x28\x27\x27\x27\x27\x27\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf9\xf2" \ +"\xf2\xf2\xf2\xeb\xeb\xeb\xeb\xeb\xeb\xe4\xe4\xe4\xe4\xe4\xdd\xdd\xdd\xdd\xdd\xdd\xde\xde\xde\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe2\xe2\xe2\xe3\xe3\xe3\xe3\xe3\xe3\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x7a\x7a\x7a\x57\x57\x57\x57\x34\x34\x34\x34\x11\x11\x11\x11\x11\x11\x18\x18\x18\x18\x18\x1f\x1f\x1f\x1f\x1f\x26\x26\x26\x26\x26\x2d\x2d\x2d\x2d\x02\x04\x07\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x02\x07\x2d\x2d\x2d\x2c\x2c\x2c\x2b\x2b\x2b\x2a\x2a\x2a\x2a\x29\x29\x29\x29\x28\x28\x28\x28\x27\x27\x27\x27\x27\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x90\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xf9\xf9\xf9\xf9\xf9\xf9\xf2\xf2\xf2\xf2\xf2\xeb\xeb\xeb\xeb\xeb\xeb\xe4\xe4\xe4\xe4\xe4\xdd\xdd\xdd\xdd\xdd\xdd\xde\xde\xde\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe2\xe2\xe3\xe3\xe3\xe3\xe3\xe3\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x7a\x7a\x7a\x57\x57\x57\x57\x34\x34\x34\x34\x11\x11\x11\x11\x11\x11\x18\x18\x18\x18\x18\x1f\x1f\x1f\x1f\x1f\x1f\x26\x26\x26\x26\x2d\x2d\x2d\x2d\x02\x04\x07\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x85\x02\x07" \ +"\x2d\x2d\x2c\x2c\x2c\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x2a\x29\x29\x29\x29\x28\x28\x28\x28\x27\x27\x27\x27\x27\x4a\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xf9\xf9\xf9\xf9\xf9\xf9\xf2\xf2\xf2\xf2\xf2\xeb\xeb\xeb\xeb\xeb\xeb\xe4\xe4\xe4\xe4\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe2\xe2\xe2\xe3\xe3\xe3\xe3\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x7a\x7a\x7a\x7a\x57\x57\x57\x57\x34\x34\x34\x34\x11\x11\x11\x11\x11\x11\x18\x18\x18\x18\x18\x1f\x1f\x1f\x1f\x1f\x1f\x26\x26\x26\x26\x26\x2d\x2d\x2d\x02\x04\x07\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x02\x07\x2d\x2d\x2c\x2c\x2c\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x29\x29\x29\x29\x29\x28\x28\x28\x28\x27\x27\x27\x27\x27\x4a\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x90\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xf9\xf9\xf9\xf9\xf2\xf2\xf2\xf2\xf2\xeb\xeb\xeb\xeb\xeb\xeb\xe4\xe4\xe4\xe4\xe4\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe2\xe2\xe3\xe3\xe3\xe3\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x7a" \ +"\x7a\x7a\x7a\x57\x57\x57\x57\x34\x34\x34\x11\x11\x11\x11\x11\x11\x11\x11\x18\x18\x18\x18\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x26\x26\x26\x26\x2d\x2d\x2d\x02\x04\x07\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x02\x07\x2d\x2c\x2c\x2c\x2b\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x29\x29\x29\x29\x28\x28\x28\x28\x27\x27\x27\x27\x27\x27\x4a\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x6d\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xf9\xf9\xf9\xf9\xf2\xf2\xf2\xf2\xf2\xeb\xeb\xeb\xeb\xeb\xeb\xe4\xe4\xe4\xe4\xe4\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe2\xe2\xe2\xe3\xe3\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x7a\x7a\x7a\x7a\x57\x57\x57\x57\x34\x34\x34\x34\x11\x11\x11\x11\x11\x11\x11\x11\x18\x18\x18\x18\x18\x1f\x1f\x1f\x1f\x1f\x1f\x26\x26\x26\x26\x26\x2d\x2d\x02\x04\x07\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x02\x07\x2d\x2c\x2c\x2c\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x29\x29\x29\x29\x29\x28\x28\x28\x28\x27\x27\x27\x27\x27\x27\x4a\x4a\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x90\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xf9\xf9\xf2\xf2" \ +"\xf2\xf2\xf2\xeb\xeb\xeb\xeb\xeb\xeb\xeb\xe4\xe4\xe4\xe4\xe4\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xde\xde\xde\xde\xdf\xdf\xdf\xdf\xdf\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe1\xe2\xe2\xe2\xc0\xc0\xc0\xc0\x9d\x9d\x9d\x9d\x7a\x7a\x7a\x7a\x57\x57\x57\x57\x34\x34\x34\x34\x11\x11\x11\x11\x11\x11\x11\x11\x18\x18\x18\x18\x18\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x26\x26\x26\x26\x26\x2d\x02\x04\x07\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x02\x07\x2c\x2c\x2c\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x2a\x29\x29\x29\x29\x29\x28\x28\x28\x28\x27\x27\x27\x27\x27\x27\x4a\x4a\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x6d\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xd6\xd6\xcf\xcf\xcf\xcf\xcf\xc8\xc8\xc8\xc8\xc8\xc8\xc1\xc1\xc1\xc1\xc1\xc1\xba\xba\xba\xba\xba\xba\xba\xbb\xbb\xbb\xbb\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbe\xbe\xbe\xbe\xbf\xbf\xbf\xbf\xbf\xbf\x9c\x9c\x9c\x9c\x79\x79\x79\x79\x56\x56\x56\x56\x56\x33\x33\x33\x33\x10\x10\x10\x10\x10\x10\x10\x10\x17\x17\x17\x17\x17\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x25\x25\x25\x25\x25\x2c\x02\x04\x07\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04" \ +"\x02\x07\x2c\x2c\x2b\x2b\x2b\x2b\x2b\x2a\x2a\x2a\x2a\x29\x29\x29\x29\x29\x28\x28\x28\x28\x27\x27\x27\x27\x27\x27\x4a\x4a\x4a\x4a\x4a\x6d\x6d\x6d\x6d\x6d\x90\x90\x90\x90\xb3\xb3\xb3\xb3\xd6\xd6\xd6\xcf\xcf\xcf\xcf\xcf\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc1\xc1\xc1\xc1\xc1\xc1\xba\xba\xba\xba\xba\xba\xba\xbb\xbb\xbb\xbb\xbb\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbe\xbe\xbe\xbe\xbe\xbf\xbf\xbf\xbf\xbf\x9c\x9c\x9c\x9c\x79\x79\x79\x79\x56\x56\x56\x56\x56\x33\x33\x33\x33\x10\x10\x10\x10\x10\x10\x10\x10\x17\x17\x17\x17\x17\x17\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x25\x25\x25\x25\x25\x02\x04\x07\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x02\x07\x25\x25\x24\x24\x24\x24\x23\x23\x23\x23\x22\x22\x22\x22\x22\x21\x21\x21\x21\x21\x20\x20\x20\x20\x20\x20\x43\x43\x43\x43\x43\x66\x66\x66\x66\x66\x89\x89\x89\x89\xac\xac\xac\xac\xac\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xc8\xc8\xc8\xc8\xc8\xc8\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xba\xba\xba\xba\xba\xba\xba\xbb\xbb\xbb\xbb\xbb\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbe\xbe\xbe\xbe\xbf\xbf\xbf\xbf\x9c\x9c\x9c\x9c\x79\x79" \ +"\x79\x79\x56\x56\x56\x56\x56\x33\x33\x33\x33\x33\x10\x10\x10\x10\x10\x10\x10\x10\x17\x17\x17\x17\x17\x17\x17\x1e\x1e\x1e\x1e\x1e\x1e\x25\x25\x25\x25\x25\x02\x04\x07\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x02\x07\x25\x24\x24\x24\x24\x24\x23\x23\x23\x23\x22\x22\x22\x22\x22\x21\x21\x21\x21\x21\x20\x20\x20\x20\x20\x20\x20\x43\x43\x43\x43\x66\x66\x66\x66\x66\x66\x89\x89\x89\x89\xac\xac\xac\xac\xcf\xcf\xcf\xcf\xcf\xcf\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc1\xc1\xc1\xc1\xc1\xc1\xba\xba\xba\xba\xba\xba\xba\xba\xbb\xbb\xbb\xbb\xbb\xbc\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbe\xbe\xbe\xbe\xbf\xbf\x9c\x9c\x9c\x9c\x9c\x79\x79\x79\x79\x56\x56\x56\x56\x56\x33\x33\x33\x33\x33\x10\x10\x10\x10\x10\x10\x10\x10\x10\x17\x17\x17\x17\x17\x17\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x25\x25\x25\x25\x02\x04\x07\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x02\x07\x25\x24\x24\x24\x24\x23\x23\x23\x23\x22\x22\x22\x22\x22\x22\x21\x21\x21\x21\x21\x20\x20\x20\x20\x20\x20\x20\x43\x43\x43\x43\x43\x66\x66\x66\x66\x66\x89\x89\x89\x89\xac\xac\xac\xac\xac\xcf\xcf" \ +"\xcf\xcf\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc1\xc1\xc1\xc1\xc1\xc1\xba\xba\xba\xba\xba\xba\xba\xba\xbb\xbb\xbb\xbb\xbb\xbc\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbe\xbe\xbe\xbe\xbe\x9c\x9c\x9c\x9c\x9c\x79\x79\x79\x79\x56\x56\x56\x56\x56\x56\x33\x33\x33\x33\x33\x10\x10\x10\x10\x10\x10\x10\x10\x10\x17\x17\x17\x17\x17\x17\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x25\x25\x25\x25\x02\x04\x07\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x02\x07\x24\x24\x24\x24\x23\x23\x23\x23\x23\x22\x22\x22\x22\x22\x21\x21\x21\x21\x21\x21\x20\x20\x20\x20\x20\x20\x20\x43\x43\x43\x43\x43\x66\x66\x66\x66\x66\x66\x89\x89\x89\x89\xac\xac\xac\xac\xac\xac\xac\xac\xa5\xa5\xa5\xa5\xa5\xa5\xa5\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x97\x97\x97\x97\x97\x97\x97\x97\x97\x98\x98\x98\x98\x98\x99\x99\x99\x99\x99\x9a\x9a\x9a\x9a\x9a\x9b\x9b\x9b\x9b\x9b\x9b\x9b\x9b\x9b\x78\x78\x78\x78\x55\x55\x55\x55\x55\x55\x32\x32\x32\x32\x32\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x24\x24\x24\x02\x04\x07\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x5a\x5a" \ +"\x5a\x5a\x02\x07\x24\x24\x24\x24\x23\x23\x23\x23\x22\x22\x22\x22\x22\x22\x21\x21\x21\x21\x21\x20\x20\x20\x20\x20\x20\x20\x20\x43\x43\x43\x43\x43\x43\x66\x66\x66\x66\x66\x89\x89\x89\x89\x89\xac\xac\xac\xac\xac\xac\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x97\x97\x97\x97\x97\x97\x97\x97\x97\x98\x98\x98\x98\x98\x99\x99\x99\x99\x99\x99\x9a\x9a\x9a\x9a\x9b\x9b\x9b\x9b\x9b\x9b\x9b\x9b\x78\x78\x78\x78\x55\x55\x55\x55\x55\x55\x32\x32\x32\x32\x32\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x24\x24\x02\x04\x07\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x02\x07\x24\x24\x24\x23\x23\x23\x23\x22\x22\x22\x22\x22\x22\x22\x21\x21\x21\x21\x21\x20\x20\x20\x20\x20\x20\x20\x20\x43\x43\x43\x43\x43\x43\x66\x66\x66\x66\x66\x66\x89\x89\x89\x89\xac\xac\xac\xac\xac\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x98\x98\x98\x98\x98\x98\x99\x99\x99\x99\x99\x99\x9a\x9a\x9a\x9a\x9b\x9b\x9b\x9b\x9b\x9b\x78\x78\x78" \ +"\x78\x55\x55\x55\x55\x55\x55\x55\x32\x32\x32\x32\x32\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x24\x02\x04\x07\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x02\x07\x24\x24\x23\x23\x23\x23\x23\x22\x22\x22\x22\x22\x22\x21\x21\x21\x21\x21\x21\x20\x20\x20\x20\x20\x20\x20\x20\x43\x43\x43\x43\x43\x43\x66\x66\x66\x66\x66\x66\x66\x89\x89\x89\x89\xac\xac\xac\xac\xa5\xa5\xa5\xa5\xa5\xa5\xa5\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x98\x98\x98\x98\x98\x98\x99\x99\x99\x99\x99\x99\x9a\x9a\x9a\x9a\x9a\x9b\x9b\x9b\x9b\x78\x78\x78\x78\x78\x55\x55\x55\x55\x55\x55\x32\x32\x32\x32\x32\x32\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x24\x02\x04\x07\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x02\x07\x24\x23\x23\x23\x23\x23\x22\x22\x22\x22\x22\x22\x22\x21\x21\x21\x21\x21\x21\x20\x20\x20\x20\x20\x20\x20\x20\x20\x43\x43\x43\x43\x43\x43\x66\x66\x66\x66\x66\x66\x89\x89\x89\x89\x89\xac" \ +"\xac\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x98\x98\x98\x98\x98\x98\x98\x99\x99\x99\x99\x99\x99\x9a\x9a\x9a\x9a\x9a\x9b\x9b\x9b\x78\x78\x78\x78\x55\x55\x55\x55\x55\x55\x55\x32\x32\x32\x32\x32\x32\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x02\x04\x07\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x02\x07\x1d\x1c\x1c\x1c\x1c\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x19\x19\x19\x19\x19\x19\x19\x19\x19\x3c\x3c\x3c\x3c\x3c\x3c\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x82\x82\x82\x82\x82\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x98\x98\x98\x98\x98\x98\x98\x99\x99\x99\x99\x99\x99\x99\x9a\x9a\x9a\x9a\x9a\x9b\x78\x78\x78\x78\x55\x55\x55\x55\x55\x55\x55\x32\x32\x32\x32\x32\x32\x32\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x16\x16\x16\x16\x16\x16\x16\x16\x16\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x02\x04\x07\x03\x03\x03\x03\x03\x03\x03" \ +"\x03\x03\x03\x03\x02\x07\x1c\x1c\x1c\x1c\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x75\x75\x75\x75\x75\x75\x75\x76\x76\x76\x76\x76\x76\x76\x77\x77\x77\x77\x77\x77\x77\x77\x77\x54\x54\x54\x54\x54\x54\x54\x31\x31\x31\x31\x31\x31\x31\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x15\x15\x15\x15\x15\x15\x15\x15\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x02\x04\x07\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x07\x1c\x1c\x1c\x1c\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x82\x82\x82\x82\x82\x82\x82\x82\x82\x82\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x75\x75\x75\x75\x75\x75\x75\x75\x76\x76\x76\x76\x76\x76\x76\x77\x77\x77\x77\x77\x77\x54" \ +"\x54\x54\x54\x54\x54\x54\x54\x31\x31\x31\x31\x31\x31\x31\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1c\x1c\x1c\x1c\x1c\x1c\x02\x04\x07\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x07\x1c\x1c\x1c\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x82\x82\x82\x82\x82\x82\x82\x82\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x75\x75\x75\x75\x75\x75\x75\x75\x76\x76\x76\x76\x76\x76\x76\x77\x77\x77\x77\x77\x77\x54\x54\x54\x54\x54\x54\x54\x31\x31\x31\x31\x31\x31\x31\x31\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1c\x1c\x1c\x1c\x1c\x02\x04\x07\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x07\x1c\x1c\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x5f\x5f\x5f\x5f\x5f\x5f\x5f" \ +"\x5f\x82\x82\x82\x82\x82\x82\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x75\x75\x75\x75\x75\x75\x75\x75\x76\x76\x76\x76\x76\x76\x76\x76\x77\x77\x77\x54\x54\x54\x54\x54\x54\x54\x54\x31\x31\x31\x31\x31\x31\x31\x31\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1c\x1c\x1c\x1c\x02\x04\x07\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x07\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x82\x82\x82\x82\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x74\x75\x75\x75\x75\x75\x75\x75\x75\x75\x76\x76\x76\x76\x76\x76\x76\x76\x54\x54\x54\x54\x54\x54\x54\x54\x31\x31\x31\x31\x31\x31\x31\x31\x31\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1c\x1c\x1c\x02\x04\x07\x02\x02\x02\x02\x02" \ +"\x02\x02\x02\x02\x02\x02\x02\x07\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x53\x53\x53\x53\x53\x53\x53\x53\x53\x53\x53\x53\x53\x53\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x1b\x1b\x02\x04\x07\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x07\x1b\x1b\x1b\x1b\x1b\x1b\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x3c\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x53\x53\x53\x53\x53\x53\x53\x53" \ +"\x53\x53\x53\x53\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x02\x04\x07\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x07\x14\x14\x14\x14\x14\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x53\x53\x53\x53\x53\x53\x53\x53\x53\x53\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x02\x04\x07\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x07\x14\x14\x14\x14\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35" \ +"\x35\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x53\x53\x53\x53\x53\x53\x53\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x02\x04\x07\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x07\x14\x14\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x53\x53\x53\x53\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x14\x14\x14\x14\x14\x14\x14\x14\x14\x02\x04\x07\x01\x01\x01" \ +"\x01\x01\x01\x01\x01\x01\x01\x01\x02\x07\x14\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x58\x58\x58\x58\x58\x58\x58\x58\x58\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x51\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x52\x53\x53\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x14\x14\x14\x14\x14\x14\x14\x02\x04\x07\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x07\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f" \ +"\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x13\x13\x13\x13\x13\x13\x02\x04\x07\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x07\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x13\x13\x13\x13\x02\x04\x07\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x07\x13\x13\x13\x13\x13\x13\x01\x01\x01\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x12\x01\x01\x01" \ +"\x35\x35\x35\x35\x35\x35\x35\x35\x35\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x13\x13\x02\x04\x07\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x07\x0c\x0c\x0c\x0c\x01\x01\x01\x01\x01\x01\x01\x12\x12\x12\x12\x12\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x12\x12\x12\x12\x01\x01\x01\x01\x01\x01\x01\x01\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x01\x01\x01\x01\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x01\x01\x01\x01\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x02\x04\x07\x0b" \ +"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x07\x0c\x01\x01\x01\x01\x01\x01\x01\x01\x01\x12\x12\x12\x12\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x12\x12\x12\x12\x12\x01\x01\x01\x01\x01\x01\x01\x01\x01\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x02\x04\x07\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x07\x01\x01\x01\x01\x01\x01\x01\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x01\x01\x01\x01\x01\x01\x01\x01\x01\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x2e\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x01\x01\x01\x01\x01" \ +"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x01\x02\x04\x07\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x07\x0c\x0c\x0c\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x2e\x2e\x2e\x2e\x2e\x2e\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0c\x0c\x02\x04\x07\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x07\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" \ +"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x04\x07\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x07\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x04" \ +"\x07\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x07\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x04\x07\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x07\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" \ +"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x04\x07\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x02\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x04\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x03\x01\x00\x14\x00\x3e\x33\x00\x00\x00\x01\x00\x00\x38\x42\x49\x4d\x03\xed\x00\x00\x00\x00\x00\x10\x00\x48\x00\x00\x00\x01\x00\x01\x00\x48\x00\x00\x00" \ +"\x01\x00\x01\x38\x42\x49\x4d\x03\xf3\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x38\x42\x49\x4d\x03\xf5\x00\x00\x00\x00\x00\x48\x00\x2f\x66\x66\x00\x01\x00\x6c\x66\x66\x00\x06\x00\x00\x00\x00\x00\x00\x00\x2f\x66\x66\x00\x01\x00\xa1\x99\x9a\x00\x06\x00\x00\x00\x00\x00\x00\x00\x32\x00\x00\x00\x01\x00\x5a\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x35\x00\x00\x00\x01\x00\x2d\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x38\x42\x49\x4d\x03\xf8\x00\x00\x00\x00\x00\x70\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x03\xe8\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x03\xe8\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x03\xe8\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x03\xe8\x00\x00\x00\x00\x00\x00\x32\x33\x00\x00\x54\x52\x55\x45\x56\x49\x53\x49\x4f\x4e\x2d\x58\x46\x49\x4c\x45\x2e" \ +"\x00"}; diff --git a/source/blender/src/cmovie.tga.c b/source/blender/src/cmovie.tga.c new file mode 100644 index 00000000000..1d468946352 --- /dev/null +++ b/source/blender/src/cmovie.tga.c @@ -0,0 +1,201 @@ +/* DataToC output of file <cmovie_tga> */ +/* + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +int datatoc_cmovie_tga_size= 6247; +char datatoc_cmovie_tga[]= {"\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x34\x00\x20\x00\x01\x0c\x0c\x0c\xff\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x17\xfe\xfe\xfe\xff\xfd\xfd\xfd\xff\xfd\xfd\xfd\xff\xfe\xfe\xfe\xff\x50\x50\x50\xff\x9c\x9c\x9c\xff\x9c\x9c\x9c\xff\x9d\x9d\x9d\xff\xac\xac\xac\xff\xb8\xb8\xb8\xff\xb6\xb6\xb6\xff\xa9\xa9\xa9\xff\x9c\x9c\x9c\xff\xa4\xa4\xa4" \ +"\xff\xb2\xb2\xb2\xff\x3b\x35\x35\xff\x58\x51\x51\xff\xa3\x9c\x9c\xff\x9a\x97\x97\xff\xb8\xb8\xb8\xff\xaf\xae\xae\xff\x47\x42\x42\xff\x86\x80\x80\xff\xb4\xb4\xb4\xff\x8c\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x8b\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x13\x52\x52\x52\xff\x9f\x9f\x9f\xff\xa0\xa0\xa0\xff\xa9\xa9\xa9\xff\xb6\xb6\xb6\xff\xb7\xb7\xb7\xff\xac\xac\xac\xff\x9d\x9d\x9d\xff\x9c\x9c\x9c\xff\xa6\xa6\xa6\xff\xa6\xa6\xa6\xff\x38\x32\x32\xff\x72\x6a\x6a\xff\x86\x80\x80\xff\xaf\xaf\xaf\xff\xb7\xb7\xb7\xff\x5d\x5a\x5a\xff\x4d\x46\x46\xff\x9a\x93\x93\xff\xb4\xb4\xb4\xff\x8b\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x95\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x13\x5a\x5a\x5a\xff\xb3\xb3\xb3\xff\xb4\xb4\xb4\xff\xb7\xb7\xb7\xff\xb8\xb8\xb8\xff\xb5\xb5\xb5\xff\xa2\xa2\xa2\xff\x9c\x9c\x9c\xff\x9d\x9d\x9d\xff\xad\xad\xad\xff\xb8\xb8\xb8\xff\x91\x8f\x8f\xff\x8e\x8b\x8b\xff\xad\xac\xac\xff\xb8\xb8\xb8\xff\x9a\x99\x99\xff\x33\x2c\x2c\xff\x84" \ +"\x7d\x7d\xff\x9e\x99\x99\xff\xb6\xb6\xb6\xff\x8b\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x8b\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x00\x5c\x5c\x5c\xff\x83\xb8\xb8\xb8\xff\x04\xb5\xb5\xb5\xff\xa3\xa3\xa3\xff\x9e\x9e\x9e\xff\xa7\xa7\xa7\xff\xb6\xb6\xb6\xff\x83\xb8\xb8\xb8\xff\x04\xb7\xb7\xb7\xff\x92\x90\x90\xff\x43\x3b\x3b\xff\x7b\x74\x74\xff\xa0\x9d\x9d\xff\x89\xb7\xb7\xb7\xff\x01\xb6\xb6\xb6\xff\xb7\xb7\xb7\xff\x86\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x00\x5c\x5c\x5c\xff\x83\xb8\xb8\xb8\xff\x03\xb7\xb7\xb7\xff\xb3\xb3\xb3\xff\xb2\xb2\xb2\xff\xb7\xb7\xb7\xff\x83\xb8\xb8\xb8\xff\x04\xb7\xb7\xb7\xff\xb7\xb7\xb7\xff\xb6\xb6\xb6\xff\x91\x8f\x8f\xff\xa2\xa0\xa0\xff\x8b\xb7\xb7\xb7\xff\x87\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83" \ +"\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x00\x5c\x5c\x5c\xff\x89\xb8\xb8\xb8\xff\x01\xb7\xb7\xb7\xff\xb8\xb8\xb8\xff\x8f\xb7\xb7\xb7\xff\x88\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x04\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\xb1\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\xff\x0c\x0c\x0c\xff\x81\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x00\x5c\x5c\x5c\xff\x85\xb8\xb8\xb8\xff\x00\xb7\xb7\xb7\xff\x83\xb6\xb6\xb6\xff\x8d\xb8\xb8\xb8\xff\x02\xb7\xb7\xb7\xff\xb7\xb7\xb7\xff\xb8\xb8\xb8\xff\x82\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x0c\x0c" \ +"\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x00\x5c\x5c\x5c\xff\x83\xb8\xb8\xb8\xff\x09\xb6\xb6\xb6\xff\xb2\xb2\xb2\xff\xae\xae\xae\xff\xa9\xa9\xa9\xff\xa6\xa6\xa6\xff\xa6\xa6\xa6\xff\xa8\xa8\xa8\xff\xab\xab\xab\xff\xb2\xb2\xb2\xff\xb6\xb6\xb6\xff\x89\xb8\xb8\xb8\xff\x86\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xb8\x7f\xff\x06\x5c\x5c\x5c\xff\xb8\xb8\xb8\xff\xb8\xb8\xb8\xff\xb7\xb7\xb7\xff\xb1\xb1\xb1\xff\xa8\xa8\xa8\xff\xa0\xa0\xa0\xff\x85\x9c\x9c\x9c\xff\x05\x9e\x9e\x9e\xff\xa4\xa4\xa4\xff\xb0\xb0\xb0\xff\xb9\xb9\xb9\xff\xba\xba\xba\xff\xb9\xb9\xb9\xff\x86\xb8\xb8\xb8\xff\x85\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x04\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0" \ +"\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x04\x5c\x5c\x5c\xff\xb8\xb8\xb8\xff\xb6\xb6\xb6\xff\xae\xae\xae\xff\xa1\xa1\xa1\xff\x87\x9c\x9c\x9c\xff\x09\x9d\x9d\x9d\xff\xa0\xa0\xa0\xff\xa3\xa3\xa3\xff\xa9\xa9\xa9\xff\x9c\x9b\x9c\xff\x8c\x8a\x8b\xff\x7f\x7e\x7e\xff\x8c\x8a\x8b\xff\xa1\xa1\xa1\xff\xb5\xb5\xb5\xff\x83\xb8\xb8\xb8\xff\x84\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x8b\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x03\x5c\x5c\x5c\xff\xb7\xb7\xb7\xff\xac\xac\xac\xff\x9f\x9f\x9f\xff\x87\x9c\x9c\x9c\xff\x0e\x9d\x9d\x9d\xff\xa0\xa0\xa0\xff\x9f\x9f\x9f\xff\x6e\x6c\x6c\xff\x36\x31\x32\xff\x21\x1b\x1c\xff\x20\x1a\x1b\xff\x1f\x19\x1a\xff\x1e\x19\x1a\xff\x24\x1f\x20\xff\x42\x3e\x3f\xff\x84\x83\x83\xff\xb2\xb2\xb2\xff\xb8\xb8\xb8\xff\xb8\xb8\xb8\xff\x84\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x95\x0c\x0c\x0c\xff\x83\xe0\xb8\x7f\xff\x02\x5c\x5c\x5c\xff\xb1\xb1\xb1\xff\xa0\xa0\xa0\xff\x88\x9c\x9c\x9c" \ +"\xff\x0d\x9d\x9d\x9d\xff\x96\x96\x96\xff\x42\x3e\x3f\xff\x21\x1b\x1c\xff\x1e\x22\x20\xff\x16\x3e\x34\xff\x10\x4f\x41\xff\x0e\x53\x44\xff\x10\x41\x35\xff\x14\x1f\x1c\xff\x19\x14\x15\xff\x1e\x19\x1a\xff\x45\x41\x42\xff\xa2\xa1\xa1\xff\x85\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x8b\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x01\x5a\x5a\x5a\xff\xa5\xa5\xa5\xff\x89\x9c\x9c\x9c\xff\x0e\x96\x96\x96\xff\x41\x3d\x3e\xff\x20\x1d\x1e\xff\x14\x4d\x3f\xff\x07\x98\x78\xff\x05\xaf\x8a\xff\x05\xbc\x94\xff\x05\xbb\x92\xff\x05\xba\x92\xff\x05\xa0\x7d\xff\x09\x62\x4d\xff\x10\x21\x1c\xff\x19\x14\x15\xff\x2f\x2a\x2b\xff\x99\x98\x99\xff\x84\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x05\xfe\xfe\xfe\xff\xfd\xfd\xfd\xff\xfd\xfd\xfd\xff\xfe\xfe\xfe\xff\x55" \ +"\x55\x55\xff\x9d\x9d\x9d\xff\x88\x9c\x9c\x9c\xff\x10\x9b\x9b\x9b\xff\x48\x45\x46\xff\x20\x1b\x1c\xff\x11\x6a\x55\xff\x06\x9d\x79\xff\x06\xa8\x82\xff\x06\xb2\x8a\xff\x06\xc3\x96\xff\x06\xd1\xa4\xff\x06\xd0\xa3\xff\x06\xbd\x94\xff\x04\xad\x88\xff\x05\x88\x6a\xff\x0b\x37\x2c\xff\x16\x12\x12\xff\x31\x2d\x2e\xff\xa2\xa2\xa2\xff\x84\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x01\x55\x55\x55\xff\x9e\x9e\x9e\xff\x88\x9c\x9c\x9c\xff\x11\x75\x74\x75\xff\x22\x1d\x1e\xff\x1a\x48\x3d\xff\x06\x9f\x7b\xff\x06\xaf\x8a\xff\x06\xb4\x8c\xff\x06\xc0\x95\xff\x08\xc9\x9c\xff\x09\xcd\xa3\xff\x08\xc5\x9b\xff\x07\xca\x9f\xff\x05\xba\x92\xff\x04\xa5\x81\xff\x04\x90\x71\xff\x0b\x33\x28\xff\x17\x12\x12\xff\x4d\x49\x4a\xff\xb3\xb3\xb3\xff\x83\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x04\xdf\xdf\xdf\xff\xdf\xdf" \ +"\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x02\x5b\x5b\x5b\xff\xb0\xb0\xb0\xff\xa2\xa2\xa2\xff\x86\x9c\x9c\x9c\xff\x12\x9b\x9b\x9b\xff\x3c\x39\x39\xff\x24\x1f\x20\xff\x0e\x92\x75\xff\x07\xab\x85\xff\x07\xaf\x88\xff\x07\xbd\x94\xff\x06\x97\x76\xff\x0b\x66\x4f\xff\x13\x3c\x33\xff\x19\x2d\x33\xff\x1d\x39\x46\xff\x17\x61\x5e\xff\x0b\x91\x77\xff\x04\x9d\x7b\xff\x05\x86\x69\xff\x0d\x20\x1b\xff\x1d\x18\x18\xff\x86\x84\x84\xff\x83\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x8b\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x02\x5c\x5c\x5c\xff\xb7\xb7\xb7\xff\xa7\xa7\xa7\xff\x86\x9c\x9c\x9c\xff\x13\x8e\x8e\x8e\xff\x27\x23\x23\xff\x1d\x4c\x42\xff\x09\xb3\x8d\xff\x08\xaf\x87\xff\x09\xbf\x95\xff\x08\x9e\x7d\xff\x0b\x48\x39\xff\x1a\x10\x14\xff\x23\x12\x2a\xff\x2c\x19\x47\xff\x2d\x1b\x56\xff\x2b\x1a\x59\xff\x26\x24\x58\xff\x12\x76\x6e\xff" \ +"\x04\xa3\x80\xff\x07\x63\x4d\xff\x13\x0f\x0f\xff\x42\x3e\x3f\xff\xb4\xb4\xb4\xff\x82\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x95\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x02\x5c\x5c\x5c\xff\xb6\xb6\xb6\xff\xa3\xa3\xa3\xff\x86\x9c\x9c\x9c\xff\x13\x9b\x9b\x9b\xff\x88\x92\x8f\xff\x0f\xa5\x83\xff\x0a\xba\x93\xff\x0b\xb5\x8d\xff\x0a\xc4\x9b\xff\x08\x6c\x57\xff\x14\x0f\x0e\xff\x1d\x10\x20\xff\x28\x18\x42\xff\x30\x1d\x5d\xff\x36\x21\x72\xff\x39\x23\x82\xff\x37\x23\x85\xff\x2e\x27\x72\xff\x0b\x9a\x82\xff\x04\x97\x74\xff\x0c\x20\x1a\xff\x20\x1a\x1c\xff\x9f\x9e\x9e\xff\x82\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x8b\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xb8\x7f\xff\x02\x5b\x5b\x5b\xff\xb3\xb3\xb3\xff\xa4\xa4\xa4\xff\x86\x9c\x9c\x9c\xff\x13\x9d\x9d\x9d\xff\x8b\xa2\x9b\xff\x11\xb9\x96\xff\x0e\xc7\xa0\xff\x0e\xc8\xa0\xff\x0b\xb4\x8e\xff\x0d\x3b\x30\xff\x16\x0b\x10\xff\x21\x14\x2f\xff\x2d\x1c\x52\xff\x36\x22\x70\xff\x4a\x33\x9c\xff\x5d\x45\xc1\xff\x59\x42" \ +"\xc9\xff\x43\x2d\xaa\xff\x1e\x65\x7c\xff\x04\xb5\x8e\xff\x08\x50\x40\xff\x20\x22\x22\xff\x86\x85\x85\xff\x82\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x02\x52\x52\x52\xff\xa1\xa1\xa1\xff\x9e\x9e\x9e\xff\x87\x9c\x9c\x9c\xff\x12\x88\xa4\x9d\xff\x14\xb6\x92\xff\x12\xbb\x95\xff\x12\xca\xa1\xff\x0f\xb0\x8a\xff\x0f\x2c\x24\xff\x18\x0c\x17\xff\x26\x15\x3c\xff\x33\x20\x67\xff\x47\x30\x94\xff\x71\x57\xd5\xff\xa3\x87\xfc\xff\x92\x76\xfc\xff\x5b\x41\xda\xff\x2d\x4d\x90\xff\x06\xbc\x92\xff\x05\xaa\x84\xff\x55\xaf\x98\xff\xbc\xbc\xbc\xff\x82\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x00\x51\x51\x51\xff\x88\x9c\x9c" \ +"\x9c\xff\x13\x98\x97\x97\xff\x93\x9d\x9a\xff\x45\xb3\x99\xff\x17\xc9\xa1\xff\x17\xca\xa1\xff\x15\xca\xa3\xff\x11\x3c\x31\xff\x17\x0b\x19\xff\x26\x15\x44\xff\x34\x21\x6f\xff\x4f\x37\xa4\xff\x85\x6b\xf0\xff\xc1\xa3\xff\xff\xad\x8f\xff\xff\x66\x4a\xec\xff\x30\x49\x91\xff\x07\xca\x9f\xff\x06\xb7\x8e\xff\x49\xb8\x9e\xff\xbe\xbe\xbe\xff\x82\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x04\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x00\x55\x55\x55\xff\x88\x9c\x9c\x9c\xff\x16\x7a\x79\x79\xff\x86\x7f\x7f\xff\xa6\xb6\xaf\xff\x23\xd0\xaa\xff\x1e\xdc\xb1\xff\x1d\xe3\xb8\xff\x15\x7e\x65\xff\x18\x0d\x17\xff\x24\x15\x3e\xff\x33\x1f\x6a\xff\x49\x32\x9e\xff\x6f\x54\xdf\xff\x95\x78\xfe\xff\x88\x69\xfe\xff\x5b\x3e\xdf\xff\x26\x76\x91\xff\x07\xcf\xa2\xff\x07\xb8\x90\xff\x4b\xb6\x9c\xff\xbf\xbf\xbf\xff\xb8\xb8\xb8\xff\xb7\xb7\xb7\xff\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff" \ +"\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x8b\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x05\x59\x59\x59\xff\xa2\xa2\xa2\xff\x9c\x9c\x9c\xff\x9c\x9c\x9c\xff\x9b\x9b\x9b\xff\x99\x99\x99\xff\x83\x9c\x9c\x9c\xff\x16\x93\x93\x93\xff\x6c\x65\x65\xff\xc1\xba\xb9\xff\x4d\xd8\xb7\xff\x25\xe2\xb8\xff\x24\xe1\xb6\xff\x1f\xd1\xa8\xff\x17\x2a\x28\xff\x21\x14\x32\xff\x2f\x1c\x5b\xff\x3e\x28\x88\xff\x50\x37\xb6\xff\x5f\x42\xdc\xff\x60\x40\xe8\xff\x46\x43\xb6\xff\x12\xd5\xb8\xff\x07\xd3\xa6\xff\x09\x85\x69\xff\x57\x5e\x5a\xff\xab\xa8\xa8\xff\xb8\xb8\xb8\xff\xb7\xb7\xb7\xff\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x95\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x20\x5c\x5c\x5c\xff\xac\xac\xac\xff\x9d\x9d\x9d\xff\x8f\x8f\x8f\xff\x4d\x48\x48\xff\x56\x50\x50\xff\x66\x62\x62\xff\x74\x71\x71\xff\x7f\x7c\x7c\xff\x8d\x8a\x8a\xff\x99\x99\x99\xff\x5d\x59\x59\xff\xc2\xba\xba\xff\xa2\xd7\xc9\xff\x2d\xdd\xb5\xff\x2b\xe9\xbf\xff\x29\xef\xc8\xff\x21\xb9\x99\xff\x1a\x28\x2e\xff\x24\x16\x3f\xff\x33\x20\x66" \ +"\xff\x3c\x24\x85\xff\x43\x2b\x9d\xff\x43\x40\xa8\xff\x1e\xbe\xb2\xff\x0a\xea\xba\xff\x07\xd6\xaa\xff\x0c\x53\x42\xff\x79\x72\x72\xff\xa9\xa6\xa6\xff\xb7\xb7\xb7\xff\xb8\xb8\xb8\xff\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x8b\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x1d\x5c\x5c\x5c\xff\xb6\xb6\xb6\xff\xa5\xa5\xa5\xff\x65\x62\x62\xff\x43\x3b\x3b\xff\x77\x6f\x6f\xff\xa0\x99\x99\xff\x9f\x98\x98\xff\x91\x8a\x8a\xff\x91\x8f\x8f\xff\x9b\x9b\x9b\xff\x7e\x7d\x7d\xff\x92\x8b\x8b\xff\xd7\xd4\xd2\xff\x5f\xda\xbd\xff\x30\xe0\xb9\xff\x2e\xd7\xb0\xff\x2b\xde\xb7\xff\x25\xbe\x9c\xff\x1f\x71\x63\xff\x21\x48\x55\xff\x26\x4d\x63\xff\x26\x88\x90\xff\x19\xe4\xc7\xff\x10\xeb\xbc\xff\x0b\xdd\xae\xff\x08\xb5\x8f\xff\x25\x34\x2f\xff\x96\x8f\x8f\xff\xb2\xb1\xb1\xff\x82\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff" \ +"\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xb8\x7f\xff\x1d\x5c\x5c\x5c\xff\xb7\xb7\xb7\xff\xb3\xb3\xb3\xff\x98\x98\x98\xff\x4d\x49\x49\xff\x5e\x57\x57\xff\x77\x70\x70\xff\x80\x7c\x7c\xff\x93\x92\x92\xff\x9c\x9c\x9c\xff\x9c\x9c\x9c\xff\x9b\x9b\x9b\xff\x61\x5d\x5d\xff\xcb\xc4\xc4\xff\xca\xda\xd4\xff\x45\xd5\xb2\xff\x31\xd3\xae\xff\x2e\xd0\xab\xff\x2b\xdc\xb8\xff\x29\xe0\xb7\xff\x24\xd8\xae\xff\x20\xe0\xb7\xff\x1b\xea\xbe\xff\x15\xe5\xb7\xff\x10\xe3\xb5\xff\x0c\xd0\xa5\xff\x0d\x69\x55\xff\x70\x6a\x6a\xff\xa3\x9d\x9d\xff\xb8\xb7\xb7\xff\x82\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x0a\xfe\xfe\xfe\xff\xfd\xfd\xfd\xff\xfd\xfd\xfd\xff\xfe\xfe\xfe\xff\x59\x59\x59\xff\xae\xae\xae\xff\xb3\xb3\xb3\xff\xb2\xb2\xb2\xff\xa2\xa2\xa2\xff\x90\x90\x90\xff\x97\x97\x97\xff\x84\x9c\x9c\x9c\xff\x10\x92\x92\x92\xff\x77\x73\x73\xff\xe0" \ +"\xd9\xd9\xff\xc7\xdd\xd6\xff\x4e\xce\xaf\xff\x33\xd8\xb4\xff\x2f\xd4\xb0\xff\x2a\xd4\xad\xff\x25\xda\xb1\xff\x21\xd0\xa8\xff\x1b\xda\xb2\xff\x15\xd7\xaf\xff\x0f\xc3\x9c\xff\x0d\x84\x6a\xff\x4f\x55\x52\xff\x9d\x96\x96\xff\xb1\xae\xae\xff\x83\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x04\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x1f\xfe\xfe\xfe\xff\xfd\xfd\xfd\xff\xfd\xfd\xfd\xff\xfe\xfe\xfe\xff\x4f\x4f\x4f\xff\xa3\xa3\xa3\xff\xb4\xb4\xb4\xff\xb8\xb8\xb8\xff\xb4\xb4\xb4\xff\xa7\xa7\xa7\xff\x9e\x9e\x9e\xff\x9c\x9c\x9c\xff\x9c\x9c\x9c\xff\x9b\x9b\x9b\xff\x96\x96\x96\xff\x85\x83\x83\xff\x95\x94\x94\xff\x89\x89\x89\xff\x85\x80\x80\xff\xe8\xe0\xe0\xff\xd8\xe4\xdf\xff\x76\xdd\xc6\xff\x37\xcd\xab\xff\x2d\xcc\xa8\xff\x27\xd3\xae\xff\x21\xc7\xa1\xff\x1a\xbe\x97\xff\x13\xa6\x84\xff\x18\x73\x5f\xff\x5d\x61\x5f\xff\x9c\x95\x95\xff\xac\xa8\xa8\xff\x84\xb7\xb7\xb7\xff\x84\xb8\xb8" \ +"\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x8b\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x01\x51\x51\x51\xff\xb0\xb0\xb0\xff\x82\xb8\xb8\xb8\xff\x16\xb6\xb6\xb6\xff\xaf\xaf\xaf\xff\x90\x90\x90\xff\x68\x65\x65\xff\x5a\x55\x55\xff\x63\x5d\x5d\xff\x88\x81\x81\xff\x9a\x9a\x9a\xff\x9c\x9c\x9c\xff\x8e\x8d\x8d\xff\x90\x8d\x8d\xff\xdf\xd8\xd8\xff\xee\xe7\xe7\xff\xcc\xda\xd4\xff\x8a\xcb\xbc\xff\x5b\xb5\x9f\xff\x48\xa0\x8b\xff\x4b\x8e\x7e\xff\x6b\x84\x7d\xff\x98\x92\x91\xff\xa5\x9e\x9e\xff\xae\xab\xab\xff\xb6\xb6\xb6\xff\x84\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x95\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x19\x59\x59\x59\xff\xb7\xb7\xb7\xff\xb8\xb8\xb8\xff\xb8\xb8\xb8\xff\xb5\xb5\xb5\xff\xae\xae\xae\xff\x8f\x8e\x8e\xff\x39\x32\x32\xff\x5f\x58\x58\xff\x91\x8a\x8a\xff\x98\x92\x92\xff\x9d\x9c\x9c\xff\xa7\xa7\xa7\xff\xa7\xa7\xa7\xff\xaa\xaa\xaa\xff\xad\xac\xac\xff\x9a\x9a\x9a\xff\xbf\xbb\xbb\xff\xd9\xd3\xd3\xff\xe2\xda\xda\xff\xd7\xcf\xcf\xff\xca\xc3\xc3\xff\xbf\xb8\xb8\xff" \ +"\xb8\xb1\xb1\xff\xb4\xaf\xaf\xff\xb5\xb3\xb3\xff\x86\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x8b\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x17\x5c\x5c\x5c\xff\xb8\xb8\xb8\xff\xb7\xb7\xb7\xff\xb1\xb1\xb1\xff\xa4\xa4\xa4\xff\xa8\xa8\xa8\xff\x71\x6e\x6e\xff\x4a\x42\x42\xff\x7f\x78\x78\xff\x91\x8a\x8a\xff\xa3\xa1\xa1\xff\xb8\xb8\xb8\xff\xb8\xb8\xb8\xff\xb7\xb7\xb7\xff\x8b\x89\x89\xff\xa1\x9e\x9e\xff\xb8\xb8\xb8\xff\xb8\xb8\xb8\xff\xab\xab\xab\xff\xb8\xb7\xb7\xff\xc1\xbe\xbe\xff\xc3\xc1\xc1\xff\xbd\xbb\xbb\xff\xb9\xb8\xb8\xff\x89\xb7\xb7\xb7\xff\x83\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x12\x5c\x5c\x5c\xff\xb4\xb4\xb4\xff\xac\xac\xac\xff\x9f\x9f\x9f\xff\x9c\x9c\x9c\xff\xae\xae\xae\xff\xb3\xb3\xb3\xff\x84\x82\x82\xff\x7d\x7a\x7a\xff" \ +"\x98\x97\x97\xff\xb6\xb6\xb6\xff\xb8\xb8\xb8\xff\xb3\xb3\xb3\xff\x73\x71\x71\xff\x6a\x63\x63\xff\xaf\xae\xae\xff\xb8\xb8\xb8\xff\xb7\xb7\xb7\xff\x97\x95\x95\xff\x8e\xb7\xb7\xb7\xff\x83\xb6\xb6\xb6\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xb8\x7f\xff\x13\x58\x58\x58\xff\xa3\xa3\xa3\xff\x9c\x9c\x9c\xff\x9c\x9c\x9c\xff\xa2\xa2\xa2\xff\xb4\xb4\xb4\xff\xb8\xb8\xb8\xff\xb5\xb5\xb5\xff\xa4\xa4\xa4\xff\xa3\xa3\xa3\xff\xb6\xb6\xb6\xff\xa0\x9f\x9f\xff\x4f\x4a\x4a\xff\x56\x4e\x4e\xff\x95\x8f\x8f\xff\xb5\xb5\xb5\xff\xb8\xb8\xb8\xff\x8e\x8d\x8d\xff\x78\x72\x72\xff\xb6\xb5\xb5\xff\x8c\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x04\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x17\xfe\xfe\xfe\xff\xfd\xfd\xfd\xff\xfd\xfd\xfd\xff\xfe" \ +"\xfe\xfe\xff\x50\x50\x50\xff\x9c\x9c\x9c\xff\x9c\x9c\x9c\xff\x9d\x9d\x9d\xff\xac\xac\xac\xff\xb8\xb8\xb8\xff\xb6\xb6\xb6\xff\xa9\xa9\xa9\xff\x9c\x9c\x9c\xff\xa4\xa4\xa4\xff\xb2\xb2\xb2\xff\x3b\x35\x35\xff\x58\x51\x51\xff\xa3\x9c\x9c\xff\x9a\x97\x97\xff\xb8\xb8\xb8\xff\xaf\xae\xae\xff\x47\x42\x42\xff\x86\x80\x80\xff\xb4\xb4\xb4\xff\x8c\xb7\xb7\xb7\xff\x84\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x8b\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x13\x52\x52\x52\xff\x9f\x9f\x9f\xff\xa0\xa0\xa0\xff\xa9\xa9\xa9\xff\xb6\xb6\xb6\xff\xb7\xb7\xb7\xff\xac\xac\xac\xff\x9d\x9d\x9d\xff\x9c\x9c\x9c\xff\xa6\xa6\xa6\xff\xa6\xa6\xa6\xff\x38\x32\x32\xff\x72\x6a\x6a\xff\x86\x80\x80\xff\xaf\xaf\xaf\xff\xb7\xb7\xb7\xff\x5d\x5a\x5a\xff\x4d\x46\x46\xff\x9a\x93\x93\xff\xb4\xb4\xb4\xff\x8b\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x95\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x13\x5a\x5a\x5a\xff\xb3\xb3\xb3\xff\xb4\xb4\xb4\xff\xb7\xb7\xb7\xff\xb8\xb8\xb8\xff\xb5\xb5\xb5\xff\xa2\xa2\xa2" \ +"\xff\x9c\x9c\x9c\xff\x9d\x9d\x9d\xff\xad\xad\xad\xff\xb8\xb8\xb8\xff\x91\x8f\x8f\xff\x8e\x8b\x8b\xff\xad\xac\xac\xff\xb8\xb8\xb8\xff\x9a\x99\x99\xff\x33\x2c\x2c\xff\x84\x7d\x7d\xff\x9e\x99\x99\xff\xb6\xb6\xb6\xff\x8b\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x8b\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x00\x5c\x5c\x5c\xff\x83\xb8\xb8\xb8\xff\x04\xb5\xb5\xb5\xff\xa3\xa3\xa3\xff\x9e\x9e\x9e\xff\xa7\xa7\xa7\xff\xb6\xb6\xb6\xff\x83\xb8\xb8\xb8\xff\x04\xb7\xb7\xb7\xff\x92\x90\x90\xff\x43\x3b\x3b\xff\x7b\x74\x74\xff\xa0\x9d\x9d\xff\x89\xb7\xb7\xb7\xff\x01\xb6\xb6\xb6\xff\xb7\xb7\xb7\xff\x86\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x00\x5c\x5c\x5c\xff\x83\xb8\xb8\xb8\xff\x03\xb7\xb7\xb7\xff\xb3\xb3\xb3\xff\xb2\xb2\xb2\xff\xb7\xb7\xb7\xff" \ +"\x83\xb8\xb8\xb8\xff\x04\xb7\xb7\xb7\xff\xb7\xb7\xb7\xff\xb6\xb6\xb6\xff\x91\x8f\x8f\xff\xa2\xa0\xa0\xff\x8b\xb7\xb7\xb7\xff\x87\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x00\x5c\x5c\x5c\xff\x89\xb8\xb8\xb8\xff\x01\xb7\xb7\xb7\xff\xb8\xb8\xb8\xff\x8f\xb7\xb7\xb7\xff\x88\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x04\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\xb1\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\xff\x0c\x0c\x0c\xff\x81\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x00\x5c\x5c\x5c\xff\x85\xb8\xb8\xb8\xff\x00\xb7\xb7\xb7\xff\x83\xb6\xb6\xb6\xff\x8d\xb8\xb8\xb8\xff\x02\xb7\xb7\xb7\xff\xb7\xb7" \ +"\xb7\xff\xb8\xb8\xb8\xff\x82\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x00\x5c\x5c\x5c\xff\x83\xb8\xb8\xb8\xff\x09\xb6\xb6\xb6\xff\xb2\xb2\xb2\xff\xae\xae\xae\xff\xa9\xa9\xa9\xff\xa6\xa6\xa6\xff\xa6\xa6\xa6\xff\xa8\xa8\xa8\xff\xab\xab\xab\xff\xb2\xb2\xb2\xff\xb6\xb6\xb6\xff\x89\xb8\xb8\xb8\xff\x86\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x03\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xb8\x7f\xff\x06\x5c\x5c\x5c\xff\xb8\xb8\xb8\xff\xb8\xb8\xb8\xff\xb7\xb7\xb7\xff\xb1\xb1\xb1\xff\xa8\xa8\xa8\xff\xa0\xa0\xa0\xff\x85\x9c\x9c\x9c\xff\x05\x9e\x9e\x9e\xff\xa4\xa4\xa4\xff\xb0\xb0\xb0\xff\xb9\xb9\xb9\xff\xba\xba\xba\xff\xb9\xb9\xb9\xff\x86\xb8\xb8\xb8\xff\x85\xb7\xb7" \ +"\xb7\xff\x85\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x83\xe0\xe0\xe0\xff\x04\xdf\xdf\xdf\xff\xdf\xdf\xdf\xff\x0c\x0c\x0c\xff\x0c\x0c\x0c\xff\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x04\x5c\x5c\x5c\xff\xb8\xb8\xb8\xff\xb6\xb6\xb6\xff\xae\xae\xae\xff\xa1\xa1\xa1\xff\x87\x9c\x9c\x9c\xff\x09\x9d\x9d\x9d\xff\xa0\xa0\xa0\xff\xa3\xa3\xa3\xff\xa9\xa9\xa9\xff\x9c\x9b\x9c\xff\x8c\x8a\x8b\xff\x7f\x7e\x7e\xff\x8c\x8a\x8b\xff\xa1\xa1\xa1\xff\xb5\xb5\xb5\xff\x83\xb8\xb8\xb8\xff\x84\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x8b\x0c\x0c\x0c\xff\x83\xc3\x73\x00\xff\x03\x5c\x5c\x5c\xff\xb7\xb7\xb7\xff\xac\xac\xac\xff\x9f\x9f\x9f\xff\x87\x9c\x9c\x9c\xff\x0e\x9d\x9d\x9d\xff\xa0\xa0\xa0\xff\x9f\x9f\x9f\xff\x6e\x6c\x6c\xff\x36\x31\x32\xff\x21\x1b\x1c\xff\x20\x1a\x1b\xff\x1f\x19\x1a\xff\x1e\x19\x1a\xff\x24\x1f\x20\xff\x42\x3e\x3f\xff\x84\x83\x83\xff\xb2\xb2\xb2\xff\xb8\xb8\xb8" \ +"\xff\xb8\xb8\xb8\xff\x84\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x95\x0c\x0c\x0c\xff\x83\xe0\xb8\x7f\xff\x02\x5c\x5c\x5c\xff\xb1\xb1\xb1\xff\xa0\xa0\xa0\xff\x88\x9c\x9c\x9c\xff\x0d\x9d\x9d\x9d\xff\x96\x96\x96\xff\x42\x3e\x3f\xff\x21\x1b\x1c\xff\x1e\x22\x20\xff\x16\x3e\x34\xff\x10\x4f\x41\xff\x0e\x53\x44\xff\x10\x41\x35\xff\x14\x1f\x1c\xff\x19\x14\x15\xff\x1e\x19\x1a\xff\x45\x41\x42\xff\xa2\xa1\xa1\xff\x85\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x8b\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x01\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x83\x0c\x0c\x0c\xff\x83\xfe\xfe\xfe\xff\x01\x5a\x5a\x5a\xff\xa5\xa5\xa5\xff\x89\x9c\x9c\x9c\xff\x0e\x96\x96\x96\xff\x41\x3d\x3e\xff\x20\x1d\x1e\xff\x14\x4d\x3f\xff\x07\x98\x78\xff\x05\xaf\x8a\xff\x05\xbc\x94\xff\x05\xbb\x92\xff\x05\xba\x92\xff\x05\xa0\x7d\xff\x09\x62\x4d\xff\x10\x21\x1c\xff\x19\x14\x15\xff\x2f\x2a\x2b\xff\x99\x98\x99\xff\x84\xb7\xb7\xb7\xff\x85\xb8\xb8\xb8\xff\x83\x0c\x0c\x0c\xff\x00\x0d\x0d\x0d\xff\x82\xe0\xe0\xe0\xff\x02\xdf\xdf\xdf\xff\x0d\x0d\x0d\xff\x0c\x0c\x0c" \ +"\xff"}; + +/* these are not the monkeys you are looking for */ +int monkeyo= 4; +int monkeynv= 271; +int monkeynf= 250; +signed char monkeyv[271][3]= { +{-71,21,98},{-63,12,88},{-57,7,74},{-82,-3,79},{-82,4,92}, +{-82,17,100},{-92,21,102},{-101,12,95},{-107,7,83}, +{-117,31,84},{-109,31,95},{-96,31,102},{-92,42,102}, +{-101,50,95},{-107,56,83},{-82,66,79},{-82,58,92}, +{-82,46,100},{-71,42,98},{-63,50,88},{-57,56,74}, +{-47,31,72},{-55,31,86},{-67,31,97},{-66,31,99}, +{-70,43,100},{-82,48,103},{-93,43,105},{-98,31,105}, +{-93,20,105},{-82,31,106},{-82,15,103},{-70,20,100}, +{-127,55,95},{-127,45,105},{-127,-87,94},{-127,-41,100}, +{-127,-24,102},{-127,-99,92},{-127,52,77},{-127,73,73}, +{-127,115,-70},{-127,72,-109},{-127,9,-106},{-127,-49,-45}, +{-101,-24,72},{-87,-56,73},{-82,-89,73},{-80,-114,68}, +{-85,-121,67},{-104,-124,71},{-127,-126,74},{-71,-18,68}, +{-46,-5,69},{-21,19,57},{-17,55,76},{-36,62,80}, +{-64,77,88},{-86,97,94},{-107,92,97},{-119,63,96}, +{-106,53,99},{-111,39,98},{-101,12,95},{-79,2,90}, +{-64,8,86},{-47,24,83},{-45,38,83},{-50,48,85}, +{-72,56,92},{-95,60,97},{-127,-98,94},{-113,-92,94}, +{-112,-107,91},{-119,-113,89},{-127,-114,88},{-127,-25,96}, +{-127,-18,95},{-114,-19,95},{-111,-29,96},{-116,-37,95}, +{-76,-6,86},{-48,7,80},{-34,26,77},{-32,48,84}, +{-39,53,93},{-71,70,102},{-87,82,107},{-101,79,109}, +{-114,55,108},{-111,-13,104},{-100,-57,91},{-95,-90,88}, +{-93,-105,85},{-97,-117,81},{-106,-119,81},{-127,-121,82}, +{-127,6,93},{-127,27,98},{-85,61,95},{-106,18,96}, +{-110,27,97},{-112,-88,94},{-117,-57,96},{-127,-57,96}, +{-127,-42,95},{-115,-35,100},{-110,-29,102},{-113,-17,100}, +{-122,-16,100},{-127,-26,106},{-121,-19,104},{-115,-20,104}, +{-113,-29,106},{-117,-32,103},{-127,-37,103},{-94,-40,71}, +{-106,-31,91},{-104,-40,91},{-97,-32,71},{-127,-112,88}, +{-121,-111,88},{-115,-105,91},{-115,-95,93},{-127,-100,84}, +{-115,-96,85},{-115,-104,82},{-121,-109,81},{-127,-110,81}, +{-105,28,100},{-103,20,99},{-84,55,97},{-92,54,99}, +{-73,51,99},{-55,45,89},{-52,37,88},{-53,25,87}, +{-66,13,92},{-79,8,95},{-98,14,100},{-104,38,100}, +{-100,48,100},{-97,46,97},{-102,38,97},{-96,16,97}, +{-79,11,93},{-68,15,90},{-57,27,86},{-56,36,86}, +{-59,43,87},{-74,50,96},{-91,51,98},{-84,52,96}, +{-101,22,96},{-102,29,96},{-113,59,78},{-102,85,79}, +{-84,88,76},{-65,71,71},{-40,58,63},{-25,52,59}, +{-28,21,48},{-50,0,53},{-71,-12,60},{-127,115,37}, +{-127,126,-10},{-127,-25,-86},{-127,-59,24},{-127,-125,59}, +{-127,-103,44},{-127,-73,41},{-127,-62,36},{-18,30,7}, +{-17,41,-6},{-28,34,-56},{-68,56,-90},{-33,-6,9}, +{-51,-16,-21},{-45,-1,-55},{-84,7,-85},{-97,-45,52}, +{-104,-53,33},{-90,-91,49},{-95,-64,50},{-85,-117,51}, +{-109,-97,47},{-111,-69,46},{-106,-121,56},{-99,-36,55}, +{-100,-29,60},{-101,-22,64},{-100,-50,21},{-89,-40,-34}, +{-83,-19,-69},{-69,111,-49},{-69,119,-9},{-69,109,30}, +{-68,67,55},{-34,52,43},{-46,58,36},{-45,90,7}, +{-25,72,16},{-25,79,-15},{-45,96,-25},{-45,87,-57}, +{-25,69,-46},{-48,42,-75},{-65,3,-70},{-22,42,-26}, +{-75,-22,19},{-72,-25,-27},{-13,52,-30},{-28,-18,-16}, +{6,-13,-42},{37,7,-55},{46,41,-54},{31,65,-54}, +{4,61,-40},{3,53,-37},{25,56,-50},{35,37,-52}, +{28,10,-52},{5,-5,-39},{-21,-9,-17},{-9,46,-28}, +{-6,39,-37},{-14,-3,-27},{6,0,-47},{25,12,-57}, +{31,32,-57},{23,46,-56},{4,44,-46},{-19,37,-27}, +{-20,22,-35},{-30,12,-35},{-22,11,-35},{-19,2,-35}, +{-23,-2,-35},{-34,0,-9},{-35,-3,-22},{-35,5,-24}, +{-25,26,-27},{-13,31,-34},{-13,30,-41},{-23,-2,-41}, +{-18,2,-41},{-21,10,-41},{-29,12,-41},{-19,22,-41}, +{6,42,-53},{25,44,-62},{34,31,-63},{28,11,-62}, +{7,0,-54},{-14,-2,-34},{-5,37,-44},{-13,14,-42}, +{-7,8,-43},{1,16,-47},{-4,22,-45},{3,30,-48}, +{8,24,-49},{15,27,-50},{12,35,-50},{4,56,-62}, +{33,60,-70},{48,38,-64},{41,7,-68},{6,-11,-63}, +{-26,-16,-42},{-17,49,-49}, +}; + +signed char monkeyf[250][4]= { +{27,4,5,26}, {25,4,5,24}, {3,6,5,4}, {1,6,5,2}, {5,6,7,4}, +{3,6,7,2}, {5,8,7,6}, {3,8,7,4}, {7,8,9,6}, +{5,8,9,4}, {7,10,9,8}, {5,10,9,6}, {9,10,11,8}, +{7,10,11,6}, {9,12,11,10}, {7,12,11,8}, {11,6,13,12}, +{5,4,13,12}, {3,-2,13,12}, {-3,-4,13,12}, {-5,-10,13,12}, +{-11,-12,14,12}, {-13,-18,14,13}, {-19,4,5,13}, {10,12,4,4}, +{10,11,9,9}, {8,7,9,9}, {7,5,6,6}, {6,3,4,4}, +{5,1,2,2}, {4,-1,0,0}, {3,-3,-2,-2}, {22,67,68,23}, +{20,65,66,21}, {18,63,64,19}, {16,61,62,17}, {14,59,60,15}, +{12,19,48,57}, {18,19,48,47}, {18,19,48,47}, {18,19,48,47}, +{18,19,48,47}, {18,19,48,47}, {18,19,48,47}, {18,19,48,47}, +{18,19,48,47}, {18,-9,-8,47}, {18,27,45,46}, {26,55,43,44}, +{24,41,42,54}, {22,39,40,23}, {20,37,38,21}, {18,35,36,19}, +{16,33,34,17}, {14,31,32,15}, {12,39,30,13}, {11,48,45,38}, +{8,36,-19,9}, {8,-20,44,47}, {42,45,46,43}, {18,19,40,39}, +{16,17,38,37}, {14,15,36,35}, {32,44,43,33}, {12,33,32,42}, +{19,44,43,42}, {40,41,42,-27}, {8,9,39,-28}, {15,43,42,16}, +{13,43,42,14}, {11,43,42,12}, {9,-30,42,10}, {37,12,38,-32}, +{-33,37,45,46}, {-33,40,41,39}, {38,40,41,37}, {36,40,41,35}, +{34,40,41,33}, {36,39,38,37}, {35,40,39,38}, {1,2,14,21}, +{1,2,40,13}, {1,2,40,39}, {1,24,12,39}, {-34,36,38,11}, +{35,38,36,37}, {-37,8,35,37}, {-11,-12,-45,40}, {-11,-12,39,38}, +{-11,-12,37,36}, {-11,-12,35,34}, {33,34,40,41}, {33,34,38,39}, +{33,34,36,37}, {33,-52,34,35}, {33,37,36,34}, {33,35,34,34}, +{8,7,37,36}, {-32,7,35,46}, {-34,-33,45,46}, {4,-33,43,34}, +{-34,-33,41,42}, {-34,-33,39,40}, {-34,-33,37,38}, {-34,-33,35,36}, +{-34,-33,33,34}, {-34,-33,31,32}, {-34,-4,28,30}, {-5,-34,28,27}, +{-35,-44,36,27}, {26,35,36,45}, {24,25,44,45}, {25,23,44,42}, +{25,24,41,40}, {25,24,39,38}, {25,24,37,36}, {25,24,35,34}, +{25,24,33,32}, {25,24,31,30}, {15,24,29,38}, {25,24,27,26}, +{23,12,37,26}, {11,12,35,36}, {-86,-59,36,-80}, {-60,-61,36,35}, +{-62,-63,36,35}, {-64,-65,36,35}, {-66,-67,36,35}, {-68,-69,36,35}, +{-70,-71,36,35}, {-72,-73,36,35}, {-74,-75,36,35}, {42,43,53,58}, +{40,41,57,56}, {38,39,55,57}, {-81,-80,37,56}, {-83,-82,55,52}, +{-85,-84,51,49}, {-87,-86,48,49}, {47,50,51,48}, {46,48,51,49}, +{43,46,49,44}, {-92,-91,45,42}, {-23,49,50,-20}, {-94,40,48,-24}, +{-96,-22,48,49}, {-97,48,21,-90}, {-100,36,50,23}, {22,49,48,-100}, +{-101,47,46,22}, {21,45,35,25}, {33,34,44,41}, {13,14,28,24}, +{-107,26,30,-106}, {14,46,45,15}, {14,44,43,-110}, {-111,42,23,-110}, +{6,7,45,46}, {45,44,47,46}, {45,46,47,48}, {47,46,49,48}, +{17,49,47,48}, {17,36,46,48}, {35,36,44,45}, {35,36,40,43}, +{35,36,38,39}, {-4,-3,37,35}, {-123,34,33,1}, {-9,-8,-7,-6}, +{-10,-7,32,-125}, {-127,-11,-126,-126}, {-7,-6,5,31}, {4,5,33,30}, +{4,39,33,32}, {4,35,32,38}, {20,21,39,38}, {4,37,38,5}, +{-11,-10,36,3}, {-11,15,14,35}, {13,16,34,34}, {-13,14,13,13}, +{-3,1,30,29}, {-3,28,29,1}, {-2,31,28,-1}, {12,13,27,30}, +{-2,26,12,12}, {35,29,42,36}, {34,35,36,33}, {32,35,36,31}, +{30,35,36,29}, {28,35,36,27}, {26,35,36,25}, {34,39,38,35}, +{32,39,38,33}, {30,39,38,31}, {28,39,38,29}, {26,39,38,27}, +{25,31,32,38}, {-18,-17,45,44}, {-18,17,28,44}, {-24,-20,42,-23}, +{11,35,27,14}, {25,28,39,41}, {37,41,40,38}, {34,40,36,35}, +{32,40,39,33}, {30,39,31,40}, {21,29,39,22}, {-31,37,28,4}, +{-32,33,35,36}, {32,33,34,34}, {18,35,36,48}, {34,25,40,35}, +{24,25,38,39}, {24,25,36,37}, {24,25,34,35}, {24,25,32,33}, +{24,13,41,31}, {17,11,41,35}, {15,16,34,35}, {13,14,34,35}, +{11,12,34,35}, {9,10,34,35}, {7,8,34,35}, {26,25,37,36}, +{35,36,37,38}, {37,36,39,38}, {37,38,39,40}, {25,31,36,39}, +{18,34,35,30}, {17,22,30,33}, {19,29,21,20}, {16,26,29,17}, +{24,29,28,25}, {22,31,28,23}, {20,31,30,21}, {18,31,30,19}, +{16,30,17,17}, {-21,-22,35,34}, {-21,-22,33,32}, {-21,-22,31,30}, +{-21,-22,29,28}, {-21,-22,27,26}, {-28,-22,25,31}, {24,28,29,30}, +{23,24,26,27}, {23,24,25,25}, {-69,-35,-32,27}, {-70,26,25,-66}, +{-68,-67,24,-33}, +}; diff --git a/source/blender/src/cre/license.jpeg.c b/source/blender/src/cre/license.jpeg.c new file mode 100644 index 00000000000..ffbc87cd495 --- /dev/null +++ b/source/blender/src/cre/license.jpeg.c @@ -0,0 +1,34 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +int datatoc_tonize= 0; +char datatoc_ton[]= {0}; diff --git a/source/blender/src/cre/license_key.c b/source/blender/src/cre/license_key.c new file mode 100644 index 00000000000..a74c74e64f2 --- /dev/null +++ b/source/blender/src/cre/license_key.c @@ -0,0 +1,195 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include "license_key.h" +#include "keyed_functions.h" +#include "BKE_utildefines.h" +#include "BIF_screen.h" // splash +#include "BIF_toolbox.h" +#include "blenkey.h" +#include <stdio.h> +#include <string.h> +#include "BLO_readfile.h" +#include "BLO_keyStore.h" + +int LICENSE_KEY_VALID = FALSE; +int I_AM_PUBLISHER = FALSE; + +static UserStruct User; + +// Python stuff + +#include "Python.h" +#include "marshal.h" +#include "compile.h" /* to give us PyCodeObject */ +#include "eval.h" /* prototype for PyEval_EvalCode */ + + +Fptr g_functab[PYKEY_TABLEN]; +Fptr g_ptrtab[PYKEY_TABLEN]; + +static int g_seed[3] = PYKEY_SEED; +static PyObject *g_module_self; +static PyObject *g_main; + + +// end Python stuff + +// **************** PYTHON STUFF ************************** +/* ----------------------------------------------------- */ +/* this is the dummy functions to demonstrate */ + +int sticky_shoes(void *vp) +{ +#ifndef NDEBUG + printf("feature not enabled: Buy our Key NOW!\n"); +#endif + return 0; +} + +/* +int key_func1(void *vp) { + printf("function 1 called\n"); +} + +*/ +int key_return_true(void *vp) { +#ifndef NDEBUG + printf("function 2 called (return true)\n"); +#endif + return 1; +} + +/* ----------------------------------------------------- */ + +/* Declarations for objects of type Fplist */ + + +#ifndef NDEBUG +void feature1(void) +{ + Fptr f; + + printf("feature 2 called\n"); + f = g_ptrtab[KEY_FUNC2]; + if (f) f(0); +} + +void feature2(void) +{ + Fptr f; + + printf("feature 3 called\n"); + f = g_ptrtab[KEY_FUNC3]; + if (f) f(0); +} + +#endif + + +/* Initialization function for the module (*must* be called initprot) */ + +static void init_ftable(void) // initializes functiontable +{ + int i; + + g_functab[0] = &key_func1; + g_functab[1] = &key_func2; + g_functab[2] = &key_func3; + + for (i = 3; i < PYKEY_TABLEN; i++) + { + g_functab[i] = &sticky_shoes; + } + + // for debugging perposes + /* + for (i = 0; i < PYKEY_TABLEN; i++) + { + g_functab[i] = (Fptr *) (i + 100); + } + */ +} + + +static void init_ptable(void) // initializes functiontable +{ + int i; + + for (i = 0; i < PYKEY_TABLEN; i++) + { + g_ptrtab[i] = &sticky_shoes; + } +} + + +#ifdef NDEBUG +static void print_ptable(void) +{ + int i; + + for (i = 0; i < PYKEY_TABLEN; i++) + { + printf ("index[%02d] = %08x\n", i, g_ptrtab[i]); + } +} +#endif + +static void insertname(PyObject *m,PyObject *p, char *name) +{ +} + +/* initialisation */ +static void initprot() +{ + init_ftable(); // malloc + init_ptable(); // malloc +} + +// ******************************* KEY STUFF ********************* + +void create_key_name(char * keyname) +{ +} + +void checkhome() +{ + initprot(); // initialize module and function tables +} + +void SHOW_LICENSE_KEY(void) +{ +} + +void loadKeyboard(char * name) +{ +} diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c new file mode 100644 index 00000000000..77319e5804b --- /dev/null +++ b/source/blender/src/drawaction.c @@ -0,0 +1,583 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * Drawing routines for the Action window type + */ + +/* System includes ----------------------------------------------------- */ + +#include <math.h> +#include <stdlib.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +/* Types --------------------------------------------------------------- */ +#include "DNA_action_types.h" +#include "DNA_curve_types.h" +#include "DNA_ipo_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_space_types.h" +#include "DNA_constraint_types.h" + +#include "BKE_action.h" +#include "BKE_global.h" + +/* Everything from source (BIF, BDR, BSE) ------------------------------ */ + +#include "BIF_gl.h" +#include "BIF_glutil.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_interface.h" +#include "BIF_mywindow.h" + +#include "BDR_editcurve.h" +#include "BSE_view.h" +#include "BSE_drawipo.h" +#include "BSE_editaction_types.h" +#include "BDR_drawaction.h" + +/* 'old' stuff": defines and types, and own include -------------------- */ + +#include "blendef.h" + +/* local functions ----------------------------------------------------- */ +void drawactionspace(void); +static void draw_channel_names(void); +static void draw_channel_strips(SpaceAction *saction); +int count_action_levels(bAction *act); +static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert); +static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert); +static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert); +static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos); + + +/* implementation ------------------------------------------------------ */ +void draw_cfra_action(void) +{ + Object *ob; + float vec[2]; + + vec[0]= (G.scene->r.cfra); + vec[0]*= G.scene->r.framelen; + + vec[1]= G.v2d->cur.ymin; + glColor3ub(0x60, 0xc0, 0x40); + glLineWidth(2.0); + + glBegin(GL_LINE_STRIP); + glVertex2fv(vec); + vec[1]= G.v2d->cur.ymax; + glVertex2fv(vec); + glEnd(); + + ob= (G.scene->basact) ? (G.scene->basact->object) : 0; + if(ob && ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) { + vec[0]-= ob->sf; + + glColor3ub(0x10, 0x60, 0); + + glBegin(GL_LINE_STRIP); + glVertex2fv(vec); + vec[1]= G.v2d->cur.ymin; + glVertex2fv(vec); + glEnd(); + } + + glLineWidth(1.0); +} + +static void draw_channel_names(void) +{ + short ofsx, ofsy = 0; + + bAction *act; + bActionChannel *chan; + bConstraintChannel *conchan; + float x, y; + + myortho2 (0, ACTWIDTH, G.v2d->cur.ymin, G.v2d->cur.ymax); // Scaling + + /* Blank out the area */ + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + if(G.v2d->scroll) { + ofsx= curarea->winrct.xmin; + ofsy= curarea->winrct.ymin; + glViewport(ofsx, ofsy+G.v2d->mask.ymin-SCROLLB, ACTWIDTH, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB)); + glScissor(ofsx, ofsy+G.v2d->mask.ymin-SCROLLB, ACTWIDTH, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB)); + } + } + + glClearColor(.8, .8, .8, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Clip to the scrollable area */ + + glColor3ub(0x00, 0x00, 0x00); + + act=G.saction->action; + x = 0.0; + + if (act) { + y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP); + + for (chan=act->chanbase.first; chan; chan=chan->next){ + glColor3ub(0xAA, 0xAA, 0xAA); + glRectf(x, y-CHANNELHEIGHT/2, (float)ACTWIDTH, y+CHANNELHEIGHT/2); + + if (chan->flag & ACHAN_SELECTED) + glColor3ub(255, 255, 255); + else + glColor3ub(0, 0, 0); + glRasterPos2f(x+8, y-4); + BMF_DrawString(G.font, chan->name); + y-=CHANNELHEIGHT+CHANNELSKIP; + + /* Draw constraint channels */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT) + glColor3ub(255, 255, 255); + else + glColor3ub(0, 0, 0); + + glRasterPos2f(x+32, y-4); + BMF_DrawString(G.font, conchan->name); + y-=CHANNELHEIGHT+CHANNELSKIP; + } + } + } + + + myortho2 (0, ACTWIDTH, 0, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB)); // Scaling + + glShadeModel(GL_SMOOTH); + + y=9; + + /* Draw sexy shaded block thingies */ + glEnable (GL_BLEND); + glBegin(GL_QUAD_STRIP); + glColor4ub (0xCC,0xCC,0xCC,0x00); + glVertex2f (0,SCROLLB*2-y); + glVertex2f (ACTWIDTH,SCROLLB*2-y); + + glColor4ub (0xCC,0xCC,0xCC,0xFF); + glVertex2f (0,SCROLLB-y); + glVertex2f (ACTWIDTH,SCROLLB-y); + + glColor4ub (0xCC,0xCC,0xCC,0xFF); + glVertex2f (0,0-y); + glVertex2f (ACTWIDTH,0-y); + + glEnd(); + +/* y=( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB); + + glBegin(GL_QUAD_STRIP); + glColor4ub (0x88,0x88,0x88,0xFF); + glVertex2f (0,y); + glVertex2f (ACTWIDTH,y); + glColor4ub (0x88,0x88,0x88,0x00); + glVertex2f (0,y-SCROLLB); + glVertex2f (ACTWIDTH,y-SCROLLB); + + glEnd(); +*/ + glDisable (GL_BLEND); + + glShadeModel(GL_FLAT); + +} + +int count_action_levels(bAction *act) +{ + int y=0; + bActionChannel *achan; + + if (!act) + return 0; + + for (achan=act->chanbase.first; achan; achan=achan->next){ + y+=1; + y+=BLI_countlist(&achan->constraintChannels); + } + + return y; +} + /** Draw a nicely beveled button (in screen space) */ +void draw_bevel_but(int x, int y, int w, int h, int sel) +{ + int xmin= x, ymin= y; + int xmax= x+w-1, ymax= y+h-1; + int i; + + glColor3ub(0,0,0); + glBegin(GL_LINE_LOOP); + glVertex2i(xmin, ymin); + glVertex2i(xmax, ymin); + glVertex2i(xmax, ymax); + glVertex2i(xmin, ymax); + glEnd(); + + glBegin(GL_LINE_LOOP); + if (sel) glColor3ub(0xD0, 0x7E, 0x06); + else glColor3ub(0x8C, 0x8C, 0x8C); + glVertex2i(xmax-1, ymin+1); + glVertex2i(xmax-1, ymax-1); + if (sel) glColor3ub(0xF4, 0xEE, 0x8E); + else glColor3ub(0xDF, 0xDF, 0xDF); + glVertex2i(xmin+1, ymax-1); + glVertex2i(xmin+1, ymin+1); + glEnd(); + + if (sel) glColor3ub(0xF1, 0xCA, 0x13); + else glColor3ub(0xAC, 0xAC, 0xAC); + glBegin(GL_LINES); + for (i=xmin+2; i<=xmax-2; i++) { + glVertex2f(i, ymin+2); + glVertex2f(i, ymax-1); + } + glEnd(); +} + +static void draw_channel_strips(SpaceAction *saction) +{ + rcti scr_rct; + gla2DDrawInfo *di; + bAction *act; + bActionChannel *chan; + bConstraintChannel *conchan; + float y; + + act= saction->action; + if (!act) + return; + + scr_rct.xmin= saction->area->winrct.xmin + ACTWIDTH; + scr_rct.ymin= saction->area->winrct.ymin + saction->v2d.mask.ymin-SCROLLB; + scr_rct.xmax= saction->area->winrct.xmin + saction->v2d.hor.xmax; + scr_rct.ymax= saction->area->winrct.ymin + saction->v2d.mask.ymax; + di= glaBegin2DDraw(&scr_rct, &G.v2d->cur); + + y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP); + + for (chan=act->chanbase.first; chan; chan=chan->next){ + int frame1_x, channel_y; + + gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y); + + glEnable(GL_BLEND); + if (chan->flag & ACHAN_SELECTED) glColor4b(0x11, 0x22, 0x55, 0x22); + else glColor4b(0x55, 0x22, 0x11, 0x22); + glRectf(0, channel_y-CHANNELHEIGHT/2, frame1_x, channel_y+CHANNELHEIGHT/2); + + if (chan->flag & ACHAN_SELECTED) glColor4b(0x11, 0x22, 0x55, 0x44); + else glColor4b(0x55, 0x22, 0x11, 0x44); + glRectf(frame1_x, channel_y-CHANNELHEIGHT/2, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2); + glDisable(GL_BLEND); + + draw_ipo_channel(di, chan->ipo, 0, y); + + /* Increment the step */ + y-=CHANNELHEIGHT+CHANNELSKIP; + + + /* Draw constraint channels */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y); + glEnable(GL_BLEND); + if (conchan->flag & ACHAN_SELECTED) glColor4b(0x11, 0x22, 0x55, 0x22); + else glColor4b(0x55, 0x22, 0x11, 0x22); + glRectf(0, channel_y-CHANNELHEIGHT/2+4, frame1_x, channel_y+CHANNELHEIGHT/2-4); + + if (conchan->flag & ACHAN_SELECTED) glColor4b(0x11, 0x22, 0x55, 0x44); + else glColor4b(0x55, 0x22, 0x11, 0x44); + glRectf(frame1_x, channel_y-CHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2-4); + glDisable(GL_BLEND); + + draw_ipo_channel(di, conchan->ipo, 0, y); + y-=CHANNELHEIGHT+CHANNELSKIP; + } + } + + glaEnd2DDraw(di); +} + +void drawactionspace(void) +{ + + short ofsx = 0, ofsy = 0; + + if (!G.saction) + return; + + + if (!G.saction->pin) { + if (OBACT) + G.saction->action = OBACT->action; + else + G.saction->action=NULL; + } + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; + + calc_scrollrcts(G.v2d, curarea->winx, curarea->winy); + + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + if(G.v2d->scroll) { + ofsx= curarea->winrct.xmin; + ofsy= curarea->winrct.ymin; + glViewport(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + glScissor(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + } + } + + glClearColor(.45, .45, .45, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); + + /* Draw backdrop */ + calc_ipogrid(); + draw_ipogrid(); + + /* Draw channel strips */ + draw_channel_strips(G.saction); + + /* Draw current frame */ + glViewport(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + glScissor(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); + draw_cfra_action(); + + /* Draw scroll */ + mywinset(curarea->win); + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5); + if(G.v2d->scroll) drawscroll(0); + } + + /* Draw channel names */ + draw_channel_names(); + + curarea->win_swap= WIN_BACK_OK; +} + +void draw_channel_name(const char* name, short type, float ypos, int selected) +{ +} + +static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos) +{ + int v; + + if (!blist) + return; + + for (v = 0; v<totvert; v++){ + if (v==0 || (blist[v]->vec[1][0] != blist[v-1]->vec[1][0])){ + int sc_x, sc_y; + gla2DDrawTranslatePt(di, blist[v]->vec[1][0], ypos, &sc_x, &sc_y); + draw_bevel_but(sc_x-2, sc_y-5, 7, 13, (blist[v]->f2 & 1)); + } + } +} + +void draw_object_channel(gla2DDrawInfo *di, Object *ob, int flags, float ypos) +{ + BezTriple **blist; + int totvert; + + blist = ob_to_keylist(ob, flags, &totvert); + if (blist){ + draw_keylist(di,totvert, blist, ypos); + MEM_freeN(blist); + } +} + +void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, int flags, float ypos) +{ + BezTriple **blist; + int totvert; + + blist = ipo_to_keylist(ipo, flags, &totvert); + if (blist){ + draw_keylist(di,totvert, blist, ypos); + MEM_freeN(blist); + } +} + +void draw_action_channel(gla2DDrawInfo *di, bAction *act, int flags, float ypos) +{ + BezTriple **blist; + int totvert; + + blist = action_to_keylist(act, flags, &totvert); + if (blist){ + draw_keylist(di,totvert, blist, ypos); + MEM_freeN(blist); + } +} + +static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert) +{ + IpoCurve *icu; + int v, count=0; + + BezTriple **list = NULL; + + if (ob){ + + /* Count Object Keys */ + if (ob->ipo){ + for (icu=ob->ipo->curve.first; icu; icu=icu->next){ + count+=icu->totvert; + } + } + + /* Count Constraint Keys */ + /* Count object data keys */ + + /* Build the list */ + if (count){ + list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist"); + count=0; + + /* Add object keyframes */ + for (icu=ob->ipo->curve.first; icu; icu=icu->next){ + for (v=0; v<icu->totvert; v++){ + list[count++]=&icu->bezt[v]; + } + } + + /* Add constraint keyframes */ + /* Add object data keyframes */ + + /* Sort */ + qsort(list, count, sizeof(BezTriple*), bezt_compare); + } + } + (*totvert)=count; + return list; +} + +static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert) +{ + IpoCurve *icu; + int v, count=0; + + BezTriple **list = NULL; + + if (ipo){ + /* Count required keys */ + for (icu=ipo->curve.first; icu; icu=icu->next){ + count+=icu->totvert; + } + + /* Build the list */ + if (count){ + list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist"); + count=0; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (v=0; v<icu->totvert; v++){ + list[count++]=&icu->bezt[v]; + } + } + qsort(list, count, sizeof(BezTriple*), bezt_compare); + } + } + (*totvert)=count; + return list; +} + +static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert) +{ + IpoCurve *icu; + bActionChannel *achan; + bConstraintChannel *conchan; + int v, count=0; + + BezTriple **list = NULL; + + if (act){ + /* Count required keys */ + for (achan=act->chanbase.first; achan; achan=achan->next){ + /* Count transformation keys */ + for (icu=achan->ipo->curve.first; icu; icu=icu->next) + count+=icu->totvert; + + /* Count constraint keys */ + for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) + for (icu=conchan->ipo->curve.first; icu; icu=icu->next) + count+=icu->totvert; + + + } + + /* Build the list */ + if (count){ + list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist"); + count=0; + + for (achan=act->chanbase.first; achan; achan=achan->next){ + /* Add transformation keys */ + for (icu=achan->ipo->curve.first; icu; icu=icu->next){ + for (v=0; v<icu->totvert; v++) + list[count++]=&icu->bezt[v]; + } + + /* Add constraint keys */ + for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){ + for (icu=conchan->ipo->curve.first; icu; icu=icu->next) + for (v=0; v<icu->totvert; v++) + list[count++]=&icu->bezt[v]; + } + + } + qsort(list, count, sizeof(BezTriple*), bezt_compare); + + } + } + (*totvert)=count; + return list; +} + diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c new file mode 100644 index 00000000000..ede04c45d6b --- /dev/null +++ b/source/blender/src/drawimage.c @@ -0,0 +1,582 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> +#ifdef WIN32 +#include <io.h> +#include "BLI_winstuff.h" +#else +#include <unistd.h> +#endif +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_editVert.h" + +#include "IMB_imbuf_types.h" + +#include "DNA_image_types.h" +#include "DNA_mesh_types.h" +#include "DNA_packedFile_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_mesh.h" +#include "BKE_image.h" + +#include "BDR_editface.h" + +#include "BIF_gl.h" +#include "BIF_space.h" +#include "BIF_screen.h" +#include "BIF_mywindow.h" +#include "BIF_drawimage.h" + +/* Modules used */ +#include "mydevice.h" +#include "render.h" + + +void rectwrite_part(int winxmin, int winymin, int winxmax, int winymax, int x1, int y1, int xim, int yim, float zoomx, float zoomy, unsigned int *rect) +{ + int cx, cy, oldxim, x2, y2; + + oldxim= xim; + + /* coordinaten hoe 't op scherm komt */ + x2= x1+ zoomx*xim; + y2= y1+ zoomy*yim; + + /* partiele clip */ + if(x1<winxmin) { + /* recten bij OpenGL mogen niet links/onder van windowrand beginnen */ + cx= winxmin-x1+(int)zoomx; + /* zorg ervoor dat de rect pixelnauwkeurig wordt neergezet */ + cx/= zoomx; + cx++; + x1+= zoomx*cx; + xim-= cx; + rect+= cx; + } + if(y1<winymin) { + cy= winymin-y1+(int)zoomy; + cy/= zoomy; + cy++; + y1+= zoomy*cy; + rect+= cy*oldxim; + yim-= cy; + } + if(x2>=winxmax) { + cx= x2-winxmax; + cx/= zoomx; + xim-= cx+3; + } + if(y2>=winymax) { + cy= y2-winymax; + cy/= zoomy; + yim-= cy+3; + } + + if(xim<=0) return; + if(yim<=0) return; + + mywinset(G.curscreen->mainwin); + glScissor(winxmin, winymin, winxmax-winxmin+1, winymax-winymin+1); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, oldxim); + + glPixelZoom(zoomx, zoomy); + + glRasterPos2i(x1, y1); + glDrawPixels(xim, yim, GL_RGBA, GL_UNSIGNED_BYTE, rect); + + glPixelZoom(1.0, 1.0); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + + mywinset(curarea->win); +} + +/** + * Sets up the fields of the View2D member of the SpaceImage struct + * This routine can be called in two modes: + * mode == 'f': float mode ??? + * mode == 'p': pixel mode ??? + * + * @param sima the image space to update + * @param mode the mode to use for the update + * @return void + * + */ +void calc_image_view(SpaceImage *sima, char mode) +{ + float xim=256, yim=256; + float x1, y1; + float zoom; + + if(sima->image && sima->image->ibuf) { + xim= sima->image->ibuf->x; + yim= sima->image->ibuf->y; + } + + sima->v2d.tot.xmin= 0; + sima->v2d.tot.ymin= 0; + sima->v2d.tot.xmax= xim; + sima->v2d.tot.ymax= yim; + + sima->v2d.mask.xmin= sima->v2d.mask.ymin= 0; + sima->v2d.mask.xmax= curarea->winx; + sima->v2d.mask.ymax= curarea->winy; + + + /* Which part of the image space do we see? */ + /* Same calculation as in lrectwrite: area left and down*/ + x1= curarea->winrct.xmin+(curarea->winx-sima->zoom*xim)/2; + y1= curarea->winrct.ymin+(curarea->winy-sima->zoom*yim)/2; + + x1-= sima->zoom*sima->xof; + y1-= sima->zoom*sima->yof; + + /* float! */ + zoom= sima->zoom; + + /* relatieve afbeeld links */ + sima->v2d.cur.xmin= ((curarea->winrct.xmin - (float)x1)/zoom); + sima->v2d.cur.xmax= sima->v2d.cur.xmin + ((float)curarea->winx/zoom); + + /* relatieve afbeeld links */ + sima->v2d.cur.ymin= ((curarea->winrct.ymin-(float)y1)/zoom); + sima->v2d.cur.ymax= sima->v2d.cur.ymin + ((float)curarea->winy/zoom); + + if(mode=='f') { + sima->v2d.cur.xmin/= xim; + sima->v2d.cur.xmax/= xim; + sima->v2d.cur.ymin/= yim; + sima->v2d.cur.ymax/= yim; + } +} + +void what_image(SpaceImage *sima) +{ + extern TFace *lasttface; /* editface.c */ + Mesh *me; + + if(sima->mode==SI_TEXTURE) { + if(G.f & G_FACESELECT) { + + sima->image= 0; + me= get_mesh((G.scene->basact) ? (G.scene->basact->object) : 0); + set_lasttface(); + + if(me && me->tface && lasttface) { + if(lasttface->mode & TF_TEX) { + sima->image= lasttface->tpage; + + if(sima->flag & SI_EDITTILE); + else sima->curtile= lasttface->tile; + + if(sima->image) { + if(lasttface->mode & TF_TILES) sima->image->tpageflag |= IMA_TILES; + else sima->image->tpageflag &= ~IMA_TILES; + } + } + } + } + } +} + +void image_changed(SpaceImage *sima, int dotile) +{ + TFace *tface; + Mesh *me; + int a; + + if(sima->mode==SI_TEXTURE) { + + if(G.f & G_FACESELECT) { + me= get_mesh((G.scene->basact) ? (G.scene->basact->object) : 0); + if(me && me->tface) { + tface= me->tface; + a= me->totface; + while(a--) { + if(tface->flag & TF_SELECT) { + + if(dotile==2) { + tface->mode &= ~TF_TILES; + } + else { + tface->tpage= sima->image; + tface->mode |= TF_TEX; + + if(dotile) tface->tile= sima->curtile; + } + + if(sima->image) { + if(sima->image->tpageflag & IMA_TILES) tface->mode |= TF_TILES; + else tface->mode &= ~TF_TILES; + + if(sima->image->id.us==0) sima->image->id.us= 1; + } + } + tface++; + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSGAME, 0); + } + } + } +} + + +void uvco_to_areaco(float *vec, short *mval) +{ + float x, y; + + mval[0]= 3200; + + x= (vec[0] - G.v2d->cur.xmin)/(G.v2d->cur.xmax-G.v2d->cur.xmin); + y= (vec[1] - G.v2d->cur.ymin)/(G.v2d->cur.ymax-G.v2d->cur.ymin); + + if(x>=0.0 && x<=1.0) { + if(y>=0.0 && y<=1.0) { + mval[0]= G.v2d->mask.xmin + x*(G.v2d->mask.xmax-G.v2d->mask.xmin); + mval[1]= G.v2d->mask.ymin + y*(G.v2d->mask.ymax-G.v2d->mask.ymin); + } + } +} + +void uvco_to_areaco_noclip(float *vec, short *mval) +{ + float x, y; + + mval[0]= 3200; + + x= (vec[0] - G.v2d->cur.xmin)/(G.v2d->cur.xmax-G.v2d->cur.xmin); + y= (vec[1] - G.v2d->cur.ymin)/(G.v2d->cur.ymax-G.v2d->cur.ymin); + + x= G.v2d->mask.xmin + x*(G.v2d->mask.xmax-G.v2d->mask.xmin); + y= G.v2d->mask.ymin + y*(G.v2d->mask.ymax-G.v2d->mask.ymin); + + mval[0]= x; + mval[1]= y; +} + + +void draw_tfaces(void) +{ + TFace *tface; + MFace *mface; + Mesh *me; + unsigned int col; + int a; + + glPointSize(2.0); + + if(G.f & G_FACESELECT) { + me= get_mesh((G.scene->basact) ? (G.scene->basact->object) : 0); + if(me && me->tface) { + + calc_image_view(G.sima, 'f'); /* float */ + myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); + + tface= me->tface; + mface= me->mface; + a= me->totface; + + while(a--) { + if(mface->v3 && (tface->flag & TF_SELECT) ) { + + cpack(0x0); + glBegin(GL_LINE_LOOP); + glVertex2fv( tface->uv[0] ); + glVertex2fv( tface->uv[1] ); + glVertex2fv( tface->uv[2] ); + if(mface->v4) glVertex2fv( tface->uv[3] ); + glEnd(); + + setlinestyle(2); + /* kleuren: R=x G=y */ + + if(tface->flag & TF_ACTIVE) cpack(0xFF00); else cpack(0xFFFFFF); + + glBegin(GL_LINE_STRIP); + glVertex2fv( tface->uv[0] ); + glVertex2fv( tface->uv[1] ); + glEnd(); + + if(tface->flag & TF_ACTIVE) cpack(0xFF); else cpack(0xFFFFFF); + + glBegin(GL_LINE_STRIP); + glVertex2fv( tface->uv[0] ); + if(mface->v4) glVertex2fv( tface->uv[3] ); else glVertex2fv( tface->uv[2] ); + glEnd(); + + cpack(0xFFFFFF); + + glBegin(GL_LINE_STRIP); + glVertex2fv( tface->uv[1] ); + glVertex2fv( tface->uv[2] ); + if(mface->v4) glVertex2fv( tface->uv[3] ); + glEnd(); + + setlinestyle(0); + + glBegin(GL_POINTS); + + if(tface->flag & TF_SEL1) col= 0x77FFFF; else col= 0xFF70FF; + cpack(col); + glVertex2fv(tface->uv[0]); + + if(tface->flag & TF_SEL2) col= 0x77FFFF; else col= 0xFF70FF; + cpack(col); + glVertex2fv(tface->uv[1]); + + if(tface->flag & TF_SEL3) col= 0x77FFFF; else col= 0xFF70FF; + cpack(col); + glVertex2fv(tface->uv[2]); + + if(mface->v4) { + if(tface->flag & TF_SEL4) col= 0x77FFFF; else col= 0xFF70FF; + cpack(col); + glVertex2fv(tface->uv[3]); + } + glEnd(); + } + + tface++; + mface++; + } + } + } + glPointSize(1.0); +} + +static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty, short endx, short endy) +{ + unsigned int *rt, *rp, *rectmain; + short y, heigth, len; + + /* de juiste offset in rectot */ + + rt= ibuf->rect+ (starty*ibuf->x+ startx); + + len= (endx-startx); + heigth= (endy-starty); + + rp=rectmain= MEM_mallocN(heigth*len*sizeof(int), "rect"); + + for(y=0; y<heigth; y++) { + memcpy(rp, rt, len*4); + rt+= ibuf->x; + rp+= len; + } + return rectmain; +} + +void drawimagespace(void) +{ + ImBuf *ibuf= NULL; + unsigned int *rect; + int x1, y1, xmin, xmax, ymin, ymax; + short sx, sy, dx, dy; + + glClearColor(.1875, .1875, .1875, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + curarea->win_swap= WIN_BACK_OK; + + xmin= curarea->winrct.xmin; xmax= curarea->winrct.xmax; + ymin= curarea->winrct.ymin; ymax= curarea->winrct.ymax; + + what_image(G.sima); + + if(G.sima->image) { + + if(G.sima->image->ibuf==0) { + load_image(G.sima->image, IB_rect, G.sce, G.scene->r.cfra); + } + ibuf= G.sima->image->ibuf; + } + + if(ibuf==0 || ibuf->rect==0) { + calc_image_view(G.sima, 'f'); + myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); + cpack(0x404040); + glRectf(0.0, 0.0, 1.0, 1.0); + draw_tfaces(); + + return; + } + + /* plek berekenen */ + x1= xmin+(curarea->winx-G.sima->zoom*ibuf->x)/2; + y1= ymin+(curarea->winy-G.sima->zoom*ibuf->y)/2; + + x1-= G.sima->zoom*G.sima->xof; + y1-= G.sima->zoom*G.sima->yof; + + + if(G.sima->flag & SI_EDITTILE) { + rectwrite_part(xmin, ymin, xmax, ymax, x1, y1, ibuf->x, ibuf->y, (float)G.sima->zoom, (float)G.sima->zoom, ibuf->rect); + + dx= ibuf->x/G.sima->image->xrep; + dy= ibuf->y/G.sima->image->yrep; + sy= (G.sima->curtile / G.sima->image->xrep); + sx= G.sima->curtile - sy*G.sima->image->xrep; + + sx*= dx; + sy*= dy; + + calc_image_view(G.sima, 'p'); /* pixel */ + myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); + + cpack(0x0); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glRects(sx, sy, sx+dx-1, sy+dy-1); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + cpack(0xFFFFFF); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glRects(sx+1, sy+1, sx+dx, sy+dy); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + else if(G.sima->mode==SI_TEXTURE) { + if(G.sima->image->tpageflag & IMA_TILES) { + + + /* eventjes laten staan */ + if(G.sima->image->xrep<1) return; + if(G.sima->image->yrep<1) return; + + if(G.sima->curtile >= G.sima->image->xrep*G.sima->image->yrep) + G.sima->curtile = G.sima->image->xrep*G.sima->image->yrep - 1; + + dx= ibuf->x/G.sima->image->xrep; + dy= ibuf->y/G.sima->image->yrep; + + sy= (G.sima->curtile / G.sima->image->xrep); + sx= G.sima->curtile - sy*G.sima->image->xrep; + + sx*= dx; + sy*= dy; + + rect= get_part_from_ibuf(ibuf, sx, sy, sx+dx, sy+dy); + + /* rect= ibuf->rect; */ + for(sy= 0; sy+dy<=ibuf->y; sy+= dy) { + for(sx= 0; sx+dx<=ibuf->x; sx+= dx) { + + rectwrite_part(xmin, ymin, xmax, ymax, + x1+sx*G.sima->zoom, y1+sy*G.sima->zoom, dx, dy, (float)G.sima->zoom, (float)G.sima->zoom, rect); + } + } + + MEM_freeN(rect); + } + else + rectwrite_part(xmin, ymin, xmax, ymax, x1, y1, ibuf->x, ibuf->y, (float)G.sima->zoom,(float)G.sima->zoom, ibuf->rect); + + draw_tfaces(); + } + + calc_image_view(G.sima, 'f'); /* float */ +} + +void image_viewmove(void) +{ + short mval[2], mvalo[2], xof, yof; + + getmouseco_sc(mvalo); + + while(get_mbut()&(L_MOUSE|M_MOUSE)) { + + getmouseco_sc(mval); + + xof= (mvalo[0]-mval[0])/G.sima->zoom; + yof= (mvalo[1]-mval[1])/G.sima->zoom; + + if(xof || yof) { + + G.sima->xof+= xof; + G.sima->yof+= yof; + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } + else BIF_wait_for_statechange(); + } +} + +/** + * Updates the fields of the View2D member of the SpaceImage struct. + * Default behavior is to reset the position of the image and set the zoom to 1 + * If the image will not fit within the window rectangle, the zoom is adjusted + * + * @return void + * + */ +void image_home(void) +{ + int width, height; + float zoomX, zoomY; + + if (curarea->spacetype != SPACE_IMAGE) return; + if ((G.sima->image == 0) || (G.sima->image->ibuf == 0)) return; + + /* Check if the image will fit in the image with zoom==1 */ + width = curarea->winx; + height = curarea->winy; + if (((G.sima->image->ibuf->x >= width) || (G.sima->image->ibuf->y >= height)) && + ((width > 0) && (height > 0))) { + /* Find the zoom value that will fit the image in the image space */ + zoomX = ((float)width) / ((float)G.sima->image->ibuf->x); + zoomY = ((float)height) / ((float)G.sima->image->ibuf->y); + G.sima->zoom= MIN2(zoomX, zoomY); + + /* Now make it a power of 2 */ + G.sima->zoom = 1 / G.sima->zoom; + G.sima->zoom = log(G.sima->zoom) / log(2); + G.sima->zoom = ceil(G.sima->zoom); + G.sima->zoom = pow(2, G.sima->zoom); + G.sima->zoom = 1 / G.sima->zoom; + } + else { + G.sima->zoom= (float)1; + } + + G.sima->xof= G.sima->yof= 0; + + calc_image_view(G.sima, 'p'); + + scrarea_queue_winredraw(curarea); +} + diff --git a/source/blender/src/drawimasel.c b/source/blender/src/drawimasel.c new file mode 100644 index 00000000000..62d5b9ac583 --- /dev/null +++ b/source/blender/src/drawimasel.c @@ -0,0 +1,843 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <string.h> + +#ifdef _WIN32 +#include "BLI_winstuff.h" +#pragma warning (once : 4761) +#endif + +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" + +#include "IMB_imbuf_types.h" + +#include "DNA_screen_types.h" +#include "DNA_space_types.h" + +#include "BKE_global.h" + +#include "BIF_fsmenu.h" +#include "BIF_gl.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_interface.h" +#include "BIF_imasel.h" +#include "BIF_mywindow.h" +#include "BIF_space.h" + +#include "BSE_drawimasel.h" +#include "BSE_filesel.h" + +#include "interface.h" +#include "blendef.h" +#include "mydevice.h" + +#define IMALINESIZE 16 +/* well, who would have thought ... */ +#define lrectwrite(a, b, c, d, rect) {glRasterPos2i(a, b);glDrawPixels((c)-(a)+1, (d)-(b)+1, GL_RGBA, GL_UNSIGNED_BYTE, rect);} + +/* GLOBALS */ +extern char *fsmenu; + +void viewgate(short sx, short sy, short ex, short ey) +{ + short wx, wy; + wx = curarea->winrct.xmin; wy = curarea->winrct.ymin; + glViewport(wx+sx, wy+sy, (wx+ex )-(wx+sx)+1, (wy+ey )-(wy+sy)+1); + glScissor(wx+sx, wy+sy, (wx+ex )-(wx+sx)+1, (wy+ey )-(wy+sy)+1); + myortho2((float)sx+0.5 , (float)ex+0.5, (float)sy+0.5, (float)ey+0.5); +} + +void areaview (void) +{ + short wx, wy; + wx = curarea->winrct.xmin; wy = curarea->winrct.ymin; + glViewport(wx, wy, curarea->winx, curarea->winy); + glScissor(wx, wy, curarea->winx, curarea->winy); + myortho2(-0.5, (float)(curarea->winx)-0.5, -0.5, (float)(curarea->winy)-0.5); + +} + +void calc_hilite(SpaceImaSel *simasel) +{ + OneSelectableIma *ima; + ImaDir *direntry; + short mx, my; + int i, area_event; + + if (simasel->hilite > -1) { + direntry = simasel->firstdir; + while(direntry){ + direntry->hilite = 0; + direntry = direntry->next; + } + simasel->hilite = -1; + } + + if (simasel->totalima){ + simasel->hilite_ima = 0; + ima = simasel->first_sel_ima; + while (ima){ + ima->selectable = 0; + ima = ima->next; + } + } + + area_event = 0; + mx = simasel->mx; + my = simasel->my; + + if (simasel->desx > 0){ + if ( (mx > simasel->desx) && (mx < simasel->deex) && (my > simasel->desy) && (my < simasel->deey) ) area_event = IMS_INDIR; + } + if (simasel->fesx > 0){ + if ( (mx > simasel->fesx) && (mx < simasel->feex) && (my > simasel->fesy) && (my < simasel->feey) ) area_event = IMS_INFILE; + } + + switch(area_event){ + case IMS_INDIR: + simasel->hilite = simasel->topdir + ((simasel->deey - my - 4) / IMALINESIZE); + + if (my >= simasel->deey) simasel->hilite = -1; + if (simasel->hilite >= simasel->totaldirs) simasel->hilite = -1; + + if (simasel->hilite > -1){ + direntry = simasel->firstdir; + for (i = simasel->hilite; i>0; i--){ + direntry = direntry->next; + } + direntry->hilite = 1; + + } + simasel->mouse_move_redraw = 1; + break; + + case IMS_INFILE: + if (simasel->totalima){ + ima = simasel->first_sel_ima; + while (ima){ + ima->selectable = 0; + + if (ima->draw_me) { + if ((mx > ima->sx) && (mx < ima->sx+76) && (my > ima->sy-16) && (my < ima->sy+76)) { + ima->selectable = 1; + simasel->hilite_ima = ima; + simasel->mouse_move_redraw = 1; + } + } + + ima = ima->next; + } + } + break; + } +} + + +void make_sima_area(SpaceImaSel *simasel) +{ + OneSelectableIma *ima; + short rh, dm, sc; + short boxperline, boxlines, boxlinesinview, boxlinesleft; + +/* ima slider box */ + simasel->fssx = 8; + simasel->fssy = 8; + simasel->fsex = 30; + simasel->fsey = curarea->winy-64; +/* ima entry's box */ + simasel->fesx = simasel->fsex + 8; + simasel->fesy = simasel->fssy; + simasel->feex = curarea->winx- 8; + simasel->feey = curarea->winy-64; +/* ima names */ + simasel->dnsx = 38; + simasel->dnsy = curarea->winy - 29; + simasel->dnw = curarea->winx - 8 - 38; + simasel->dnh = 21; + simasel->fnsx = simasel->fesx; + simasel->fnsy = curarea->winy - 29 - 29; + simasel->fnw = curarea->winx - 8 - simasel->fnsx; + simasel->fnh = 21; + + if ((simasel->mode & 1)==1){ + /* dir slider box */ + simasel->dssx = 8; + + simasel->dsex = 30; + simasel->dsey = curarea->winy-64; + /* dir entry's box */ + simasel->desx = 38; + simasel->desy = 8; + + simasel->deex = 208; + simasel->deey = curarea->winy-64; + simasel->dssy = simasel->desy; + if (simasel->deex > (curarea->winx -8) ) simasel->deex = curarea->winx - 8; + if (simasel->deex <= simasel->desx ) simasel->dssx = 0; + /* file slider & entry & name box ++ */ + simasel->fssx += 216; + simasel->fsex += 216; + simasel->fesx += 216; + simasel->fnsx += 216; + simasel->fnw -= 216; + }else{ + simasel->desx = 0; + } + + if ((simasel->mode & 2) == 2){ + simasel->fesy += 32; + simasel->infsx = simasel->fesx; simasel->infsy = 8; + simasel->infex = simasel->feex; simasel->infey = 28; + }else{ + simasel->infsx = 0; + } + + simasel->dsdh = simasel->deey - simasel->desy - 4; + + if (simasel->dsdh <= 16) { simasel->desx = 0; } + if ((simasel->feex-16) <= simasel->fesx) { simasel->fesx = 0; } + if ((simasel->infex-16) <= simasel->infsx) { simasel->infsx = 0; } + + if ((simasel->deey ) <= simasel->desy) { simasel->desx = 0; } + if ((simasel->feey ) <= simasel->fesy) { simasel->fesx = 0; } + if ((simasel->infey ) > simasel->feey) { simasel->infsx = 0;} + + /* Dir Slider */ + if (simasel->desx != 0){ + simasel->dirsli = 0; + + simasel->dirsli_lines = (simasel->dsdh / IMALINESIZE); + simasel->dirsli_h = 0; + + if (simasel->topdir < 0) simasel->topdir = 0; + if (simasel->topdir > (simasel->totaldirs - simasel->dirsli_lines) ) simasel->topdir = (simasel->totaldirs - simasel->dirsli_lines); + + if ( (simasel->totaldirs * IMALINESIZE) >= simasel->dsdh ){ + simasel->dirsli = 1; + simasel->dirsli_sx = simasel->dssx+2; + simasel->dirsli_ex = simasel->dsex-2; + + simasel->dirsli_h = (simasel->dsdh) * (float)simasel->dirsli_lines / (float)simasel->totaldirs; + simasel->dirsli_ey = simasel->dsey - 2; + if (simasel->topdir) { + rh = (simasel->dsdh - simasel->dirsli_h); + simasel->dirsli_ey -= rh * (float)((float)simasel->topdir / (float)(simasel->totaldirs - simasel->dirsli_lines )); + } + + if (simasel->dirsli_h < 4) simasel->dirsli_h = 4; + + }else{ + simasel->topdir = 0; + } + } + + if (simasel->totalima){ + /* there are images */ + + ima = simasel->first_sel_ima; + + + boxperline = (simasel->feex - simasel->fesx) / 80; + if (boxperline) boxlines = 1 + (simasel->totalima / boxperline); else boxlines = 1; + boxlinesinview = (simasel->feey - simasel->fesy) / 100; + boxlinesleft = boxlines - boxlinesinview; + + if (boxlinesleft > 0){ + /* slider needed */ + + simasel->slider_height = boxlinesinview / (float)(boxlines+1); + simasel->slider_space = 1.0 - simasel->slider_height; + + simasel->imasli_sx = simasel->fssx+1; + simasel->imasli_ex = simasel->fsex-1; + simasel->fsdh = simasel->fsey - simasel->fssy - 4; + + simasel->imasli_h = simasel->fsdh * simasel->slider_height; + if (simasel->imasli_h < 6) simasel->imasli_h = 6; + simasel->imasli_ey = simasel->fsey - 2 - (simasel->fsdh * simasel->slider_space * simasel->image_slider); + + simasel->imasli = 1; + + }else{ + simasel->image_slider = 0; + simasel->imasli = 0; + } + + sc = simasel->image_slider * (boxlinesleft * 100); + + simasel->curimax = simasel->fesx + 8; + simasel->curimay = simasel->feey - 90 + sc; + + dm = 1; + if (simasel->curimay-2 < simasel->fesy) dm = 0; + if (simasel->curimay+80 > simasel->feey) dm = 0; + if (simasel->curimax+72 > simasel->feex) dm = 0; + + simasel->total_selected = 0; + while (ima){ + ima->draw_me = dm; + + if (ima->selected) simasel->total_selected++; + + ima->sx = simasel->curimax; + ima->sy = simasel->curimay+16; + + ima->ex = ima->sx + ima->dw; + ima->ey = ima->sy + ima->dh; + + simasel->curimax += 80; + if (simasel->curimax + 72 > simasel->feex){ + + simasel->curimax = simasel->fesx + 8; + simasel->curimay -= 100; + + dm = 1; + if (simasel->curimay+80 > simasel->feey) dm = 0; + if (simasel->curimay-8 < simasel->fesy) dm = 0; + + } + ima = ima->next; + } + } +} + +static void str_image_type(int ftype, char *name) +{ + strcpy(name, ""); + + if((ftype & JPG_MSK) == JPG_STD) strcat(name, "std "); + if((ftype & JPG_MSK) == JPG_VID) strcat(name, "video "); + if((ftype & JPG_MSK) == JPG_JST) strcat(name, "amiga "); + if((ftype & JPG_MSK) == JPG_MAX) strcat(name, "max "); + + if( ftype == AN_hamx) { strcat(name, "hamx "); return; } + + if( ftype == IMAGIC ) { strcat(name, "sgi "); return; } + if( ftype & JPG ) { strcat(name, "jpeg "); } + if( ftype & TGA ) { strcat(name, "targa "); } + if( ftype & PNG ) { strcat(name, "png "); } + if( ftype & AMI ) { strcat(name, "iff "); } +} + +void draw_sima_area(SpaceImaSel *simasel) +{ + uiBlock *block; + OneSelectableIma *ima; + ImaDir *direntry; + int i, info; + short sx, sy, ex, ey, sc; + char naam[256], infostr[256]; + + glClearColor(0.4375, 0.4375, 0.4375, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + sprintf(naam, "win %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSF, UI_HELV, curarea->win); + uiBlockSetCol(block, BUTBLUE); + + if (simasel->desx > 0){ + /* DIR ENTRYS */ + cpack(C_DERK); + glRecti(simasel->dssx, simasel->dssy, simasel->dsex, simasel->dsey); + glRecti(simasel->desx, simasel->desy, simasel->deex, simasel->deey); + + uiEmboss(simasel->dssx, simasel->dssy, simasel->dsex, simasel->dsey,1); + uiEmboss(simasel->desx, simasel->desy, simasel->deex, simasel->deey,1); + + if (simasel->dirsli == 1) { + sx = simasel->dirsli_sx+2; + sy = simasel->dirsli_ey - simasel->dirsli_h+2; + ex = simasel->dirsli_ex-2; + ey = simasel->dirsli_ey-2; + + cpack(C_BACK); + + glRecti(sx, sy, ex, ey); + uiEmboss(sx, sy, ex,ey,0); + } + if (simasel->totaldirs) { + sx = simasel->desx+8; + sy = simasel->deey-IMALINESIZE; + + direntry = simasel->firstdir; + if (simasel->topdir){ + for(i = simasel->topdir; i>0; i--){ + direntry = direntry->next; + } + } + viewgate(simasel->desx, simasel->desy, simasel->deex-4, simasel->deey); + + i = simasel->dirsli_lines; + if (i > simasel->totaldirs) i = simasel->totaldirs; + for(;i > 0; i--){ + strcpy(naam, direntry->name); + + cpack(0xFFFFFF); + if (direntry->selected == 1){ + cpack(0x7777CC); + glRecti(simasel->desx+2, sy-4, simasel->deex-4, sy+IMALINESIZE-4); + cpack(0xFFFFFF); + } + if (direntry->hilite == 1){ + cpack(0x999999); + glRecti(simasel->desx+2, sy-4, simasel->deex-4, sy+IMALINESIZE-4); + cpack(0xFFFFFF); + } + + glRasterPos2i(sx, sy); + BMF_DrawString(G.font, naam); + + direntry = direntry->next; + sy-=IMALINESIZE; + } + areaview(); + + } + + /* status icons */ + + sx = simasel->desx; + sy = simasel->deey+6; + + glRasterPos2f(sx+16*0, sy); + if (bitset(simasel->fase, IMS_FOUND_BIP)) { + BIF_draw_icon(ICON_BPIBFOLDER_HLT); + } else if (bitset(simasel->fase, IMS_WRITE_NO_BIP)) { + BIF_draw_icon(ICON_BPIBFOLDER_DEHLT); + } else { + BIF_draw_icon(ICON_BPIBFOLDER_DEHLT); + } + + glRasterPos2f(sx+16*1, sy); + if (bitset(simasel->fase, IMS_KNOW_INF)) { + BIF_draw_icon(ICON_FOLDER_HLT); + } else { + BIF_draw_icon(ICON_FOLDER_DEHLT); + } + + glRasterPos2f(sx+16*2, sy); + if (bitset(simasel->fase, IMS_KNOW_IMA)) { + BIF_draw_icon(ICON_BLUEIMAGE_HLT); + } else { + BIF_draw_icon(ICON_BLUEIMAGE_DEHLT); + } + } + + if (simasel->fesx > 0) { + int extrabutsize; + + cpack(C_DARK); + + glRecti(simasel->fssx, simasel->fssy, simasel->fsex, simasel->fsey); + + glRecti(simasel->fesx, simasel->fesy, simasel->feex, simasel->feey); + + uiEmboss(simasel->fssx-1, simasel->fssy-1, simasel->fsex+1, simasel->fsey+1,1); + uiEmboss(simasel->fesx-1, simasel->fesy-1, simasel->feex+1, simasel->feey+1,1); + + if (simasel->imasli == 1){ + sx = simasel->imasli_sx; + sy = simasel->imasli_ey - simasel->imasli_h; + ex = simasel->imasli_ex; + ey = simasel->imasli_ey; + + cpack(C_BACK); + + glRecti(sx, sy, ex, ey); + uiEmboss(sx, sy, ex, ey, 1); + } + + info = 0; + strcpy(infostr, ""); + if (simasel->totalima){ + viewgate(simasel->fesx, simasel->fesy, simasel->feex, simasel->feey); + + ima = simasel->first_sel_ima; + + while (ima){ + sc = 0; + + sx = ima->sx- 6; sy = ima->sy-20 + sc; + ex = ima->sx+71; ey = ima->sy+70 + sc; + + if(ima->selected == 1){ + cpack(0xCC6666); + glRecti(sx, sy, ex, ey); + } + if(ima->selectable == 1){ + if (ima->selected ) cpack(0xEE8888); else cpack(0x999999); + + if (((simasel->mode & 8) != 8) && (simasel->hilite_ima == ima)){ + glRecti(sx, sy, ex, ey); uiEmboss(sx,sy, ex,ey, 1); + } + if (ima->disksize/1000 > 1000){ sprintf(infostr, "%s %.2fMb x%i y%i %i bits ",ima->file_name,(ima->disksize/1024)/1024.0, ima->orgx, ima->orgy, ima->orgd); + }else{ sprintf(infostr, "%s %dKb x%i y%i %i bits ", ima->file_name,ima->disksize/1024, ima->orgx, ima->orgy, ima->orgd); + } + if (ima->anim == 1){ strcat (infostr, "movie"); }else{ + str_image_type(ima->ibuf_type, naam); + strcat (infostr, naam); + } + info = 1; + } + + sx = ima->sx; sy = ima->sy + sc; + ex = ima->ex; ey = ima->ey + sc; + + if (ima->anim == 0) cpack(C_DARK); else cpack(C_DERK); + + glRecti(sx, sy, ex, ey); + uiEmboss(sx-1,sy-1, ex+1,ey+1, 1); + + cpack(0); + strcpy(naam, ima->file_name); + naam[11] = 0; + + glRasterPos2i(sx+32-BMF_GetStringWidth(G.fonts, naam) / 2 , sy-16); + BMF_DrawString(G.fonts, naam); + + if ((ima) && (ima->pict) && (ima->pict->rect)){ + if ( (ey > simasel->fesy) && (sy < simasel->feey)){ + lrectwrite(sx, sy, ex-1, ey-1, ima->pict->rect); + } + } + + ima = ima->next; + } + + if ((simasel->mode & 8) == 8) { /* if loep */ + + if (bitset(simasel->fase, IMS_KNOW_IMA) && (simasel->hilite_ima)) { + + ima = simasel->hilite_ima; + glPixelZoom(2.0, 2.0); + + sx = ima->sx + (ima->ex - ima->sx)/2 - (ima->ex - ima->sx); + sy = ima->sy + (ima->ey - ima->sy)/2 - (ima->ey - ima->sy); + + ex = sx + 2*(ima->ex - ima->sx); + ey = sy + 2*(ima->ey - ima->sy); + + /* cpack(C_DERK); */ + /* uiEmboss(sx-8,sy-8, ex+8,ey+8, 1); */ + /* glRecti(sx-7, sy-7, ex+7, ey+7); */ + uiEmboss(sx-1,sy-1, ex+1,ey+1, 0); + + lrectwrite(sx, sy, sx+ (ima->ex - ima->sx)-1, sy+ (ima->ey - ima->sy)-1, ima->pict->rect); + + glPixelZoom(1.0, 1.0); + } + } + areaview(); /* reset viewgate */ + } + + + /* INFO */ + if (simasel->infsx > 0){ + cpack(C_DARK); + + glRecti(simasel->infsx, simasel->infsy, simasel->infex, simasel->infey); + uiEmboss(simasel->infsx, simasel->infsy, simasel->infex, simasel->infey,1); + + if ((info)&&(strlen(infostr) > 0)){ + + sx = curarea->winrct.xmin; + sy = curarea->winrct.ymin; + + viewgate(simasel->infsx, simasel->infsy, simasel->infex, simasel->infey); + + cpack(0xAAAAAA); + glRasterPos2i(simasel->infsx+4, simasel->infsy+6); + BMF_DrawString(G.font, infostr); + + areaview(); /* reset viewgate */ + + } + } + + extrabutsize= (simasel->returnfunc)?60:0; + if (simasel->dnw > extrabutsize+8) { + simasel->dnw-= extrabutsize; + uiDefBut(block, TEX, 1,"", simasel->dnsx, simasel->dnsy, simasel->dnw, simasel->dnh, simasel->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + if (extrabutsize) + uiDefBut(block, BUT, 5, "Load", simasel->dnsx+simasel->dnw, simasel->dnsy, extrabutsize, 21, NULL, 0.0, 0.0, 0, 0, "Load the selected image"); + } + if (simasel->fnw > extrabutsize+8) { + simasel->fnw-= extrabutsize; + uiDefBut(block, TEX, 2,"", simasel->fnsx, simasel->fnsy, simasel->fnw, simasel->fnh, simasel->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + if (extrabutsize) + uiDefBut(block, BUT, 6, "Cancel", simasel->fnsx+simasel->fnw, simasel->fnsy, extrabutsize, 21, NULL, 0.0, 0.0, 0, 0, "Cancel image loading"); + } + } + + if (curarea->winx > 16) { + char *menu= fsmenu_build_menu(); + + uiDefBut(block, BUT, 13, "P", 8, (short)(curarea->winy-29), 20, 21, 0, 0, 0, 0, 0, ""); + uiDefButS(block, MENU, 3 , menu, 8, (short)(curarea->winy-58), 20, 21, &simasel->fileselmenuitem, 0, 0, 0, 0, ""); + + MEM_freeN(menu); + } + + uiDrawBlock(block); +} + +void select_ima_files(SpaceImaSel *simasel) +{ + short set_reset; + short mval[2], oval[2]; + + set_reset = 1 - (simasel->hilite_ima->selected); + + getmouseco_areawin(mval); + oval[0] = mval[0] + 1; + + while(get_mbut()&R_MOUSE) { + getmouseco_areawin(mval); + if ((oval[0] != mval[0]) || (oval[1] != mval[1])){ + simasel->mx = mval[0]; + simasel->my = mval[1]; + + calc_hilite(simasel); + + if (simasel->hilite_ima){ + simasel->hilite_ima->selected = set_reset; + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } + oval[0] = mval[0]; + oval[1] = mval[1]; + } + } +} + +void move_imadir_sli(SpaceImaSel *simasel) +{ + + short mval[2], lval[2], fh; + float rh; + + getmouseco_areawin(mval); + + if ((mval[0] > simasel->dirsli_sx) && + (mval[0] < simasel->dirsli_ex) && + (mval[1] > simasel->dirsli_ey - simasel->dirsli_h) && + (mval[1] < simasel->dirsli_ey) ){ + + /* extactly in the slider */ + fh = simasel->dirsli_ey - mval[1]; + lval[1]=1; + while(get_mbut()&L_MOUSE) { + getmouseco_areawin(mval); + if (mval[1] != lval[1]){ + + rh = (float)(simasel->dsey - mval[1] - fh - simasel->dssy) / (simasel->dsdh - simasel->dirsli_h); + + simasel->topdir = 1 + rh * (simasel->totaldirs - simasel->dirsli_lines); + + scrarea_do_windraw(curarea); + uiEmboss(simasel->dirsli_sx, simasel->dirsli_ey - simasel->dirsli_h, + simasel->dirsli_ex, simasel->dirsli_ey,1); + screen_swapbuffers(); + lval[1] = mval[1]; + } + } + }else{ + if (mval[1] < simasel->dirsli_ey - simasel->dirsli_h) + simasel->topdir += (simasel->dirsli_lines - 1); + else + simasel->topdir -= (simasel->dirsli_lines - 1); + + while(get_mbut()&L_MOUSE) { } + } +} + +void move_imafile_sli(SpaceImaSel *simasel) +{ + short mval[2], cmy, omy = 0; + short ssl, sdh, ssv; + + getmouseco_areawin(mval); + cmy = mval[1]; + + if ((mval[0] > simasel->imasli_sx) && + (mval[0] < simasel->imasli_ex) && + (mval[1] > simasel->imasli_ey - simasel->imasli_h) && + (mval[1] < simasel->imasli_ey) ){ + + ssv = simasel->fsey - simasel->imasli_ey - 2; + + while(get_mbut() & L_MOUSE) { + getmouseco_areawin(mval); + if (mval[1] != omy){ + sdh = simasel->fsdh - simasel->imasli_h; + ssl = cmy - mval[1] + ssv; + + if (ssl < 0) { ssl = 0; } + if (ssl > sdh) { ssl = sdh; } + + simasel->image_slider = ssl / (float)sdh; + + scrarea_do_windraw(curarea); + uiEmboss(simasel->imasli_sx, simasel->imasli_ey - simasel->imasli_h, + simasel->imasli_ex, simasel->imasli_ey, 1); + + screen_swapbuffers(); + omy = mval[1]; + } + } + }else{ + while(get_mbut() & L_MOUSE) { } + } +} + +void ima_select_all(SpaceImaSel *simasel) +{ + OneSelectableIma *ima; + int reselect = 0; + + ima = simasel->first_sel_ima; + if (!ima) return; + + while(ima){ + if (ima->selected == 1) reselect = 1; + ima = ima->next; + } + ima = simasel->first_sel_ima; + if (reselect == 1){ + while(ima){ + ima->selected = 0; + ima = ima->next; + } + }else{ + while(ima){ + ima->selected = 1; + ima = ima->next; + } + } +} + +void pibplay(SpaceImaSel *simasel) +{ + OneSelectableIma *ima; + int sx= 8, sy= 8; + + ima = simasel->first_sel_ima; + if (!ima) return ; + + sx = curarea->winrct.xmin + 8; + sy = curarea->winrct.ymin + 8; + + while(!(get_mbut()&L_MOUSE)){ + scrarea_do_windraw(curarea); + + lrectwrite(sx, sy, sx+ima->dw-1, sy+ima->dh-1, ima->pict->rect); + + ima = ima->next; + if (!ima) ima = simasel->first_sel_ima; + screen_swapbuffers(); + } +} + + + +/* ************** hoofdtekenfunktie ************** */ + +void drawimasel() /* hoofdtekenfunktie */ +{ + SpaceImaSel *simasel; + simasel= curarea->spacedata.first; + + /* ortho: xmin xmax, ymin, ymax! */ + myortho2(-0.5, (float)(curarea->winx)-0.5, -0.5, (float)(curarea->winy)-0.5); + + if (simasel->fase == 0){ + checkdir(simasel->dir); + clear_ima_dir(simasel); + } + + if (!bitset(simasel->fase, IMS_KNOW_DIR)){ + if(simasel->firstdir) free_ima_dir(simasel->firstdir); + if(simasel->firstfile) free_ima_dir(simasel->firstfile); + simasel->firstdir = 0; + simasel->firstfile = 0; + + if (get_ima_dir(simasel->dir, IMS_DIR, &simasel->totaldirs, &simasel->firstdir) < 0){ + /* error */ + strcpy(simasel->dir, simasel->dor); + get_ima_dir(simasel->dir, IMS_DIR, &simasel->totaldirs, &simasel->firstdir); + } + + if (get_ima_dir(simasel->dir, IMS_FILE, &simasel->totalfiles, &simasel->firstfile) < 0){ + /* error */ + strcpy(simasel->file, simasel->fole); + get_ima_dir(simasel->dir, IMS_FILE, &simasel->totalfiles, &simasel->firstfile); + } + + simasel->topdir = 0; + simasel->topfile = 0; + simasel->fase |= IMS_KNOW_DIR; + + check_for_pib(simasel); + + strcpy(simasel->fole, simasel->file); + strcpy(simasel->dor, simasel->dir); + } + + if (!bitset(simasel->fase, IMS_FOUND_BIP)){ + /* Make the first Bip file ever in this directory */ + if ( !bitset(simasel->fase, IMS_KNOW_INF)){ + if (!bitset(simasel->fase, IMS_DOTHE_INF)){ + if(simasel->first_sel_ima) free_sel_ima(simasel->first_sel_ima); + simasel->first_sel_ima = 0; + simasel->fase |= IMS_DOTHE_INF; + addafterqueue(curarea->win, AFTERIMASELIMA, 1); + } + } + }else{ + if (!bitset(simasel->fase, IMS_KNOW_BIP)){ + addafterqueue(curarea->win, AFTERPIBREAD, 1); + } + } + + make_sima_area(simasel); + calc_hilite(simasel); + draw_sima_area(simasel); + + curarea->win_swap= WIN_BACK_OK; +} + diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c new file mode 100644 index 00000000000..95f391c2dab --- /dev/null +++ b/source/blender/src/drawipo.c @@ -0,0 +1,1622 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdio.h> +#include <math.h> + +#ifndef _WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" + +#include "DNA_curve_types.h" +#include "DNA_ipo_types.h" +#include "DNA_key_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_sequence_types.h" + +#include "BKE_utildefines.h" +#include "BKE_curve.h" +#include "BKE_ipo.h" +#include "BKE_global.h" + +#include "BIF_gl.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_interface.h" +#include "BIF_mywindow.h" +#include "BIF_space.h" + +#include "BSE_drawipo.h" +#include "BSE_view.h" +#include "BSE_editipo.h" +#include "BSE_editaction_types.h" +#include "BSE_editnla_types.h" + +#include "mydevice.h" +#include "interface.h" +#include "ipo.h" /* retains old stuff */ +#include "blendef.h" + +/* local define... also used in editipo ... */ +#define ISPOIN(a, b, c) ( (a->b) && (a->c) ) +#define ISPOIN3(a, b, c, d) ( (a->b) && (a->c) && (a->d) ) +#define ISPOIN4(a, b, c, d, e) ( (a->b) && (a->c) && (a->d) && (a->e) ) + +#define IPOBUTX 65 +#define IPOSTEP 35 /* minimum pixels per gridstep */ + +static float ipogrid_dx, ipogrid_dy, ipogrid_startx, ipogrid_starty; +static int ipomachtx, ipomachty; + +static int vertymin, vertymax, horxmin, horxmax; /* globals om LEFTMOUSE op scrollbar te testen */ + + + +static void scroll_prstr(float x, float y, float val, char dir, int disptype) +{ + int len, macht; + char str[32]; + + if(dir=='v') { + macht= ipomachty; + if ELEM(disptype, IPO_DISPDEGR, IPO_DISPTIME) { + macht+=1; + val *= 10; + } + } + else macht= ipomachtx; + + if (macht<=0) sprintf(str, "%.*f", 1-macht, val); + else sprintf(str, "%d", (int)val); + + len= strlen(str); + if(dir=='h') x-= 4*len; + else y-= 4*len; + + if(dir=='v' && disptype==IPO_DISPDEGR) { + str[len]= 186; /* Degree symbol */ + str[len+1]= 0; + } + + glRasterPos2f(x, y); + BMF_DrawString(G.fonts, str); +} + +static void step_to_grid(float *step, int *macht) +{ + float loga, rem; + + /* proberen step als 10e macht te schrijven */ + + loga= log10(*step); + *macht= (int)(loga); + + rem= loga- *macht; + rem= pow(10.0, rem); + + if(loga<0.0) { + if(rem < 0.2) rem= 0.2; + else if(rem < 0.5) rem= 0.5; + else rem= 1.0; + + *step= rem*pow(10.0, (float)*macht); + } + else { + if(rem < 2.0) rem= 2.0; + else if(rem < 5.0) rem= 5.0; + else rem= 10.0; + + *step= rem*pow(10.0, (float)*macht); + + (*macht)++; + } + +} + +void calc_ipogrid() +{ + float space, pixels; + + /* regel: gridstep is minimaal IPOSTEP pixels */ + /* hoe groot zijn IPOSTEP pixels? */ + + if(G.v2d==0) return; + + space= G.v2d->cur.xmax - G.v2d->cur.xmin; + pixels= G.v2d->mask.xmax-G.v2d->mask.xmin; + + ipogrid_dx= IPOSTEP*space/pixels; + step_to_grid(&ipogrid_dx, &ipomachtx); + + if ELEM(curarea->spacetype, SPACE_SEQ, SPACE_SOUND) { + if(ipogrid_dx < 0.1) ipogrid_dx= 0.1; + ipomachtx-= 2; + if(ipomachtx<-2) ipomachtx= -2; + } + + space= (G.v2d->cur.ymax - G.v2d->cur.ymin); + pixels= curarea->winy; + ipogrid_dy= IPOSTEP*space/pixels; + step_to_grid(&ipogrid_dy, &ipomachty); + + if ELEM(curarea->spacetype, SPACE_SEQ, SPACE_SOUND) { + if(ipogrid_dy < 1.0) ipogrid_dy= 1.0; + if(ipomachty<1) ipomachty= 1; + } + + ipogrid_startx= G.v2d->cur.xmin-fmod(G.v2d->cur.xmin, ipogrid_dx); + if(G.v2d->cur.xmin<0.0) ipogrid_startx-= ipogrid_dx; + ipogrid_starty= (G.v2d->cur.ymin-fmod(G.v2d->cur.ymin, ipogrid_dy)); + if(G.v2d->cur.ymin<0.0) ipogrid_starty-= ipogrid_dy; + +} + +void draw_ipogrid(void) +{ + float vec1[2], vec2[2]; + int a, step; + + vec1[0]= vec2[0]= ipogrid_startx; + vec1[1]= ipogrid_starty; + vec2[1]= G.v2d->cur.ymax; + + step= (G.v2d->mask.xmax-G.v2d->mask.xmin+1)/IPOSTEP; + + if(curarea->spacetype==SPACE_SOUND) glColor3ub(0x70, 0x70, 0x60); + else glColor3ub(0x40, 0x40, 0x40); + + for(a=0; a<step; a++) { + glBegin(GL_LINE_STRIP); + glVertex2fv(vec1); glVertex2fv(vec2); + glEnd(); + vec2[0]= vec1[0]+= ipogrid_dx; + } + + vec2[0]= vec1[0]-= 0.5*ipogrid_dx; + + if(curarea->spacetype==SPACE_SOUND) glColor3ub(0x80, 0x80, 0x70); + else glColor3ub(0x50, 0x50, 0x50); + + step++; + for(a=0; a<=step; a++) { + glBegin(GL_LINE_STRIP); + glVertex2fv(vec1); glVertex2fv(vec2); + glEnd(); + vec2[0]= vec1[0]-= ipogrid_dx; + } + + if(curarea->spacetype!=SPACE_SOUND && curarea->spacetype!=SPACE_ACTION && curarea->spacetype!=SPACE_NLA) { + vec1[0]= ipogrid_startx; + vec1[1]= vec2[1]= ipogrid_starty; + vec2[0]= G.v2d->cur.xmax; + + step= (curarea->winy+1)/IPOSTEP; + + glColor3ub(0x40, 0x40, 0x40); + for(a=0; a<=step; a++) { + glBegin(GL_LINE_STRIP); + glVertex2fv(vec1); glVertex2fv(vec2); + glEnd(); + vec2[1]= vec1[1]+= ipogrid_dy; + } + vec2[1]= vec1[1]-= 0.5*ipogrid_dy; + step++; + + if(curarea->spacetype==SPACE_IPO) { + glColor3ub(0x50, 0x50, 0x50); + for(a=0; a<step; a++) { + glBegin(GL_LINE_STRIP); + glVertex2fv(vec1); glVertex2fv(vec2); + glEnd(); + vec2[1]= vec1[1]-= ipogrid_dy; + } + } + } + + glColor3ub(0, 0, 0); + + if (curarea->spacetype!=SPACE_ACTION && curarea->spacetype!=SPACE_NLA) + { /* Horizontal axis */ + vec1[0]= G.v2d->cur.xmin; + vec2[0]= G.v2d->cur.xmax; + vec1[1]= vec2[1]= 0.0; + glBegin(GL_LINE_STRIP); + + glVertex2fv(vec1); + glVertex2fv(vec2); + + glEnd(); + } + + /* Vertical axis */ + + vec1[1]= G.v2d->cur.ymin; + vec2[1]= G.v2d->cur.ymax; + vec1[0]= vec2[0]= 0.0; + glBegin(GL_LINE_STRIP); + glVertex2fv(vec1); glVertex2fv(vec2); + glEnd(); + + /* Limits box */ + if(curarea->spacetype==SPACE_IPO) { + if(G.sipo->blocktype==ID_SEQ) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glRectf(0.0, 0.0, 100.0, 1.0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + else if(ELEM(G.sipo->blocktype, ID_CU, IPO_CO)) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glRectf(0.0, 1.0, G.v2d->cur.xmax, 1.0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + } +} + +void areamouseco_to_ipoco(View2D *v2d, short *mval, float *x, float *y) +{ + float div, ofs; + + div= v2d->mask.xmax-v2d->mask.xmin; + ofs= v2d->mask.xmin; + + *x= v2d->cur.xmin+ (v2d->cur.xmax-v2d->cur.xmin)*(mval[0]-ofs)/div; + + div= v2d->mask.ymax-v2d->mask.ymin; + ofs= v2d->mask.ymin; + + *y= v2d->cur.ymin+ (v2d->cur.ymax-v2d->cur.ymin)*(mval[1]-ofs)/div; +} + +void ipoco_to_areaco(View2D *v2d, float *vec, short *mval) +{ + float x, y; + + mval[0]= 3200; + + x= (vec[0] - v2d->cur.xmin)/(v2d->cur.xmax-v2d->cur.xmin); + y= (vec[1] - v2d->cur.ymin)/(v2d->cur.ymax-v2d->cur.ymin); + + if(x>=0.0 && x<=1.0) { + if(y>=0.0 && y<=1.0) { + mval[0]= v2d->mask.xmin + x*(v2d->mask.xmax-v2d->mask.xmin); + mval[1]= v2d->mask.ymin + y*(v2d->mask.ymax-v2d->mask.ymin); + } + } +} + +void ipoco_to_areaco_noclip(View2D *v2d, float *vec, short *mval) +{ + float x, y; + + x= (vec[0] - v2d->cur.xmin)/(v2d->cur.xmax-v2d->cur.xmin); + y= (vec[1] - v2d->cur.ymin)/(v2d->cur.ymax-v2d->cur.ymin); + + x= v2d->mask.xmin + x*(v2d->mask.xmax-v2d->mask.xmin); + y= v2d->mask.ymin + y*(v2d->mask.ymax-v2d->mask.ymin); + + if(x<-32760) mval[0]= -32760; + else if(x>32760) mval[0]= 32760; + else mval[0]= x; + + if(y<-32760) mval[1]= -32760; + else if(y>32760) mval[1]= 32760; + else mval[1]= y; +} + +int in_ipo_buttons(void) +{ + short mval[2]; + + getmouseco_areawin(mval); + + if(mval[0]< G.v2d->mask.xmax) return 0; + else return 1; +} + + +void test_view2d(View2D *v2d, int winx, int winy) +{ + /* cur mag niet groter dan max, kleiner dan min of buiten tot vallen */ + rctf *cur, *tot; + float dx, dy, temp, fac, zoom; + + cur= &v2d->cur; + tot= &v2d->tot; + + dx= cur->xmax-cur->xmin; + dy= cur->ymax-cur->ymin; + + + /* Reevan's test */ + if (v2d->keepzoom & V2D_LOCKZOOM_Y) + v2d->cur.ymax=v2d->cur.ymin+((float)winy); + + if (v2d->keepzoom & V2D_LOCKZOOM_X) + v2d->cur.xmax=v2d->cur.xmin+((float)winx); + + if(v2d->keepzoom & V2D_KEEPZOOM) { + /* niet op min/max testen: ahv curarea de zoom fixeren */ + zoom= ((float)winx)/dx; + + if(zoom<v2d->minzoom || zoom>v2d->maxzoom) { + if(zoom<v2d->minzoom) fac= zoom/v2d->minzoom; + else fac= zoom/v2d->maxzoom; + + dx*= fac; + temp= 0.5*(cur->xmax+cur->xmin); + + cur->xmin= temp-0.5*dx; + cur->xmax= temp+0.5*dx; + } + + zoom= ((float)winy)/dy; + + if(zoom<v2d->minzoom || zoom>v2d->maxzoom) { + if(zoom<v2d->minzoom) fac= zoom/v2d->minzoom; + else fac= zoom/v2d->maxzoom; + + dy*= fac; + temp= 0.5*(cur->ymax+cur->ymin); + cur->ymin= temp-0.5*dy; + cur->ymax= temp+0.5*dy; + } + + + } + + else{ + + /* end test */ + + if(dx<v2d->min[0]) { + dx= v2d->min[0]; + temp= 0.5*(cur->xmax+cur->xmin); + cur->xmin= temp-0.5*dx; + cur->xmax= temp+0.5*dx; + } + else if(dx>v2d->max[0]) { + dx= v2d->max[0]; + temp= 0.5*(cur->xmax+cur->xmin); + cur->xmin= temp-0.5*dx; + cur->xmax= temp+0.5*dx; + } + + if(dy<v2d->min[1]) { + dy= v2d->min[1]; + temp= 0.5*(cur->ymax+cur->ymin); + cur->ymin= temp-0.5*dy; + cur->ymax= temp+0.5*dy; + } + else if(dy>v2d->max[1]) { + dy= v2d->max[1]; + temp= 0.5*(cur->ymax+cur->ymin); + cur->ymin= temp-0.5*dy; + cur->ymax= temp+0.5*dy; + } + + } + + + + + if(v2d->keeptot) { + dx= cur->xmax-cur->xmin; + dy= cur->ymax-cur->ymin; + + if(dx > tot->xmax-tot->xmin) { + if(v2d->keepzoom==0) { + if(cur->xmin<tot->xmin) cur->xmin= tot->xmin; + if(cur->xmax>tot->xmax) cur->xmax= tot->xmax; + } + else { + if(cur->xmax < tot->xmax) { + dx= tot->xmax-cur->xmax; + cur->xmin+= dx; + cur->xmax+= dx; + } + else if(cur->xmin > tot->xmin) { + dx= cur->xmin-tot->xmin; + cur->xmin-= dx; + cur->xmax-= dx; + } + } + } + else { + if(cur->xmin < tot->xmin) { + dx= tot->xmin-cur->xmin; + cur->xmin+= dx; + cur->xmax+= dx; + } + else if(cur->xmax > tot->xmax) { + dx= cur->xmax-tot->xmax; + cur->xmin-= dx; + cur->xmax-= dx; + } + } + + if(dy > tot->ymax-tot->ymin) { + if(v2d->keepzoom==0) { + if(cur->ymin<tot->ymin) cur->ymin= tot->ymin; + if(cur->ymax>tot->ymax) cur->ymax= tot->ymax; + } + else { + if(cur->ymax < tot->ymax) { + dy= tot->ymax-cur->ymax; + cur->ymin+= dy; + cur->ymax+= dy; + } + else if(cur->ymin > tot->ymin) { + dy= cur->ymin-tot->ymin; + cur->ymin-= dy; + cur->ymax-= dy; + } + } + } + else { + if(cur->ymin < tot->ymin) { + dy= tot->ymin-cur->ymin; + cur->ymin+= dy; + cur->ymax+= dy; + } + else if(cur->ymax > tot->ymax) { + dy= cur->ymax-tot->ymax; + cur->ymin-= dy; + cur->ymax-= dy; + } + } + } + + if(v2d->keepaspect) { + dx= (cur->ymax-cur->ymin)/(cur->xmax-cur->xmin); + dy= ((float)winy)/((float)winx); + + /* dx/dy is de totale aspect */ + + /* this exception is for buttons...keepzoom doesnt work proper */ + if(v2d->keepzoom) fac= dy; + else fac= dx/dy; + + if(fac>1.0) { + + /* portrait window: x corrigeren */ + dx= cur->ymax-cur->ymin; + temp= (cur->xmax+cur->xmin); + + cur->xmin= temp/2.0 - 0.5*dx/dy; + cur->xmax= temp/2.0 + 0.5*dx/dy; + } + else { + dx= cur->xmax-cur->xmin; + temp= (cur->ymax+cur->ymin); + + cur->ymin= temp/2.0 - 0.5*dy*dx; + cur->ymax= temp/2.0 + 0.5*dy*dx; + } + } +} + +void calc_scrollrcts(View2D *v2d, int winx, int winy) +{ + v2d->mask.xmin= v2d->mask.ymin= 0; + v2d->mask.xmax= winx; + v2d->mask.ymax= winy; + + if(curarea->spacetype==SPACE_ACTION) { + v2d->mask.xmin+= ACTWIDTH; + v2d->hor.xmin+=ACTWIDTH; + } + else if(curarea->spacetype==SPACE_NLA){ + v2d->mask.xmin+= NLAWIDTH; + v2d->hor.xmin+=NLAWIDTH; + } + else if(curarea->spacetype==SPACE_IPO) { + v2d->mask.xmax-= IPOBUTX; + + if(v2d->mask.xmax<IPOBUTX) + v2d->mask.xmax= winx; + } + + if(v2d->scroll) { + if(v2d->scroll & L_SCROLL) { + v2d->vert= v2d->mask; + v2d->vert.xmax= SCROLLB; + v2d->mask.xmin= SCROLLB+1; + } + else if(v2d->scroll & R_SCROLL) { + v2d->vert= v2d->mask; + v2d->vert.xmin= v2d->vert.xmax-SCROLLB; + v2d->mask.xmax= v2d->vert.xmin-1; + } + + if(v2d->scroll & B_SCROLL) { + v2d->hor= v2d->mask; + v2d->hor.ymax= SCROLLH; + v2d->mask.ymin= SCROLLH+1; + } + else if(v2d->scroll & T_SCROLL) { + v2d->hor= v2d->mask; + v2d->hor.ymin= v2d->hor.ymax-SCROLLH; + v2d->mask.ymax= v2d->hor.ymin-1; + } + } +} + + /* draws a line in left vertical scrollbar at the given height */ +static void draw_solution_line(View2D *v2d, float h) +{ + float vec[2]; + short mval[2]; + + vec[0]= v2d->cur.xmin; + vec[1]= h; + ipoco_to_areaco(v2d, vec, mval); + if(mval[0]!=3200) { + glBegin(GL_LINES); + glVertex2f(v2d->vert.xmin, mval[1]); + glVertex2f(v2d->vert.xmax, mval[1]); + glEnd(); + } +} + +static void draw_solution(SpaceIpo *sipo) +{ + View2D *v2d= &sipo->v2d; + EditIpo *ei; + int a; + + if (!(v2d->scroll & VERT_SCROLL)) return; + + ei= sipo->editipo; + for(a=0; a<sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + cpack(ei->col); + + /* DISPBITS ipo's have 'multiple' values. */ + if(ei->disptype==IPO_DISPBITS) { + int b, val= ei->icu->curval; + + for (b=0; b<31; b++) + if (val & (1<<b)) + draw_solution_line(v2d, b+1); + } else { + draw_solution_line(v2d, ei->icu->curval); + } + } + } +} + +void drawscroll(int disptype) +{ + rcti vert, hor; + float fac, dfac, val, fac2, tim; + unsigned int dark, darker, light; + + vert= (G.v2d->vert); + hor= (G.v2d->hor); + + darker= 0x525252; + dark= 0x656565; + light= 0x989898; + + cpack(dark); + if(G.v2d->scroll & HOR_SCROLL) { + glRecti(hor.xmin, hor.ymin, hor.xmax, hor.ymax); + glColor3ub(0, 0, 0); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glRecti(hor.xmin, hor.ymin, hor.xmax, hor.ymax); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + /* slider */ + fac= (G.v2d->cur.xmin- G.v2d->tot.xmin)/(G.v2d->tot.xmax-G.v2d->tot.xmin); + if(fac<0.0) fac= 0.0; + horxmin= hor.xmin+fac*(hor.xmax-hor.xmin) + 1; + + fac= (G.v2d->cur.xmax- G.v2d->tot.xmin)/(G.v2d->tot.xmax-G.v2d->tot.xmin); + if(fac>1.0) fac= 1.0; + horxmax= hor.xmin+fac*(hor.xmax-hor.xmin) -1; + + if(horxmin > horxmax-2) horxmin= horxmax-2; + + glColor3ub(0x78, 0x78, 0x78); + glRecti(horxmin, hor.ymin+1, horxmax, hor.ymax-1); + + cpack(light); + sdrawline(horxmin, hor.ymax-1, horxmax, hor.ymax-1); /* boven */ + sdrawline(horxmin, hor.ymin+1, horxmin, hor.ymax-1); /* links */ + cpack(darker); + sdrawline(horxmin, hor.ymin+1, horxmax, hor.ymin+1); /* onder */ + sdrawline(horxmax, hor.ymin+1, horxmax, hor.ymax-1); /* rechts */ + + /* de cijfers: ipogrid_startx en -dx omzetten naar scroll coordinaten */ + fac= (ipogrid_startx- G.v2d->cur.xmin)/(G.v2d->cur.xmax-G.v2d->cur.xmin); + fac= hor.xmin+fac*(hor.xmax-hor.xmin); + + dfac= (ipogrid_dx)/(G.v2d->cur.xmax-G.v2d->cur.xmin); + dfac= dfac*(hor.xmax-hor.xmin); + + glColor3ub(0, 0, 0); + val= ipogrid_startx; + while(fac < hor.xmax) { + + if(curarea->spacetype==SPACE_SEQ) { + fac2= val/(float)G.scene->r.frs_sec; + tim= floor(fac2); + fac2= fac2-tim; + scroll_prstr(fac, 3.0+(float)(hor.ymin), tim+G.scene->r.frs_sec*fac2/100.0, 'h', disptype); + } + else if(curarea->spacetype==SPACE_SOUND) { + fac2= val/(float)G.scene->r.frs_sec; + scroll_prstr(fac, 3.0+(float)(hor.ymin), fac2, 'h', disptype); + } + else { + scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype); + } + + fac+= dfac; + val+= ipogrid_dx; + } + } + cpack(dark); + if(G.v2d->scroll & VERT_SCROLL) { + glRecti(vert.xmin, vert.ymin, vert.xmax, vert.ymax); + glColor3ub(0, 0, 0); + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glRecti(vert.xmin, vert.ymin, vert.xmax, vert.ymax); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + /* slider */ + fac= (G.v2d->cur.ymin- G.v2d->tot.ymin)/(G.v2d->tot.ymax-G.v2d->tot.ymin); + if(fac<0.0) fac= 0.0; + vertymin= vert.ymin+fac*(vert.ymax-vert.ymin) + 1; + + fac= (G.v2d->cur.ymax- G.v2d->tot.ymin)/(G.v2d->tot.ymax-G.v2d->tot.ymin); + if(fac>1.0) fac= 1.0; + vertymax= vert.ymin+fac*(vert.ymax-vert.ymin) -1; + + if(vertymin > vertymax-2) vertymin= vertymax-2; + + glColor3ub(0x78, 0x78, 0x78); + glRecti(vert.xmin+1, vertymin, vert.xmax-1, vertymax); + + cpack(light); + + sdrawline(vert.xmin+1, vertymax, vert.xmax-1, vertymax); /* boven */ + sdrawline(vert.xmin+1, vertymin, vert.xmin+1, vertymax); /* links */ + cpack(darker); + sdrawline(vert.xmin+1, vertymin, vert.xmax-1, vertymin); /* onder */ + sdrawline(vert.xmax-1, vertymin, vert.xmax-1, vertymax); /* rechts */ + + /* de cijfers: ipogrid_starty en -dy omzetten naar scroll coordinaten */ + fac= (ipogrid_starty- G.v2d->cur.ymin)/(G.v2d->cur.ymax-G.v2d->cur.ymin); + fac= vert.ymin+SCROLLH+fac*(vert.ymax-vert.ymin-SCROLLH); + + dfac= (ipogrid_dy)/(G.v2d->cur.ymax-G.v2d->cur.ymin); + dfac= dfac*(vert.ymax-vert.ymin-SCROLLH); + + if(curarea->spacetype==SPACE_SEQ) { + glColor3ub(0, 0, 0); + val= ipogrid_starty; + fac+= 0.5*dfac; + while(fac < vert.ymax) { + scroll_prstr((float)(vert.xmax)-14.0, fac, val, 'v', disptype); + fac+= dfac; + val+= ipogrid_dy; + } + } + else if (curarea->spacetype==SPACE_NLA){ + } + else if (curarea->spacetype==SPACE_ACTION){ + /* No digits on vertical axis in action mode! */ + } + else { + glColor3ub(0, 0, 0); + val= ipogrid_starty; + while(fac < vert.ymax) { + scroll_prstr((float)(vert.xmax)-3.0, fac, val, 'v', disptype); + fac+= dfac; + val+= ipogrid_dy; + } + } + } +} + +static void draw_ipobuts(SpaceIpo *sipo) +{ + ScrArea *area= sipo->area; + View2D *v2d= &sipo->v2d; + uiBlock *block; + uiBut *but; + EditIpo *ei; + int a, y, sel, tot; + char naam[20]; + + if(area->winx<IPOBUTX) return; + + if(sipo->butofs) { + tot= 30+IPOBUTY*sipo->totipo; + if(tot<area->winy) sipo->butofs= 0; + } + + drawedge(v2d->mask.xmax+3, 0, v2d->mask.xmax+3, area->winy); + glColor3ub(0x7f, 0x70, 0x70); + + glRects(v2d->mask.xmax+6, 0, area->winx, area->winy); + + if(sipo->totipo==0) return; + if(sipo->editipo==0) return; + + sprintf(naam, "ipowin %d", area->win); + block= uiNewBlock(&area->uiblocks, naam, UI_EMBOSSN, UI_HELV, area->win); + uiBlockSetCol(block, BUTRUST); + + ei= sipo->editipo; + y= area->winy-30+sipo->butofs; + for(a=0; a<sipo->totipo; a++, ei++, y-=IPOBUTY) { + + but= uiDefButI(block, TOG|BIT|a, a+1, ei->name, v2d->mask.xmax+18, y, IPOBUTX-15, IPOBUTY-1, &(sipo->rowbut), 0, 0, 0, 0, ""); + /* XXXXX, is this, the sole caller + * of this function, really necessary? + */ + uiButSetFlag(but, UI_TEXT_LEFT); + + if(ei->icu) { + cpack(ei->col); + + glRects(v2d->mask.xmax+8, y+2, v2d->mask.xmax+15, y+IPOBUTY-2); + sel= ei->flag & (IPO_SELECT + IPO_EDIT); + + uiEmboss((float)(v2d->mask.xmax+8), (float)(y+2), (float)(v2d->mask.xmax+15), (float)(y+IPOBUTY-2), sel); + } + + if(sipo->blocktype==ID_KE) { + Key *key= (Key *)sipo->from; + if(key==0 || key->type==KEY_NORMAL) break; + } + } + uiDrawBlock(block); +} + +static void calc_ipoverts(SpaceIpo *sipo) +{ + View2D *v2d= &sipo->v2d; + EditIpo *ei; + BezTriple *bezt; + BPoint *bp; + int a, b; + + ei= G.sipo->editipo; + for(a=0; a<sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + ipoco_to_areaco(v2d, bezt->vec[0], bezt->s[0]); + ipoco_to_areaco(v2d, bezt->vec[1], bezt->s[1]); + ipoco_to_areaco(v2d, bezt->vec[2], bezt->s[2]); + bezt++; + } + } + else if(ei->icu->bp) { + bp= ei->icu->bp; + b= ei->icu->totvert; + while(b--) { + ipoco_to_areaco(v2d, bp->vec, bp->s); + bp++; + } + } + } + } +} + + +static void draw_ipovertices(int sel) +{ + EditIpo *ei; + BezTriple *bezt; + float v1[2]; + unsigned int col; + int val, ok, nr, a, b; + + if(G.f & G_PICKSEL) return; + + glPointSize(3.0); + glBegin(GL_POINTS); + + ei= G.sipo->editipo; + for(nr=0; nr<G.sipo->totipo; nr++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + + if(G.sipo->showkey) { + if(sel) col= 0xFFFFFF; else col= 0x0; + } else if(ei->flag & IPO_EDIT) { + if(sel) col= 0x77FFFF; else col= 0xFF70FF; + } else { + if(sel) col= 0xFFFFFF; else col= 0x0; + val= (ei->icu->flag & IPO_SELECT)!=0; + if(sel != val) continue; + } + + cpack(col); + + bezt= ei->icu->bezt; + a= ei->icu->totvert; + while(a--) { + + if(ei->disptype==IPO_DISPBITS) { + ok= 0; + if(ei->flag & IPO_EDIT) { + if( (bezt->f2 & 1) == sel ) ok= 1; + } + else ok= 1; + + if(ok) { + val= bezt->vec[1][1]; + b= 0; + v1[0]= bezt->vec[1][0]; + + while(b<31) { + if(val & (1<<b)) { + v1[1]= b+1; + glVertex3fv(v1); + } + b++; + } + } + } + else { + + if(ei->flag & IPO_EDIT) { + if(ei->icu->ipo==IPO_BEZ) { + if( (bezt->f1 & 1) == sel ) + glVertex3fv(bezt->vec[0]); + if( (bezt->f3 & 1) == sel ) + glVertex3fv(bezt->vec[2]); + } + if( (bezt->f2 & 1) == sel ) + glVertex3fv(bezt->vec[1]); + + } + else { + glVertex3fv(bezt->vec[1]); + } + } + + bezt++; + } + } + } + + glEnd(); + glPointSize(1.0); +} + +static void draw_ipohandles(int sel) +{ + extern unsigned int nurbcol[]; + EditIpo *ei; + BezTriple *bezt; + float *fp; + unsigned int *col; + int a, b; + + if(sel) col= nurbcol+4; + else col= nurbcol; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, disptype!=IPO_DISPBITS) { + if(ei->icu->ipo==IPO_BEZ) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + + if( (bezt->f2 & 1)==sel) { + fp= bezt->vec[0]; + cpack(col[bezt->h1]); + + glBegin(GL_LINE_STRIP); + glVertex2fv(fp); glVertex2fv(fp+3); + glEnd(); + cpack(col[bezt->h2]); + + glBegin(GL_LINE_STRIP); + glVertex2fv(fp+3); glVertex2fv(fp+6); + glEnd(); + } + else if( (bezt->f1 & 1)==sel) { + fp= bezt->vec[0]; + cpack(col[bezt->h1]); + + glBegin(GL_LINE_STRIP); + glVertex2fv(fp); glVertex2fv(fp+3); + glEnd(); + } + else if( (bezt->f3 & 1)==sel) { + fp= bezt->vec[1]; + cpack(col[bezt->h2]); + + glBegin(GL_LINE_STRIP); + glVertex2fv(fp); glVertex2fv(fp+3); + glEnd(); + } + + bezt++; + } + } + } + } +} + +int pickselcode; + +static void init_pickselcode(void) +{ + pickselcode= 1; +} + +static void draw_ipocurves(int sel) +{ + EditIpo *ei; + IpoCurve *icu; + BezTriple *bezt, *prevbezt; + float *fp, fac, data[120], v1[2], v2[2], v3[2], v4[2]; + float cycdx=0, cycdy=0, cycxofs, cycyofs; + int a, b, resol, cycount, val, nr; + + + ei= G.sipo->editipo; + for(nr=0; nr<G.sipo->totipo; nr++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) { + + if(G.f & G_PICKSEL) { + glLoadName(pickselcode++); + val= 1; + } + else { + val= (ei->flag & (IPO_SELECT+IPO_EDIT))!=0; + val= (val==sel); + } + + if(val) { + + cycyofs= cycxofs= 0.0; + cycount= 1; + + icu= ei->icu; + + /* curve */ + if(G.sipo->showkey) glColor3ub(0, 0, 0); else cpack(ei->col); + + /* cyclic */ + if(icu->extrap & IPO_CYCL) { + cycdx= (icu->bezt+icu->totvert-1)->vec[1][0] - icu->bezt->vec[1][0]; + cycdy= (icu->bezt+icu->totvert-1)->vec[1][1] - icu->bezt->vec[1][1]; + if(cycdx>0.01) { + + while(icu->bezt->vec[1][0]+cycxofs > G.v2d->cur.xmin) { + cycxofs-= cycdx; + if(icu->extrap & IPO_DIR) cycyofs-= cycdy; + cycount++; + } + bezt= icu->bezt+(icu->totvert-1); + fac= 0.0; + while(bezt->vec[1][0]+fac < G.v2d->cur.xmax) { + cycount++; + fac+= cycdx; + } + } + } + + while(cycount--) { + + if(ei->disptype==IPO_DISPBITS) { + + /* lijnen */ + cpack(ei->col); + bezt= icu->bezt; + a= icu->totvert; + + while(a--) { + val= bezt->vec[1][1]; + b= 0; + + while(b<31) { + if(val & (1<<b)) { + v1[1]= b+1; + + glBegin(GL_LINE_STRIP); + if(icu->extrap & IPO_CYCL) ; + else if(a==icu->totvert-1) { + v1[0]= G.v2d->cur.xmin+cycxofs; + glVertex2fv(v1); + } + v1[0]= bezt->vec[1][0]+cycxofs; + glVertex2fv(v1); + + if(a) v1[0]= (bezt+1)->vec[1][0]+cycxofs; + else if(icu->extrap & IPO_CYCL) ; + else v1[0]= G.v2d->cur.xmax+cycxofs; + + glVertex2fv(v1); + glEnd(); + } + b++; + } + bezt++; + } + + } + else { + + b= icu->totvert-1; + prevbezt= icu->bezt; + bezt= prevbezt+1; + + glBegin(GL_LINE_STRIP); + + /* extrap naar links? */ + if( (icu->extrap & IPO_CYCL)==0) { + if(prevbezt->vec[1][0] > G.v2d->cur.xmin) { + v1[0]= G.v2d->cur.xmin; + if(icu->extrap==IPO_HORIZ || icu->ipo==IPO_CONST) v1[1]= prevbezt->vec[1][1]; + else { + fac= (prevbezt->vec[0][0]-prevbezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]); + if(fac!=0.0) fac= 1.0/fac; + v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[0][1]-prevbezt->vec[1][1]); + } + glVertex2fv(v1); + } + } + + if(b==0) { + v1[0]= prevbezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + glVertex2fv(v1); + } + + while(b--) { + if(icu->ipo==IPO_CONST) { + v1[0]= prevbezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + glVertex2fv(v1); + v1[0]= bezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + glVertex2fv(v1); + } + else if(icu->ipo==IPO_LIN) { + v1[0]= prevbezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + glVertex2fv(v1); + } + else { + resol= 3.0*sqrt(bezt->vec[1][0] - prevbezt->vec[1][0]); + + if(resol<2) { + v1[0]= prevbezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + glVertex2fv(v1); + } + else { + if(resol>32) resol= 32; + + v1[0]= prevbezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + v2[0]= prevbezt->vec[2][0]+cycxofs; + v2[1]= prevbezt->vec[2][1]+cycyofs; + + v3[0]= bezt->vec[0][0]+cycxofs; + v3[1]= bezt->vec[0][1]+cycyofs; + v4[0]= bezt->vec[1][0]+cycxofs; + v4[1]= bezt->vec[1][1]+cycyofs; + + correct_bezpart(v1, v2, v3, v4); + + maakbez(v1[0], v2[0], v3[0], v4[0], data, resol); + maakbez(v1[1], v2[1], v3[1], v4[1], data+1, resol); + + fp= data; + while(resol--) { + glVertex2fv(fp); + fp+= 3; + } + } + } + prevbezt= bezt; + bezt++; + + /* laatste punt? */ + if(b==0) { + v1[0]= prevbezt->vec[1][0]+cycxofs; + v1[1]= prevbezt->vec[1][1]+cycyofs; + glVertex2fv(v1); + } + } + + /* extrap naar rechts? */ + if( (icu->extrap & IPO_CYCL)==0) { + if(prevbezt->vec[1][0] < G.v2d->cur.xmax) { + v1[0]= G.v2d->cur.xmax; + if(icu->extrap==IPO_HORIZ || icu->ipo==IPO_CONST) v1[1]= prevbezt->vec[1][1]; + else { + fac= (prevbezt->vec[2][0]-prevbezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]); + if(fac!=0.0) fac= 1.0/fac; + v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[2][1]-prevbezt->vec[1][1]); + } + glVertex2fv(v1); + } + } + + glEnd(); + + } + cycxofs+= cycdx; + if(icu->extrap & IPO_DIR) cycyofs+= cycdy; + } + + /* lijn die het einde van een snelheidscurve aangeeft */ + if(G.sipo->blocktype==ID_CU && icu->adrcode==CU_SPEED) { + b= icu->totvert-1; + if(b) { + glColor3ub(0, 0, 0); + bezt= icu->bezt+b; + glBegin(GL_LINES); + glVertex2f(bezt->vec[1][0], 0.0); + glVertex2f(bezt->vec[1][0], bezt->vec[1][1]); + glEnd(); + } + } + } + } + } +} + +static void draw_cfra(SpaceIpo *sipo) +{ + View2D *v2d= &sipo->v2d; + Object *ob; + float vec[2]; + + vec[0]= (G.scene->r.cfra); + vec[0]*= G.scene->r.framelen; + + vec[1]= v2d->cur.ymin; + glColor3ub(0x60, 0xc0, 0x40); + glLineWidth(2.0); + + glBegin(GL_LINE_STRIP); + glVertex2fv(vec); + vec[1]= v2d->cur.ymax; + glVertex2fv(vec); + glEnd(); + + if(sipo->blocktype==ID_OB) { + ob= (G.scene->basact) ? (G.scene->basact->object) : 0; + if(ob && ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) { + vec[0]-= ob->sf; + + glColor3ub(0x10, 0x60, 0); + + glBegin(GL_LINE_STRIP); + glVertex2fv(vec); + vec[1]= G.v2d->cur.ymin; + glVertex2fv(vec); + glEnd(); + } + } + + glLineWidth(1.0); +} + +static void draw_ipokey(SpaceIpo *sipo) +{ + IpoKey *ik; + + glBegin(GL_LINES); + for (ik= sipo->ipokey.first; ik; ik= ik->next) { + if(ik->flag & 1) glColor3ub(0xFF, 0xFF, 0x99); + else glColor3ub(0xAA, 0xAA, 0x55); + + glVertex2f(ik->val, G.v2d->cur.ymin); + glVertex2f(ik->val, G.v2d->cur.ymax); + } + glEnd(); +} + +static void draw_key(SpaceIpo *sipo, int visible) +{ + View2D *v2d= &sipo->v2d; + Key *key; + KeyBlock *kb, *act=NULL; + unsigned int col; + + key= (Key *)sipo->from; + if(key==0) + return; + + if(key->type== KEY_RELATIVE) if(visible==0) return; + + kb= key->block.first; + while(kb) { + if(kb->type==KEY_LINEAR) setlinestyle(2); + else if(kb->type==KEY_BSPLINE) setlinestyle(4); + else setlinestyle(0); + + if(kb==key->refkey) col= 0x22FFFF; + else col= 0xFFFF00; + + if( (kb->flag & SELECT)==0) col-= 0x225500; + else act= kb; + + cpack(col); + + glBegin(GL_LINE_STRIP); + glVertex2f(v2d->cur.xmin, kb->pos); + glVertex2f(v2d->cur.xmax, kb->pos); + glEnd(); + + kb= kb->next; + } + + if(act) { + if(act->type==KEY_LINEAR) setlinestyle(2); + else if(act->type==KEY_BSPLINE) setlinestyle(4); + else setlinestyle(0); + + if(act==key->refkey) cpack(0x22FFFF); + else cpack(0xFFFF00); + + glBegin(GL_LINE_STRIP); + glVertex2f(v2d->cur.xmin, act->pos); + glVertex2f(v2d->cur.xmax, act->pos); + glEnd(); + } + + setlinestyle(0); +} + +void drawipo(void) +{ + SpaceIpo *sipo= curarea->spacedata.first; + View2D *v2d= &sipo->v2d; + EditIpo *ei; + int ofsx, ofsy, a, disptype; + + v2d->hor.xmax+=IPOBUTX; + calc_scrollrcts(G.v2d, curarea->winx, curarea->winy); + + + if (sipo->pin) + glClearColor(.45, .40, .40, 0.0); // litepink + else + glClearColor(.45, .45, .45, 0.0); + + glClear(GL_COLOR_BUFFER_BIT); + + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + if(v2d->scroll) { + ofsx= curarea->winrct.xmin; // ivm mywin + ofsy= curarea->winrct.ymin; + glViewport(ofsx+v2d->mask.xmin, ofsy+v2d->mask.ymin, ( ofsx+v2d->mask.xmax-1)-(ofsx+v2d->mask.xmin)+1, ( ofsy+v2d->mask.ymax-1)-( ofsy+v2d->mask.ymin)+1); + glScissor(ofsx+v2d->mask.xmin, ofsy+v2d->mask.ymin, ( ofsx+v2d->mask.xmax-1)-(ofsx+v2d->mask.xmin)+1, ( ofsy+v2d->mask.ymax-1)-( ofsy+v2d->mask.ymin)+1); + } + } + + test_editipo(); /* test of huidige editipo klopt, make_editipo zet de v2d->cur */ + + myortho2(v2d->cur.xmin, v2d->cur.xmax, v2d->cur.ymin, v2d->cur.ymax); + + + if(sipo->editipo) { + + /* schaal corrigeren voor graden? */ + disptype= -1; + ei= sipo->editipo; + for(a=0; a<sipo->totipo; a++, ei++) { + if(ei->flag & IPO_VISIBLE) { + if(disptype== -1) disptype= ei->disptype; + else if(disptype!=ei->disptype) disptype= 0; + } + } + + calc_ipogrid(); + draw_ipogrid(); + + calc_ipoverts(sipo); + + draw_cfra(sipo); + + /* ipokeys */ + if(sipo->showkey) { + if(sipo->ipokey.first==0) make_ipokey(); + draw_ipokey(sipo); + } + + if(sipo->blocktype==ID_KE) { + ei= sipo->editipo; + draw_key(sipo, ei->flag & IPO_VISIBLE); + } + + /* draw deselect */ + draw_ipocurves(0); + draw_ipohandles(0); + draw_ipovertices(0); + + /* draw select */ + draw_ipocurves(1); + draw_ipohandles(1); + draw_ipovertices(1); + + /* restore viewport */ + mywinset(curarea->win); + + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + + /* ortho op pixelnivo curarea */ + myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5); + + if(v2d->scroll) { + drawscroll(disptype); + draw_solution(sipo); + } + + draw_ipobuts(sipo); + } + } + else { + calc_ipogrid(); + draw_ipogrid(); + } + + curarea->win_swap= WIN_BACK_OK; +} + +void scroll_ipobuts() +{ + int tot; + short yo, mval[2]; + + tot= 30+IPOBUTY*G.sipo->totipo; + if(tot<curarea->winy) return; + + getmouseco_areawin(mval); + yo= mval[1]; + + while(get_mbut()&M_MOUSE) { + getmouseco_areawin(mval); + if(mval[1]!=yo) { + G.sipo->butofs+= (mval[1]-yo); + if(G.sipo->butofs<0) G.sipo->butofs= 0; + else if(G.sipo->butofs+curarea->winy>tot) G.sipo->butofs= tot-curarea->winy; + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + + yo= mval[1]; + } + else BIF_wait_for_statechange(); + } +} + + + +void view2dzoom() +{ + float fac, dx, dy; + short mval[2], mvalo[2]; + + areawinset(curarea->win); /* vanuit buttons */ + curarea->head_swap= 0; + getmouseco_areawin(mvalo); + + while(get_mbut()&(L_MOUSE|M_MOUSE)) { + getmouseco_areawin(mval); + + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + + fac= 0.001*(mval[0]-mvalo[0]); + dx= fac*(G.v2d->cur.xmax-G.v2d->cur.xmin); + fac= 0.001*(mval[1]-mvalo[1]); + dy= fac*(G.v2d->cur.ymax-G.v2d->cur.ymin); + + G.v2d->cur.xmin+= dx; + G.v2d->cur.xmax-= dx; + if(curarea->spacetype!=SPACE_SEQ && curarea->spacetype!=SPACE_SOUND && curarea->spacetype!=SPACE_NLA && curarea->spacetype!=SPACE_ACTION) { + G.v2d->cur.ymin+= dy; + G.v2d->cur.ymax-= dy; + } + + test_view2d(G.v2d, curarea->winx, curarea->winy); /* cur min max rects */ + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } + else BIF_wait_for_statechange(); + } +} + +int view2dmove() +{ + /* return 1 als er iets gedaan is */ + float facx=0.0, facy=0.0, dx, dy, left=1.0, right=1.0; + short mval[2], mvalo[2], leftret=1; + + /* alles goedzetten */ + scrarea_do_windraw(curarea); + curarea->head_swap= 0; + + + if(G.qual & LR_CTRLKEY) { + view2dzoom(); + curarea->head_swap= 0; + return 0; + } + + /* testen waar muis is */ + getmouseco_areawin(mvalo); + + if ELEM6(curarea->spacetype, SPACE_IPO, SPACE_SEQ, SPACE_OOPS, SPACE_SOUND, SPACE_ACTION, SPACE_NLA) + { + if( BLI_in_rcti(&G.v2d->mask, (int)mvalo[0], (int)mvalo[1]) ) { + facx= (G.v2d->cur.xmax-G.v2d->cur.xmin)/(float)(G.v2d->mask.xmax-G.v2d->mask.xmin); + facy= (G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)(G.v2d->mask.ymax-G.v2d->mask.ymin); + } + else if(BLI_in_rcti(&G.v2d->vert, (int)mvalo[0], (int)mvalo[1])) { + facy= -(G.v2d->tot.ymax-G.v2d->tot.ymin)/(float)(G.v2d->mask.ymax-G.v2d->mask.ymin); + if(get_mbut()&L_MOUSE) { + /* welk deel van de scrollbar moet bewegen? */ + if(mvalo[1]< (vertymin+vertymax)/2 ) right= 0.0; + else left= 0.0; + leftret= 0; + } + } + else if(BLI_in_rcti(&G.v2d->hor, (int)mvalo[0], (int)mvalo[1])) { + facx= -(G.v2d->tot.xmax-G.v2d->tot.xmin)/(float)(G.v2d->mask.xmax-G.v2d->mask.xmin); + if(get_mbut()&L_MOUSE) { + /* welk deel van de scrollbar moet bewegen? */ + if(mvalo[0]< (horxmin+horxmax)/2 ) right= 0.0; + else left= 0.0; + leftret= 0; + } + } + } + else { + facx= (G.v2d->cur.xmax-G.v2d->cur.xmin)/(float)(curarea->winx); + facy= (G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)(curarea->winy); + } + + + /* no y move in audio */ + if(curarea->spacetype==SPACE_SOUND) facy= 0.0; + + if(get_mbut()&L_MOUSE && leftret) return 0; + if(facx==0.0 && facy==0.0) return 1; + + while(get_mbut()&(L_MOUSE|M_MOUSE)) { + getmouseco_areawin(mval); + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + dx= facx*(mvalo[0]-mval[0]); + dy= facy*(mvalo[1]-mval[1]); + G.v2d->cur.xmin+= left*dx; + G.v2d->cur.xmax+= right*dx; + G.v2d->cur.ymin+= left*dy; + G.v2d->cur.ymax+= right*dy; + + test_view2d(G.v2d, curarea->winx, curarea->winy); + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + } + else BIF_wait_for_statechange(); + } + curarea->head_swap= 0; + return 1; +} + + +void view2dborder(void) +{ + +} + +EditIpo *select_proj_ipo(rctf *rectf, int event) +{ + EditIpo *ei; + float xmin, ymin, xmax, ymax; + /* this was IGLuint, but it's a useless typedef... */ + GLuint buffer[MAXPICKBUF]; + int a, b; + int code, hits; + short mval[2]; + + G.f |= G_PICKSEL; + + if(rectf==0) { + getmouseco_areawin(mval); + + mval[0]-= 6; mval[1]-= 6; + areamouseco_to_ipoco(G.v2d, mval, &xmin, &ymin); + mval[0]+= 12; mval[1]+= 12; + areamouseco_to_ipoco(G.v2d, mval, &xmax, &ymax); + + myortho2(xmin, xmax, ymin, ymax); + } + else myortho2(rectf->xmin, rectf->xmax, rectf->ymin, rectf->ymax); + + glSelectBuffer( MAXPICKBUF, buffer); + glRenderMode(GL_SELECT); + glInitNames(); /* deze twee fies zijn waarvoor? Anders werkt het niet */ + glPushName(-1); + + init_pickselcode(); /* drawipo.c */ + draw_ipocurves(0); + + G.f -= G_PICKSEL; + + hits= glRenderMode(GL_RENDER); + glPopName(); /* zie boven (pushname) */ + if(hits<1) return 0; + + code= 1; + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, icu, flag & IPO_VISIBLE) { + if(rectf) { + for(b=0; b<hits; b++) { + /* conversion for glSelect */ + if(code == buffer[ (4 * b) + 3] ) { + if(event==LEFTMOUSE) ei->flag |= IPO_SELECT; + else ei->flag &= ~IPO_SELECT; + ei->icu->flag= ei->flag; + } + } + } + else { + /* also conversion for glSelect */ + if(code==buffer[ 3 ]) return ei; + } + code++; + } + } + return 0; +} + diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c new file mode 100644 index 00000000000..805dbe84693 --- /dev/null +++ b/source/blender/src/drawmesh.c @@ -0,0 +1,999 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <string.h> +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "IMB_imbuf_types.h" + +#include "DNA_image_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_property_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_bmfont.h" +#include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_image.h" +#include "BKE_property.h" +#include "BKE_global.h" +#include "BKE_displist.h" +#include "BKE_object.h" +#include "BKE_material.h" + +#include "BIF_gl.h" +#include "BIF_mywindow.h" + +#include "BDR_editface.h" +#include "BDR_vpaint.h" +#include "BDR_drawmesh.h" + +#include "BSE_drawview.h" + +#include "blendef.h" +#include "nla.h" + +//#include "glext.h" +/* some local functions */ +static void draw_hide_tfaces(Object *ob, Mesh *me); + +#if defined(GL_EXT_texture_object) && !defined(__sun__) && !defined(__APPLE__) + + /* exception for mesa... not according th opengl specs */ + #ifndef __linux__ + #define glBindTexture(A,B) glBindTextureEXT(A,B) + #endif + + #define glGenTextures(A,B) glGenTexturesEXT(A,B) + #define glDeleteTextures(A,B) glDeleteTexturesEXT(A,B) + #define glPolygonOffset(A,B) glPolygonOffsetEXT(A,B) + +#else + +/* #define GL_FUNC_ADD_EXT GL_FUNC_ADD */ +/* #define GL_FUNC_REVERSE_SUBTRACT_EXT GL_FUNC_REVERSE_SUBTRACT */ +/* #define GL_POLYGON_OFFSET_EXT GL_POLYGON_OFFSET */ + +#endif + + /* (n&(n-1)) zeros the least significant bit of n */ +static int is_pow2(int num) { + return ((num)&(num-1))==0; +} +static int smaller_pow2(int num) { + while (!is_pow2(num)) + num= num&(num-1); + return num; +} + +static int fCurtile=0, fCurmode=0,fCurtileXRep=0,fCurtileYRep=0; +static Image *fCurpage=0; +static short fTexwindx, fTexwindy, fTexwinsx, fTexwinsy; +static int fDoMipMap = 1; +static int fLinearMipMap = 0; + +/* static int source, dest; also not used */ + +/** + * Enables or disable mipmapping for realtime images. + * @param mipmap Turn mipmapping on (mipmap!=0) or off (mipmap==0). + */ +void set_mipmap(int mipmap) +{ + if (fDoMipMap != (mipmap != 0)) { + free_all_realtime_images(); + fDoMipMap = mipmap != 0; + } +} + + +/** + * Returns the current setting for mipmapping. + */ +int get_mipmap(void) +{ + return fDoMipMap; +} + +/** + * Enables or disable linear mipmap setting for realtime images (textures). + * Note that this will will destroy all texture bindings in OpenGL. + * @see free_realtime_image() + * @param mipmap Turn linear mipmapping on (linear!=0) or off (linear==0). + */ +void set_linear_mipmap(int linear) +{ + if (fLinearMipMap != (linear != 0)) { + free_all_realtime_images(); + fLinearMipMap = linear != 0; + } +} + +/** + * Returns the current setting for linear mipmapping. + */ +int get_linear_mipmap(void) +{ + return fLinearMipMap; +} + + +/** + * Resets the realtime image cache variables. + */ +void clear_realtime_image_cache() +{ + fCurpage = NULL; + fCurtile = 0; + fCurmode = 0; + fCurtileXRep = 0; + fCurtileYRep = 0; +} + +/* REMEMBER! Changes here must go into my_set_tpage() as well */ +int set_tpage(TFace *tface) +{ + static int alphamode= -1; + static TFace *lasttface= 0; + Image *ima; + unsigned int *rect, *bind; + int tpx, tpy, tilemode, tileXRep,tileYRep; + + /* afschakelen */ + if(tface==0) { + if(lasttface==0) return 0; + + lasttface= 0; + fCurtile= 0; + fCurpage= 0; + if(fCurmode!=0) { + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + } + fCurmode= 0; + fCurtileXRep=0; + fCurtileYRep=0; + alphamode= -1; + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + + return 0; + } + lasttface= tface; + + if( alphamode != tface->transp) { + alphamode= tface->transp; + + if(alphamode) { + glEnable(GL_BLEND); + + if(alphamode==TF_ADD) { + glBlendFunc(GL_ONE, GL_ONE); + /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */ + } + else if(alphamode==TF_ALPHA) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */ + } + /* else { */ + /* glBlendFunc(GL_ONE, GL_ONE); */ + /* glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); */ + /* } */ + } + else glDisable(GL_BLEND); + } + + ima= tface->tpage; + + /* Enable or disable reflection mapping */ + if (ima && (ima->flag & IMA_REFLECT)){ + +// glActiveTextureARB(GL_TEXTURE0_ARB); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + + /* Handle multitexturing here */ + } + else{ + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + } + + tilemode= tface->mode & TF_TILES; + tileXRep = 0; + tileYRep = 0; + if (ima) + { + tileXRep = ima->xrep; + tileYRep = ima->yrep; + } + + + if(ima==fCurpage && fCurtile==tface->tile && tilemode==fCurmode && fCurtileXRep==tileXRep && fCurtileYRep == tileYRep) return ima!=0; + + if(tilemode!=fCurmode || fCurtileXRep!=tileXRep || fCurtileYRep != tileYRep) + { + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + if(tilemode && ima!=0) + glScalef(ima->xrep, ima->yrep, 1.0); + + glMatrixMode(GL_MODELVIEW); + } + + if(ima==0 || ima->ok==0) { + glDisable(GL_TEXTURE_2D); + + fCurtile= tface->tile; + fCurpage= 0; + fCurmode= tilemode; + fCurtileXRep = tileXRep; + fCurtileYRep = tileYRep; + + return 0; + } + + if(ima->ibuf==0) { + load_image(ima, IB_rect, G.sce, G.scene->r.cfra); + + if(ima->ibuf==0) { + ima->ok= 0; + + fCurtile= tface->tile; + fCurpage= 0; + fCurmode= tilemode; + fCurtileXRep = tileXRep; + fCurtileYRep = tileYRep; + + glDisable(GL_TEXTURE_2D); + return 0; + } + + } + + if(ima->tpageflag & IMA_TWINANIM) fCurtile= ima->lastframe; + else fCurtile= tface->tile; + + if(tilemode) { + + if(ima->repbind==0) make_repbind(ima); + + if(fCurtile>=ima->totbind) fCurtile= 0; + + /* this happens when you change repeat buttons */ + if(ima->repbind) bind= ima->repbind+fCurtile; + else bind= &ima->bindcode; + + if(*bind==0) { + + fTexwindx= ima->ibuf->x/ima->xrep; + fTexwindy= ima->ibuf->y/ima->yrep; + + if(fCurtile>=ima->xrep*ima->yrep) fCurtile= ima->xrep*ima->yrep-1; + + fTexwinsy= fCurtile / ima->xrep; + fTexwinsx= fCurtile - fTexwinsy*ima->xrep; + + fTexwinsx*= fTexwindx; + fTexwinsy*= fTexwindy; + + tpx= fTexwindx; + tpy= fTexwindy; + + rect= ima->ibuf->rect + fTexwinsy*ima->ibuf->x + fTexwinsx; + } + } + else { + bind= &ima->bindcode; + + if(*bind==0) { + tpx= ima->ibuf->x; + tpy= ima->ibuf->y; + rect= ima->ibuf->rect; + } + } + + if(*bind==0) { + int rectw= tpx, recth= tpy; + unsigned int *tilerect= NULL, *scalerect= NULL; + + /* + * Maarten: + * According to Ton this code is not needed anymore. It was used only + * in really old Blenders. + * Reevan: + * Actually it is needed for backwards compatibility. Simpledemo 6 does not display correctly without it. + */ +#if 1 + if (tilemode) { + int y; + + tilerect= MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect"); + for (y=0; y<recth; y++) { + unsigned int *rectrow= &rect[y*ima->ibuf->x]; + unsigned int *tilerectrow= &tilerect[y*rectw]; + + memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow)); + } + + rect= tilerect; + } +#endif + if (!is_pow2(rectw) || !is_pow2(recth)) { + rectw= smaller_pow2(rectw); + recth= smaller_pow2(recth); + + scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect"); + gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect); + rect= scalerect; + } + + glGenTextures(1, bind); + + if(G.f & G_DEBUG) { + printf("var1: %s\n", ima->id.name+2); + printf("var1: %d, var2: %d\n", *bind, tpx); + printf("var1: %d, var2: %d\n", fCurtile, tilemode); + } + glBindTexture( GL_TEXTURE_2D, *bind); + + if (!fDoMipMap) + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else + { + int minfilter= fLinearMipMap?GL_LINEAR_MIPMAP_LINEAR:GL_LINEAR_MIPMAP_NEAREST; + + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + if (tilerect) + MEM_freeN(tilerect); + if (scalerect) + MEM_freeN(scalerect); + } + else glBindTexture( GL_TEXTURE_2D, *bind); + + + + glEnable(GL_TEXTURE_2D); + + fCurpage= ima; + fCurmode= tilemode; + fCurtileXRep = tileXRep; + fCurtileYRep = tileYRep; + + return 1; +} + +void free_realtime_image(Image *ima) +{ + if(ima->bindcode) { + glDeleteTextures(1, &ima->bindcode); + ima->bindcode= 0; + } + if(ima->repbind) { + glDeleteTextures(ima->totbind, ima->repbind); + + MEM_freeN(ima->repbind); + ima->repbind= 0; + } +} + +void free_all_realtime_images(void) +{ + Image* ima; + + ima= G.main->image.first; + while(ima) { + free_realtime_image(ima); + ima= ima->id.next; + } +} + +void make_repbind(Image *ima) +{ + if(ima==0 || ima->ibuf==0) return; + + if(ima->repbind) { + glDeleteTextures(ima->totbind, ima->repbind); + MEM_freeN(ima->repbind); + ima->repbind= 0; + } + ima->totbind= ima->xrep*ima->yrep; + if(ima->totbind>1) { + ima->repbind= MEM_callocN(sizeof(int)*ima->totbind, "repbind"); + } +} + +void update_realtime_textures() +{ + Image *ima; + + ima= G.main->image.first; + while(ima) { + if(ima->tpageflag & IMA_TWINANIM) { + if(ima->twend >= ima->xrep*ima->yrep) ima->twend= ima->xrep*ima->yrep-1; + + /* check: zit de bindcode niet het array? Vrijgeven. (nog doen) */ + + ima->lastframe++; + if(ima->lastframe > ima->twend) ima->lastframe= ima->twsta; + + } + ima= ima->id.next; + } +} + + +/* XXX, this routine should die but + * the great wisdom of NaN has inspired + * its progation. + */ +void spack(unsigned int ucol) +{ + char *cp= (char *)&ucol; + + glColor3ub(cp[3], cp[2], cp[1]); +} + +static void draw_hide_tfaces(Object *ob, Mesh *me) +{ + TFace *tface; + MFace *mface; + float *v1, *v2, *v3, *v4; + int a; + + if(me==0 || me->tface==0) return; + + mface= me->mface; + tface= me->tface; + + cpack(0x0); + setlinestyle(1); + for(a=me->totface; a>0; a--, mface++, tface++) { + if(mface->v3==0) continue; + + if( (tface->flag & TF_HIDE)) { + + v1= (me->mvert+mface->v1)->co; + v2= (me->mvert+mface->v2)->co; + v3= (me->mvert+mface->v3)->co; + if(mface->v4) v4= (me->mvert+mface->v4)->co; else v4= 0; + + glBegin(GL_LINE_LOOP); + glVertex3fv( v1 ); + glVertex3fv( v2 ); + glVertex3fv( v3 ); + if(mface->v4) glVertex3fv( v4 ); + glEnd(); + } + } + setlinestyle(0); +} + + +void draw_tfaces3D(Object *ob, Mesh *me) +{ + MFace *mface; + TFace *tface; + DispList *dl; + float *v1, *v2, *v3, *v4, *extverts= NULL; + int a; + + if(me==0 || me->tface==0) return; + + glDisable(GL_DEPTH_TEST); + + mface= me->mface; + tface= me->tface; + + dl= find_displist(&ob->disp, DL_VERTS); + if (dl) extverts= dl->verts; + + /* SELECT faces */ + for(a=me->totface; a>0; a--, mface++, tface++) { + if(mface->v3==0) continue; + if(tface->flag & TF_HIDE) continue; + + if( tface->flag & (TF_ACTIVE|TF_SELECT) ) { + if (extverts) { + v1= extverts+3*mface->v1; + v2= extverts+3*mface->v2; + v3= extverts+3*mface->v3; + v4= mface->v4?(extverts+3*mface->v4):NULL; + } else { + v1= (me->mvert+mface->v1)->co; + v2= (me->mvert+mface->v2)->co; + v3= (me->mvert+mface->v3)->co; + v4= mface->v4?(me->mvert+mface->v4)->co:NULL; + } + + if(tface->flag & TF_ACTIVE) { + /* kleuren: R=x G=y */ + cpack(0xFF); + glBegin(GL_LINE_STRIP); glVertex3fv(v1); if(v4) glVertex3fv(v4); else glVertex3fv(v3); glEnd(); + cpack(0xFF00); + glBegin(GL_LINE_STRIP); glVertex3fv(v1); glVertex3fv(v2); glEnd(); + cpack(0x0); + glBegin(GL_LINE_STRIP); glVertex3fv(v2); glVertex3fv(v3); if(v4) glVertex3fv(v4); glEnd(); + } + else { + cpack(0x0); + glBegin(GL_LINE_LOOP); + glVertex3fv( v1 ); + glVertex3fv( v2 ); + glVertex3fv( v3 ); + if(v4) glVertex3fv( v4 ); + glEnd(); + } + + if(tface->flag & TF_SELECT) { + cpack(0xFFFFFF); + setlinestyle(1); + glBegin(GL_LINE_LOOP); + glVertex3fv( v1 ); + glVertex3fv( v2 ); + glVertex3fv( v3 ); + if(v4) glVertex3fv( v4 ); + glEnd(); + setlinestyle(0); + } + } + } + + glEnable(GL_DEPTH_TEST); +} + +static int set_gl_light(Object *ob) +{ + Base *base; + Lamp *la; + int count; + /* float zero[4]= {0.0, 0.0, 0.0, 0.0}; */ + float vec[4]; + + vec[3]= 1.0; + + for(count=0; count<8; count++) glDisable(GL_LIGHT0+count); + + count= 0; + + base= FIRSTBASE; + while(base) { + if(base->object->type==OB_LAMP ) { + if(base->lay & G.vd->lay) { + if(base->lay & ob->lay) + { + la= base->object->data; + + glPushMatrix(); + glLoadMatrixf((float *)G.vd->viewmat); + + where_is_object_simul(base->object); + VECCOPY(vec, base->object->obmat[3]); + + if(la->type==LA_SUN) { + vec[0]= base->object->obmat[2][0]; + vec[1]= base->object->obmat[2][1]; + vec[2]= base->object->obmat[2][2]; + vec[3]= 0.0; + glLightfv(GL_LIGHT0+count, GL_POSITION, vec); + } + else { + vec[3]= 1.0; + glLightfv(GL_LIGHT0+count, GL_POSITION, vec); + glLightf(GL_LIGHT0+count, GL_CONSTANT_ATTENUATION, 1.0); + glLightf(GL_LIGHT0+count, GL_LINEAR_ATTENUATION, la->att1/la->dist); + /* without this next line it looks backward compatible. attennuation still is acceptable */ + /* glLightf(GL_LIGHT0+count, GL_QUADRATIC_ATTENUATION, la->att2/(la->dist*la->dist)); */ + + if(la->type==LA_SPOT) { + vec[0]= -base->object->obmat[2][0]; + vec[1]= -base->object->obmat[2][1]; + vec[2]= -base->object->obmat[2][2]; + glLightfv(GL_LIGHT0+count, GL_SPOT_DIRECTION, vec); + glLightf(GL_LIGHT0+count, GL_SPOT_CUTOFF, la->spotsize/2.0); + glLightf(GL_LIGHT0+count, GL_SPOT_EXPONENT, 128.0*la->spotblend); + } + else glLightf(GL_LIGHT0+count, GL_SPOT_CUTOFF, 180.0); + } + + vec[0]= la->energy*la->r; + vec[1]= la->energy*la->g; + vec[2]= la->energy*la->b; + vec[3]= 1.0; + glLightfv(GL_LIGHT0+count, GL_DIFFUSE, vec); + glLightfv(GL_LIGHT0+count, GL_SPECULAR, vec);//zero); + glEnable(GL_LIGHT0+count); + + glPopMatrix(); + + count++; + if(count>7) break; + } + } + } + base= base->next; + } + + return count; +} + +static Material *give_current_material_or_def(Object *ob, int matnr) +{ + extern Material defmaterial; + Material *ma= give_current_material(ob, matnr); + + return ma?ma:&defmaterial; +} + +static int set_draw_settings_cached(int clearcache, int textured, TFace *texface, int lit, Object *litob, int litmatnr, int doublesided) +{ + static int c_textured; + static int c_lit; + static int c_doublesided; + static TFace *c_texface; + static Object *c_litob; + static int c_litmatnr; + static int c_badtex; + + if (clearcache) { + c_textured= c_lit= c_doublesided= -1; + c_texface= (TFace*) -1; + c_litob= (Object*) -1; + c_litmatnr= -1; + c_badtex= 0; + } + + if (doublesided!=c_doublesided) { + if (doublesided) glDisable(GL_CULL_FACE); + else glEnable(GL_CULL_FACE); + + c_doublesided= doublesided; + } + + if (textured!=c_textured || texface!=c_texface) { + if (textured) { + c_badtex= !set_tpage(texface); + } else { + set_tpage(0); + c_badtex= 0; + } + c_textured= textured; + c_texface= texface; + } + + if (c_badtex) lit= 0; + if (lit!=c_lit || litob!=c_litob || litmatnr!=c_litmatnr) { + if (lit) { + Material *ma= give_current_material_or_def(litob, litmatnr); + float spec[4]; + + spec[0]= ma->spec*ma->specr; + spec[1]= ma->spec*ma->specg; + spec[2]= ma->spec*ma->specb; + spec[3]= 1.0; + + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_LIGHTING); + glEnable(GL_COLOR_MATERIAL); + } + else { + glDisable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); + } + c_lit= lit; + c_litob= litob; + c_litmatnr= litmatnr; + } + + return c_badtex; +} + +void draw_tface_mesh(Object *ob, Mesh *me, int dt) /* maximum dt: precies volgens ingestelde waardes */ +{ + TFace *tface; + MFace *mface; + float *extverts= NULL; + unsigned char obcol[4]; + int a, mode; + short islight, istex; + + if (!me || !me->tface) return; + + + glShadeModel(GL_SMOOTH); + + islight= set_gl_light(ob); + + obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255); + obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255); + obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255); + obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255); + + /* eerst alle texture polys */ + + glCullFace(GL_BACK); glEnable(GL_CULL_FACE); + if(G.vd->drawtype==OB_TEXTURE) istex= 1; + else istex= 0; + + set_draw_settings_cached(1, 0, 0, 0, 0, 0, 0); + + if(dt > OB_SOLID) { + bProperty *prop = get_property(ob, "Text"); + MFaceInt *mfaceint= NULL; + int editing= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0)); + MVert *mvert; + int totface; + + if (mesh_uses_displist(me) && !editing) { + DispList *dl= find_displist(&me->disp, DL_MESH); + DispListMesh *dlm= dl->mesh; + + totface= dlm->totface; + + if (!dl) + totface= 0; + else { + totface= dlm->totface; + mvert= dlm->mvert; + mfaceint= dlm->mface; + tface= dlm->tface; + } + } else { + DispList *dl= find_displist(&ob->disp, DL_VERTS); + if (dl) extverts= dl->verts; + + totface= me->totface; + mvert= me->mvert; + mface= me->mface; + tface= me->tface; + } + + for (a=0; a<totface; a++, tface++) { + int v1idx, v2idx, v3idx, v4idx, mf_smooth, matnr, badtex; + float *v1, *v2, *v3, *v4; + + if (mfaceint) { + MFaceInt *mf= &mfaceint[a]; + + v1idx= mf->v1; + v2idx= mf->v2; + v3idx= mf->v3; + v4idx= mf->v4; + mf_smooth= mf->flag & ME_SMOOTH; + matnr= mf->mat_nr; + } else { + MFace *mf= &mface[a]; + + v1idx= mf->v1; + v2idx= mf->v2; + v3idx= mf->v3; + v4idx= mf->v4; + mf_smooth= mf->flag & ME_SMOOTH; + matnr= mf->mat_nr; + } + + if(v3idx==0) continue; + if(tface->flag & TF_HIDE) continue; + if(tface->mode & TF_INVISIBLE) continue; + + mode= tface->mode; + + if (extverts) { + v1= extverts+3*v1idx; + v2= extverts+3*v2idx; + v3= extverts+3*v3idx; + v4= v4idx?(extverts+3*v4idx):NULL; + } else { + v1= (mvert+v1idx)->co; + v2= (mvert+v2idx)->co; + v3= (mvert+v3idx)->co; + v4= v4idx?(mvert+v4idx)->co:NULL; + } + + badtex= set_draw_settings_cached(0, istex && (mode&TF_TEX), tface, islight && (mode&TF_LIGHT), ob, matnr, mode&TF_TWOSIDE); + + if (prop && !badtex && !editing && (mode & TF_BMFONT)) { + char string[MAX_PROPSTRING]; + int characters, index; + Image *ima; + float curpos; + + // The BM_FONT handling code is duplicated in the gameengine + // Search for 'Frank van Beek' ;-) + + // string = "Frank van Beek"; + + set_property_valstr(prop, string); + characters = strlen(string); + + ima = tface->tpage; + if (ima == NULL) { + characters = 0; + } + + if (1 || !mf_smooth) { + float nor[3]; + + CalcNormFloat(v1, v2, v3, nor); + + glNormal3fv(nor); + } + + curpos= 0.0; + glBegin(v4?GL_QUADS:GL_TRIANGLES); + for (index = 0; index < characters; index++) { + float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance; + int character = string[index]; + char *cp= NULL; + + // lets calculate offset stuff + // space starts at offset 1 + // character = character - ' ' + 1; + + matrixGlyph(ima->ibuf, character, & centerx, ¢ery, &sizex, &sizey, &transx, &transy, &movex, &movey, &advance); + movex+= curpos; + + if (mode & TF_OBCOL) glColor3ubv(obcol); + else cp= (char *)&(tface->col[0]); + + glTexCoord2f((tface->uv[0][0] - centerx) * sizex + transx, (tface->uv[0][1] - centery) * sizey + transy); + if (cp) glColor3ub(cp[3], cp[2], cp[1]); + glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]); + + glTexCoord2f((tface->uv[1][0] - centerx) * sizex + transx, (tface->uv[1][1] - centery) * sizey + transy); + if (cp) glColor3ub(cp[7], cp[6], cp[5]); + glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]); + + glTexCoord2f((tface->uv[2][0] - centerx) * sizex + transx, (tface->uv[2][1] - centery) * sizey + transy); + if (cp) glColor3ub(cp[11], cp[10], cp[9]); + glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]); + + if(v4) { + glTexCoord2f((tface->uv[3][0] - centerx) * sizex + transx, (tface->uv[3][1] - centery) * sizey + transy); + if (cp) glColor3ub(cp[15], cp[14], cp[13]); + glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]); + } + + curpos+= advance; + } + glEnd(); + } + else { + char *cp= NULL; + + if (badtex) glColor3ub(0xFF, 0x00, 0xFF); + else if (mode & TF_OBCOL) glColor3ubv(obcol); + else cp= (char *)&(tface->col[0]); + + if (!mf_smooth) { + float nor[3]; + + CalcNormFloat(v1, v2, v3, nor); + + glNormal3fv(nor); + } + + glBegin(v4?GL_QUADS:GL_TRIANGLES); + + glTexCoord2fv(tface->uv[0]); + if (cp) glColor3ub(cp[3], cp[2], cp[1]); + if (mf_smooth) glNormal3sv(mvert[v1idx].no); + glVertex3fv(v1); + + glTexCoord2fv(tface->uv[1]); + if (cp) glColor3ub(cp[7], cp[6], cp[5]); + if (mf_smooth) glNormal3sv(mvert[v2idx].no); + glVertex3fv(v2); + + glTexCoord2fv(tface->uv[2]); + if (cp) glColor3ub(cp[11], cp[10], cp[9]); + if (mf_smooth) glNormal3sv(mvert[v3idx].no); + glVertex3fv(v3); + + if(v4) { + glTexCoord2fv(tface->uv[3]); + if (cp) glColor3ub(cp[15], cp[14], cp[13]); + if (mf_smooth) glNormal3sv(mvert[v4idx].no); + glVertex3fv(v4); + } + glEnd(); + } + } + + /* textures uitzetten */ + set_tpage(0); + } + + glShadeModel(GL_FLAT); + glDisable(GL_CULL_FACE); + + draw_hide_tfaces(ob, me); + + if(ob==OBACT && (G.f & G_FACESELECT)) { + draw_tfaces3D(ob, me); + } + + /* XXX, bad patch - default_gl_light() calls + * glLightfv(GL_LIGHT_POSITION, ...) which + * is transformed by the current matrix... we + * need to make sure that matrix is identity. + * + * It would be better if drawmesh.c kept track + * of and restored the light settings it changed. + * - zr + */ + glPushMatrix(); + glLoadIdentity(); + default_gl_light(); + glPopMatrix(); +} + +void init_realtime_GL(void) +{ + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + +} + diff --git a/source/blender/src/drawnla.c b/source/blender/src/drawnla.c new file mode 100644 index 00000000000..d5a729b7378 --- /dev/null +++ b/source/blender/src/drawnla.c @@ -0,0 +1,523 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifdef _WIN32 +#pragma warning (once : 4761) +#include "BLI_winstuff.h" +#endif + +#include "BMF_Api.h" + +#include <stdlib.h> +#include <stdio.h> +#include "BSE_drawnla.h" +#include "BSE_drawipo.h" +#include "BSE_editnla_types.h" + +#include "BIF_gl.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_mywindow.h" +#include "BIF_glutil.h" + +#include "DNA_view3d_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_curve_types.h" +#include "DNA_ipo_types.h" +#include "DNA_action_types.h" +#include "DNA_nla_types.h" +#include "DNA_constraint_types.h" + +#include "BLI_blenlib.h" +#include "MEM_guardedalloc.h" +#include "BKE_global.h" + +#include "BDR_drawaction.h" +#include "BDR_editcurve.h" + +#include "blendef.h" +#include "interface.h" + +/* Local function prototypes */ +static void draw_nlastrips(SpaceNla *snla); +static void draw_nlatree(void); + +int count_nla_levels(void); +int nla_filter (Base* base, int flags); + +#define TESTBASE_SAFE(base) ((base)->flag & SELECT) + +/* Implementation */ +static void draw_nlatree(void) +{ + + short ofsx, ofsy = 0; + Base *base; + float x, y; + bActionStrip *strip; + bConstraintChannel *conchan; + + myortho2 (0, NLAWIDTH, G.v2d->cur.ymin, G.v2d->cur.ymax); // Scaling + + /* Blank out the area */ + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + if(G.v2d->scroll) { + ofsx= curarea->winrct.xmin; + ofsy= curarea->winrct.ymin; + glViewport(ofsx, ofsy+G.v2d->mask.ymin-SCROLLB, NLAWIDTH, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB)); + glScissor(ofsx, ofsy+G.v2d->mask.ymin-SCROLLB, NLAWIDTH, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB)); + } + } + + glClearColor(.6, .6, .6, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Clip to the scrollable area */ + + glColor3ub(0x00, 0x00, 0x00); + + x = 0.0; + + y = count_nla_levels(); + + y*= (NLACHANNELHEIGHT+NLACHANNELSKIP); + + for (base=G.scene->base.first; base; base=base->next){ + if (nla_filter(base, 0)){ + cpack (0xAAAAAA); + glRectf(x, y-NLACHANNELHEIGHT/2, (float)NLAWIDTH, y+NLACHANNELHEIGHT/2); + + /* Draw the name / ipo timeline*/ + if (TESTBASE_SAFE(base)) + cpack(0xFFFFFF); + else + cpack (0x000000); + glRasterPos2f(x+16, y-4); + BMF_DrawString(G.font, base->object->id.name+2); + + /* Draw the constraint ipos */ + for (conchan = base->object->constraintChannels.first; conchan; conchan=conchan->next){ + y-=NLACHANNELHEIGHT+NLACHANNELSKIP; + cpack (0x888888); + glRectf(x+16, y-NLACHANNELHEIGHT/2, (float)NLAWIDTH, y+NLACHANNELHEIGHT/2); + + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT) + cpack(0xFFFFFF); + else + cpack (0x000000); + + glRasterPos2f(x+32, y-4); + BMF_DrawString(G.font, conchan->name); + } + + /* Draw the action timeline */ + if (ACTIVE_ARMATURE(base)){ + glRasterPos2f(x, y-8); + BIF_draw_icon(ICON_DOWNARROW_HLT); + y-=NLACHANNELHEIGHT+NLACHANNELSKIP; + + if (base->object->action){ + cpack (0x888888); + glRectf(x+16, y-NLACHANNELHEIGHT/2, (float)NLAWIDTH, y+NLACHANNELHEIGHT/2); + + if (TESTBASE_SAFE(base)) + cpack(0xFFFFFF); + else + cpack (0x000000); + + glRasterPos2f(x+32, y-4); + BMF_DrawString(G.font, base->object->action->id.name+2); + } + } + y-=NLACHANNELHEIGHT+NLACHANNELSKIP; + + /* Draw the nla strips */ + if (base->object->type==OB_ARMATURE){ + for (strip = base->object->nlastrips.first; strip; strip=strip->next){ + cpack (0x666666); + glRectf(x+32, y-NLACHANNELHEIGHT/2, (float)NLAWIDTH, y+NLACHANNELHEIGHT/2); + + if (TESTBASE_SAFE(base)) + cpack(0xFFFFFF); + else + cpack (0x000000); + + glRasterPos2f(x+48, y-4); + BMF_DrawString(G.font, strip->act->id.name+2); + + y-=(NLACHANNELHEIGHT+NLACHANNELSKIP); + + } + } + } + } + + myortho2 (0, NLAWIDTH, 0, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB)); // Scaling + + glShadeModel(GL_SMOOTH); + + y=9; + +#if 1 + /* Draw sexy shaded block thingies */ + glEnable (GL_BLEND); + glBegin(GL_QUAD_STRIP); + glColor4ub (0x99,0x99,0x99,0x00); + glVertex2f (0,SCROLLB*2-y); + glVertex2f (NLAWIDTH,SCROLLB*2-y); + + glColor4ub (0x99,0x99,0x99,0xFF); + glVertex2f (0,SCROLLB-y); + glVertex2f (NLAWIDTH,SCROLLB-y); + + glColor4ub (0x99,0x99,0x99,0xFF); + glVertex2f (0,0-y); + glVertex2f (NLAWIDTH,0-y); + + glEnd(); + + glDisable (GL_BLEND); +#endif + + glShadeModel(GL_FLAT); +} + +static void draw_nlastrips(SpaceNla *snla) +{ + rcti scr_rct; + gla2DDrawInfo *di; + Base *base; + int offset = 0; + bConstraintChannel *conchan; + + float y; + + /* Draw strips */ + + scr_rct.xmin= snla->area->winrct.xmin + NLAWIDTH; + scr_rct.ymin= snla->area->winrct.ymin + snla->v2d.mask.ymin-SCROLLB; + scr_rct.xmax= snla->area->winrct.xmin + snla->v2d.hor.xmax; + scr_rct.ymax= snla->area->winrct.ymin + snla->v2d.mask.ymax; + di= glaBegin2DDraw(&scr_rct, &G.v2d->cur); + + y=count_nla_levels(); + y*= (NLACHANNELHEIGHT+NLACHANNELSKIP); + + for (base=G.scene->base.first; base; base=base->next){ + Object *ob; + bActionStrip *strip; + int frame1_x, channel_y; + + ob=base->object; + + if (nla_filter(base, 0)){ + /* Draw the field */ + glEnable (GL_BLEND); + if (TESTBASE_SAFE(base)) + glColor4b (0x11, 0x22, 0x55, 0x22); + else + glColor4b (0x55, 0x22, 0x11, 0x22); + + gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y); + glRectf(0, channel_y-NLACHANNELHEIGHT/2, frame1_x, channel_y+NLACHANNELHEIGHT/2); + + + if (TESTBASE_SAFE(base)) + glColor4b (0x11, 0x22, 0x55, 0x44); + else + glColor4b (0x55, 0x22, 0x11, 0x44); + glRectf(frame1_x, channel_y-NLACHANNELHEIGHT/2, G.v2d->hor.xmax, channel_y+NLACHANNELHEIGHT/2); + + glDisable (GL_BLEND); + + /* Draw the ipo */ + draw_object_channel(di, ob, 0, y); + y-=NLACHANNELHEIGHT+NLACHANNELSKIP; + + /* Draw the constraints */ + for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next){ + glEnable (GL_BLEND); + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT) + glColor4b (0x11, 0x22, 0x55, 0x22); + else + glColor4b (0x55, 0x22, 0x11, 0x22); + + gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y); + glRectf(0, channel_y-NLACHANNELHEIGHT/2+4, frame1_x, channel_y+NLACHANNELHEIGHT/2-4); + + + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT) + glColor4b (0x11, 0x22, 0x55, 0x44); + else + glColor4b (0x55, 0x22, 0x11, 0x44); + glRectf(frame1_x, channel_y-NLACHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+NLACHANNELHEIGHT/2-4); + + glDisable (GL_BLEND); + + /* Draw the ipo */ + draw_ipo_channel(di, conchan->ipo, 0, y); + y-=NLACHANNELHEIGHT+NLACHANNELSKIP; + + } + } + + + + + /* Draw the action strip */ + if (ACTIVE_ARMATURE(base)){ + + /* Draw the field */ + glEnable (GL_BLEND); + if (TESTBASE_SAFE(base)) + glColor4ub (0x11, 0x22, 0x55, 0x22); + else + glColor4ub (0x55, 0x22, 0x11, 0x22); + gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y); + glRectf(0, channel_y-NLACHANNELHEIGHT/2+4, frame1_x, channel_y+NLACHANNELHEIGHT/2-4); + + + if (TESTBASE_SAFE(base)) + glColor4ub (0x11, 0x22, 0x55, 0x44); + else + glColor4ub (0x55, 0x22, 0x11, 0x44); + glRectf(frame1_x, channel_y-NLACHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+NLACHANNELHEIGHT/2-4); + + glDisable (GL_BLEND); + + /* Draw the action keys */ + draw_action_channel(di, ob->action, 0, y); + + y-=NLACHANNELHEIGHT+NLACHANNELSKIP; + + } + + /* Draw the nla strips */ + if (ob->type==OB_ARMATURE){ + for (strip=ob->nlastrips.first; strip; strip=strip->next){ + int stripstart, stripend; + int blendstart, blendend; + unsigned char r,g,b; + + /* Draw rect */ + if (strip->flag & ACTSTRIP_SELECT){ + r = 0xFF; g=0xFF; b=0xAA; + } + else{ + r = 0xE4; g=0x9C; b=0xC6; + } + + glColor4ub (r, g, b, 0xFF); + + gla2DDrawTranslatePt(di, strip->start+strip->blendin, y, &stripstart, &channel_y); + gla2DDrawTranslatePt(di, strip->end-strip->blendout, y, &stripend, &channel_y); + glRectf(stripstart, channel_y-NLACHANNELHEIGHT/2+3, stripend, channel_y+NLACHANNELHEIGHT/2-3); + + + /* Draw blendin */ + if (strip->blendin>0){ + glBegin(GL_TRIANGLES); + + gla2DDrawTranslatePt(di, strip->start, y, &blendstart, &channel_y); + + glColor4ub (r*0.75, g*0.75, b*0.75, 0xFF); + glVertex2f(blendstart, channel_y-NLACHANNELHEIGHT/2+3); + glVertex2f(stripstart, channel_y+NLACHANNELHEIGHT/2-3); + glVertex2f(stripstart, channel_y-NLACHANNELHEIGHT/2+3); + + + glEnd(); + } + if (strip->blendout>0){ + glBegin(GL_TRIANGLES); + gla2DDrawTranslatePt(di, strip->end, y, &blendend, &channel_y); + glColor4ub (r*0.75, g*0.75, b*0.75, 0xFF); + glVertex2f(blendend, channel_y-NLACHANNELHEIGHT/2+3); + glVertex2f(stripend, channel_y+NLACHANNELHEIGHT/2-3); + glVertex2f(stripend, channel_y-NLACHANNELHEIGHT/2+3); + glEnd(); + } + + /* Draw border */ + glBegin(GL_LINE_STRIP); + glColor4f(1, 1, 1, 0.5); + gla2DDrawTranslatePt(di, strip->start, y, &stripstart, &channel_y); + gla2DDrawTranslatePt(di, strip->end, y, &stripend, &channel_y); + + glVertex2f(stripstart, channel_y-NLACHANNELHEIGHT/2+3); + glVertex2f(stripstart, channel_y+NLACHANNELHEIGHT/2-3); + glVertex2f(stripend, channel_y+NLACHANNELHEIGHT/2-3); + glColor4f(0, 0, 0, 0.5); + glVertex2f(stripend, channel_y-NLACHANNELHEIGHT/2+3); + glVertex2f(stripstart, channel_y-NLACHANNELHEIGHT/2+3); + glEnd(); + + glEnable (GL_BLEND); + + /* Show strip extension */ + if (strip->flag & ACTSTRIP_HOLDLASTFRAME){ + glColor4ub (r, g, b, 0x55); + + glRectf(stripend, channel_y-NLACHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+NLACHANNELHEIGHT/2-2); + } + + /* Show repeat */ + if (strip->repeat > 1.0 && !(strip->flag & ACTSTRIP_USESTRIDE)){ + float rep = 1; + glBegin(GL_LINES); + while (rep<strip->repeat){ + /* Draw line */ + glColor4f(0, 0, 0, 0.5); + gla2DDrawTranslatePt(di, strip->start+(rep*((strip->end-strip->start)/strip->repeat)), y, &frame1_x, &channel_y); + glVertex2f(frame1_x, channel_y-NLACHANNELHEIGHT/2+4); + glVertex2f(frame1_x, channel_y+NLACHANNELHEIGHT/2-2); + + glColor4f(1.0, 1.0, 1.0, 0.5); + gla2DDrawTranslatePt(di, strip->start+(rep*((strip->end-strip->start)/strip->repeat)), y, &frame1_x, &channel_y); + glVertex2f(frame1_x+1, channel_y-NLACHANNELHEIGHT/2+4); + glVertex2f(frame1_x+1, channel_y+NLACHANNELHEIGHT/2-2); + rep+=1.0; + } + glEnd(); + + } + glDisable (GL_BLEND); + + y-=(NLACHANNELHEIGHT+NLACHANNELSKIP); + } + + } + } + glaEnd2DDraw(di); + +} + +void drawnlaspace(void) +{ + short ofsx = 0, ofsy = 0; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; + + calc_scrollrcts(G.v2d, curarea->winx, curarea->winy); + + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + if(G.v2d->scroll) { + ofsx= curarea->winrct.xmin; + ofsy= curarea->winrct.ymin; + glViewport(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + glScissor(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + } + } + + glClearColor(.45, .45, .45, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); + + /* Draw backdrop */ + calc_ipogrid(); + draw_ipogrid(); + + /* Draw channel strips */ + draw_nlastrips(G.snla); + + /* Draw current frame */ + glViewport(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + glScissor(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); + draw_cfra_action(); + + /* Draw scroll */ + mywinset(curarea->win); + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5); + if(G.v2d->scroll) drawscroll(0); + } + + /* Draw channel names */ + draw_nlatree(); + + curarea->win_swap= WIN_BACK_OK; +} + +int count_nla_levels(void) +{ + Base *base; + int y=0; + + for (y=0, base=G.scene->base.first; base; base=base->next) + { + if (nla_filter(base,0 )){ + /* Ipo */ + y++; + /* Constraint channels */ + y+=BLI_countlist(&base->object->constraintChannels); + + if (base->object->type==OB_ARMATURE){ + /* Action */ + if(base->object->action){ + // bActionChannel *achan; + y++; + + // for (achan=base->object->action->chanbase.first; achan; achan=achan->next){ + // y+=BLI_countlist(&achan->constraintChannels); + // } + } + /* Nla strips */ + y+= BLI_countlist(&base->object->nlastrips); + } + } + } + + return y; +} + +int nla_filter (Base* base, int flags) +{ + Object *ob = base->object; + + /* Only objects with ipos */ + if (ob->ipo) + return 1; + + if (ob->constraintChannels.first) + return 1; + + /* Only armatures */ + if (ob->type==OB_ARMATURE) + return 1; + + else return 0; +}
\ No newline at end of file diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c new file mode 100644 index 00000000000..83657303628 --- /dev/null +++ b/source/blender/src/drawobject.c @@ -0,0 +1,3579 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <string.h> +#include <math.h> + +#ifdef _WIN32 +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "IMB_imbuf.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "MTC_matrixops.h" + +#include "DNA_camera_types.h" +#include "DNA_curve_types.h" +#include "DNA_effect_types.h" +#include "DNA_ipo_types.h" +#include "DNA_lamp_types.h" +#include "DNA_lattice_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_object_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" +#include "DNA_world_types.h" + +#include "BKE_utildefines.h" +#include "BKE_curve.h" +#include "BKE_object.h" +#include "BKE_global.h" +#include "BKE_displist.h" +#include "BKE_material.h" +#include "BKE_ipo.h" +#include "BKE_mesh.h" +#include "BKE_effect.h" +#include "BKE_lattice.h" + +#include "BIF_gl.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_editarmature.h" +#include "BIF_editika.h" +#include "BIF_editmesh.h" + +#include "BDR_drawmesh.h" +#include "BDR_drawobject.h" +#include "BDR_editobject.h" + +#include "BSE_view.h" +#include "BSE_drawview.h" +#include "BSE_trans_types.h" + +#include "blendef.h" +#include "mydevice.h" +#include "nla.h" + +#ifdef __NLA +#include "BKE_deform.h" +#endif + +/* pretty stupid */ +/* extern Lattice *editLatt; already in BKE_lattice.h */ +/* editcurve.c */ +extern ListBase editNurb; +/* editmball.c */ +extern ListBase editelems; + +/* more or less needed forwards */ +static void drawmeshwire(Object *ob); + + /***/ + +// Materials start counting at # one.... +#define MAXMATBUF (MAXMAT + 1) +static float matbuf[MAXMATBUF][2][4]; + +static void init_gl_materials(Object *ob) +{ + extern Material defmaterial; + Material *ma; + int a; + + if(ob->totcol==0) { + matbuf[0][0][0]= defmaterial.r; + matbuf[0][0][1]= defmaterial.g; + matbuf[0][0][2]= defmaterial.b; + matbuf[0][0][3]= 1.0; + + matbuf[0][1][0]= defmaterial.specr; + matbuf[0][1][1]= defmaterial.specg; + matbuf[0][1][2]= defmaterial.specb; + matbuf[0][1][3]= 1.0; + + /* ook matnr 1, displists! */ + VECCOPY(matbuf[1][0], matbuf[0][0]); + VECCOPY(matbuf[1][1], matbuf[0][1]); + } + + for(a=1; a<=ob->totcol; a++) { + ma= give_current_material(ob, a); + if(ma==NULL) ma= &defmaterial; + if(a<MAXMATBUF) { + matbuf[a][0][0]= (ma->ref+ma->emit)*ma->r; + matbuf[a][0][1]= (ma->ref+ma->emit)*ma->g; + matbuf[a][0][2]= (ma->ref+ma->emit)*ma->b; + matbuf[a][0][3]= 1.0; + + matbuf[a][1][0]= ma->spec*ma->specr; + matbuf[a][1][1]= ma->spec*ma->specg; + matbuf[a][1][2]= ma->spec*ma->specb; + matbuf[a][1][3]= 1.0; + } + } +} + +static void set_gl_material(int nr) +{ + if(nr<MAXMATBUF) { + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matbuf[nr][0]); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matbuf[nr][1]); + } +} + + /***/ + +unsigned int rect_desel[16]= {0x707070,0x0,0x0,0x707070,0x407070,0x70cccc,0x407070,0x0,0xaaffff,0xffffff,0x70cccc,0x0,0x70cccc,0xaaffff,0x407070,0x707070}; +unsigned int rect_sel[16]= {0x707070,0x0,0x0,0x707070,0x702070,0xcc50cc,0x702070,0x0,0xff80ff,0xffffff,0xcc50cc,0x0,0xcc50cc,0xff80ff,0x702070,0x707070}; + +unsigned int rectu_desel[16]= {0xff4e4e4e,0xff5c2309,0xff000000,0xff4e4f4d,0xff000000,0xffff9d72,0xffff601c,0xff000000,0xff5d2409,0xffffffff,0xffff9d72,0xff5b2209,0xff4e4e4e,0xff5c2309,0xff010100,0xff4f4f4f}; +unsigned int rectu_sel[16]= {0xff4e4e4e,0xff403c00,0xff000000,0xff4e4e4d,0xff000000,0xfffff64c,0xffaaa100,0xff000000,0xff403c00,0xffffffff,0xfffff64c,0xff403c00,0xff4f4f4f,0xff403c00,0xff010100,0xff4e4e4e}; + +unsigned int rectl_desel[81]= {0x777777,0x777777,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777,0x777777,0xa9fefe,0xaafefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0xaaffff,0xa9fefe,0x4e4e4e,0x0,0x124040,0x0,0x4e4e4e,0xaafefe,0xaaffff,0xaaffff,0x777777,0x0,0x227777,0x55cccc,0x227777,0x0,0x777777,0xaaffff,0xaaffff,0x777777,0x124040,0x88ffff,0xffffff,0x55cccc,0x124040,0x777777,0xaaffff,0xaaffff,0x777777,0x0,0x55cccc,0x88ffff,0x227777,0x0,0x777777,0xaaffff,0xaafefe,0xaafefe,0x4f4f4f,0x0,0x124040,0x0,0x4e4e4e,0xa9fefe,0xaaffff,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777}; +unsigned int rectl_sel[81]= {0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x4e4e4e,0x10101,0x402440,0x0,0x4e4e4e,0xffaaff,0xffaaff,0xffaaff,0x777777,0x0,0x774477,0xcc77cc,0x774477,0x0,0x777777,0xffaaff,0xffaaff,0x777777,0x402440,0xffaaff,0xffffff,0xcc77cc,0x412541,0x777777,0xffaaff,0xffaaff,0x777777,0x10101,0xcc77cc,0xffaaff,0x774477,0x0,0x777777,0xffaaff,0xffaaff,0xffaaff,0x4e4e4e,0x10101,0x402440,0x0,0x4e4e4e,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777}; +unsigned int rectlus_desel[81]= {0x777777,0x777777,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777,0x777777,0xa9fefe,0xaafefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0xaaffff,0xa9fefe,0x4e4e4e,0x0,0x5c2309,0x0,0x4e4f4d,0xaafefe,0xaaffff,0xaaffff,0x777777,0x0,0xff601c,0xff9d72,0xff601c,0x0,0x777777,0xaaffff,0xaaffff,0x777777,0x5d2409,0xffceb8,0xff9d72,0xff9d72,0x5b2209,0x777777,0xaaffff,0xaaffff,0x777777,0x10100,0xffceb8,0xffceb8,0xff601c,0x0,0x777777,0xaaffff,0xaafefe,0xaafefe,0x4e4e4e,0x0,0x5c2309,0x10100,0x4f4f4f,0xa9fefe,0xaaffff,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777}; +unsigned int rectlus_sel[81]= {0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x4e4e4e,0x10100,0x403c00,0x0,0x4e4e4d,0xffaaff,0xffaaff,0xffaaff,0x777777,0x0,0xaaa100,0xfff64c,0xaaa100,0x0,0x777777,0xffaaff,0xffaaff,0x777777,0x403c00,0xfffde2,0xffffff,0xfff64c,0x403c00,0x777777,0xffaaff,0xffaaff,0x777777,0x10100,0xfff64c,0xfffde2,0xaaa100,0x0,0x777777,0xffaaff,0xffaaff,0xffaaff,0x4f4f4f,0x0,0x403c00,0x10100,0x4e4e4e,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777}; +unsigned int rectllib_desel[81]= {0xff777777,0xff777777,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xb9b237,0xb9b237,0x4e4e4e,0x0,0x5c2309,0x0,0x4e4f4d,0xb9b237,0xb9b237,0xb9b237,0xff777777,0x0,0xff601c,0xff9d72,0xff601c,0x0,0xff777777,0xb9b237,0xb9b237,0xff777777,0x5d2409,0xffceb8,0xff9d72,0xff9d72,0x5b2209,0xff777777,0xb9b237,0xb9b237,0xff777777,0x10100,0xffceb8,0xffceb8,0xff601c,0x0,0xff777777,0xb9b237,0xb9b237,0xb9b237,0x4e4e4e,0x0,0x5c2309,0x10100,0x4f4f4f,0xb9b237,0xb9b237,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xff777777,0xff777777}; +unsigned int rectllib_sel[81]= {0xff777777,0xff777777,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xfff64c,0xfff64c,0x4e4e4e,0x10100,0x403c00,0x0,0x4e4e4d,0xfff64c,0xfff64c,0xfff64c,0xff777777,0x0,0xaaa100,0xfff64c,0xaaa100,0x0,0xff777777,0xfff64c,0xfff64c,0xff777777,0x403c00,0xfffde2,0xffffff,0xfff64c,0x403c00,0xff777777,0xfff64c,0xfff64c,0xff777777,0x10100,0xfff64c,0xfffde2,0xaaa100,0x0,0xff777777,0xfff64c,0xfff64c,0xfff64c,0x4f4f4f,0x0,0x403c00,0x10100,0x4e4e4e,0xfff64c,0xfff64c,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xff777777,0xff777777}; + +unsigned int rectl_set[81]= {0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xaaaaaa,0xaaaaaa,0x4e4e4e,0x10100,0x202020,0x0,0x4e4e4d,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0x0,0xaaa100,0xaaaaaa,0xaaa100,0x0,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0x202020,0xfffde2,0xffffff,0xaaaaaa,0x202020,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0x10100,0xaaaaaa,0xfffde2,0xaaa100,0x0,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0x4f4f4f,0x0,0x202020,0x10100,0x4e4e4e,0xaaaaaa,0xaaaaaa,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777}; + +#define B_YELLOW 0x77FFFF +#define B_PURPLE 0xFF70FF + + +unsigned int selcol= 0xFF88FF; +unsigned int actselcol= 0xFFBBFF; + +static unsigned int colortab[24]= + {0x0, 0xFF88FF, 0xFFBBFF, + 0x403000, 0xFFFF88, 0xFFFFBB, + 0x104040, 0x66CCCC, 0x77CCCC, + 0x101040, 0x5588FF, 0x88BBFF, + 0xFFFFFF + }; + + +static float cube[8][3] = { + {-1.0, -1.0, -1.0}, + {-1.0, -1.0, 1.0}, + {-1.0, 1.0, 1.0}, + {-1.0, 1.0, -1.0}, + { 1.0, -1.0, -1.0}, + { 1.0, -1.0, 1.0}, + { 1.0, 1.0, 1.0}, + { 1.0, 1.0, -1.0}, +}; + +void init_draw_rects(void) +{ + if(G.order==B_ENDIAN) { + IMB_convert_rgba_to_abgr(16, rect_desel); + IMB_convert_rgba_to_abgr(16, rect_sel); + + IMB_convert_rgba_to_abgr(16, rectu_desel); + IMB_convert_rgba_to_abgr(16, rectu_sel); + + IMB_convert_rgba_to_abgr(81, rectl_desel); + IMB_convert_rgba_to_abgr(81, rectl_sel); + + IMB_convert_rgba_to_abgr(81, rectlus_desel); + IMB_convert_rgba_to_abgr(81, rectlus_sel); + + IMB_convert_rgba_to_abgr(81, rectllib_desel); + IMB_convert_rgba_to_abgr(81, rectllib_sel); + + IMB_convert_rgba_to_abgr(81, rectl_set); + } +} + +static void draw_icon_centered(float *pos, unsigned int *rect, int rectsize) +{ + float hsize= (float) rectsize/2.0; + GLubyte dummy= 0; + + glRasterPos3fv(pos); + + /* use bitmap to shift rasterpos in pixels */ + glBitmap(1, 1, 0.0, 0.0, -hsize, -hsize, &dummy); + glFinish(); /* for sun */ + + glDrawPixels(rectsize, rectsize, GL_RGBA, GL_UNSIGNED_BYTE, rect); +} + +void helpline(float *vec) +{ + float vecrot[3]; + short mval[2], mval1[2]; + + VECCOPY(vecrot, vec); + if(G.obedit) Mat4MulVecfl(G.obedit->obmat, vecrot); + + getmouseco_areawin(mval); + project_short_noclip(vecrot, mval1); + + persp(0); + + glDrawBuffer(GL_FRONT); + + cpack(0); + + setlinestyle(3); + glBegin(GL_LINE_STRIP); + glVertex2sv(mval); + glVertex2sv(mval1); + glEnd(); + setlinestyle(0); + + persp(1); + + glDrawBuffer(GL_BACK); +} + +void drawaxes(float size) +{ + int axis; + + for (axis=0; axis<3; axis++) { + float v1[3]= {0.0, 0.0, 0.0}; + float v2[3]= {0.0, 0.0, 0.0}; + int arrow_axis= (axis==0)?1:0; + + glBegin(GL_LINES); + + v2[axis]= size; + glVertex3fv(v1); + glVertex3fv(v2); + + v1[axis]= size*0.8; + v1[arrow_axis]= -size*0.125; + glVertex3fv(v1); + glVertex3fv(v2); + + v1[arrow_axis]= size*0.125; + glVertex3fv(v1); + glVertex3fv(v2); + + glEnd(); + + v2[axis]+= size*0.125; + glRasterPos3fv(v2); + + if (axis==0) + BMF_DrawString(G.font, "x"); + else if (axis==1) + BMF_DrawString(G.font, "y"); + else + BMF_DrawString(G.font, "z"); + } +} + +#if 0 +static void drawgourcube(void) +{ + float n[3]; + + n[0]=0; n[1]=0; n[2]=0; + glBegin(GL_QUADS); + n[0]= -1.0; + glNormal3fv(n); + glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]); + n[0]=0; + glEnd(); + + glBegin(GL_QUADS); + n[1]= -1.0; + glNormal3fv(n); + glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]); + n[1]=0; + glEnd(); + + glBegin(GL_QUADS); + n[0]= 1.0; + glNormal3fv(n); + glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]); + n[0]=0; + glEnd(); + + glBegin(GL_QUADS); + n[1]= 1.0; + glNormal3fv(n); + glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]); + n[1]=0; + glEnd(); + + glBegin(GL_QUADS); + n[2]= 1.0; + glNormal3fv(n); + glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]); + n[2]=0; + glEnd(); + + glBegin(GL_QUADS); + n[2]= -1.0; + glNormal3fv(n); + glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]); + glEnd(); +} +#endif + +static void drawcube(void) +{ + + glBegin(GL_LINE_STRIP); + glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]); + glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]); + glVertex3fv(cube[7]); glVertex3fv(cube[4]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(cube[1]); glVertex3fv(cube[5]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(cube[2]); glVertex3fv(cube[6]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(cube[3]); glVertex3fv(cube[7]); + glEnd(); +} + +#if 0 +static void drawcube_size(float *size) +{ + + glPushMatrix(); + glScalef(size[0], size[1], size[2]); + + + glBegin(GL_LINE_STRIP); + glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]); + glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]); + glVertex3fv(cube[7]); glVertex3fv(cube[4]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(cube[1]); glVertex3fv(cube[5]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(cube[2]); glVertex3fv(cube[6]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(cube[3]); glVertex3fv(cube[7]); + glEnd(); + + glPopMatrix(); +} +#endif + +static void tekenshadbuflimits(Lamp *la, float mat[][4]) +{ + float sta[3], end[3], lavec[3]; + + lavec[0]= -mat[2][0]; + lavec[1]= -mat[2][1]; + lavec[2]= -mat[2][2]; + Normalise(lavec); + + sta[0]= mat[3][0]+ la->clipsta*lavec[0]; + sta[1]= mat[3][1]+ la->clipsta*lavec[1]; + sta[2]= mat[3][2]+ la->clipsta*lavec[2]; + + end[0]= mat[3][0]+ la->clipend*lavec[0]; + end[1]= mat[3][1]+ la->clipend*lavec[1]; + end[2]= mat[3][2]+ la->clipend*lavec[2]; + + + glBegin(GL_LINE_STRIP); + glVertex3fv(sta); + glVertex3fv(end); + glEnd(); + + glPointSize(3.0); + glBegin(GL_POINTS); + cpack(0); + glVertex3fv(sta); + glVertex3fv(end); + glEnd(); + glPointSize(1.0); +} + + + +static void spotvolume(float *lvec, float *vvec, float inp) +{ + /* camera staat op 0,0,0 */ + float temp[3],plane[3],mat1[3][3],mat2[3][3],mat3[3][3],mat4[3][3],q[4],co,si,hoek; + + Normalise(lvec); + Normalise(vvec); /* is dit de goede vector ? */ + + Crossf(temp,vvec,lvec); /* vergelijking van vlak door vvec en lvec */ + Crossf(plane,lvec,temp); /* en dan het vlak loodrecht daarop en evenwijdig aan lvec */ + + Normalise(plane); + + /* nu hebben we twee vergelijkingen: die van de kegel en die van het vlak, maar we hebben + drie onbekenden We halen nu een onbekende weg door het vlak naar z=0 te roteren */ + /* Ik heb geen flauw idee of dat mag, we moeten tenslotte twee oplossingen krijgen, maar we + proberen het gewoon: vlak vector moet (0,0,1) worden*/ + + /* roteer om uitproduct vector van (0,0,1) en vlakvector, inproduct graden */ + /* volgens defenitie volgt dat uitproduct is (plane[1],-plane[0],0), en cos() = plane[2]);*/ + + q[1] = plane[1] ; + q[2] = -plane[0] ; + q[3] = 0 ; + Normalise(&q[1]); + + hoek = saacos(plane[2])/2.0; + co = cos(hoek); + si = sqrt(1-co*co); + + q[0] = co; + q[1] *= si; + q[2] *= si; + q[3] = 0; + + QuatToMat3(q,mat1); + + /* lampvector nu over acos(inp) graden roteren */ + + vvec[0] = lvec[0] ; + vvec[1] = lvec[1] ; + vvec[2] = lvec[2] ; + + Mat3One(mat2); + co = inp; + si = sqrt(1-inp*inp); + + mat2[0][0] = co; + mat2[1][0] = -si; + mat2[0][1] = si; + mat2[1][1] = co; + Mat3MulMat3(mat3,mat2,mat1); + + mat2[1][0] = si; + mat2[0][1] = -si; + Mat3MulMat3(mat4,mat2,mat1); + Mat3Transp(mat1); + + Mat3MulMat3(mat2,mat1,mat3); + Mat3MulVecfl(mat2,lvec); + Mat3MulMat3(mat2,mat1,mat4); + Mat3MulVecfl(mat2,vvec); + + return; +} + + + +static void drawlamp(Object *ob) +{ + Lamp *la; + float vec[3], lvec[3], vvec[3],x,y,z; + + la= ob->data; + vec[0]=vec[1]=vec[2]= 0.0; + + setlinestyle(4); + + if(la->type==LA_SPOT) { + + lvec[0]=lvec[1]= 0.0; + lvec[2] = 1.0; + x = G.vd->persmat[0][2]; + y = G.vd->persmat[1][2]; + z = G.vd->persmat[2][2]; + vvec[0]= x*ob->obmat[0][0] + y*ob->obmat[0][1] + z*ob->obmat[0][2]; + vvec[1]= x*ob->obmat[1][0] + y*ob->obmat[1][1] + z*ob->obmat[1][2]; + vvec[2]= x*ob->obmat[2][0] + y*ob->obmat[2][1] + z*ob->obmat[2][2]; + + y = cos( M_PI*la->spotsize/360.0 ); + spotvolume(lvec, vvec, y); + x = -la->dist; + lvec[0] *= x ; + lvec[1] *= x ; + lvec[2] *= x; + vvec[0] *= x ; + vvec[1] *= x ; + vvec[2] *= x; + + glBegin(GL_LINE_STRIP); + glVertex3fv(vvec); + glVertex3fv(vec); + glVertex3fv(lvec); + glEnd(); + + z = x*sqrt(1.0 - y*y); + x *= y; + + glTranslatef(0.0 , 0.0 , x); + if(la->mode & LA_SQUARE) { + vvec[0]= fabs(z); + vvec[1]= fabs(z); + vvec[2]= 0.0; + glBegin(GL_LINE_LOOP); + glVertex3fv(vvec); + vvec[1]= -fabs(z); + glVertex3fv(vvec); + vvec[0]= -fabs(z); + glVertex3fv(vvec); + vvec[1]= fabs(z); + glVertex3fv(vvec); + glEnd(); + } + else circ(0.0, 0.0, fabs(z)); + + } + else if ELEM(la->type, LA_HEMI, LA_SUN) { + glBegin(GL_LINE_STRIP); + glVertex3fv(vec); + vec[2]= -la->dist; + glVertex3fv(vec); + glEnd(); + } + else { + if(la->mode & LA_SPHERE) { + + float tmat[4][4], imat[4][4]; + + vec[0]= vec[1]= vec[2]= 0.0; + mygetmatrix(tmat); + Mat4Invert(imat, tmat); + + drawcircball(vec, la->dist, imat); + + } + } + myloadmatrix(G.vd->viewmat); + + VECCOPY(vec, ob->obmat[3]); + + glBegin(GL_LINE_STRIP); + glVertex3fv(vec); + vec[2]= 0; + glVertex3fv(vec); + glEnd(); + setlinestyle(0); + + if(la->type==LA_SPOT && (la->mode & LA_SHAD) ) { + tekenshadbuflimits(la, ob->obmat); + } +} + +static void draw_limit_line(float sta, float end, unsigned int col) +{ + glBegin(GL_LINES); + glVertex3f(0.0, 0.0, -sta); + glVertex3f(0.0, 0.0, -end); + glEnd(); + + glPointSize(3.0); + glBegin(GL_POINTS); + cpack(col); + glVertex3f(0.0, 0.0, -sta); + glVertex3f(0.0, 0.0, -end); + glEnd(); + glPointSize(1.0); +} + + +void drawcamera(Object *ob) +{ + /* een staande piramide met (0,0,0) als top */ + Camera *cam; + World *wrld; + float vec[8][4], tmat[4][4], fac, facx, facy, depth; + + cam= ob->data; + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + + /* zo is ie altijd te zien */ + fac= cam->drawsize; + if(G.vd->persp>=2) fac= cam->clipsta+0.1; + + depth= - fac*cam->lens/16.0; + facx= fac*1.28; + facy= fac*1.024; + + vec[0][0]= 0; vec[0][1]= 0; vec[0][2]= 0.001; /* GLBUG: z niet op nul vanwege picking op entry */ + vec[1][0]= facx; vec[1][1]= facy; vec[1][2]= depth; + vec[2][0]= facx; vec[2][1]= -facy; vec[2][2]= depth; + vec[3][0]= -facx; vec[3][1]= -facy; vec[3][2]= depth; + vec[4][0]= -facx; vec[4][1]= facy; vec[4][2]= depth; + + glBegin(GL_LINE_LOOP); + glVertex3fv(vec[0]); + glVertex3fv(vec[1]); + glVertex3fv(vec[2]); + glVertex3fv(vec[0]); + glVertex3fv(vec[3]); + glVertex3fv(vec[4]); + glEnd(); + + glBegin(GL_LINES); + glVertex3fv(vec[2]); + glVertex3fv(vec[3]); + glEnd(); + + glBegin(GL_LINES); + glVertex3fv(vec[4]); + glVertex3fv(vec[1]); + glEnd(); + + if(G.vd->persp>=2) return; + if(G.f & G_BACKBUFSEL) return; + + /* pijl aan top */ + vec[0][2]= depth; + + glBegin(GL_QUADS); + + vec[0][0]= -0.2*cam->drawsize; + vec[0][1]= cam->drawsize; + glVertex3fv(vec[0]); + + vec[0][0]= 0.2*cam->drawsize; + glVertex3fv(vec[0]); + + vec[0][1]= 1.6*cam->drawsize; + glVertex3fv(vec[0]); + + vec[0][0]= -0.2*cam->drawsize; + glVertex3fv(vec[0]); + glEnd(); + + glBegin(GL_TRIANGLES); + + vec[0][0]= -0.4*cam->drawsize; + vec[0][1]= 1.6*cam->drawsize; + glVertex3fv(vec[0]); + + vec[0][0]= 0.0; + vec[0][1]= 2.0*cam->drawsize; + glVertex3fv(vec[0]); + + vec[0][0]= 0.4*cam->drawsize; + vec[0][1]= 1.6*cam->drawsize; + glVertex3fv(vec[0]); + + glEnd(); + + if(cam->flag & (CAM_SHOWLIMITS+CAM_SHOWMIST)) { + myloadmatrix(G.vd->viewmat); + Mat4CpyMat4(vec, ob->obmat); + Mat4Ortho(vec); + mymultmatrix(vec); + + MTC_Mat4SwapMat4(G.vd->persmat, tmat); + mygetsingmatrix(G.vd->persmat); + + if(cam->flag & CAM_SHOWLIMITS) + draw_limit_line(cam->clipsta, cam->clipend, B_YELLOW); + + wrld= G.scene->world; + if(cam->flag & CAM_SHOWMIST) + if(wrld) draw_limit_line(wrld->miststa, wrld->miststa+wrld->mistdist, 0xFFFFFF); + + MTC_Mat4SwapMat4(G.vd->persmat, tmat); + } +} + +static void tekenvertslatt(short sel) +{ + Lattice *lt; + BPoint *bp; + int a, uxt, u, vxt, v, wxt, w; + + glPointSize(3.0); + + if(sel) cpack(B_YELLOW); + else cpack(B_PURPLE); + + glBegin(GL_POINTS); + + bp= editLatt->def; + lt= editLatt; + + if(lt->flag & LT_OUTSIDE) { + + for(w=0; w<lt->pntsw; w++) { + if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0; + for(v=0; v<lt->pntsv; v++) { + if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0; + + for(u=0; u<lt->pntsu; u++, bp++) { + if(u==0 || u==lt->pntsu-1) uxt= 1; else uxt= 0; + if(uxt || vxt || wxt) { + if(bp->hide==0) { + if((bp->f1 & 1)==sel) glVertex3fv(bp->vec); + } + } + } + } + } + } + else { + + a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + while(a--) { + if(bp->hide==0) { + if((bp->f1 & 1)==sel) glVertex3fv(bp->vec); + } + bp++; + } + } + + glPointSize(1.0); + glEnd(); +} + +static void calc_lattverts(void) +{ + BPoint *bp; + float mat[4][4]; + int a; + + MTC_Mat4SwapMat4(G.vd->persmat, mat); + mygetsingmatrix(G.vd->persmat); + + bp= editLatt->def; + + a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + while(a--) { + project_short(bp->vec, bp->s); + bp++; + } + + MTC_Mat4SwapMat4(G.vd->persmat, mat); +} + + +void calc_lattverts_ext(void) +{ + + areawinset(curarea->win); + mymultmatrix(G.obedit->obmat); + calc_lattverts(); + myloadmatrix(G.vd->viewmat); + +} + + +static void drawlattice(Object *ob) +{ + Lattice *lt; + BPoint *bp, *bpu; + int u, v, w, dv, dw, uxt, vxt, wxt; + + lt= ob->data; + if(ob==G.obedit) { + bp= editLatt->def; + + cpack(0x004000); + } + else { + bp= lt->def; + } + + dv= lt->pntsu; + dw= dv*lt->pntsv; + + if(lt->flag & LT_OUTSIDE) { + + for(w=0; w<lt->pntsw; w++) { + + if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0; + + for(v=0; v<lt->pntsv; v++) { + + if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0; + + for(u=0, bpu=0; u<lt->pntsu; u++, bp++) { + + if(u==0 || u==lt->pntsu-1) uxt= 1; else uxt= 0; + + if(uxt || vxt || wxt) { + + if(w && (uxt || vxt)) { + + glBegin(GL_LINE_STRIP); + glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec); + glEnd(); + } + if(v && (uxt || wxt)) { + + glBegin(GL_LINES); + glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec); + glEnd(); + } + if(u && (vxt || wxt)) { + + glBegin(GL_LINES); + glVertex3fv(bpu->vec); glVertex3fv(bp->vec); + glEnd(); + } + } + + bpu= bp; + } + } + } + } + else { + for(w=0; w<lt->pntsw; w++) { + + for(v=0; v<lt->pntsv; v++) { + + for(u=0, bpu=0; u<lt->pntsu; u++, bp++) { + + if(w) { + + glBegin(GL_LINES); + glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec); + glEnd(); + } + if(v) { + + glBegin(GL_LINES); + glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec); + glEnd(); + } + if(u) { + + glBegin(GL_LINES); + glVertex3fv(bpu->vec); glVertex3fv(bp->vec); + glEnd(); + } + bpu= bp; + } + } + } + } + + if(ob==G.obedit) { + + calc_lattverts(); + + if(G.zbuf) glDisable(GL_DEPTH_TEST); + + tekenvertslatt(0); + tekenvertslatt(1); + + if(G.zbuf) glEnable(GL_DEPTH_TEST); + } +} + +/* ***************** ******************** */ + +void calc_meshverts(void) +{ + EditVert *eve; + float mat[4][4]; + + if(G.edve.first==0) return; + eve= G.edve.first; + + MTC_Mat4SwapMat4(G.vd->persmat, mat); + mygetsingmatrix(G.vd->persmat); + + eve= G.edve.first; + while(eve) { + if(eve->h==0) { + project_short(eve->co, &(eve->xs)); + } + eve= eve->next; + } + MTC_Mat4SwapMat4(G.vd->persmat, mat); +} + +void calc_meshverts_ext(void) +{ + + areawinset(curarea->win); + mymultmatrix(G.obedit->obmat); + calc_meshverts(); + myloadmatrix(G.vd->viewmat); + +} + +static void calc_Nurbverts(Nurb *nurb) +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + float mat[4][4]; + int a; + + MTC_Mat4SwapMat4(G.vd->persmat, mat); + mygetsingmatrix(G.vd->persmat); + + nu= nurb; + while(nu) { + if((nu->type & 7)==1) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + project_short(bezt->vec[0], bezt->s[0]); + project_short(bezt->vec[1], bezt->s[1]); + project_short(bezt->vec[2], bezt->s[2]); + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + project_short(bp->vec, bp->s); + bp++; + } + } + nu= nu->next; + } + + MTC_Mat4SwapMat4(G.vd->persmat, mat); +} + +void calc_nurbverts_ext(void) +{ + + areawinset(curarea->win); + mymultmatrix(G.obedit->obmat); + calc_Nurbverts(editNurb.first); + myloadmatrix(G.vd->viewmat); + +} + +void tekenvertices(short sel) +{ + EditVert *eve; + + glPointSize(2.0); + + if(sel) cpack(B_YELLOW); + else cpack(B_PURPLE); +#ifdef __NLA /* __TEKENTEST */ +// if (sel==2) +// cpack (0x0000FF); +#endif /* __TEKENTEST */ + glBegin(GL_POINTS); + + eve= (EditVert *)G.edve.first; + while(eve) { + if(eve->h==0 && (eve->f & 1)==sel ) { + glVertex3fv(eve->co); + } +#ifdef __NLA /* __TEKENTEST */ +// if (eve->totweight && sel==2) +// glVertex3fv(eve->co); + +#endif /* __TEKENTEST */ + eve= eve->next; + } + glEnd(); + + glPointSize(1.0); +} + +void tekenvertices_ext(int mode) +{ + ScrArea *tempsa, *sa; + View3D *vd; + + if(G.f & (G_FACESELECT+G_DRAWFACES)) { + allqueue(REDRAWVIEW3D, 0); + return; + } + + if(G.zbuf) glDisable(GL_DEPTH_TEST); + + glDrawBuffer(GL_FRONT); + + /* alle views aflopen */ + tempsa= curarea; + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==SPACE_VIEW3D) { + vd= sa->spacedata.first; + if(G.obedit->lay & vd->lay) { + areawinset(sa->win); + mymultmatrix(G.obedit->obmat); + + calc_meshverts(); + if(mode==0 || mode==2) tekenvertices(0); + if(mode==1 || mode==2) tekenvertices(1); + sa->win_swap= WIN_FRONT_OK; + + myloadmatrix(G.vd->viewmat); + } + } + sa= sa->next; + } + if(curarea!=tempsa) areawinset(tempsa->win); + + glDrawBuffer(GL_BACK); + if(G.zbuf) glEnable(GL_DEPTH_TEST); +} + +/* ************** DRAW DISPLIST ****************** */ + + /* DispListMesh */ + +static void displistmesh_draw_wire(DispListMesh *dlm) { + int i; + + for (i=0; i<dlm->totface; i++) { + MFaceInt *mf= &dlm->mface[i]; + + glBegin(GL_LINE_LOOP); + glVertex3fv(dlm->mvert[mf->v1].co); + glVertex3fv(dlm->mvert[mf->v2].co); + if (mf->v3) { + glVertex3fv(dlm->mvert[mf->v3].co); + if (mf->v4) + glVertex3fv(dlm->mvert[mf->v4].co); + } + glEnd(); + } +} + +static void displistmesh_draw_solid(DispListMesh *dlm, int drawsmooth, float *nors) { + int lmode, lshademodel= -1, lmat_nr= -1; + int i; + +#define PASSVERT(ind) { \ + if (drawsmooth && lshademodel==GL_SMOOTH) \ + glNormal3sv(dlm->mvert[(ind)].no); \ + glVertex3fv(dlm->mvert[(ind)].co); \ +} + + glBegin(lmode= GL_QUADS); + for (i=0; i<dlm->totface; i++) { + MFaceInt *mf= &dlm->mface[i]; + + if (mf->v3) { + int nmode= mf->v4?GL_QUADS:GL_TRIANGLES; + + if (nmode!=lmode) { + glEnd(); + glBegin(lmode= nmode); + } + + if (drawsmooth) { + int nshademodel= (mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT; + + if (nshademodel!=lshademodel) { + glEnd(); + glShadeModel(lshademodel= nshademodel); + glBegin(lmode); + } + + if (mf->mat_nr!=lmat_nr) + set_gl_material((lmat_nr= mf->mat_nr)+1); + } + + if (drawsmooth && lshademodel==GL_FLAT) + glNormal3fv(&nors[i*3]); + + PASSVERT(mf->v1); + PASSVERT(mf->v2); + PASSVERT(mf->v3); + if (mf->v4) + PASSVERT(mf->v4); + } + } + glEnd(); + +#undef PASSVERT +} + +static void displistmesh_draw_shaded(DispListMesh *dlm, unsigned char *vcols1, unsigned char *vcols2) { + int i, lmode; + + glShadeModel(GL_SMOOTH); + if (vcols2) + glEnable(GL_CULL_FACE); + +#define PASSVERT(vidx, fidx) { \ + unsigned char *col= &colbase[fidx*4]; \ + glColor3ub(col[3], col[2], col[1]); \ + glVertex3fv(dlm->mvert[(vidx)].co); \ +} + + glBegin(lmode= GL_QUADS); + for (i=0; i<dlm->totface; i++) { + MFaceInt *mf= &dlm->mface[i]; + + if (mf->v3) { + int nmode= mf->v4?GL_QUADS:GL_TRIANGLES; + unsigned char *colbase= &vcols1[i*16]; + + if (nmode!=lmode) { + glEnd(); + glBegin(lmode= nmode); + } + + PASSVERT(mf->v1, 0); + PASSVERT(mf->v2, 1); + PASSVERT(mf->v3, 2); + if (mf->v4) + PASSVERT(mf->v4, 3); + + if (vcols2) { + unsigned char *colbase= &vcols2[i*16]; + + if (mf->v4) + PASSVERT(mf->v4, 3); + PASSVERT(mf->v3, 2); + PASSVERT(mf->v2, 1); + PASSVERT(mf->v1, 0); + } + } + } + glEnd(); + + if (vcols2) + glDisable(GL_CULL_FACE); + +#undef PASSVERT +} + + /***/ + +static int draw_index_wire= 1; +static int index3_nors_incr= 1; + +static void drawDispListwire(ListBase *dlbase) +{ + DispList *dl; + int parts, nr, ofs, *index; + float *data; + + if(dlbase==0) return; + + dl= dlbase->first; + while(dl) { + data= dl->verts; + + switch(dl->type) { + case DL_SEGM: + parts= dl->parts; + while(parts--) { + nr= dl->nr; + glBegin(GL_LINE_STRIP); + while(nr--) { + glVertex3fv(data); + data+=3; + } + glEnd(); + } + break; + case DL_POLY: + parts= dl->parts; + while(parts--) { + nr= dl->nr; + glBegin(GL_LINE_LOOP); + while(nr--) { + glVertex3fv(data); + data+=3; + } + glEnd(); + } + break; + case DL_SURF: + parts= dl->parts; + while(parts--) { + nr= dl->nr; + if(dl->flag & 1) glBegin(GL_LINE_LOOP); + else glBegin(GL_LINE_STRIP); + + while(nr--) { + glVertex3fv(data); + data+=3; + } + glEnd(); + } + ofs= 3*dl->nr; + nr= dl->nr; + while(nr--) { + data= ( dl->verts )+3*nr; + parts= dl->parts; + if(dl->flag & 2) glBegin(GL_LINE_LOOP); + else glBegin(GL_LINE_STRIP); + + while(parts--) { + glVertex3fv(data); + data+=ofs; + } + glEnd(); + } + break; + + case DL_INDEX3: + if(draw_index_wire) { + parts= dl->parts; + data= dl->verts; + index= dl->index; + while(parts--) { + + glBegin(GL_LINE_LOOP); + glVertex3fv(data+3*index[0]); + glVertex3fv(data+3*index[1]); + glVertex3fv(data+3*index[2]); + glEnd(); + index+= 3; + } + } + break; + + case DL_INDEX4: + if(draw_index_wire) { + parts= dl->parts; + data= dl->verts; + index= dl->index; + while(parts--) { + + glBegin(GL_LINE_LOOP); + glVertex3fv(data+3*index[0]); + glVertex3fv(data+3*index[1]); + glVertex3fv(data+3*index[2]); + if(index[3]) glVertex3fv(data+3*index[3]); + glEnd(); + index+= 4; + } + } + break; + + case DL_MESH: + displistmesh_draw_wire(dl->mesh); + break; + } + dl= dl->next; + } +} + +static void drawDispListsolid(ListBase *lb, Object *ob) +{ + DispList *dl; + int parts, ofs, p1, p2, p3, p4, a, b, *index; + float *data, *v1, *v2, *v3, *v4; + float *ndata, *n1, *n2, *n3, *n4; + int drawsmooth= !(G.f & G_BACKBUFSEL); + + if(lb==0) return; + if (drawsmooth) { + glShadeModel(GL_SMOOTH); + glEnable(GL_LIGHTING); + } + + dl= lb->first; + while(dl) { + data= dl->verts; + ndata= dl->nors; + + switch(dl->type) { + case DL_SURF: + if(!drawsmooth) { + for(a=0; a<dl->parts; a++) { + + DL_SURFINDEX(dl->flag & 1, dl->flag & 2, dl->nr, dl->parts); + + v1= data+ 3*p1; + v2= data+ 3*p2; + v3= data+ 3*p3; + v4= data+ 3*p4; + + glBegin(GL_QUAD_STRIP); + + glVertex3fv(v2); + glVertex3fv(v4); + + for(; b<dl->nr; b++) { + + glVertex3fv(v1); + glVertex3fv(v3); + + v2= v1; v1+= 3; + v4= v3; v3+= 3; + } + + + glEnd(); + } + } + else { + + set_gl_material(dl->col+1); +/* + glBegin(GL_LINES); + for(a=0; a<dl->parts*dl->nr; a++) { + float nor[3]; + + VECCOPY(nor, data+3*a); + glVertex3fv(nor); + VecAddf(nor, nor, ndata+3*a); + glVertex3fv(nor); + } + glEnd(); +*/ + for(a=0; a<dl->parts; a++) { + + DL_SURFINDEX(dl->flag & 1, dl->flag & 2, dl->nr, dl->parts); + + v1= data+ 3*p1; + v2= data+ 3*p2; + v3= data+ 3*p3; + v4= data+ 3*p4; + n1= ndata+ 3*p1; + n2= ndata+ 3*p2; + n3= ndata+ 3*p3; + n4= ndata+ 3*p4; + + glBegin(GL_QUAD_STRIP); + + glNormal3fv(n2); glVertex3fv(v2); + glNormal3fv(n4); glVertex3fv(v4); + + for(; b<dl->nr; b++) { + + glNormal3fv(n1); glVertex3fv(v1); + glNormal3fv(n3); glVertex3fv(v3); + + v2= v1; v1+= 3; + v4= v3; v3+= 3; + n2= n1; n1+= 3; + n4= n3; n3+= 3; + } + + + glEnd(); + } + } + break; + + case DL_INDEX3: + + parts= dl->parts; + data= dl->verts; + ndata= dl->nors; + index= dl->index; + + if(!drawsmooth) { + while(parts--) { + + glBegin(GL_TRIANGLES); + glVertex3fv(data+3*index[0]); + glVertex3fv(data+3*index[1]); + glVertex3fv(data+3*index[2]); + glEnd(); + index+= 3; + } + } + else { + + set_gl_material(dl->col+1); + + /* voor poly's is er maar 1 normaal nodig */ + if(index3_nors_incr==0) { + while(parts--) { + + glBegin(GL_TRIANGLES); + glNormal3fv(ndata); + glVertex3fv(data+3*index[0]); + glVertex3fv(data+3*index[1]); + glVertex3fv(data+3*index[2]); + glEnd(); + index+= 3; + } + } + else { + while(parts--) { + + glBegin(GL_TRIANGLES); + ofs= 3*index[0]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + ofs= 3*index[1]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + ofs= 3*index[2]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + glEnd(); + index+= 3; + } + } + } + break; + + case DL_INDEX4: + + parts= dl->parts; + data= dl->verts; + ndata= dl->nors; + index= dl->index; + + if(!drawsmooth) { + while(parts--) { + + glBegin(index[3]?GL_QUADS:GL_TRIANGLES); + glVertex3fv(data+3*index[0]); + glVertex3fv(data+3*index[1]); + glVertex3fv(data+3*index[2]); + if(index[3]) glVertex3fv(data+3*index[3]); + glEnd(); + index+= 4; + } + } + else { + + set_gl_material(dl->col+1); + + while(parts--) { + + glBegin(index[3]?GL_QUADS:GL_TRIANGLES); + ofs= 3*index[0]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + ofs= 3*index[1]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + ofs= 3*index[2]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + if(index[3]) { + ofs= 3*index[3]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + } + glEnd(); + index+= 4; + } + } + break; + + case DL_MESH: + if (!dl->nors) + addnormalsDispList(ob, lb); + displistmesh_draw_solid(dl->mesh, drawsmooth, dl->nors); + break; + + } + dl= dl->next; + } + + if(drawsmooth) { + glShadeModel(GL_FLAT); + glDisable(GL_LIGHTING); + } +} + +static void drawDispListshaded(ListBase *lb, Object *ob) +{ + DispList *dl, *dlob; + int parts, p1, p2, p3, p4, a, b, *index; + float *data, *v1, *v2, *v3, *v4;/* , *extverts=0 */ + unsigned int *cdata, *c1, *c2, *c3, *c4; + char *cp; + + if(lb==0) return; + + glShadeModel(GL_SMOOTH); + + dl= lb->first; + dlob= ob->disp.first; + while(dl && dlob) { + + cdata= dlob->col1; + data= dl->verts; + if(cdata==0) break; + + switch(dl->type) { + case DL_SURF: + + for(a=0; a<dl->parts; a++) { + + DL_SURFINDEX(dl->flag & 1, dl->flag & 2, dl->nr, dl->parts); + + v1= data+ 3*p1; + v2= data+ 3*p2; + v3= data+ 3*p3; + v4= data+ 3*p4; + c1= cdata+ p1; + c2= cdata+ p2; + c3= cdata+ p3; + c4= cdata+ p4; + + for(; b<dl->nr; b++) { + + glBegin(GL_QUADS); + cp= (char *)c1; + glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(v1); + cp= (char *)c2; + glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(v2); + cp= (char *)c4; + glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(v4); + cp= (char *)c3; + glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(v3); + glEnd(); + + v2= v1; v1+= 3; + v4= v3; v3+= 3; + c2= c1; c1++; + c4= c3; c3++; + } + } + break; + + case DL_INDEX3: + + parts= dl->parts; + index= dl->index; + + while(parts--) { + + glBegin(GL_TRIANGLES); + cp= (char *)(cdata+index[0]); + glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(data+3*index[0]); + + cp= (char *)(cdata+index[1]); + glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(data+3*index[1]); + + cp= (char *)(cdata+index[2]); + glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(data+3*index[2]); + glEnd(); + index+= 3; + } + break; + + case DL_INDEX4: + + parts= dl->parts; + index= dl->index; + while(parts--) { + + glBegin(index[3]?GL_QUADS:GL_TRIANGLES); + cp= (char *)(cdata+index[0]); + glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(data+3*index[0]); + + cp= (char *)(cdata+index[1]); + glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(data+3*index[1]); + + cp= (char *)(cdata+index[2]); + glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(data+3*index[2]); + + if(index[3]) { + + cp= (char *)(cdata+index[3]); + glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(data+3*index[3]); + } + glEnd(); + index+= 4; + } + break; + + case DL_MESH: + displistmesh_draw_shaded(dl->mesh, (unsigned char*) dlob->col1, (unsigned char*) dlob->col2); + break; + + } + dl= dl->next; + dlob= dlob->next; + } + + glShadeModel(GL_FLAT); +} + +static void drawmeshsolid(Object *ob, float *nors) +{ + Mesh *me; + DispList *dl; + MVert *mvert; + TFace *tface; + MFace *mface; + EditVlak *evl; + float *extverts=0, *v1, *v2, *v3, *v4; + int glmode, setsmooth=0, a, start, end, matnr= -1, vertexpaint, i; + short no[3], *n1, *n2, *n3, *n4 = NULL; + + vertexpaint= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0)); + + me= get_mesh(ob); + if(me==0) return; + + glShadeModel(GL_FLAT); + + if( (G.f & G_BACKBUFSEL)==0 ) { + glEnable(GL_LIGHTING); + init_gl_materials(ob); + two_sided( me->flag & ME_TWOSIDED ); + } + + mface= me->mface; + if( (G.f & G_FACESELECT) && ob==((G.scene->basact) ? (G.scene->basact->object) : 0)) tface= me->tface; + else tface= 0; + + mvert= me->mvert; + a= me->totface; + + /* SOLVE */ + /* if ELEM(ob->type, OB_SECTOR, OB_LIFE) glEnable(GL_CULL_FACE); */ + + if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) { + + evl= G.edvl.first; + while(evl) { + if(evl->v1->h==0 && evl->v2->h==0 && evl->v3->h==0) { + + if(evl->mat_nr!=matnr) { + matnr= evl->mat_nr; + set_gl_material(matnr+1); + } + + if(evl->v4 && evl->v4->h==0) { + + glBegin(GL_QUADS); + glNormal3fv(evl->n); + glVertex3fv(evl->v1->co); + glVertex3fv(evl->v2->co); + glVertex3fv(evl->v3->co); + glVertex3fv(evl->v4->co); + glEnd(); + } + else { + + glBegin(GL_TRIANGLES); + glNormal3fv(evl->n); + glVertex3fv(evl->v1->co); + glVertex3fv(evl->v2->co); + glVertex3fv(evl->v3->co); + glEnd(); + } + } + evl= evl->next; + } + + glDisable(GL_LIGHTING); + glShadeModel(GL_FLAT); + + if(ob==G.obedit) { + calc_meshverts(); + + if(G.zbuf) glDisable(GL_DEPTH_TEST); + tekenvertices(0); + tekenvertices(1); + if(G.zbuf) glEnable(GL_DEPTH_TEST); + } + + } + else { + + start= 0; end= me->totface; + set_buildvars(ob, &start, &end); + mface+= start; + if(tface) tface+= start; + + dl= find_displist(&ob->disp, DL_VERTS); + if(dl) extverts= dl->verts; + + glBegin(GL_QUADS); + glmode= GL_QUADS; + + for(a=start; a<end; a++, mface++, nors+=3) { + if(mface->v3) { + if(tface && (tface->flag & TF_HIDE)) { + if( (G.f & G_BACKBUFSEL)==0) { + glBegin(GL_LINE_LOOP); + glVertex3fv( (mvert+mface->v1)->co); + glVertex3fv( (mvert+mface->v2)->co); + glVertex3fv( (mvert+mface->v3)->co); + if(mface->v4) glVertex3fv( (mvert+mface->v1)->co); + glEnd(); + tface++; + } + } + else { + if(extverts) { + v1= extverts+3*mface->v1; + v2= extverts+3*mface->v2; + v3= extverts+3*mface->v3; + if(mface->v4) v4= extverts+3*mface->v4; + else v4= 0; + } + else { + v1= (mvert+mface->v1)->co; + v2= (mvert+mface->v2)->co; + v3= (mvert+mface->v3)->co; + if(mface->v4) v4= (mvert+mface->v4)->co; + else v4= 0; + } + + + if(tface) { + if(tface->mode & TF_TWOSIDE) glEnable(GL_CULL_FACE); + else glDisable(GL_CULL_FACE); + } + + + /* dit GL_QUADS grapje is op snelheid getest: factor 2! */ + + if(v4) {if(glmode==GL_TRIANGLES) {glmode= GL_QUADS; glEnd(); glBegin(GL_QUADS);}} + else {if(glmode==GL_QUADS) {glmode= GL_TRIANGLES; glEnd(); glBegin(GL_TRIANGLES);}} + + if(G.f & G_BACKBUFSEL) { + if(vertexpaint) { + i= index_to_framebuffer(a+1); + cpack(i); + } + + glVertex3fv( v1 ); + glVertex3fv( v2 ); + glVertex3fv( v3 ); + if(v4) glVertex3fv( v4 ); + + } + else { + + if(mface->mat_nr!=matnr) { + matnr= mface->mat_nr; + set_gl_material(matnr+1); + } + + if( (me->flag & ME_AUTOSMOOTH)==0 && (mface->flag & ME_SMOOTH)) { + if(setsmooth==0) { + glEnd(); + glShadeModel(GL_SMOOTH); + if(glmode==GL_TRIANGLES) glBegin(GL_TRIANGLES); + else glBegin(GL_QUADS); + setsmooth= 1; + } + n1= (mvert+mface->v1)->no; + n2= (mvert+mface->v2)->no; + n3= (mvert+mface->v3)->no; + if(v4) n4= (mvert+mface->v4)->no; + + if(mface->puno & ME_FLIPV1) { + no[0]= -n1[0]; no[1]= -n1[1]; no[2]= -n1[2]; + glNormal3sv(no); + } + else glNormal3sv(n1); + glVertex3fv( v1 ); + + if(mface->puno & ME_FLIPV2) { + no[0]= -n2[0]; no[1]= -n2[1]; no[2]= -n2[2]; + glNormal3sv(no); + } + else glNormal3sv(n2); + glVertex3fv( v2 ); + + if(mface->puno & ME_FLIPV3) { + no[0]= -n3[0]; no[1]= -n3[1]; no[2]= -n3[2]; + glNormal3sv(no); + } + else glNormal3sv(n3); + glVertex3fv( v3 ); + + if(v4) { + if(mface->puno & ME_FLIPV4) { + no[0]= -n4[0]; no[1]= -n4[1]; no[2]= -n4[2]; + glNormal3sv(no); + } + else glNormal3sv(n4); + glVertex3fv( v4 ); + } + } + else { + if(setsmooth==1) { + glEnd(); + glShadeModel(GL_FLAT); + if(glmode==GL_TRIANGLES) glBegin(GL_TRIANGLES); + else glBegin(GL_QUADS); + setsmooth= 0; + } + glNormal3fv(nors); + glVertex3fv( v1 ); + glVertex3fv( v2 ); + glVertex3fv( v3 ); + if(v4) glVertex3fv( v4 ); + } + } + } + if(tface) tface++; + } + } + + glEnd(); + } + + /* SOLVE */ +/* if ELEM(ob->type, OB_SECTOR, OB_LIFE) glDisable(GL_CULL_FACE); */ + + if(G.f & G_BACKBUFSEL) { + glDisable(GL_CULL_FACE); + } + glDisable(GL_LIGHTING); + +} + +static void drawmeshshaded(Object *ob, unsigned int *col1, unsigned int *col2) +{ + Mesh *me; + MVert *mvert; + MFace *mface; + TFace *tface; + DispList *dl; + float *extverts=0, *v1, *v2, *v3, *v4; + int a, start, end, twoside; + char *cp1, *cp2 = NULL; + int lglmode; + + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + + me= ob->data; + mface= me->mface; + + /* tekent ie geen hide */ + if( (G.f & G_FACESELECT) && ob==((G.scene->basact) ? (G.scene->basact->object) : 0)) tface= me->tface; + else tface= 0; + + mvert= me->mvert; + a= me->totface; + + twoside= me->flag & ME_TWOSIDED; + if(col2==0) twoside= 0; + + if(twoside) glEnable(GL_CULL_FACE); + + start= 0; end= me->totface; + set_buildvars(ob, &start, &end); + mface+= start; + if(tface) tface+= start; + col1+= 4*start; + if(col2) col2+= 4*start; + + dl= find_displist(&ob->disp, DL_VERTS); + if(dl) extverts= dl->verts; + + glBegin(lglmode= GL_QUADS); + + cp1= (char *)col1; + if(col2) cp2= (char *)col2; + + for(a=start; a<end; a++, mface++, cp1+= 16) { + if(mface->v3) { + if(tface && (tface->flag & TF_HIDE)) tface++; + else { + int nglmode= mface->v4?GL_QUADS:GL_TRIANGLES; + + if (nglmode!=lglmode) { + glEnd(); + glBegin(lglmode= nglmode); + } + + if(extverts) { + v1= extverts+3*mface->v1; + v2= extverts+3*mface->v2; + v3= extverts+3*mface->v3; + if(mface->v4) v4= extverts+3*mface->v4; + else v4= 0; + } + else { + v1= (mvert+mface->v1)->co; + v2= (mvert+mface->v2)->co; + v3= (mvert+mface->v3)->co; + if(mface->v4) v4= (mvert+mface->v4)->co; + else v4= 0; + } + + if(tface) { + if(tface->mode & TF_TWOSIDE) glEnable(GL_CULL_FACE); + else glDisable(GL_CULL_FACE); + } + + glColor3ub(cp1[3], cp1[2], cp1[1]); + glVertex3fv( v1 ); + glColor3ub(cp1[7], cp1[6], cp1[5]); + glVertex3fv( v2 ); + glColor3ub(cp1[11], cp1[10], cp1[9]); + glVertex3fv( v3 ); + if(v4) { + glColor3ub(cp1[15], cp1[14], cp1[13]); + glVertex3fv( v4 ); + } + + if(twoside) { + + glColor3ub(cp2[11], cp2[10], cp2[9]); + glVertex3fv( v3 ); + glColor3ub(cp2[7], cp2[6], cp2[5]); + glVertex3fv( v2 ); + glColor3ub(cp2[3], cp2[2], cp2[1]); + glVertex3fv( v1 ); + if(mface->v4) { + glColor3ub(cp2[15], cp2[14], cp2[13]); + glVertex3fv( v4 ); + } + } + } + } + if(col2) cp2+= 16; + } + + glEnd(); + glShadeModel(GL_FLAT); + if(twoside) glDisable(GL_CULL_FACE); + +} + +static void drawDispList(Object *ob, int dt) +{ + ListBase *lb=0; + DispList *dl; + Mesh *me; + int solid; + + + solid= (dt > OB_WIRE); + + switch(ob->type) { + case OB_MESH: + + me= get_mesh(ob); + if(me==0) return; + + if(me->bb==0) tex_space_mesh(me); + if(me->totface>4) if(boundbox_clip(ob->obmat, me->bb)==0) return; + + + + if(dt==OB_SOLID ) { + + lb= &me->disp; + if(lb->first==0) addnormalsDispList(ob, lb); + + dl= lb->first; + if(dl==0) return; + + if(mesh_uses_displist(me)) { + int vertexpaint= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0)); + + /* vertexpaint only true when selecting */ + if (vertexpaint) + drawmeshsolid(ob, NULL); + else { + init_gl_materials(ob); + two_sided(me->flag & ME_TWOSIDED); + drawDispListsolid(lb, ob); + } + } + else drawmeshsolid(ob, dl->nors); + + } + else if(dt==OB_SHADED) { +#ifdef __NLA + if( G.f & G_WEIGHTPAINT && me->dvert) { + unsigned char *wtcol, *curwt; + MFace *curface; + int i; + unsigned char r,g,b; + float val1,val2,val3,val4; + + wtcol = curwt= MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap"); + + memset (wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4); + for (i=0, curface=(MFace*)me->mface; i<me->totface; i++, curface++){ + + val1 = get_mvert_weight (ob, curface->v1, ob->actdef-1); + val2 = get_mvert_weight (ob, curface->v2, ob->actdef-1); + val3 = get_mvert_weight (ob, curface->v3, ob->actdef-1); + if (curface->v4) + val4 = get_mvert_weight (ob, curface->v4, ob->actdef-1); + + color_temperature (val1, &r, &g, &b); + *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r; + color_temperature (val2, &r, &g, &b); + *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r; + color_temperature (val3, &r, &g, &b); + *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r; + color_temperature (val4, &r, &g, &b); + *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r; + + } + + drawmeshshaded(ob, (unsigned int*)wtcol, 0); + MEM_freeN (wtcol); + + } + else +#endif + if( G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) { + /* in deze volgorde: vertexpaint heeft soms al mcol gemaakt */ +///* + +//*/ + if(me->mcol) + drawmeshshaded(ob, (unsigned int *)me->mcol, 0); + else if(me->tface) { + tface_to_mcol(me); + drawmeshshaded(ob, (unsigned int *)me->mcol, 0); + MEM_freeN(me->mcol); me->mcol= 0; + } + else + drawmeshwire(ob); + + } + else { + dl= ob->disp.first; + + if(dl==0 || dl->col1==0) { + shadeDispList(ob); + dl= ob->disp.first; + } + if(dl) { + if(mesh_uses_displist(me)) + drawDispListshaded(&me->disp, ob); + else + drawmeshshaded(ob, dl->col1, dl->col2); + } + } + } + + if(ob==((G.scene->basact) ? (G.scene->basact->object) : 0) && (G.f & G_FACESELECT)) { + draw_tfaces3D(ob, me); + } + + break; + + case OB_FONT: + case OB_CURVE: + + lb= &((Curve *)ob->data)->disp; + if(lb->first==0) makeDispList(ob); + + if(solid && ob!=G.obedit) { + dl= lb->first; + if(dl==0) return; + + /* regel: dl->type INDEX3 altijd vooraan in lijst */ + if(dl->type!=DL_INDEX3) { + curve_to_filledpoly(ob->data, lb); + dl= lb->first; + } + if(dl->nors==0) addnormalsDispList(ob, lb); + + index3_nors_incr= 0; + + if(dt==OB_SHADED) { + if(ob->disp.first==0) shadeDispList(ob); + drawDispListshaded(lb, ob); + } + else { + init_gl_materials(ob); + two_sided(0); + drawDispListsolid(lb, ob); + } + index3_nors_incr= 1; + } + else { + draw_index_wire= 0; + drawDispListwire(lb); + draw_index_wire= 1; + } + break; + case OB_SURF: + + lb= &((Curve *)ob->data)->disp; + if(lb->first==0) makeDispList(ob); + + if(solid) { + dl= lb->first; + if(dl==0) return; + + if(dl->nors==0) addnormalsDispList(ob, lb); + + if(dt==OB_SHADED) { + if(ob->disp.first==0) shadeDispList(ob); + drawDispListshaded(lb, ob); + } + else { + init_gl_materials(ob); + two_sided(0); + + drawDispListsolid(lb, ob); + } + } + else { + drawDispListwire(lb); + } + break; + case OB_MBALL: + + lb= &ob->disp; + if(lb->first==0) makeDispList(ob); + + if(solid) { + + if(dt==OB_SHADED) { + dl= lb->first; + if(dl && dl->col1==0) shadeDispList(ob); + drawDispListshaded(lb, ob); + } + else { + init_gl_materials(ob); + two_sided(0); + + drawDispListsolid(lb, ob); + } + } + else drawDispListwire(lb); + break; + } + +} + +/* ******************************** */ + + +static void draw_particle_system(Object *ob, PartEff *paf) +{ + Particle *pa; + float ptime, ctime, vec[3], vec1[3]; + int a; + + pa= paf->keys; + if(pa==0) { + build_particle_system(ob); + pa= paf->keys; + if(pa==0) return; + } + + myloadmatrix(G.vd->viewmat); + + if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf; + else ptime= 0.0; + ctime= bsystem_time(ob, 0, (float)(G.scene->r.cfra), ptime); + + glPointSize(1.0); + if(paf->stype!=PAF_VECT) glBegin(GL_POINTS); + + for(a=0; a<paf->totpart; a++, pa+=paf->totkey) { + + if(ctime > pa->time) { + if(ctime < pa->time+pa->lifetime) { + + if(paf->stype==PAF_VECT) { + where_is_particle(paf, pa, ctime, vec); + where_is_particle(paf, pa, ctime+1.0, vec1); + + + glBegin(GL_LINE_STRIP); + glVertex3fv(vec); + glVertex3fv(vec1); + glEnd(); + + } + else { + where_is_particle(paf, pa, ctime, vec); + + glVertex3fv(vec); + + } + } + } + } + if(paf->stype!=PAF_VECT) glEnd(); + +} + +static void draw_static_particle_system(Object *ob, PartEff *paf) +{ + Particle *pa; + float ctime, mtime, vec[3], vec1[3]; + int a; + + pa= paf->keys; + if(pa==0) { + build_particle_system(ob); + pa= paf->keys; + if(pa==0) return; + } + + glPointSize(1.0); + if(paf->stype!=PAF_VECT) glBegin(GL_POINTS); + + for(a=0; a<paf->totpart; a++, pa+=paf->totkey) { + + where_is_particle(paf, pa, pa->time, vec1); + + mtime= pa->time+pa->lifetime+paf->staticstep-1; + + for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) { + + /* make sure hair grows until the end.. */ + if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime; + + if(paf->stype==PAF_VECT) { + where_is_particle(paf, pa, ctime+1, vec); + + glBegin(GL_LINE_STRIP); + glVertex3fv(vec); + glVertex3fv(vec1); + glEnd(); + + VECCOPY(vec1, vec); + } + else { + where_is_particle(paf, pa, ctime, vec); + + glVertex3fv(vec); + + } + } + } + if(paf->stype!=PAF_VECT) glEnd(); + +} + +static void drawmeshwire(Object *ob) +{ + extern float editbutsize; /* buttons.c */ + Mesh *me; + MVert *mvert; + MFace *mface; + DispList *dl; + Material *ma; + EditEdge *eed; + EditVlak *evl; + float fvec[3], cent[3], *f1, *f2, *f3, *f4, *extverts=0; + int a, start, end, test, /* colbcol=0, */ ok; + + me= get_mesh(ob); + + if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) { + + if(G.zbuf==0 && mesh_uses_displist(me)) { + cpack(0x505050); + drawDispListwire(&me->disp); + } + cpack(0x0); + + eed= G.eded.first; + + glBegin(GL_LINES); + while(eed) { + if(eed->h==0) { + glVertex3fv(eed->v1->co); + glVertex3fv(eed->v2->co); + } + eed= eed->next; + } + glEnd(); + + if(ob!=G.obedit) return; + + calc_meshverts(); + + if(G.zbuf) glDisable(GL_DEPTH_TEST); + tekenvertices(0); + tekenvertices(1); +#ifdef __NLA + tekenvertices(2); /* __TEKENTEST */ +#endif + if(G.zbuf) glEnable(GL_DEPTH_TEST); + + if(G.f & G_DRAWNORMALS) { /* normals */ + cpack(0xDDDD22); + + glBegin(GL_LINES); + + evl= G.edvl.first; + while(evl) { + if(evl->v1->h==0 && evl->v2->h==0 && evl->v3->h==0) { + if(evl->v4) CalcCent4f(fvec, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co); + else CalcCent3f(fvec, evl->v1->co, evl->v2->co, evl->v3->co); + + glVertex3fv(fvec); + fvec[0]+= editbutsize*evl->n[0]; + fvec[1]+= editbutsize*evl->n[1]; + fvec[2]+= editbutsize*evl->n[2]; + glVertex3fv(fvec); + + } + evl= evl->next; + } + + glEnd(); + } + if(G.f & (G_FACESELECT+G_DRAWFACES)) { /* vlakken */ + + evl= G.edvl.first; + while(evl) { + if(evl->v1->h==0 && evl->v2->h==0 && evl->v3->h==0) { + + if(vlakselectedAND(evl, 1)) cpack(0x559999); + else cpack(0x664466); + + if(evl->v4 && evl->v4->h==0) { + + CalcCent4f(cent, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co); + glBegin(GL_LINE_LOOP); + VecMidf(fvec, cent, evl->v1->co); glVertex3fv(fvec); + VecMidf(fvec, cent, evl->v2->co); glVertex3fv(fvec); + VecMidf(fvec, cent, evl->v3->co); glVertex3fv(fvec); + VecMidf(fvec, cent, evl->v4->co); glVertex3fv(fvec); + glEnd(); + } + else { + + CalcCent3f(cent, evl->v1->co, evl->v2->co, evl->v3->co); + glBegin(GL_LINE_LOOP); + VecMidf(fvec, cent, evl->v1->co); glVertex3fv(fvec); + VecMidf(fvec, cent, evl->v2->co); glVertex3fv(fvec); + VecMidf(fvec, cent, evl->v3->co); glVertex3fv(fvec); + glEnd(); + } + } + evl= evl->next; + } + } + } + else { + + if(me==0) return; + + if(me->bb==0) tex_space_mesh(me); + if(me->totface>4) if(boundbox_clip(ob->obmat, me->bb)==0) return; + + if(mesh_uses_displist(me)) drawDispListwire(&me->disp); + else { + + mvert= me->mvert; + mface= me->mface; + + ok= 0; + if(me->totface==0) ok= 1; + else { + ma= give_current_material(ob, 1); + if(ma && (ma->mode & MA_HALO)) ok= 1; + } + + dl= find_displist(&ob->disp, DL_VERTS); + if(dl) extverts= dl->verts; + + if(ok) { + + start= 0; end= me->totvert; + set_buildvars(ob, &start, &end); + + glPointSize(1.5); + glBegin(GL_POINTS); + + if(extverts) { + extverts+= 3*start; + for(a= start; a<end; a++, extverts+=3) { + glVertex3fv(extverts); + } + } + else { + mvert+= start; + for(a= start; a<end; a++, mvert++) { + glVertex3fv(mvert->co); + } + } + + glEnd(); + glPointSize(1.0); + } + else { + + start= 0; end= me->totface; + set_buildvars(ob, &start, &end); + mface+= start; + + for(a=start; a<end; a++, mface++) { + test= mface->edcode; + + if(test) { + if(extverts) { + f1= extverts+3*mface->v1; + f2= extverts+3*mface->v2; + } + else { + f1= (mvert+mface->v1)->co; + f2= (mvert+mface->v2)->co; + } + + if(mface->v4) { + if(extverts) { + f3= extverts+3*mface->v3; + f4= extverts+3*mface->v4; + } + else { + f3= (mvert+mface->v3)->co; + f4= (mvert+mface->v4)->co; + } + + if(test== ME_V1V2+ME_V2V3+ME_V3V4+ME_V4V1) { + glBegin(GL_LINE_LOOP); + glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4); + glEnd(); + } + else if(test== ME_V1V2+ME_V2V3+ME_V3V4) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4); + glEnd(); + } + else if(test== ME_V2V3+ME_V3V4+ME_V4V1) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4); glVertex3fv(f1); + glEnd(); + } + else if(test== ME_V3V4+ME_V4V1+ME_V1V2) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f3); glVertex3fv(f4); glVertex3fv(f1); glVertex3fv(f2); + glEnd(); + } + else if(test== ME_V4V1+ME_V1V2+ME_V2V3) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f4); glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3); + glEnd(); + } + else { + if(test & ME_V1V2) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f1); glVertex3fv(f2); + glEnd(); + } + if(test & ME_V2V3) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f2); glVertex3fv(f3); + glEnd(); + } + if(test & ME_V3V4) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f3); glVertex3fv(f4); + glEnd(); + } + if(test & ME_V4V1) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f4); glVertex3fv(f1); + glEnd(); + } + } + } + else if(mface->v3) { + if(extverts) f3= extverts+3*mface->v3; + else f3= (mvert+mface->v3)->co; + + if(test== ME_V1V2+ME_V2V3+ME_V3V1) { + glBegin(GL_LINE_LOOP); + glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3); + glEnd(); + } + else if(test== ME_V1V2+ME_V2V3) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3); + glEnd(); + } + else if(test== ME_V2V3+ME_V3V1) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f1); + glEnd(); + } + else if(test== ME_V1V2+ME_V3V1) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f3); glVertex3fv(f1); glVertex3fv(f2); + glEnd(); + } + else { + if(test & ME_V1V2) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f1); glVertex3fv(f2); + glEnd(); + } + if(test & ME_V2V3) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f2); glVertex3fv(f3); + glEnd(); + } + if(test & ME_V3V1) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f3); glVertex3fv(f1); + glEnd(); + } + } + } + else if(test & ME_V1V2) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(f1); glVertex3fv(f2); + glEnd(); + } + } + } + } + + } + } +} + +unsigned int nurbcol[8]= { + 0, 0x9090, 0x409030, 0x603080, 0, 0x40fff0, 0x40c033, 0xA090F0 }; + +static void tekenhandlesN(Nurb *nu, short sel) +{ + BezTriple *bezt; + float *fp; + unsigned int *col; + int a; + + if(nu->hide) return; + if( (nu->type & 7)==1) { + if(sel) col= nurbcol+4; + else col= nurbcol; + + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(bezt->hide==0) { + if( (bezt->f2 & 1)==sel) { + fp= bezt->vec[0]; + cpack(col[bezt->h1]); + + glBegin(GL_LINE_STRIP); + glVertex3fv(fp); + glVertex3fv(fp+3); + glEnd(); + cpack(col[bezt->h2]); + + glBegin(GL_LINE_STRIP); + glVertex3fv(fp+3); + glVertex3fv(fp+6); + glEnd(); + } + else if( (bezt->f1 & 1)==sel) { + fp= bezt->vec[0]; + cpack(col[bezt->h1]); + + glBegin(GL_LINE_STRIP); + glVertex3fv(fp); + glVertex3fv(fp+3); + glEnd(); + } + else if( (bezt->f3 & 1)==sel) { + fp= bezt->vec[1]; + cpack(col[bezt->h2]); + + glBegin(GL_LINE_STRIP); + glVertex3fv(fp); + glVertex3fv(fp+3); + glEnd(); + } + } + bezt++; + } + } +} + +static void tekenvertsN(Nurb *nu, short sel) +{ + BezTriple *bezt; + BPoint *bp; + int a; + + if(nu->hide) return; + + if(sel) cpack(B_YELLOW); + else cpack(B_PURPLE); + glPointSize(3.0); + + glBegin(GL_POINTS); + + if((nu->type & 7)==1) { + + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(bezt->hide==0) { + if((bezt->f1 & 1)==sel) glVertex3fv(bezt->vec[0]); + if((bezt->f2 & 1)==sel) glVertex3fv(bezt->vec[1]); + if((bezt->f3 & 1)==sel) glVertex3fv(bezt->vec[2]); + } + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->hide==0) { + if((bp->f1 & 1)==sel) glVertex3fv(bp->vec); + } + bp++; + } + } + + glEnd(); + glPointSize(1.0); +} + +static void draw_editnurb(Object *ob, Nurb *nurb, int sel) +{ + Nurb *nu; + BPoint *bp, *bp1; + int a, b, ofs; + + nu= nurb; + while(nu) { + if(nu->hide==0) { + switch(nu->type & 7) { + case CU_POLY: + cpack(nurbcol[3]); + bp= nu->bp; + for(b=0; b<nu->pntsv; b++) { + if(nu->flagu & 1) glBegin(GL_LINE_LOOP); + + else glBegin(GL_LINE_STRIP); + + for(a=0; a<nu->pntsu; a++, bp++) { + glVertex3fv(bp->vec); + } + + if(nu->flagu & 1) glEnd(); + else glEnd(); + } + break; + case CU_NURBS: + + bp= nu->bp; + for(b=0; b<nu->pntsv; b++) { + bp1= bp; + bp++; + for(a=nu->pntsu-1; a>0; a--, bp++) { + if(bp->hide==0 && bp1->hide==0) { + if(sel) { + if( (bp->f1 & 1) && ( bp1->f1 & 1) ) { + cpack(nurbcol[5]); + + glBegin(GL_LINE_STRIP); + glVertex3fv(bp->vec); + glVertex3fv(bp1->vec); + glEnd(); + } + } + else { + if( (bp->f1 & 1) && ( bp1->f1 & 1) ); + else { + cpack(nurbcol[1]); + + glBegin(GL_LINE_STRIP); + glVertex3fv(bp->vec); + glVertex3fv(bp1->vec); + glEnd(); + } + } + } + bp1= bp; + } + } + if(nu->pntsv > 1) { /* surface */ + + ofs= nu->pntsu; + for(b=0; b<nu->pntsu; b++) { + bp1= nu->bp+b; + bp= bp1+ofs; + for(a=nu->pntsv-1; a>0; a--, bp+=ofs) { + if(bp->hide==0 && bp1->hide==0) { + if(sel) { + if( (bp->f1 & 1) && ( bp1->f1 & 1) ) { + cpack(nurbcol[7]); + + glBegin(GL_LINE_STRIP); + glVertex3fv(bp->vec); + glVertex3fv(bp1->vec); + glEnd(); + } + } + else { + if( (bp->f1 & 1) && ( bp1->f1 & 1) ); + else { + cpack(nurbcol[3]); + + glBegin(GL_LINE_STRIP); + glVertex3fv(bp->vec); + glVertex3fv(bp1->vec); + glEnd(); + } + } + } + bp1= bp; + } + } + + } + break; + } + } + nu= nu->next; + } +} + +static void drawnurb(Object *ob, Nurb *nurb, int dt) +{ + extern float editbutsize; /* buttons.c */ + Curve *cu; + Nurb *nu; + BevPoint *bevp; + BevList *bl; + float vec[3]; + int a, nr, skip; + + /* eerst handles niet select */ + nu= nurb; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + tekenhandlesN(nu, 0); + } + nu= nu->next; + } + + /* dan DispList */ + + cpack(0); + cu= ob->data; + drawDispList(ob, dt); + + draw_editnurb(ob, nurb, 0); + draw_editnurb(ob, nurb, 1); + + if(cu->flag & CU_3D) { + + if(cu->bev.first==0) makeBevelList(ob); + + cpack(0x0); + bl= cu->bev.first; + nu= nurb; + while(nu && bl) { + bevp= (BevPoint *)(bl+1); + nr= bl->nr; + + skip= nu->resolu/16; + + while(nr-- > 0) { + + glBegin(GL_LINE_STRIP); + vec[0]= bevp->x-editbutsize*bevp->mat[0][0]; + vec[1]= bevp->y-editbutsize*bevp->mat[0][1]; + vec[2]= bevp->z-editbutsize*bevp->mat[0][2]; + glVertex3fv(vec); + vec[0]= bevp->x+editbutsize*bevp->mat[0][0]; + vec[1]= bevp->y+editbutsize*bevp->mat[0][1]; + vec[2]= bevp->z+editbutsize*bevp->mat[0][2]; + glVertex3fv(vec); + + glEnd(); + + bevp++; + + a= skip; + while(a--) { + bevp++; + nr--; + } + } + + bl= bl->next; + nu= nu->next; + } + } + + calc_Nurbverts(nurb); + + if(G.zbuf) glDisable(GL_DEPTH_TEST); + + nu= nurb; + while(nu) { + if((nu->type & 7)==1) tekenhandlesN(nu, 1); + tekenvertsN(nu, 0); + nu= nu->next; + } + + nu= nurb; + while(nu) { + tekenvertsN(nu, 1); + nu= nu->next; + } + + if(G.zbuf) glEnable(GL_DEPTH_TEST); +} + +static void tekentextcurs(void) +{ + cpack(0); + + glBegin(GL_QUADS); + glVertex2fv(G.textcurs[0]); + glVertex2fv(G.textcurs[1]); + glVertex2fv(G.textcurs[2]); + glVertex2fv(G.textcurs[3]); + glEnd(); +} + +void drawcircball(float *cent, float rad, float tmat[][4]) +{ + float si, co, phi, dphi, vec[3], vx[3], vy[3]; + int a, tot=32; + + VECCOPY(vx, tmat[0]); + VECCOPY(vy, tmat[1]); + VecMulf(vx, rad); + VecMulf(vy, rad); + + dphi= 2.0*M_PI/tot; + phi= 0.0; + + glBegin(GL_LINE_LOOP); + for(a=0; a<tot; a++, phi+= dphi) { + si= sin(phi); + co= cos(phi); + vec[0]= cent[0]+si*vx[0]+co*vy[0]; + vec[1]= cent[1]+si*vx[1]+co*vy[1]; + vec[2]= cent[2]+si*vx[2]+co*vy[2]; + glVertex3fv(vec); + } + glEnd(); +} + +static void drawmball(Object *ob, int dt) +{ + MetaBall *mb; + MetaElem *ml; + float imat[4][4], tmat[4][4]; + int code= 1; + + mb= ob->data; + + if(ob==G.obedit) { + cpack(0x0); + if((G.f & G_PICKSEL)==0 ) drawDispList(ob, dt); + ml= editelems.first; + } + else { + drawDispList(ob, dt); + ml= mb->elems.first; + } + + mygetmatrix(tmat); + Mat4Invert(imat, tmat); + Normalise(imat[0]); + Normalise(imat[1]); + + while(ml) { + + if(ob==G.obedit) { + if(ml->flag & SELECT) cpack(0xA0A0F0); + else cpack(0x3030A0); + + if(G.f & G_PICKSEL) { + ml->selcol= code; + glLoadName(code++); + } + } + drawcircball(&(ml->x), ml->rad, imat); + + ml= ml->next; + } + +} + +static void draw_bb_box(BoundBox *bb) +{ + float *vec; + + vec= bb->vec[0]; + + glBegin(GL_LINE_STRIP); + glVertex3fv(vec); glVertex3fv(vec+3);glVertex3fv(vec+6); glVertex3fv(vec+9); + glVertex3fv(vec); glVertex3fv(vec+12);glVertex3fv(vec+15); glVertex3fv(vec+18); + glVertex3fv(vec+21); glVertex3fv(vec+12); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(vec+3); glVertex3fv(vec+15); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(vec+6); glVertex3fv(vec+18); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(vec+9); glVertex3fv(vec+21); + glEnd(); + +} + +void get_local_bounds(Object *ob, float *centre, float *size) +{ + BoundBox *bb= NULL; + /* uses boundbox, function used by Ketsji */ + + if(ob->type==OB_MESH) { + bb= ( (Mesh *)ob->data )->bb; + if(bb==0) { + tex_space_mesh(ob->data); + bb= ( (Mesh *)ob->data )->bb; + } + } + else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) { + bb= ( (Curve *)ob->data )->bb; + } + else if(ob->type==OB_MBALL) { + bb= ob->bb; + } + if(bb==NULL) { + centre[0]= centre[1]= centre[2]= 0.0; + VECCOPY(size, ob->size); + } + else { + size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]); + size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]); + size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]); + + centre[0]= (bb->vec[0][0] + bb->vec[4][0])/2.0; + centre[1]= (bb->vec[0][1] + bb->vec[2][1])/2.0; + centre[2]= (bb->vec[0][2] + bb->vec[1][2])/2.0; + } +} + + + +static void draw_bb_quadric(BoundBox *bb, short type) +{ + float size[3], cent[3]; + GLUquadricObj *qobj = gluNewQuadric(); + + gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); + + size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]); + size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]); + size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]); + + cent[0]= (bb->vec[0][0] + bb->vec[4][0])/2.0; + cent[1]= (bb->vec[0][1] + bb->vec[2][1])/2.0; + cent[2]= (bb->vec[0][2] + bb->vec[1][2])/2.0; + + if(type==OB_BOUND_SPHERE) { + glTranslatef(cent[0], cent[1], cent[2]); + glScalef(size[0], size[1], size[2]); + gluSphere(qobj, 1.0, 8, 5); + } + else if(type==OB_BOUND_CYLINDER) { + glTranslatef(cent[0], cent[1], cent[2]-size[2]); + glScalef(size[0], size[1], 2.0*size[2]); + gluCylinder(qobj, 1.0, 1.0, 1.0, 8, 1); + } + else if(type==OB_BOUND_CONE) { + glTranslatef(cent[0], cent[1], cent[2]-size[2]); + glScalef(size[0], size[1], 2.0*size[2]); + gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1); + } + + gluDeleteQuadric(qobj); +} + +static void draw_bounding_volume(Object *ob) +{ + BoundBox *bb=0; + + if(ob->type==OB_MESH) { + bb= ( (Mesh *)ob->data )->bb; + if(bb==0) { + tex_space_mesh(ob->data); + bb= ( (Mesh *)ob->data )->bb; + } + } + else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) { + bb= ( (Curve *)ob->data )->bb; + if(bb==0) { + makeDispList(ob); + bb= ( (Curve *)ob->data )->bb; + } + } + else if(ob->type==OB_MBALL) { + bb= ob->bb; + if(bb==0) { + makeDispList(ob); + bb= ob->bb; + } + } + else { + drawcube(); + return; + } + + if(bb==0) return; + + if(ob->boundtype==OB_BOUND_BOX) draw_bb_box(bb); + else draw_bb_quadric(bb, ob->boundtype); + +} + +static void drawtexspace(Object *ob) +{ + Mesh *me; + MetaBall *mb; + Curve *cu; + BoundBox bb; + float *vec, *loc, *size; + + if(ob->type==OB_MESH) { + me= ob->data; + size= me->size; + loc= me->loc; + } + else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) { + cu= ob->data; + size= cu->size; + loc= cu->loc; + } + else if(ob->type==OB_MBALL) { + mb= ob->data; + size= mb->size; + loc= mb->loc; + } + else return; + + bb.vec[0][0]=bb.vec[1][0]=bb.vec[2][0]=bb.vec[3][0]= loc[0]-size[0]; + bb.vec[4][0]=bb.vec[5][0]=bb.vec[6][0]=bb.vec[7][0]= loc[0]+size[0]; + + bb.vec[0][1]=bb.vec[1][1]=bb.vec[4][1]=bb.vec[5][1]= loc[1]-size[1]; + bb.vec[2][1]=bb.vec[3][1]=bb.vec[6][1]=bb.vec[7][1]= loc[1]+size[1]; + + bb.vec[0][2]=bb.vec[3][2]=bb.vec[4][2]=bb.vec[7][2]= loc[2]-size[2]; + bb.vec[1][2]=bb.vec[2][2]=bb.vec[5][2]=bb.vec[6][2]= loc[2]+size[2]; + + setlinestyle(2); + + vec= bb.vec[0]; + + glBegin(GL_LINE_STRIP); + glVertex3fv(vec); glVertex3fv(vec+3);glVertex3fv(vec+6); glVertex3fv(vec+9); + glVertex3fv(vec); glVertex3fv(vec+12);glVertex3fv(vec+15); glVertex3fv(vec+18); + glVertex3fv(vec+21); glVertex3fv(vec+12); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(vec+3); glVertex3fv(vec+15); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(vec+6); glVertex3fv(vec+18); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(vec+9); glVertex3fv(vec+21); + glEnd(); + + setlinestyle(0); +} + +static int ob_from_decimator(Object *ob) +{ + /* note: this is a temporal solution, a reconstruction of the + displist system should take care of it (ton) + */ + DispList *dl; + + dl= ob->disp.first; + + if(dl && dl->mesh) return 1; + + return 0; +} + +void draw_object(Base *base) +{ + PartEff *paf; + Object *ob; + Curve *cu; + Mesh *me; + ListBase elems; + CfraElem *ce; + float cfraont, axsize=1.0; + unsigned int *rect, col=0; + static int warning_recursive= 0; + int sel, drawtype, colindex= 0, ipoflag; + short dt, dtx, zbufoff= 0; + + ob= base->object; + + /* keys tekenen? */ + if(base==(G.scene->basact) || (base->flag & (SELECT+BA_WASSEL))) { + if(warning_recursive==0 && ob!=G.obedit) { + if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { + float temp[7][3]; + + warning_recursive= 1; + + elems.first= elems.last= 0; + make_cfra_list(ob->ipo, &elems); + + cfraont= (G.scene->r.cfra); + drawtype= G.vd->drawtype; + if(drawtype>OB_WIRE) G.vd->drawtype= OB_WIRE; + sel= base->flag; + memcpy(temp, &ob->loc, 7*3*sizeof(float)); + + ipoflag= ob->ipoflag; + ob->ipoflag &= ~OB_OFFS_OB; + + set_no_parent_ipo(1); + disable_speed_curve(1); + + if ((ob->ipoflag & OB_DRAWKEYSEL)==0) { + ce= elems.first; + while(ce) { + if(!ce->sel) { + (G.scene->r.cfra)= ce->cfra/G.scene->r.framelen; + + base->flag= 0; + + where_is_object_time(ob, (G.scene->r.cfra)); + draw_object(base); + } + ce= ce->next; + } + } + + ce= elems.first; + while(ce) { + if(ce->sel) { + (G.scene->r.cfra)= ce->cfra/G.scene->r.framelen; + + base->flag= SELECT; + + where_is_object_time(ob, (G.scene->r.cfra)); + draw_object(base); + } + ce= ce->next; + } + + set_no_parent_ipo(0); + disable_speed_curve(0); + + base->flag= sel; + ob->ipoflag= ipoflag; + + /* restore icu->curval */ + (G.scene->r.cfra)= cfraont; + + memcpy(&ob->loc, temp, 7*3*sizeof(float)); + where_is_object(ob); + G.vd->drawtype= drawtype; + + BLI_freelistN(&elems); + + warning_recursive= 0; + } + } + } + + /* patch? kinderen met timeoffs verprutsen ouders. Hoe los je dat op! */ + /* if( ((int)ob->ctime) != F_(G.scene->r.cfra)) where_is_object(ob); */ + + mymultmatrix(ob->obmat); + + /* welke wire kleur */ + if((G.f & (G_BACKBUFSEL+G_PICKSEL)) == 0) { + project_short(ob->obmat[3], &base->sx); + + if(G.moving==1 && (base->flag & (SELECT+BA_PARSEL))) colindex= 12; + else { + if((G.scene->basact)==base) { + if(base->flag & (SELECT+BA_WASSEL)) colindex= 2; + } + else { + if(base->flag & (SELECT+BA_WASSEL)) colindex= 1; + } + if(ob->id.lib) colindex+= 3; + else if(warning_recursive==1) colindex+= 6; + else if(ob->flag & OB_FROMGROUP) colindex+= 9; + } + + col= colortab[colindex]; + cpack(col); + + } + + /* maximum drawtype */ + dt= MIN2(G.vd->drawtype, ob->dt); + if(G.zbuf==0 && dt>OB_WIRE) dt= OB_WIRE; + dtx= 0; + + /* faceselect uitzondering: ook solid tekenen als dt==wire, behalve in editmode */ + if(ob==((G.scene->basact) ? (G.scene->basact->object) : 0) && (G.f & (G_FACESELECT+G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT))) { + if(ob->type==OB_MESH) { + + if(ob==G.obedit) dt= OB_WIRE; + else { + if(G.f & G_BACKBUFSEL) dt= OB_SOLID; + else dt= OB_SHADED; + + glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + zbufoff= 1; + } + } + else { + if(dt<OB_SOLID) { + dt= OB_SOLID; + glClearDepth(1.); glClear(GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + zbufoff= 1; + } + } + } + else if(dt>=OB_WIRE ) { + + if(dt>OB_SOLID) if(G.f & G_BACKBUFSEL) dt= OB_SOLID; + + dtx= ob->dtx; + if(G.obedit==ob) { + if(dtx & OB_TEXSPACE) dtx= OB_TEXSPACE; + else dtx= 0; + } + + if(G.f & G_DRAW_EXT) { + if(ob->type==OB_EMPTY || ob->type==OB_CAMERA || ob->type==OB_LAMP) dt= OB_WIRE; + } + + } + + if( (G.f & G_DRAW_EXT) && dt>OB_WIRE) { + + switch( ob->type) { + case OB_MBALL: + drawmball(ob, dt); + break; + } + } + else { + + switch( ob->type) { + + case OB_MESH: + me= ob->data; + +#if 1 +#ifdef __NLA + /* Force a refresh of the display list if the parent is an armature */ + if (ob->parent && ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL){ +#if 0 /* Turn this on if there are problems with deformation lag */ + where_is_armature (ob->parent); +#endif + if (ob != G.obedit) + makeDispList (ob); + } +#endif +#endif + if(base->flag & OB_RADIO); + else if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) { + if(dt<=OB_WIRE) drawmeshwire(ob); + else { + if(mesh_uses_displist(me)) { + init_gl_materials(ob); + two_sided( me->flag & ME_TWOSIDED ); + drawDispListsolid(&me->disp, ob); + drawmeshwire(ob); + } + else drawmeshsolid(ob, 0); + } + if(ob==G.obedit && (G.f & G_PROPORTIONAL)) draw_prop_circle(); + } + else { + Material *ma= give_current_material(ob, 1); + + if(ob_from_decimator(ob)) drawDispListwire(&ob->disp); + else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob); + else if(dt==OB_WIRE) drawmeshwire(ob); + else if(ma && (ma->mode & MA_HALO)) drawmeshwire(ob); + else if(me->tface) { + if(G.f & G_BACKBUFSEL) drawmeshsolid(ob, 0); + else if(G.f & G_FACESELECT || G.vd->drawtype==OB_TEXTURE) draw_tface_mesh(ob, ob->data, dt); + else drawDispList(ob, dt); + } + else drawDispList(ob, dt); + } + if( (ob!=G.obedit) + && ((G.f & (G_BACKBUFSEL+G_PICKSEL)) == 0) ) { + paf = give_parteff(ob); + if( paf ) { + if(col) cpack(0xFFFFFF); /* zichtbaarheid */ + if(paf->flag & PAF_STATIC) draw_static_particle_system(ob, paf); + else draw_particle_system(ob, paf); + cpack(col); + } + } + + break; + case OB_FONT: + cu= ob->data; + if(ob==G.obedit) { + tekentextcurs(); + cpack(0xFFFF90); + drawDispList(ob, OB_WIRE); + } + else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob); + else if(boundbox_clip(ob->obmat, cu->bb)) drawDispList(ob, dt); + + break; + case OB_CURVE: + case OB_SURF: + cu= ob->data; + /* een pad niet solid tekenen: wel dus!!! */ + /* if(cu->flag & CU_PATH) if(dt>OB_WIRE) dt= OB_WIRE; */ + + if(ob==G.obedit) { + drawnurb(ob, editNurb.first, dt); + if((G.f & G_PROPORTIONAL)) draw_prop_circle(); + } + else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob); + else if(boundbox_clip(ob->obmat, cu->bb)) drawDispList(ob, dt); + + break; + case OB_MBALL: + if(ob==G.obedit) drawmball(ob, dt); + else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob); + else drawmball(ob, dt); + break; + case OB_EMPTY: + drawaxes(1.0); + break; + case OB_LAMP: + /* doet myloadmatrix */ + drawlamp(ob); + break; + case OB_CAMERA: + drawcamera(ob); + break; + case OB_LATTICE: + drawlattice(ob); + if(ob==G.obedit && (G.f & G_PROPORTIONAL)) draw_prop_circle(); + break; + case OB_IKA: + draw_ika(ob, base->flag & SELECT); + break; +#ifdef __NLA + case OB_ARMATURE: + draw_armature (ob); + break; +#endif + default: + drawaxes(1.0); + } + } + + /* draw extra: na gewone draw ivm makeDispList */ + if(dtx) { + if(G.f & G_SIMULATION); + else if(dtx & OB_AXIS) { + drawaxes(axsize); + } + if(dtx & OB_BOUNDBOX) draw_bounding_volume(ob); + if(dtx & OB_TEXSPACE) drawtexspace(ob); + if(dtx & OB_DRAWNAME) { + if(ob->type==OB_LAMP) glRasterPos3fv(ob->obmat[3]); + else glRasterPos3f(0.0, 0.0, 0.0); + + BMF_DrawString(G.font, " "); + BMF_DrawString(G.font, ob->id.name+2); + } + if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp); + } + + if(dt<OB_SHADED) { + if((ob->gameflag & OB_ACTOR) && (ob->gameflag & OB_DYNAMIC)) { + float tmat[4][4], imat[4][4], vec[3]; + + vec[0]= vec[1]= vec[2]= 0.0; + mygetmatrix(tmat); + Mat4Invert(imat, tmat); + + setlinestyle(2); + drawcircball(vec, ob->inertia, imat); + setlinestyle(0); + } + } + + myloadmatrix(G.vd->viewmat); + + if(zbufoff) glDisable(GL_DEPTH_TEST); + + if(warning_recursive) return; + if(base->flag & OB_FROMDUPLI) return; + if(base->flag & OB_RADIO) return; + if(G.f & G_SIMULATION) return; + + if((G.f & (G_BACKBUFSEL+G_PICKSEL))==0) { + /* hulplijnen e.d. */ + if(ob->parent && (ob->parent->lay & G.vd->lay)) { + setlinestyle(3); + glBegin(GL_LINES); + glVertex3fv(ob->obmat[3]); + glVertex3fv(ob->orig); + glEnd(); + setlinestyle(0); + } + + /* object centers */ + if(G.zbuf) glDisable(GL_DEPTH_TEST); + if(ob->type == OB_LAMP) { + if(ob->id.lib) { + if(base->flag & SELECT) rect= rectllib_sel; + else rect= rectllib_desel; + } + else if(ob->id.us>1) { + if(base->flag & SELECT) rect= rectlus_sel; + else rect= rectlus_desel; + } + else { + if(base->flag & SELECT) rect= rectl_sel; + else rect= rectl_desel; + } + draw_icon_centered(ob->obmat[3], rect, 9); + } + else { + if(ob->id.lib || ob->id.us>1) { + if(base->flag & SELECT) rect= rectu_sel; + else rect= rectu_desel; + } + else { + if(base->flag & SELECT) rect= rect_sel; + else if(base==(G.scene->basact)) rect= rect_sel; + else rect= rect_desel; + } + draw_icon_centered(ob->obmat[3], rect, 4); + } + if(G.zbuf) glEnable(GL_DEPTH_TEST); + + } + else if((G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT))==0) { + + glBegin(GL_POINTS); + glVertex3fv(ob->obmat[3]); + glEnd(); + + } +} + +void draw_object_ext(Base *base) +{ + ScrArea *tempsa, *sa; + View3D *vd; + + if(G.vd==0) return; + + if(G.vd->drawtype > OB_WIRE) { + G.zbuf= 1; + glEnable(GL_DEPTH_TEST); + } + + G.f |= G_DRAW_EXT; + + glDrawBuffer(GL_FRONT); + + /* alle views aflopen */ + tempsa= curarea; + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==SPACE_VIEW3D) { + /* er wordt beperkt in beide buffers getekend: selectbuffer! */ + + vd= sa->spacedata.first; + if(base->lay & vd->lay) { + areawinset(sa->win); + + draw_object(base); + + sa->win_swap= WIN_FRONT_OK; + } + } + sa= sa->next; + } + if(curarea!=tempsa) areawinset(tempsa->win); + + G.f &= ~G_DRAW_EXT; + + glFinish(); + glDrawBuffer(GL_BACK); + + if(G.zbuf) { + G.zbuf= 0; + glDisable(GL_DEPTH_TEST); + } +} diff --git a/source/blender/src/drawoops.c b/source/blender/src/drawoops.c new file mode 100644 index 00000000000..c37d7747c28 --- /dev/null +++ b/source/blender/src/drawoops.c @@ -0,0 +1,437 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdio.h> +#include <string.h> +#include <math.h> + +#ifdef _WIN32 +#include "BLI_winstuff.h" +#endif + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_ID.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_oops_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_view2d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" + +#include "BIF_gl.h" +#include "BIF_interface.h" +#include "BIF_glutil.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_interface.h" +#include "BIF_mywindow.h" + +/* #include "BIF_drawoops.h" bad name :(*/ +#include "BIF_oops.h" + +#include "BSE_drawipo.h" +#include "BSE_drawoops.h" +#include "interface.h" + +float oopscalex; + +void boundbox_oops() +{ + Oops *oops; + float min[2], max[2]; + int ok= 0; + + if(G.soops==0) return; + + min[0]= 1000.0; + max[0]= -10000.0; + min[1]= 1000.0; + max[1]= -1000.0; + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + ok= 1; + + min[0]= MIN2(min[0], oops->x); + max[0]= MAX2(max[0], oops->x+OOPSX); + min[1]= MIN2(min[1], oops->y); + max[1]= MAX2(max[1], oops->y+OOPSY); + } + oops= oops->next; + } + + if(ok==0) return; + + G.v2d->tot.xmin= min[0]; + G.v2d->tot.xmax= max[0]; + G.v2d->tot.ymin= min[1]; + G.v2d->tot.ymax= max[1]; + +} + +void give_oopslink_line(Oops *oops, OopsLink *ol, float *v1, float *v2) +{ + + if(ol->to && ol->to->hide==0) { + v1[0]= oops->x+ol->xof; + v1[1]= oops->y+ol->yof; + v2[0]= ol->to->x+OOPSX/2; + v2[1]= ol->to->y; + } + else if(ol->from && ol->from->hide==0) { + v1[0]= ol->from->x + ol->xof; + v1[1]= ol->from->y + ol->xof; + v2[0]= oops->x+OOPSX/2; + v2[1]= oops->y; + } +} + +void draw_oopslink(Oops *oops) +{ + OopsLink *ol; + float vec[4]; + + if(oops->type==ID_SCE) { + if(oops->flag & SELECT) { + if(oops->id->lib) cpack(0x4080A0); + else cpack(0x808080); + } + else cpack(0x606060); + } + else { + if(oops->flag & SELECT) { + if(oops->id->lib) cpack(0x11AAFF); + else cpack(0xFFFFFF); + } + else cpack(0x0); + } + + ol= oops->link.first; + while(ol) { + if(ol->to && ol->to->hide==0) { + + give_oopslink_line(oops, ol, vec, vec+2); + + glBegin(GL_LINE_STRIP); + glVertex2fv(vec); + glVertex2fv(vec+2); + glEnd(); + } + ol= ol->next; + } +} + +void draw_icon_oops(float *co, short type) +{ + BIFIconID icon; + + switch(type) { + default: return; + + case ID_OB: icon= ICON_OBJECT_HLT; break; + case ID_ME: icon= ICON_MESH_HLT; break; + case ID_CU: icon= ICON_CURVE_HLT; break; + case ID_MB: icon= ICON_MBALL_HLT; break; + case ID_LT: icon= ICON_LATTICE_HLT; break; + case ID_LA: icon= ICON_LAMP_HLT; break; + case ID_MA: icon= ICON_MATERIAL_HLT; break; + case ID_TE: icon= ICON_TEXTURE_HLT; break; + case ID_IP: icon= ICON_IPO_HLT; break; + case ID_LI: icon= ICON_LIBRARY_HLT; break; + case ID_IM: icon= ICON_IMAGE_HLT; break; + } + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glRasterPos2f(co[0], co[1]-0.2); + BIF_draw_icon(icon); + + glBlendFunc(GL_ONE, GL_ZERO); + glDisable(GL_BLEND); +} + +void mysbox(float x1, float y1, float x2, float y2) +{ + float vec[2]; + + glBegin(GL_LINE_LOOP); + vec[0]= x1; vec[1]= y1; + glVertex2fv(vec); + vec[0]= x2; + glVertex2fv(vec); + vec[1]= y2; + glVertex2fv(vec); + vec[0]= x1; + glVertex2fv(vec); + glEnd(); +} + +unsigned int give_oops_color(short type, short sel, unsigned int *border) +{ + unsigned int body; + /* geeft ook aan of stippellijn getekend moet */ + + switch(type) { + case ID_OB: + body= 0x707070; break; + case ID_SCE: + body= 0x608060; break; + case ID_MA: + body= 0x808060; break; + case ID_TE: + body= 0x7080a0; break; + case ID_IP: + body= 0x906050; break; + case ID_LA: + body= 0x608080; break; + case ID_LI: + body= 0x2198DC; break; + case ID_IM: + body= 0x35659F; break; + default: + body= 0x606070; break; + } + + if(sel) { + if(G.moving) *border= 0xf0f0f0; + else *border= 0xc0c0c0; + } + else *border= 0x0; + + + return body; +} + +void calc_oopstext(char *str, float *v1) +{ + float f1, f2, size; + short mval[2], len, flen; + + ipoco_to_areaco_noclip(G.v2d, v1, mval); + f1= mval[0]; + v1[0]+= OOPSX; + ipoco_to_areaco_noclip(G.v2d, v1, mval); + f2= mval[0]; + size= f2-f1; + + len= strlen(str); + + while( (flen= BMF_GetStringWidth(G.fonts, str)) > size) { + if(flen < 10 || len<2) break; + len--; + str[len]= 0; + } + + mval[0]= (f1+f2-flen+1)/2; + mval[1]= 1; + areamouseco_to_ipoco(G.v2d, mval, &f1, &f2); + + v1[0]= f1; + +} + +void draw_oops(Oops *oops, uiBlock *block) +{ + OopsLink *ol; + float v1[2], x1, y1, x2, y2, f1, f2; + unsigned int body, border; + short line= 0; + char str[32]; + + x1= oops->x; + x2= oops->x+OOPSX; + y1= oops->y; + y2= oops->y+OOPSY; + + if(x2 < G.v2d->cur.xmin || x1 > G.v2d->cur.xmax) return; + if(y2 < G.v2d->cur.ymin || y1 > G.v2d->cur.ymax) return; + + body= give_oops_color(oops->type, oops->flag & SELECT, &border); + if(oops->id== (ID *)((G.scene->basact) ? (G.scene->basact->object) : 0)) line= 1; + else if(oops->id== (ID *)G.scene) line= 1; + + if(oops->id->us) { + cpack(body); + + glRectf(x1, y1, x2, y2); + } + if(oops->id->lib) { + if(oops->id->flag & LIB_INDIRECT) cpack(0x1144FF); + else cpack(0x11AAFF); + + glRectf(x2-0.2*OOPSX, y2-0.2*OOPSX, x2-0.1*OOPSX, y2-0.1*OOPSX); + } + + v1[0]= x1; + v1[1]= (y1+y2)/2 -0.3; + if(oops->type==ID_LI) { + sprintf(str, " %s", ((Library *)oops->id)->name); + } + else { + sprintf(str, " %s", oops->id->name+2); + } + calc_oopstext(str, v1); + + /* ICON */ + if(str[1] && oopscalex>1.1) { + draw_icon_oops(v1, oops->type); + } + if(oops->flag & SELECT) cpack(0xFFFFFF); + else cpack(0x0); + glRasterPos3f(v1[0], v1[1], 0.0); + BMF_DrawString(G.fonts, str); + + if(line) setlinestyle(2); + cpack(border); + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glRectf(x1, y1, x2, y2); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if(line) setlinestyle(0); + + /* connectieblokjes */ + ol= oops->link.first; + while(ol) { + + f1= x1+ol->xof; + f2= y1+ol->yof; + + body= give_oops_color(ol->type, oops->flag & SELECT, &border); + cpack(body); + + glRectf(f1-.2, f2-.2, f1+.2, f2+.2); + cpack(border); + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + glRectf(f1-.2, f2-.2, f1+.2, f2+.2); + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + ol= ol->next; + } + + if(oops->flag & OOPS_REFER) { + /* Draw the little rounded connection point */ + glColor3ub(0, 0, 0); + glPushMatrix(); + + glTranslatef(oops->x + 0.5*OOPSX, oops->y, 0.0); + glutil_draw_filled_arc(0.0, M_PI, 0.05*OOPSX, 7); + + glPopMatrix(); + } +} + +void drawoopsspace() +{ + uiBlock *block; + Oops *oops; + int ofsx, ofsy; + char name[32]; + + glClearColor(0.55, 0.55, 0.55, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + if(G.soops==0) return; + + sprintf(name, "win %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, name, UI_EMBOSSF, UI_HELVB, curarea->win); + + boundbox_oops(); + calc_scrollrcts(G.v2d, curarea->winx, curarea->winy); + + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + if(G.v2d->scroll) { + ofsx= curarea->winrct.xmin; /* ivm mywin */ + ofsy= curarea->winrct.ymin; + + glViewport(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + glScissor(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + } + } + + myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); + + oopscalex= .14*((float)curarea->winx)/(G.v2d->cur.xmax-G.v2d->cur.xmin); + calc_ipogrid(); /* voor scrollvariables */ + build_oops(); + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + draw_oopslink(oops); + } + oops= oops->next; + } + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if(oops->flag & SELECT); else draw_oops(oops, block); + } + oops= oops->next; + } + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if(oops->flag & SELECT) draw_oops(oops, block); + } + oops= oops->next; + } + + /* restore viewport */ + mywinset(curarea->win); + + + if(G.v2d->scroll) { + /* ortho op pixelnivo curarea */ + myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5); + drawscroll(0); + } + + uiDrawBlock(block); + + curarea->win_swap= WIN_BACK_OK; +} + + + diff --git a/source/blender/src/drawscene.c b/source/blender/src/drawscene.c new file mode 100644 index 00000000000..d5b75645dff --- /dev/null +++ b/source/blender/src/drawscene.c @@ -0,0 +1,118 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * drawing graphics and editing + */ + +#include <math.h> + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_scene_types.h" +#include "DNA_space_types.h" +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_scene.h" + +#include "BDR_editobject.h" + +#include "BIF_space.h" +#include "BIF_drawscene.h" + +#include "BSE_view.h" + +#include "blendef.h" /* DIE ! */ +#include "mydevice.h" + + +void set_scene(Scene *sce) /* zie ook scene.c: set_scene_bg() */ +{ + bScreen *sc; + + G.scene= sce; + + sc= G.main->screen.first; + while(sc) { + if((U.flag & SCENEGLOBAL) || sc==G.curscreen) { + + if(sce != sc->scene) { + /* alle area's endlocalview */ + ScrArea *sa= sc->areabase.first; + while(sa) { + endlocalview(sa); + sa= sa->next; + } + sc->scene= sce; + } + + } + sc= sc->id.next; + } + + copy_view3d_lock(0); /* space.c */ + + /* zijn er camera's in de views die niet in de scene zitten? */ + sc= G.main->screen.first; + while(sc) { + if( (U.flag & SCENEGLOBAL) || sc==G.curscreen) { + ScrArea *sa= sc->areabase.first; + while(sa) { + SpaceLink *sl= sa->spacedata.first; + while(sl) { + if(sl->spacetype==SPACE_VIEW3D) { + View3D *v3d= (View3D*) sl; + if (!v3d->camera || !object_in_scene(v3d->camera, sce)) { + v3d->camera= scene_find_camera(sc->scene); + if (sc==G.curscreen) handle_view3d_lock(); + if (!v3d->camera && v3d->persp>1) v3d->persp= 1; + } + } + sl= sl->next; + } + sa= sa->next; + } + } + sc= sc->id.next; + } + + set_scene_bg(G.scene); + + /* volledige redraw */ + allqueue(REDRAWALL, 0); + allqueue(REDRAWDATASELECT, 0); /* doet remake */ +} + + diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c new file mode 100644 index 00000000000..22b397abde6 --- /dev/null +++ b/source/blender/src/drawseq.c @@ -0,0 +1,617 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifdef _WIN32 +#include "BLI_winstuff.h" +#endif + +#include <string.h> +#include <math.h> + +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "IMB_imbuf_types.h" + +#include "DNA_sequence_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_view2d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" + +#include "BIF_gl.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_drawseq.h" +#include "BIF_editseq.h" +#include "BIF_drawimage.h" + +#include "BSE_view.h" +#include "BSE_drawipo.h" +#include "BSE_sequence.h" + +/* Modules used */ +#include "blendertimer.h" /* timer functions */ + +int no_rightbox=0, no_leftbox= 0; + +static void EmbossBoxf(float x1, float y1, float x2, float y2, int sel, unsigned int dark, unsigned int light) +{ + + if(sel) cpack(dark); + else cpack(light); + if(sel) glLineWidth(2.0); + fdrawline(x1, y2, x2, y2); /* boven */ + if(no_leftbox==0) fdrawline(x1, y1, x1, y2); /* links */ + + if(sel) glLineWidth(1.0); + + if(sel) cpack(light); + else cpack(dark); + fdrawline(x1, y1, x2, y1); /* onder */ + if(no_rightbox==0) fdrawline(x2, y1, x2, y2); /* rechts */ + +} + +static char *give_seqname(Sequence *seq) +{ + if(seq->type==SEQ_META) { + if(seq->name[2]) return seq->name+2; + return "META"; + } + else if(seq->type==SEQ_SCENE) return "SCENE"; + else if(seq->type==SEQ_MOVIE) return "MOVIE"; + else if(seq->type<SEQ_EFFECT) return seq->strip->dir; + else if(seq->type==SEQ_CROSS) return "CROSS"; + else if(seq->type==SEQ_GAMCROSS) return "GAMMA CROSS"; + else if(seq->type==SEQ_ADD) return "ADD"; + else if(seq->type==SEQ_SUB) return "SUB"; + else if(seq->type==SEQ_MUL) return "MUL"; + else if(seq->type==SEQ_ALPHAOVER) return "ALPHAOVER"; + else if(seq->type==SEQ_ALPHAUNDER) return "ALPHAUNDER"; + else if(seq->type==SEQ_OVERDROP) return "OVER DROP"; + else if(seq->type==SEQ_PLUGIN) { + if(seq->plugin && seq->plugin->doit) return seq->plugin->pname; + return "PLUGIN"; + } + else return "EFFECT"; + +} + +static void draw_cfra_seq(void) +{ + glColor3ub(0x30, 0x90, 0x50); + glLineWidth(2.0); + glBegin(GL_LINES); + glVertex2f(G.scene->r.cfra, G.v2d->cur.ymin); + glVertex2f(G.scene->r.cfra, G.v2d->cur.ymax); + glEnd(); + glLineWidth(1.0); +} + +static unsigned int seq_color(Sequence *seq) +{ + switch(seq->type) { + case SEQ_META: + return 0x509090; + case SEQ_MOVIE: + return 0x805040; + case SEQ_SCENE: + if(seq->scene==G.scene) return 0x709050; + return 0x609060; + case SEQ_CROSS: + return 0x505090; + case SEQ_GAMCROSS: + return 0x5040A0; + case SEQ_ADD: + return 0x6060A0; + case SEQ_SUB: + return 0x8060A0; + case SEQ_MUL: + return 0x8080A0; + case SEQ_ALPHAOVER: + return 0x6080A0; + case SEQ_ALPHAUNDER: + return 0x9080A0; + case SEQ_OVERDROP: + return 0x5080B0; + case SEQ_PLUGIN: + return 0x906000; + default: + return 0x906060; + } + +} + +static void drawmeta_contents(Sequence *seqm, float x1, float y1, float x2, float y2) +{ + Sequence *seq; + float dx; + int nr; + + nr= 0; + WHILE_SEQ(&seqm->seqbase) { + nr++; + } + END_SEQ + + dx= (x2-x1)/nr; + + WHILE_SEQ(&seqm->seqbase) { + cpack(seq_color(seq)); + glRectf(x1, y1, x1+0.9*dx, y2); + EmbossBoxf(x1, y1, x1+0.9*dx, y2, 0, 0x404040, 0xB0B0B0); + x1+= dx; + } + END_SEQ +} + +void drawseq(Sequence *seq) +{ + float v1[2], v2[2], x1, x2, y1, y2; + unsigned int body, dark, light; + int len, size; + short mval[2]; + char str[120], *strp; + + + if(seq->startdisp > seq->enddisp) body= 0x707070; + + body= seq_color(seq); + dark= 0x202020; + light= 0xB0B0B0; + + if(G.moving && (seq->flag & SELECT)) { + if(seq->flag & SEQ_OVERLAP) dark= light= 0x4040FF; + else { + if(seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL)); + else dark= light= 0xFFFFFF; + } + } + + /* body */ + if(seq->startstill) x1= seq->start; + else x1= seq->startdisp; + y1= seq->machine+0.2; + if(seq->endstill) x2= seq->start+seq->len; + else x2= seq->enddisp; + y2= seq->machine+0.8; + + cpack(body); + glRectf(x1, y1, x2, y2); + EmbossBoxf(x1, y1, x2, y2, seq->flag & 1, dark, light); + + v1[1]= y1; + v2[1]= y2; + if(seq->type < SEQ_EFFECT) { + + /* decoratie: balkjes */ + x1= seq->startdisp; + x2= seq->enddisp; + + if(seq->startofs) { + cpack(0x707070); + glRectf((float)(seq->start), y1-0.2, x1, y1); + EmbossBoxf((float)(seq->start), y1-0.2, x1, y1, seq->flag & 1, dark, light); + } + if(seq->endofs) { + cpack(0x707070); + glRectf(x2, y2, (float)(seq->start+seq->len), y2+0.2); + EmbossBoxf(x2, y2, (float)(seq->start+seq->len), y2+0.2, seq->flag & 1, dark, light); + } + + if(seq->startstill) { + cpack(body); + glRectf(x1, y1+0.1, (float)(seq->start), y1+0.5); + no_rightbox= 1; + EmbossBoxf(x1, y1+0.1, (float)(seq->start), y1+0.5, seq->flag & 1, dark, light); + no_rightbox= 0; + } + if(seq->endstill) { + cpack(body); + glRectf((float)(seq->start+seq->len), y1+0.1, x2, y1+0.5); + no_leftbox= 1; + EmbossBoxf((float)(seq->start+seq->len), y1+0.1, x2, y1+0.5, seq->flag & 1, dark, light); + no_leftbox= 0; + } + + } + + /* berekenen of seq lang genoeg is om naam te printen */ + x1= seq->startdisp+seq->handsize; + x2= seq->enddisp-seq->handsize; + + /* maar eerst de inhoud van de meta */ + if(seq->type==SEQ_META) drawmeta_contents(seq, x1, y1+0.15, x2, y2-0.15); + + if(x1<G.v2d->cur.xmin) x1= G.v2d->cur.xmin; + else if(x1>G.v2d->cur.xmax) x1= G.v2d->cur.xmax; + if(x2<G.v2d->cur.xmin) x2= G.v2d->cur.xmin; + else if(x2>G.v2d->cur.xmax) x2= G.v2d->cur.xmax; + + if(x1 != x2) { + v1[0]= x1; + ipoco_to_areaco_noclip(G.v2d, v1, mval); + x1= mval[0]; + v2[0]= x2; + ipoco_to_areaco_noclip(G.v2d, v2, mval); + x2= mval[0]; + size= x2-x1; + + if(seq->type == SEQ_META) sprintf(str, "%d %s", seq->len, give_seqname(seq)); + else if(seq->type == SEQ_SCENE) { + if(seq->scene) sprintf(str, "%d %s %s", seq->len, give_seqname(seq), seq->scene->id.name+2); + else sprintf(str, "%d %s", seq->len, give_seqname(seq)); + } + else if(seq->type & SEQ_EFFECT) { + if(seq->seq3!=seq->seq2 && seq->seq1!=seq->seq3) + sprintf(str, "%d %s: %d-%d (use %d)", seq->len, give_seqname(seq), seq->seq1->machine, seq->seq2->machine, seq->seq3->machine); + else + sprintf(str, "%d %s: %d-%d", seq->len, give_seqname(seq), seq->seq1->machine, seq->seq2->machine); + } + else if(seq->name[2]) sprintf(str, "%s", seq->name+2); + else sprintf(str, "%d %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name); + + strp= str; + + while( (len= BMF_GetStringWidth(G.font, strp)) > size) { + if(len < 10) break; + if(strp[1]==0) break; + strp++; + } + + mval[0]= (x1+x2-len+1)/2; + mval[1]= 1; + areamouseco_to_ipoco(G.v2d, mval, &x1, &x2); + + if(seq->flag & SELECT) cpack(0xFFFFFF); + else cpack(0x0); + glRasterPos3f(x1, y1+0.2, 0.0); + BMF_DrawString(G.font, strp); + } + + if(seq->type < SEQ_EFFECT) { + + /* decoratie: driehoekjes */ + x1= seq->startdisp; + x2= seq->enddisp; + + body+= 0x101010; + dark= 0x202020; + light= 0xB0B0B0; + + /* linker driehoek */ + + if(seq->flag & SEQ_LEFTSEL) { + cpack(body+0x20); + if(G.moving) { + if(seq->flag & SEQ_OVERLAP) dark= light= 0x4040FF; + else dark= light= 0xFFFFFF; + } + } + else { + cpack(body); + } + + glBegin(GL_TRIANGLES); + v1[0]= x1; glVertex2fv(v1); + v2[0]= x1; glVertex2fv(v2); + v2[0]+= seq->handsize; v2[1]= (y1+y2)/2.0; glVertex2fv(v2); v2[1]= y2; + glEnd(); + + cpack(light); + + glBegin(GL_LINE_STRIP); + v1[0]= x1; glVertex2fv(v1); + v2[0]= x1; glVertex2fv(v2); + v2[0]+= seq->handsize; v2[1]= (y1+y2)/2.0; glVertex2fv(v2); v2[1]= y2; + cpack(dark); + glVertex2fv(v1); + glEnd(); + + if(G.moving || (seq->flag & SEQ_LEFTSEL)) { + cpack(0xFFFFFF); + glRasterPos3f(x1, y1+0.2, 0.0); + sprintf(str, "%d", seq->startdisp); + BMF_DrawString(G.font, str); + } + + /* rechter driehoek */ + + dark= 0x202020; + light= 0xB0B0B0; + + if(seq->flag & SEQ_RIGHTSEL) { + cpack(body+0x20); + if(G.moving) { + if(seq->flag & SEQ_OVERLAP) dark= light= 0x4040FF; + else dark= light= 0xFFFFFF; + } + } + else { + cpack(body); + } + glBegin(GL_TRIANGLES); + v2[0]= x2; glVertex2fv(v2); + v1[0]= x2; glVertex2fv(v1); + v2[0]-= seq->handsize; v2[1]= (y1+y2)/2.0; glVertex2fv(v2); v2[1]= y2; + glEnd(); + + cpack(dark); + glBegin(GL_LINE_STRIP); + v2[0]= x2; glVertex2fv(v2); + v1[0]= x2; glVertex2fv(v1); + v1[0]-= seq->handsize; v1[1]= (y1+y2)/2.0; glVertex2fv(v1); v1[1]= y2; + cpack(light); + glVertex2fv(v2); + glEnd(); + + if(G.moving || (seq->flag & SEQ_RIGHTSEL)) { + cpack(0xFFFFFF); + glRasterPos3f(x2-seq->handsize/2, y1+0.2, 0.0); + sprintf(str, "%d", seq->enddisp-1); + BMF_DrawString(G.font, str); + } + + + } +} + +static Sequence *special_seq_update= 0; + +void set_special_seq_update(int val) +{ + int x; + + /* als met muis in sequence && LEFTMOUSE */ + if(val) { + special_seq_update= find_nearest_seq(&x); + } + else special_seq_update= 0; +} + + +static void draw_image_seq(void) +{ + SpaceSeq *sseq; + StripElem *se; + struct ImBuf *ibuf; + int x1, y1; + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + curarea->win_swap= WIN_BACK_OK; + + ibuf= (ImBuf *)give_ibuf_seq( (G.scene->r.cfra)); + + if(special_seq_update) { + se = special_seq_update->curelem; + if(se) { + if(se->ok==2) { + if(se->se1) + ibuf= se->se1->ibuf; + } + else ibuf= se->ibuf; + } + } + if(ibuf==0 || ibuf->rect==0) return; + + sseq= curarea->spacedata.first; + if(sseq==0) return; + + /* plek berekenen */ + x1= curarea->winrct.xmin+(curarea->winx-sseq->zoom*ibuf->x)/2; + y1= curarea->winrct.ymin+(curarea->winy-sseq->zoom*ibuf->y)/2; + + /* convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); */ + + rectwrite_part(curarea->winrct.xmin, curarea->winrct.ymin, + curarea->winrct.xmax, curarea->winrct.ymax, + x1, y1, ibuf->x, ibuf->y, (float)sseq->zoom,(float)sseq->zoom, ibuf->rect); + + /* convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); */ +} + +static void draw_extra_seqinfo(void) +{ + extern Sequence *last_seq; + StripElem *se, *last; + float xco, xfac; + int sta, end; + char str[256]; + + if(last_seq==0) return; + + /* xfac: afm 1 pixel */ + xfac= G.v2d->cur.xmax - G.v2d->cur.xmin; + xfac/= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin); + xco= G.v2d->cur.xmin+40*xfac; + + cpack(0); + + /* NAAM */ + glRasterPos3f(xco, 0.3, 0.0); + strcpy(str, give_seqname(last_seq)); + BMF_DrawString(G.font, str); + xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac; + + if(last_seq->type==SEQ_SCENE && last_seq->scene) { + glRasterPos3f(xco, 0.3, 0.0); + BMF_DrawString(G.font, last_seq->scene->id.name+2); + xco += xfac*BMF_GetStringWidth(G.font, last_seq->scene->id.name+2) +30.0*xfac; + } + + /* LEN */ + if(last_seq->type & SEQ_EFFECT) + sprintf(str, "len: %d From %d - %d", last_seq->len, last_seq->startdisp, last_seq->enddisp-1); + else + sprintf(str, "len: %d (%d)", last_seq->enddisp-last_seq->startdisp, last_seq->len); + + glRasterPos3f(xco, 0.3, 0.0); + BMF_DrawString(G.font, str); + xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac; + + if(last_seq->type==SEQ_IMAGE) { + + /* CURRENT */ + se= (StripElem *)give_stripelem(last_seq, (G.scene->r.cfra)); + if(se) { + sprintf(str, "cur: %s", se->name); + glRasterPos3f(xco, 0.3, 0.0); + BMF_DrawString(G.font, str); + xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac; + } + + /* FIRST EN LAST */ + + if(last_seq->strip) { + se= last_seq->strip->stripdata; + last= se+last_seq->len-1; + if(last_seq->startofs) se+= last_seq->startofs; + if(last_seq->endofs) last-= last_seq->endofs; + + sprintf(str, "First: %s at %d Last: %s at %d", se->name, last_seq->startdisp, last->name, last_seq->enddisp-1); + glRasterPos3f(xco, 0.3, 0.0); + BMF_DrawString(G.font, str); + xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac; + + /* orig size */ + sprintf(str, "OrigSize: %d x %d", last_seq->strip->orx, last_seq->strip->ory); + glRasterPos3f(xco, 0.3, 0.0); + BMF_DrawString(G.font, str); + xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac; + } + } + else if(last_seq->type==SEQ_MOVIE) { + + sta= last_seq->startofs; + end= last_seq->len-1-last_seq->endofs; + + sprintf(str, "%s %s%s First: %d at %d Last: %d at %d Cur: %d", + last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name, + sta, last_seq->startdisp, end, last_seq->enddisp-1, (G.scene->r.cfra)-last_seq->startdisp); + + glRasterPos3f(xco, 0.3, 0.0); + BMF_DrawString(G.font, str); + } +} + +void drawseqspace(void) +{ + SpaceSeq *sseq; + Editing *ed; + Sequence *seq; + int ofsx, ofsy; + + ed= G.scene->ed; + + sseq= curarea->spacedata.first; + if(sseq->mainb==1) { + draw_image_seq(); + return; + } + + if(ed && ed->metastack.first) glClearColor(0.5, 0.5, 0.4, 0.0); + else glClearColor(.40625, .40625, .40625, 0.0); + + glClear(GL_COLOR_BUFFER_BIT); + + calc_scrollrcts(G.v2d, curarea->winx, curarea->winy); + + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + if(G.v2d->scroll) { + ofsx= curarea->winrct.xmin; /* ivm mywin */ + ofsy= curarea->winrct.ymin; + glViewport(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + glScissor(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + } + } + + + myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); + + cpack(0x585858); + glRectf(G.v2d->cur.xmin, 0.0, G.v2d->cur.xmax, 1.0); + + boundbox_seq(); + calc_ipogrid(); + draw_ipogrid(); + draw_cfra_seq(); + + /* sequenties: eerst de deselect */ + + if(ed) { + seq= ed->seqbasep->first; + while(seq) { + if(seq->flag & SELECT); else drawseq(seq); + seq= seq->next; + } + } + ed= G.scene->ed; + if(ed) { + seq= ed->seqbasep->first; + while(seq) { + if(seq->flag & SELECT) drawseq(seq); + seq= seq->next; + } + } + + draw_extra_seqinfo(); + + /* restore viewport */ + mywinset(curarea->win); + + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + + /* ortho op pixelnivo curarea */ + myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5); + + if(G.v2d->scroll) { + drawscroll(0); + } + + + } + + curarea->win_swap= WIN_BACK_OK; +} + + diff --git a/source/blender/src/drawsound.c b/source/blender/src/drawsound.c new file mode 100644 index 00000000000..c17ba472e5d --- /dev/null +++ b/source/blender/src/drawsound.c @@ -0,0 +1,207 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_scene_types.h" +#include "DNA_sound_types.h" +#include "DNA_space_types.h" +#include "DNA_screen_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" + +#include "BIF_gl.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_editsound.h" + +#include "BSE_drawipo.h" + +/* local */ +void drawsoundspace(void); + +/*implementation */ +static void draw_wave(int startsamp, int endsamp, short sampdx, short offset, short *sp, float sampfac, float y) +{ + float min, max, v1[2], v2[3]; + int i, j; + short value, deltasp; + + sp+= offset*startsamp; + + deltasp= offset*sampdx; + + glBegin(GL_LINES); + for(i=startsamp; i<endsamp; i+=sampdx, sp+=deltasp) { + + /* filter */ + min= max= 0.0; + for(j=0; j<sampdx; j++) { + value= sp[offset*j]; + if(value < min) min= value; + else if(value > max) max= value; + } + v1[1]= y + 0.002*min; + v2[1]= y + 0.002*max; + + v1[0]=v2[0]= sampfac*i; + + glVertex2fv(v1); + glVertex2fv(v2); + } + glEnd(); +} + +static void draw_sample(bSample *sample) +{ + float sampxlen, sampfac; + int samples, startsamp, endsamp; + short *sp, sampdx; + + /* one sample is where in v2d space? (v2d space in frames!) */ + sampfac= 25.0/(sample->rate); + + /* how many samples? */ + samples= sample->len/(sample->channels*(sample->bits/8)); + /* total len in v2d space */ + sampxlen= sampfac*samples; + + /* one pixel is how many samples? */ + sampdx= (samples*((G.v2d->cur.xmax-G.v2d->cur.xmin)/sampxlen))/curarea->winx; + + if(sampdx==0) sampdx= 1; + + /* start and and */ + startsamp = G.v2d->cur.xmin/sampfac; + CLAMP(startsamp, 0, samples-1); + endsamp= G.v2d->cur.xmax/sampfac; + CLAMP(endsamp, 0, samples-1); + endsamp-= sampdx; + + /* set 'tot' for sliders */ + G.v2d->tot.xmax= sampfac*samples; + + /* channels? */ + if(sample->channels==2) { + + cpack(0x905050); + sp= (short *)(sample->data); + draw_wave(startsamp, endsamp, sampdx, 2, sp, sampfac, 85.0); + + cpack(0x506890); + sp++; + draw_wave(startsamp, endsamp, sampdx, 2, sp, sampfac, 190.0); + } + else { + cpack(0x905050); + sp= (short *)(sample->data); + + draw_wave(startsamp, endsamp, sampdx, 1, sp, sampfac, 128.0); + } +} + +static void draw_cfra_sound(void) +{ + float vec[2]; + + vec[0]= (G.scene->r.cfra); + vec[0]*= G.scene->r.framelen; + + vec[1]= G.v2d->cur.ymin; + glColor3ub(0x20, 0x80, 0x20); + glLineWidth(3.0); + + glBegin(GL_LINE_STRIP); + glVertex2fv(vec); + vec[1]= G.v2d->cur.ymax; + glVertex2fv(vec); + glEnd(); + + glLineWidth(1.0); +} + + +void drawsoundspace(void) +{ + short ofsx, ofsy; + + glClearColor(.6275, .6275, .6275, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + calc_scrollrcts(G.v2d, curarea->winx, curarea->winy); + + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + if(G.v2d->scroll) { + ofsx= curarea->winrct.xmin; /* ivm mywin */ + ofsy= curarea->winrct.ymin; + glViewport(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + glScissor(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); + } + } + + myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); + + /* boundbox_seq(); */ + calc_ipogrid(); + draw_ipogrid(); + + if (G.ssound->sound) { + sound_initialize_sample(G.ssound->sound); + draw_sample(G.ssound->sound->sample); + } + + draw_cfra_sound(); + + /* restore viewport */ + mywinset(curarea->win); + + if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + + /* ortho op pixelnivo curarea */ + myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5); + + if(G.v2d->scroll) { + drawscroll(0); + } + } + + curarea->win_swap= WIN_BACK_OK; +} diff --git a/source/blender/src/drawtext.c b/source/blender/src/drawtext.c new file mode 100644 index 00000000000..0b511149996 --- /dev/null +++ b/source/blender/src/drawtext.c @@ -0,0 +1,1101 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <math.h> +#ifndef _WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" +#include "PIL_time.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_text_types.h" +#include "DNA_space_types.h" +#include "DNA_screen_types.h" + +#include "BKE_utildefines.h" +#include "BKE_text.h" +#include "BKE_global.h" +#include "BKE_main.h" + +#include "BPY_extern.h" + +#include "BIF_gl.h" +#include "BIF_keyval.h" +#include "BIF_interface.h" +#include "BIF_drawtext.h" +#include "BIF_spacetypes.h" +#include "BIF_usiblender.h" +#include "BIF_screen.h" +#include "BIF_toolbox.h" +#include "BIF_space.h" +#include "BIF_mywindow.h" + +#include "BSE_filesel.h" + +#include "mydevice.h" +#include "blendef.h" +#include "interface.h" + +/* locals */ +void drawtextspace(void); +void winqreadtextspace(unsigned short event, short val, char ascii); + +static void *last_txt_find_string= NULL; + +static BMF_Font *spacetext_get_font(SpaceText *st) { + static BMF_Font *scr12= NULL; + static BMF_Font *scr15= NULL; + + switch (st->font_id) { + default: + case 0: + if (!scr12) + scr12= BMF_GetFont(BMF_kScreen12); + return scr12; + case 1: + if (!scr15) + scr15= BMF_GetFont(BMF_kScreen15); + return scr15; + } +} + +static int spacetext_get_fontwidth(SpaceText *st) { + return BMF_GetCharacterWidth(spacetext_get_font(st), ' '); +} + +static char *temp_char_buf= NULL; +static int *temp_char_accum= NULL; +static int temp_char_len= 0; +static int temp_char_pos= 0; + +static void temp_char_write(char c, int accum) { + if (temp_char_len==0 || temp_char_pos>=temp_char_len) { + char *nbuf; int *naccum; + int olen= temp_char_len; + + if (olen) temp_char_len*= 2; + else temp_char_len= 256; + + nbuf= MEM_mallocN(sizeof(*temp_char_buf)*temp_char_len, "temp_char_buf"); + naccum= MEM_mallocN(sizeof(*temp_char_accum)*temp_char_len, "temp_char_accum"); + + if (olen) { + memcpy(nbuf, temp_char_buf, olen); + memcpy(naccum, temp_char_accum, olen); + + MEM_freeN(temp_char_buf); + MEM_freeN(temp_char_accum); + } + + temp_char_buf= nbuf; + temp_char_accum= naccum; + } + + temp_char_buf[temp_char_pos]= c; + temp_char_accum[temp_char_pos]= accum; + + if (c==0) temp_char_pos= 0; + else temp_char_pos++; +} + +void free_txt_data(void) { + txt_free_cut_buffer(); + + if (last_txt_find_string) MEM_freeN(last_txt_find_string); + if (temp_char_buf) MEM_freeN(temp_char_buf); + if (temp_char_accum) MEM_freeN(temp_char_accum); +} + +static int render_string (char *in) { + int r= 0, i; + + while(*in) { + if (*in=='\t') { + if (temp_char_pos && *(in-1)=='\t') i= TXT_TABSIZE; + else i= TXT_TABSIZE - (temp_char_pos%TXT_TABSIZE); + + while(i--) temp_char_write(' ', r); + } else temp_char_write(*in, r); + + r++; + in++; + } + r= temp_char_pos; + temp_char_write(0, 0); + + return r; +} + +static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int draw, int x, int y) { + int r=0, w= 0; + char *in; + int *acc; + + w= render_string(str); + if(w<cshift ) return 0; /* String is shorter than shift */ + + in= temp_char_buf+cshift; + acc= temp_char_accum+cshift; + w= w-cshift; + + if (draw) { + glRasterPos2i(x, y); + BMF_DrawString(spacetext_get_font(st), in); + } else { + while (w-- && *acc++ < maxwidth) { + r+= spacetext_get_fontwidth(st); + } + } + + if (cshift && r==0) return 0; + else return r+TXT_OFFSET; +} + +static void set_cursor_to_pos (SpaceText *st, int x, int y, int sel) +{ + Text *text; + TextLine **linep; + int *charp; + int w; + + text= st->text; + + if(sel) { linep= &text->sell; charp= &text->selc; } + else { linep= &text->curl; charp= &text->curc; } + + y= (curarea->winy - y)/st->lheight; + + y-= txt_get_span(text->lines.first, *linep) - st->top; + + if (y>0) { + while (y-- != 0) if((*linep)->next) *linep= (*linep)->next; + } else if (y<0) { + while (y++ != 0) if((*linep)->prev) *linep= (*linep)->prev; + } + + x-= TXT_OFFSET; + if (x<0) x= 0; + x = (x/spacetext_get_fontwidth(st)) + st->left; + + w= render_string((*linep)->line); + if(x<w) *charp= temp_char_accum[x]; + else *charp= (*linep)->len; + + if(!sel) txt_pop_sel(text); +} + +static void draw_cursor(SpaceText *st) { + int h, x, i; + Text *text= st->text; + TextLine *linef, *linel; + int charf, charl; + + if (text->curl==text->sell && text->curc==text->selc) { + x= text_draw(st, text->curl->line, st->left, text->curc, 0, 0, 0); + + if (x) { + h= txt_get_span(text->lines.first, text->curl) - st->top; + + glColor3f(1.0, 0.0, 0.0); + + glRecti(x-1, curarea->winy-st->lheight*(h)-2, x+1, curarea->winy-st->lheight*(h+1)-2); + } + } else { + int span= txt_get_span(text->curl, text->sell); + + if (span<0) { + linef= text->sell; + charf= text->selc; + + linel= text->curl; + charl= text->curc; + } else if (span>0) { + linef= text->curl; + charf= text->curc; + + linel= text->sell; + charl= text->selc; + } else { + linef= linel= text->curl; + + if (text->curc<text->selc) { + charf= text->curc; + charl= text->selc; + } else { + charf= text->selc; + charl= text->curc; + } + } + + /* Walk to the beginning of visible text */ + h= txt_get_span(text->lines.first, linef) - st->top; + while (h++<-1 && linef!=linel) linef= linef->next; + + x= text_draw(st, linef->line, st->left, charf, 0, 0, 0); + + glColor3f(0.75, 0.44, 0.44); + + if (!x) x= TXT_OFFSET-10; + while (linef && linef != linel) { + h= txt_get_span(text->lines.first, linef) - st->top; + if (h>st->viewlines) break; + + glRecti(x, curarea->winy-st->lheight*(h)-2, curarea->winx, curarea->winy-st->lheight*(h+1)-2); + glRecti(TXT_OFFSET-10, curarea->winy-st->lheight*(h+1)-2, TXT_OFFSET, curarea->winy-st->lheight*(h+2)-2); + x= TXT_OFFSET; + + linef= linef->next; + } + + h= txt_get_span(text->lines.first, linef) - st->top; + + i= text_draw(st, linel->line, st->left, charl, 0, 0, 0); + if(i) glRecti(x, curarea->winy-st->lheight*(h)-2, i, curarea->winy-st->lheight*(h+1)-2); + } + + glColor3f(0.0, 0.0, 0.0); +} + +static void calc_text_rcts(SpaceText *st) +{ + short barheight, barstart; + int lbarstart, lbarh, ltexth; + + lbarstart= st->top; + lbarh= st->viewlines; + ltexth= txt_get_span(st->text->lines.first, st->text->lines.last)+1; + + barheight= (lbarh*(curarea->winy-4))/ltexth; + if (barheight<20) barheight=20; + + barstart= (lbarstart*(curarea->winy-4))/ltexth + 8; + + st->txtbar.xmin= 5; + st->txtbar.xmax= 17; + st->txtbar.ymax= curarea->winy - barstart; + st->txtbar.ymin= st->txtbar.ymax - barheight; + + CLAMP(st->txtbar.ymin, 2, curarea->winy-2); + CLAMP(st->txtbar.ymax, 2, curarea->winy-2); + + st->pix_per_line= (float) ltexth/curarea->winy; + if (st->pix_per_line<.1) st->pix_per_line=.1; + + lbarstart= MIN2(txt_get_span(st->text->lines.first, st->text->curl), + txt_get_span(st->text->lines.first, st->text->sell)); + lbarh= abs(txt_get_span(st->text->lines.first, st->text->curl)-txt_get_span(st->text->lines.first, st->text->sell)); + + barheight= (lbarh*(curarea->winy-4))/ltexth; + if (barheight<2) barheight=2; + + barstart= (lbarstart*(curarea->winy-4))/ltexth + 8; + + st->txtscroll.xmin= 5; + st->txtscroll.xmax= 17; + st->txtscroll.ymax= curarea->winy-barstart; + st->txtscroll.ymin= st->txtscroll.ymax - barheight; + + CLAMP(st->txtscroll.ymin, 2, curarea->winy-2); + CLAMP(st->txtscroll.ymax, 2, curarea->winy-2); +} + +static void draw_textscroll(SpaceText *st) +{ + if (!st->text) return; + + calc_text_rcts(st); + + cpack(0x707070); + glRecti(2, 2, 20, curarea->winy-6); + uiEmboss(2, 2, 20, curarea->winy-6, 1); + + cpack(0x909090); + glRecti(st->txtbar.xmin, st->txtbar.ymin, st->txtbar.xmax, st->txtbar.ymax); + + cpack(0x7777c6); + glRecti(st->txtscroll.xmin, st->txtscroll.ymin, st->txtscroll.xmax, st->txtscroll.ymax); + + uiEmboss(st->txtbar.xmin, st->txtbar.ymin, st->txtbar.xmax, st->txtbar.ymax, st->flags & ST_SCROLL_SELECT); +} + +static void screen_skip(SpaceText *st, int lines) +{ + int last; + + if (!st) return; + if (st->spacetype != SPACE_TEXT) return; + if (!st->text) return; + + st->top += lines; + + last= txt_get_span(st->text->lines.first, st->text->lines.last); + last= last - (st->viewlines/2); + + if (st->top>last) st->top= last; + if (st->top<0) st->top= 0; +} + +/* + * mode 1 == view scroll + * mode 2 == scrollbar + */ +static void do_textscroll(SpaceText *st, int mode) +{ + short delta[2]= {0, 0}; + short mval[2], hold[2], old[2]; + + if (!st->text) return; + + calc_text_rcts(st); + + st->flags|= ST_SCROLL_SELECT; + + glDrawBuffer(GL_FRONT); + uiEmboss(st->txtbar.xmin, st->txtbar.ymin, st->txtbar.xmax, st->txtbar.ymax, st->flags & ST_SCROLL_SELECT); + glDrawBuffer(GL_BACK); + + getmouseco_areawin(mval); + old[0]= hold[0]= mval[0]; + old[1]= hold[1]= mval[1]; + + while(get_mbut()&(L_MOUSE|M_MOUSE)) { + getmouseco_areawin(mval); + + if(old[0]!=mval[0] || old[1]!=mval[1]) { + if (mode==1) { + delta[0]= (hold[0]-mval[0])/spacetext_get_fontwidth(st); + delta[1]= (mval[1]-hold[1])/st->lheight; + } + else delta[1]= (hold[1]-mval[1])*st->pix_per_line; + + if (delta[0] || delta[1]) { + screen_skip(st, delta[1]); + st->left+= delta[0]; + if (st->left<0) st->left= 0; + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + + hold[0]=mval[0]; + hold[1]=mval[1]; + } + old[0]=mval[0]; + old[1]=mval[1]; + } else { + BIF_wait_for_statechange(); + } + } + st->flags^= ST_SCROLL_SELECT; + + glDrawBuffer(GL_FRONT); + uiEmboss(st->txtbar.xmin, st->txtbar.ymin, st->txtbar.xmax, st->txtbar.ymax, st->flags & ST_SCROLL_SELECT); + glDrawBuffer(GL_BACK); +} + +static void do_selection(SpaceText *st, int selecting) +{ + short mval[2], old[2]; + int sell, selc; + int linep2, charp2; + int first= 1; + + getmouseco_areawin(mval); + old[0]= mval[0]; + old[1]= mval[1]; + + if (!selecting) { + int curl= txt_get_span(st->text->lines.first, st->text->curl); + int curc= st->text->curc; + int linep2, charp2; + + set_cursor_to_pos(st, mval[0], mval[1], 0); + + linep2= txt_get_span(st->text->lines.first, st->text->curl); + charp2= st->text->selc; + + if (curl!=linep2 || curc!=charp2) + txt_undo_add_toop(st->text, UNDO_CTO, curl, curc, linep2, charp2); + } + + sell= txt_get_span(st->text->lines.first, st->text->sell); + selc= st->text->selc; + + while(get_mbut()&L_MOUSE) { + getmouseco_areawin(mval); + + if (mval[1]<0 || mval[1]>curarea->winy) { + int d= (old[1]-mval[1])*st->pix_per_line; + if (d) screen_skip(st, d); + + set_cursor_to_pos(st, mval[0], mval[1]<0?0:curarea->winy, 1); + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } else if (mval[0]<0 || mval[0]>curarea->winx) { + if (mval[0]>curarea->winx) st->left++; + else if (mval[0]<0 && st->left>0) st->left--; + + set_cursor_to_pos(st, mval[0], mval[1], 1); + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + + PIL_sleep_ms(10); + } else if (first || old[0]!=mval[0] || old[1]!=mval[1]) { + set_cursor_to_pos(st, mval[0], mval[1], 1); + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + + old[0]= mval[0]; + old[1]= mval[1]; + first= 1; + } else { + BIF_wait_for_statechange(); + } + } + + linep2= txt_get_span(st->text->lines.first, st->text->sell); + charp2= st->text->selc; + + if (sell!=linep2 || selc!=charp2) + txt_undo_add_toop(st->text, UNDO_STO, sell, selc, linep2, charp2); +} + +void drawtextspace(void) +{ + SpaceText *st= curarea->spacedata.first; + Text *text; + int i; + TextLine *tmp; + + if (BPY_spacetext_is_pywin(st)) { + BPY_spacetext_do_pywin_draw(st); + return; + } + + glClearColor(0.6, 0.6, 0.6, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + myortho2(-0.5, curarea->winrct.xmax-curarea->winrct.xmin-0.5, -0.5, curarea->winrct.ymax-curarea->winrct.ymin-0.5); + + text= st->text; + if(!text) return; + + /* Make sure all the positional pointers exist */ + if (!text->curl || !text->sell || !text->lines.first || !text->lines.last) + txt_clean_text(text); + + if(st->lheight) st->viewlines= (int) curarea->winy/st->lheight; + else st->viewlines= 0; + + glColor3f(0.0, 0.0, 0.0); + + draw_cursor(st); + + tmp= text->lines.first; + for (i= 0; i<st->top && tmp; i++) + tmp= tmp->next; + for (i=0; i<st->viewlines && tmp; i++, tmp= tmp->next) + text_draw(st, tmp->line, st->left, 0, 1, TXT_OFFSET, curarea->winy-st->lheight*(i+1)); + + draw_textscroll(st); + + curarea->win_swap= WIN_BACK_OK; +} + +void pop_space_text (SpaceText *st) +{ + int i, x; + + if(!st) return; + if(!st->text) return; + if(!st->text->curl) return; + + i= txt_get_span(st->text->lines.first, st->text->curl); + if (st->top+st->viewlines <= i || st->top > i) { + st->top= i - st->viewlines/2; + } + + x= text_draw(st, st->text->curl->line, st->left, st->text->curc, 0, 0, 0); + + if (x==0 || x>curarea->winx) { + st->left= st->text->curc-0.5*(curarea->winx)/spacetext_get_fontwidth(st); + } + + if (st->top < 0) st->top= 0; + if (st->left <0) st->left= 0; +} + +void add_text_fs(char *file) +{ + SpaceText *st= curarea->spacedata.first; + Text *text; + + if (!st) return; + if (st->spacetype != SPACE_TEXT) return; + + text= add_text(file); + + st->text= text; + + st->top= 0; + + allqueue(REDRAWTEXT, 0); + allqueue(REDRAWHEADERS, 0); +} + +void free_textspace(SpaceText *st) +{ + if (!st) return; + + st->text= NULL; +} + +static void save_mem_text(char *str) +{ + SpaceText *st= curarea->spacedata.first; + Text *text; + + if (!str) return; + + if (!st) return; + if (st->spacetype != SPACE_TEXT) return; + + text= st->text; + if(!text) return; + + if (text->name) MEM_freeN(text->name); + text->name= MEM_mallocN(strlen(str)+1, "textname"); + strcpy(text->name, str); + + text->flags ^= TXT_ISMEM; + + txt_write_file(text); +} + +void txt_write_file(Text *text) +{ + FILE *fp; + TextLine *tmp; + + /* Do we need to get a filename? */ + if (text->flags & TXT_ISMEM) { + activate_fileselect(FILE_SPECIAL, "SAVE TEXT FILE", G.sce, save_mem_text); + return; + } + + /* Should we ask to save over? */ + if (text->flags & TXT_ISTMP) { + if (BLI_exists(text->name)) { + if (!okee("Save over?")) return; + } else if (!okee("Create new file?")) return; + + text->flags ^= TXT_ISTMP; + } + + fp= fopen(text->name, "w"); + if (fp==NULL) { + error("Unable to save file"); + return; + } + + tmp= text->lines.first; + while (tmp) { + if (tmp->next) fprintf(fp, "%s\n", tmp->line); + else fprintf(fp, "%s", tmp->line); + + tmp= tmp->next; + } + + fclose (fp); + + if (text->flags & TXT_ISDIRTY) text->flags ^= TXT_ISDIRTY; +} + +void unlink_text(Text *text) +{ + bScreen *scr; + ScrArea *area; + SpaceLink *sl; + + for (scr= G.main->screen.first; scr; scr= scr->id.next) { + for (area= scr->areabase.first; area; area= area->next) { + for (sl= area->spacedata.first; sl; sl= sl->next) { + if (sl->spacetype==SPACE_TEXT) { + SpaceText *st= (SpaceText*) sl; + + if (st->text==text) { + st->text= NULL; + st->top= 0; + + if (st==area->spacedata.first) { + scrarea_queue_redraw(area); + } + } + } + } + } + } +} + +static int jumptoline_interactive(SpaceText *st) { + short nlines= txt_get_span(st->text->lines.first, st->text->lines.last)+1; + short tmp= txt_get_span(st->text->lines.first, st->text->curl)+1; + + if (button(&tmp, 1, nlines, "Jump to line:")) { + txt_move_toline(st->text, tmp-1, 0); + pop_space_text(st); + return 1; + } else { + return 0; + } +} + +void winqreadtextspace(unsigned short event, short val, char ascii) +{ + SpaceText *st= curarea->spacedata.first; + Text *text= st->text; + char *py_filename; + int do_draw=0, p; + + if (BPY_spacetext_is_pywin(st)) { + BPY_spacetext_do_pywin_event(st, event, val); + return; + } + + text= st->text; + + if (!text) { + if (val && !ELEM(G.qual, 0, LR_SHIFTKEY)) { + if (event==FKEY && (G.qual & LR_ALTKEY) && (G.qual & LR_SHIFTKEY)) { + switch (pupmenu("File %t|New %x0|Open... %x1")) { + case 0: + st->text= add_empty_text(); + st->top= 0; + + allqueue(REDRAWTEXT, 0); + allqueue(REDRAWHEADERS, 0); + break; + case 1: + activate_fileselect(FILE_SPECIAL, "LOAD TEXT FILE", G.sce, add_text_fs); + break; + } + } else if (event==QKEY) { + if(okee("QUIT BLENDER")) exit_usiblender(); + } + } + + return; + } + + if (event==LEFTMOUSE) { + if (val) { + short mval[2]; + + getmouseco_areawin(mval); + + if (mval[0]>2 && mval[0]<20 && mval[1]>2 && mval[1]<curarea->winy-2) { + do_textscroll(st, 2); + } else { + do_selection(st, G.qual&LR_SHIFTKEY); + do_draw= 1; + } + } + } else if (event==MIDDLEMOUSE) { + if (val) { + do_textscroll(st, 1); + } + } else if (ascii) { + if (txt_add_char(text, ascii)) { + pop_space_text(st); + do_draw= 1; + } + } else if (val) { + switch (event) { + case FKEY: + if ((G.qual & LR_ALTKEY) && (G.qual & LR_SHIFTKEY)) { + p= pupmenu("File %t|New %x0|Open... %x1|Save %x2|Save As...%x3"); + + switch(p) { + case 0: + st->text= add_empty_text(); + st->top= 0; + + allqueue(REDRAWTEXT, 0); + allqueue(REDRAWHEADERS, 0); + break; + + case 1: + activate_fileselect(FILE_SPECIAL, "LOAD TEXT FILE", G.sce, add_text_fs); + break; + + case 3: + text->flags |= TXT_ISMEM; + + case 2: + txt_write_file(text); + do_draw= 1; + break; + + default: + break; + } + } else if (G.qual & LR_ALTKEY) { + char *findstr= last_txt_find_string; + + if (txt_has_sel(text) && !(G.qual & LR_CTRLKEY)) { + findstr= txt_sel_to_buf(text); + } else if (!last_txt_find_string || (G.qual & LR_CTRLKEY)) { + char buf[256]; + + if (findstr && strlen(findstr)<(sizeof(buf)-1)) + strcpy(buf, findstr); + else + buf[0]= 0; + + if (sbutton(buf, 0, sizeof(buf)-1, "Find: ") && buf[0]) + findstr= BLI_strdup(buf); + else + findstr= NULL; + } + + if (findstr!=last_txt_find_string) { + if (last_txt_find_string) + MEM_freeN(last_txt_find_string); + last_txt_find_string= findstr; + } + + if (findstr) { + if (txt_find_string(text, findstr)) + pop_space_text(st); + else + error("Not found: %s", findstr); + } + + do_draw= 1; + } + + break; + + case EKEY: + if (G.qual & LR_ALTKEY && G.qual & LR_SHIFTKEY) { + p= pupmenu("Edit %t|" + "Cut %x0|" + "Copy %x1|" + "Paste %x2|" + "Print Cut Buffer %x3"); + switch(p) { + case 0: + txt_cut_sel(text); + do_draw= 1; + break; + case 1: + txt_copy_sel(text); + do_draw= 1; + break; + case 2: + txt_paste(text); + do_draw= 1; + break; + case 3: + txt_print_cutbuffer(); + break; + } + } + break; + + case VKEY: + if (G.qual & LR_ALTKEY && G.qual & LR_SHIFTKEY) { + p= pupmenu("View %t|" + "Top of File %x0|" + "Bottom of File %x1|" + "Page Up %x2|" + "Page Down %x3"); + switch(p) { + case 0: + txt_move_bof(text, 0); + do_draw= 1; + pop_space_text(st); + break; + + case 1: + txt_move_eof(text, 0); + do_draw= 1; + pop_space_text(st); + break; + + case 2: + screen_skip(st, -st->viewlines); + do_draw= 1; + break; + + case 3: + screen_skip(st, st->viewlines); + do_draw= 1; + break; + } + } + break; + + case SKEY: + if (G.qual & LR_ALTKEY && G.qual & LR_SHIFTKEY) { + p= pupmenu("Select %t|" + "Select All %x0|" + "Select Line %x1|" + "Jump to Line %x3"); + switch(p) { + case 0: + txt_sel_all(text); + do_draw= 1; + break; + + case 1: + txt_sel_line(text); + do_draw= 1; + break; + + case 3: + do_draw= jumptoline_interactive(st); + break; + } + } + break; + + case QKEY: + if(okee("QUIT BLENDER")) exit_usiblender(); + break; + } + + switch(event) { + case AKEY: + if (G.qual & LR_CTRLKEY) { + txt_move_bol(text, G.qual & LR_SHIFTKEY); + do_draw= 1; + pop_space_text(st); + } else if (G.qual & LR_ALTKEY) { + txt_sel_all(text); + do_draw= 1; + } + break; + + case CKEY: + if (G.qual & LR_ALTKEY) { + txt_copy_sel(text); + do_draw= 1; + } + break; + + case DKEY: + if (G.qual & LR_CTRLKEY) { + txt_delete_char(text); + do_draw= 1; + pop_space_text(st); + } + break; + + case EKEY: + if (G.qual & LR_CTRLKEY) { + txt_move_eol(text, G.qual & LR_SHIFTKEY); + do_draw= 1; + pop_space_text(st); + } + break; + + case JKEY: + if (G.qual & LR_ALTKEY) { + do_draw= jumptoline_interactive(st); + } + break; + + case OKEY: + if (G.qual & LR_ALTKEY) { + activate_fileselect(FILE_SPECIAL, "LOAD TEXT FILE", G.sce, add_text_fs); + } + break; + + case PKEY: + if (G.qual & LR_ALTKEY) { + if (!BPY_txt_do_python(st)) { + int lineno = BPY_Err_getLinenumber(); + // jump to error if happened in current text: + py_filename = (char*) BPY_Err_getFilename(); + if (!strcmp(py_filename, st->text->id.name+2)) { + error("Python script error, check console"); + if (lineno >= 0) { + txt_move_toline(text, lineno-1, 0); + txt_sel_line(text); + do_draw= 1; + pop_space_text(st); + } + } else { + error("Error in other (possibly external) file, "\ + "check console"); + } + } + } + break; + + case RKEY: + if (G.qual & LR_ALTKEY) { + txt_do_redo(text); + do_draw= 1; + } + if (G.qual & LR_CTRLKEY) { + if (text->compiled) BPY_free_compiled_text(text); + text->compiled = NULL; + if (okee("Reopen Text")) { + if (!reopen_text(text)) { + error("Could not reopen file"); + } + } + do_draw= 1; + } + break; + + case SKEY: + if (G.qual & LR_ALTKEY) { + if (G.qual & LR_SHIFTKEY) + if (text) text->flags |= TXT_ISMEM; + + txt_write_file(text); + do_draw= 1; + } + break; + + case UKEY: + if (G.qual & LR_ALTKEY) { + if (G.qual & LR_SHIFTKEY) txt_print_undo(text); + else { + txt_do_undo(text); + do_draw= 1; + } + } + break; + + case VKEY: + if (G.qual & LR_ALTKEY) { + txt_paste(text); + do_draw= 1; + pop_space_text(st); + } + break; + + case XKEY: + if (G.qual & LR_ALTKEY) { + txt_cut_sel(text); + do_draw= 1; + pop_space_text(st); + } + break; + + case TABKEY: + txt_add_char(text, '\t'); + pop_space_text(st); + do_draw= 1; + break; + + case RETKEY: + txt_split_curline(text); + do_draw= 1; + pop_space_text(st); + break; + + case BACKSPACEKEY: + txt_backspace_char(text); + do_draw= 1; + pop_space_text(st); + break; + + case DELKEY: + txt_delete_char(text); + do_draw= 1; + pop_space_text(st); + break; + + case DOWNARROWKEY: + txt_move_down(text, G.qual & LR_SHIFTKEY); + do_draw= 1; + pop_space_text(st); + break; + + case LEFTARROWKEY: + txt_move_left(text, G.qual & LR_SHIFTKEY); + do_draw= 1; + pop_space_text(st); + break; + + case RIGHTARROWKEY: + txt_move_right(text, G.qual & LR_SHIFTKEY); + do_draw= 1; + pop_space_text(st); + break; + + case UPARROWKEY: + txt_move_up(text, G.qual & LR_SHIFTKEY); + do_draw= 1; + pop_space_text(st); + break; + + case PAGEDOWNKEY: + screen_skip(st, st->viewlines); + do_draw= 1; + break; + + case PAGEUPKEY: + screen_skip(st, -st->viewlines); + do_draw= 1; + break; + } + } + + if (do_draw) { + ScrArea *sa; + + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + SpaceText *st= sa->spacedata.first; + + if (st && st->spacetype==SPACE_TEXT) { + scrarea_queue_redraw(sa); + } + } + } +} diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c new file mode 100644 index 00000000000..1db14d8cad9 --- /dev/null +++ b/source/blender/src/drawview.c @@ -0,0 +1,1650 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +//#define NAN_LINEAR_PHYSICS + +#include <math.h> +#ifndef WIN32 +#include <unistd.h> +#include <sys/times.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "PIL_time.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "IMB_imbuf_types.h" + +#include "DNA_object_types.h" +#include "DNA_constraint_types.h" +#include "DNA_group_types.h" +#include "DNA_image_types.h" +#include "DNA_screen_types.h" +#include "DNA_texture_types.h" +#include "DNA_view3d_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_action.h" +#include "BKE_anim.h" +#include "BKE_constraint.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_ika.h" +#include "BKE_image.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_main.h" +#include "BKE_object.h" +#include "BKE_texture.h" +#include "BKE_utildefines.h" + +#include "BIF_gl.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_interface.h" +#include "BIF_space.h" +#include "BIF_buttons.h" +#include "BIF_drawimage.h" +#include "BIF_editgroup.h" +#include "BIF_mywindow.h" + +#include "BDR_drawmesh.h" +#include "BDR_drawobject.h" + +#include "BSE_view.h" +#include "BSE_drawview.h" +#include "BSE_headerbuttons.h" + +#include "RE_renderconverter.h" + +#include "BPY_extern.h" // Blender Python library + +#include "interface.h" +#include "blendef.h" +#include "mydevice.h" + +/* Modules used */ +#include "render.h" +#include "radio.h" + +/* for physics in animation playback */ +#ifdef NAN_LINEAR_PHYSICS +#include "sumo.h" +#endif + +/* locals */ +void drawname(Object *ob); +void star_stuff_init_func(void); +void star_stuff_vertex_func(float* i); +void star_stuff_term_func(void); + +void star_stuff_init_func(void) +{ + cpack(-1); + glPointSize(1.0); + glBegin(GL_POINTS); +} +void star_stuff_vertex_func(float* i) +{ + glVertex3fv(i); +} +void star_stuff_term_func(void) +{ + glEnd(); +} + +void setalpha_bgpic(BGpic *bgpic) +{ + int x, y, alph; + char *rect; + + alph= (int)(255.0*(1.0-bgpic->blend)); + + rect= (char *)bgpic->rect; + for(y=0; y< bgpic->yim; y++) { + for(x= bgpic->xim; x>0; x--, rect+=4) { + rect[3]= alph; + } + } +} + + +static float light_pos1[] = { -0.3, 0.3, 0.90, 0.0 }; +/* static float light_pos2[] = { 0.3, -0.3, -0.90, 0.0 }; never used? */ + +void default_gl_light(void) +{ + float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 }; + float light_col1[] = { 0.8, 0.8, 0.8, 0.0 }; + + int a; + + glLightfv(GL_LIGHT0, GL_POSITION, light_pos1); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_col1); + glLightfv(GL_LIGHT0, GL_SPECULAR, mat_specular); + + glEnable(GL_LIGHT0); + for(a=1; a<8; a++) glDisable(GL_LIGHT0+a); + glDisable(GL_LIGHTING); + + glDisable(GL_COLOR_MATERIAL); +} + +void init_gl_stuff(void) +{ + float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 }; + float mat_shininess[] = { 35.0 }; +/* float one= 1.0; */ + int a, x, y; + GLubyte pat[32*32]; + const GLubyte *patc= pat; + + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); + + default_gl_light(); + + /* no local viewer, looks ugly in ortho mode */ + /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */ + + glDepthFunc(GL_LEQUAL); + /* scaling matrices */ + glEnable(GL_NORMALIZE); + + glShadeModel(GL_FLAT); + + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glDisable(GL_LIGHTING); + glDisable(GL_LOGIC_OP); + glDisable(GL_STENCIL_TEST); + glDisable(GL_TEXTURE_1D); + glDisable(GL_TEXTURE_2D); + + glPixelTransferi(GL_MAP_COLOR, GL_FALSE); + glPixelTransferi(GL_RED_SCALE, 1); + glPixelTransferi(GL_RED_BIAS, 0); + glPixelTransferi(GL_GREEN_SCALE, 1); + glPixelTransferi(GL_GREEN_BIAS, 0); + glPixelTransferi(GL_BLUE_SCALE, 1); + glPixelTransferi(GL_BLUE_BIAS, 0); + glPixelTransferi(GL_ALPHA_SCALE, 1); + glPixelTransferi(GL_ALPHA_BIAS, 0); + + a= 0; + for(x=0; x<32; x++) { + for(y=0; y<4; y++) { + if( (x) & 1) pat[a++]= 0x88; + else pat[a++]= 0x22; + } + } + + glPolygonStipple(patc); + + + init_realtime_GL(); +} + +void two_sided(int val) +{ + + /* twosided aan: geft errors bij x flip! */ + glLightModeliv(GL_LIGHT_MODEL_TWO_SIDE, (GLint *)&val); +} + +void circf(float x, float y, float rad) +{ + GLUquadricObj *qobj = gluNewQuadric(); + + gluQuadricDrawStyle(qobj, GLU_FILL); + + glPushMatrix(); + + glTranslatef(x, y, 0.); + + gluDisk( qobj, 0.0, rad, 32, 1); + + glPopMatrix(); + + gluDeleteQuadric(qobj); +} + +void circ(float x, float y, float rad) +{ + GLUquadricObj *qobj = gluNewQuadric(); + + gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); + + glPushMatrix(); + + glTranslatef(x, y, 0.); + + gluDisk( qobj, 0.0, rad, 32, 1); + + glPopMatrix(); + + gluDeleteQuadric(qobj); +} + +/* ********** IN ONTWIKKELING ********** */ + +static void draw_bgpic(void) +{ + BGpic *bgpic; + Image *ima; + float vec[3], fac, asp, zoomx, zoomy; + int x1, y1, x2, y2, cx, cy; + short mval[2]; + + bgpic= G.vd->bgpic; + if(bgpic==0) return; + + if(bgpic->tex) { + init_render_texture(bgpic->tex); + free_unused_animimages(); + ima= bgpic->tex->ima; + end_render_texture(bgpic->tex); + } + else { + ima= bgpic->ima; + } + + if(ima==0) return; + if(ima->ok==0) return; + + /* plaatje testen */ + if(ima->ibuf==0) { + + if(bgpic->rect) MEM_freeN(bgpic->rect); + bgpic->rect= 0; + + if(bgpic->tex) { + ima_ibuf_is_nul(bgpic->tex); + } + else { + waitcursor(1); + load_image(ima, IB_rect, G.sce, G.scene->r.cfra); + waitcursor(0); + } + if(ima->ibuf==0) { + ima->ok= 0; + return; + } + } + + if(bgpic->rect==0) { + + bgpic->rect= MEM_dupallocN(ima->ibuf->rect); + bgpic->xim= ima->ibuf->x; + bgpic->yim= ima->ibuf->y; + setalpha_bgpic(bgpic); + } + + if(G.vd->persp==2) { + rcti vb; + + calc_viewborder(G.vd, &vb); + + x1= vb.xmin; + y1= vb.ymin; + x2= vb.xmax; + y2= vb.ymax; + } + else { + /* windowco berekenen */ + initgrabz(0.0, 0.0, 0.0); + window_to_3d(vec, 1, 0); + fac= MAX3( fabs(vec[0]), fabs(vec[1]), fabs(vec[1]) ); + fac= 1.0/fac; + + asp= ( (float)ima->ibuf->y)/(float)ima->ibuf->x; + + vec[0]= vec[1]= vec[2]= 0.0; + project_short_noclip(vec, mval); + cx= mval[0]; + cy= mval[1]; + + x1= cx+ fac*(bgpic->xof-bgpic->size); + y1= cy+ asp*fac*(bgpic->yof-bgpic->size); + x2= cx+ fac*(bgpic->xof+bgpic->size); + y2= cy+ asp*fac*(bgpic->yof+bgpic->size); + } + + /* volledige clip? */ + + if(x2 < 0 ) return; + if(y2 < 0 ) return; + if(x1 > curarea->winx ) return; + if(y1 > curarea->winy ) return; + + zoomx= x2-x1; + zoomx /= (float)ima->ibuf->x; + zoomy= y2-y1; + zoomy /= (float)ima->ibuf->y; + + glEnable(GL_BLEND); + if(G.zbuf) glDisable(GL_DEPTH_TEST); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + rectwrite_part(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winrct.xmax, curarea->winrct.ymax, + x1+curarea->winrct.xmin, y1+curarea->winrct.ymin, ima->ibuf->x, ima->ibuf->y, zoomx, zoomy, bgpic->rect); + + glBlendFunc(GL_ONE, GL_ZERO); + glDisable(GL_BLEND); + if(G.zbuf) glEnable(GL_DEPTH_TEST); + +} + +void timestr(double time, char *str) +{ + /* formaat 00:00:00.00 (hr:min:sec) string moet 12 lang */ + int hr= (int) time/(60*60); + int min= (int) fmod(time/60, 60.0); + int sec= (int) fmod(time, 60.0); + int hun= (int) fmod(time*100.0, 100.0); + + if (hr) { + sprintf(str, "%.2d:%.2d:%.2d.%.2d",hr,min,sec,hun); + } else { + sprintf(str, "%.2d:%.2d.%.2d",min,sec,hun); + } + + str[11]=0; +} + + +static void drawgrid(void) +{ + /* extern short bgpicmode; */ + float wx, wy, x, y, fw, fx, fy, dx; + float vec4[4]; + + vec4[0]=vec4[1]=vec4[2]=0.0; + vec4[3]= 1.0; + Mat4MulVec4fl(G.vd->persmat, vec4); + fx= vec4[0]; + fy= vec4[1]; + fw= vec4[3]; + + wx= (curarea->winx/2.0); /* ivm afrondfoutjes, grid op verkeerde plek */ + wy= (curarea->winy/2.0); + + x= (wx)*fx/fw; + y= (wy)*fy/fw; + + vec4[0]=vec4[1]=G.vd->grid; + vec4[2]= 0.0; + vec4[3]= 1.0; + Mat4MulVec4fl(G.vd->persmat, vec4); + fx= vec4[0]; + fy= vec4[1]; + fw= vec4[3]; + + dx= fabs(x-(wx)*fx/fw); + if(dx==0) dx= fabs(y-(wy)*fy/fw); + + if(dx<6.0) { + dx*= 10.0; + setlinestyle(3); + if(dx<6.0) { + dx*= 10.0; + if(dx<6.0) { + setlinestyle(0); + return; + } + } + } + + persp(0); + + cpack(0x484848); + + x+= (wx); + y+= (wy); + fx= x/dx; + fx= x-dx*floor(fx); + + while(fx< curarea->winx) { + fdrawline(fx, 0.0, fx, (float)curarea->winy); + fx+= dx; + } + + fy= y/dx; + fy= y-dx*floor(fy); + + + while(fy< curarea->winy) { + fdrawline(0.0, fy, (float)curarea->winx, fy); + fy+= dx; + } + + /* kruis in midden */ + if(G.vd->view==3) cpack(0xA0D0A0); /* y-as */ + else cpack(0xA0A0D0); /* x-as */ + + fdrawline(0.0, y, (float)curarea->winx, y); + + if(G.vd->view==7) cpack(0xA0D0A0); /* y-as */ + else cpack(0xE0A0A0); /* z-as */ + + fdrawline(x, 0.0, x, (float)curarea->winy); + + persp(1); + setlinestyle(0); +} + + +static void drawfloor(void) +{ + View3D *vd; + float vert[3], grid; + int a, gridlines; + + vd= curarea->spacedata.first; + + vert[2]= 0.0; + + if(vd->gridlines<3) return; + + gridlines= vd->gridlines/2; + grid= gridlines*vd->grid; + + cpack(0x484848); + + for(a= -gridlines;a<=gridlines;a++) { + + if(a==0) { + if(vd->persp==0) cpack(0xA0D0A0); + else cpack(0x402000); + } + else if(a==1) { + cpack(0x484848); + } + + + glBegin(GL_LINE_STRIP); + vert[0]= a*vd->grid; + vert[1]= grid; + glVertex3fv(vert); + vert[1]= -grid; + glVertex3fv(vert); + glEnd(); + } + + cpack(0x484848); + + for(a= -gridlines;a<=gridlines;a++) { + if(a==0) { + if(vd->persp==0) cpack(0xA0A0D0); + else cpack(0); + } + else if(a==1) { + cpack(0x484848); + } + + glBegin(GL_LINE_STRIP); + vert[1]= a*vd->grid; + vert[0]= grid; + glVertex3fv(vert ); + vert[0]= -grid; + glVertex3fv(vert); + glEnd(); + } + +} + +static void drawcursor(void) +{ + + if(G.f & G_PLAYANIM) return; + + project_short( give_cursor(), &G.vd->mx); + + G.vd->mxo= G.vd->mx; + G.vd->myo= G.vd->my; + + if( G.vd->mx!=3200) { + + setlinestyle(0); + cpack(0xFF); + circ((float)G.vd->mx, (float)G.vd->my, 10.0); + setlinestyle(4); + cpack(0xFFFFFF); + circ((float)G.vd->mx, (float)G.vd->my, 10.0); + setlinestyle(0); + cpack(0x0); + + sdrawline(G.vd->mx-20, G.vd->my, G.vd->mx-5, G.vd->my); + sdrawline(G.vd->mx+5, G.vd->my, G.vd->mx+20, G.vd->my); + sdrawline(G.vd->mx, G.vd->my-20, G.vd->mx, G.vd->my-5); + sdrawline(G.vd->mx, G.vd->my+5, G.vd->mx, G.vd->my+20); + } +} + +static void view3d_get_viewborder_size(View3D *v3d, float size_r[2]) +{ + float winmax= MAX2(v3d->area->winx, v3d->area->winy); + float aspect= (float) (G.scene->r.xsch*G.scene->r.xasp)/(G.scene->r.ysch*G.scene->r.yasp); + + if(aspect>1.0) { + size_r[0]= winmax; + size_r[1]= winmax/aspect; + } else { + size_r[0]= winmax*aspect; + size_r[1]= winmax; + } +} + +void calc_viewborder(struct View3D *v3d, rcti *viewborder_r) +{ + float zoomfac, size[2]; + + view3d_get_viewborder_size(v3d, size); + + /* magic zoom calculation, no idea what + * it signifies, if you find out, tell me! -zr + */ + zoomfac= (M_SQRT2 + v3d->camzoom/50.0); + zoomfac= (zoomfac*zoomfac)*0.25; + + size[0]= size[0]*zoomfac; + size[1]= size[1]*zoomfac; + + /* center in window */ + viewborder_r->xmin= 0.5*v3d->area->winx - 0.5*size[0]; + viewborder_r->ymin= 0.5*v3d->area->winy - 0.5*size[1]; + viewborder_r->xmax= viewborder_r->xmin + size[0]; + viewborder_r->ymax= viewborder_r->ymin + size[1]; +} + +void view3d_set_1_to_1_viewborder(View3D *v3d) +{ + float size[2]; + int im_width= (G.scene->r.size*G.scene->r.xsch)/100; + + view3d_get_viewborder_size(v3d, size); + + v3d->camzoom= (sqrt(4.0*im_width/size[0]) - M_SQRT2)*50.0; + v3d->camzoom= CLAMPIS(v3d->camzoom, -30, 300); +} + +static void drawviewborder(void) +{ + float fac, a; + float x1, x2, y1, y2; + float x3, y3, x4, y4; + rcti viewborder; + + calc_viewborder(G.vd, &viewborder); + x1= viewborder.xmin; + y1= viewborder.ymin; + x2= viewborder.xmax; + y2= viewborder.ymax; + + /* rand */ + setlinestyle(3); + cpack(0); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glRectf(x1+1, y1-1, x2+1, y2-1); + + cpack(0xFFFFFF); + glRectf(x1, y1, x2, y2); + + /* border */ + if(G.scene->r.mode & R_BORDER) { + + cpack(0); + x3= x1+ G.scene->r.border.xmin*(x2-x1); + y3= y1+ G.scene->r.border.ymin*(y2-y1); + x4= x1+ G.scene->r.border.xmax*(x2-x1); + y4= y1+ G.scene->r.border.ymax*(y2-y1); + + glRectf(x3+1, y3-1, x4+1, y4-1); + + cpack(0x4040FF); + glRectf(x3, y3, x4, y4); + } + + /* safetykader */ + + fac= 0.1; + + a= fac*(x2-x1); + x1+= a; + x2-= a; + + a= fac*(y2-y1); + y1+= a; + y2-= a; + + cpack(0); + glRectf(x1+1, y1-1, x2+1, y2-1); + cpack(0xFFFFFF); + glRectf(x1, y1, x2, y2); + + setlinestyle(0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + +} + + +void backdrawview3d(int test) +{ + struct Base *base; + int tel=1; + + if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)); + else { + G.vd->flag &= ~V3D_NEEDBACKBUFDRAW; + return; + } + + if(G.vd->flag & V3D_NEEDBACKBUFDRAW); else return; + if(G.obedit) { + G.vd->flag &= ~V3D_NEEDBACKBUFDRAW; + return; + } + + if(test) { + if(qtest()) { + addafterqueue(curarea->win, BACKBUFDRAW, 1); + return; + } + } + + if(G.vd->drawtype > OB_WIRE) G.zbuf= TRUE; + curarea->win_swap &= ~WIN_BACK_OK; + + glDisable(GL_DITHER); + + glClearColor(0.0, 0.0, 0.0, 0.0); + if(G.zbuf) { + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + else { + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_DEPTH_TEST); + } + + G.f |= G_BACKBUFSEL; + + if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) { + base= (G.scene->basact); + if(base && (base->lay & G.vd->lay)) { + draw_object(base); + } + } + else { + + base= (G.scene->base.first); + while(base) { + + /* elke base ivm meerdere windows */ + base->selcol= 0x070707 | ( ((tel & 0xF00)<<12) + ((tel & 0xF0)<<8) + ((tel & 0xF)<<4) ); + tel++; + + if(base->lay & G.vd->lay) { + + if(test) { + if(qtest()) { + addafterqueue(curarea->win, BACKBUFDRAW, 1); + break; + } + } + + cpack(base->selcol); + draw_object(base); + } + base= base->next; + } + } + + if(base==0) G.vd->flag &= ~V3D_NEEDBACKBUFDRAW; + + G.f &= ~G_BACKBUFSEL; + G.zbuf= FALSE; + glDisable(GL_DEPTH_TEST); + glEnable(GL_DITHER); +} + + +void drawname(Object *ob) +{ + cpack(0x404040); + glRasterPos3f(0.0, 0.0, 0.0); + + BMF_DrawString(G.font, " "); + BMF_DrawString(G.font, ob->id.name+2); +} + +static void draw_view_icon(void) +{ + BIFIconID icon; + + if(G.vd->view==7) icon= ICON_AXIS_TOP; + else if(G.vd->view==1) icon= ICON_AXIS_FRONT; + else if(G.vd->view==3) icon= ICON_AXIS_SIDE; + else return ; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glRasterPos2f(5.0, 5.0); + BIF_draw_icon(icon); + + glBlendFunc(GL_ONE, GL_ZERO); + glDisable(GL_BLEND); +} + +void drawview3d(void) +{ + Base *base; + Object *ob; + + setwinmatrixview3d(0); /* 0= geen pick rect */ + + setviewmatrixview3d(); + + Mat4MulMat4(G.vd->persmat, G.vd->viewmat, curarea->winmat); + Mat4Invert(G.vd->persinv, G.vd->persmat); + Mat4Invert(G.vd->viewinv, G.vd->viewmat); + + if(G.vd->drawtype > OB_WIRE) { + G.zbuf= TRUE; + glEnable(GL_DEPTH_TEST); + if(G.f & G_SIMULATION) { + glClearColor(0.0, 0.0, 0.0, 0.0); + } + else { + glClearColor(0.45, 0.45, 0.45, 0.0); + } + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glLoadIdentity(); + } + else { + glClearColor(0.45, 0.45, 0.45, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + } + + myloadmatrix(G.vd->viewmat); + + if(G.vd->view==0 || G.vd->persp!=0) { + drawfloor(); + if(G.vd->persp==2) { + if(G.scene->world) { + if(G.scene->world->mode & WO_STARS) RE_make_stars(star_stuff_init_func, + star_stuff_vertex_func, + star_stuff_term_func); + } + if(G.vd->flag & V3D_DISPBGPIC) draw_bgpic(); + } + } + else { + drawgrid(); + + if(G.vd->flag & V3D_DISPBGPIC) { + draw_bgpic(); + } + } + + /* Clear the constraint "done" flags */ + for (base = G.scene->base.first; base; base=base->next){ + clear_object_constraint_status(base->object); + } + + /* eerst set tekenen */ + if(G.scene->set) { + + /* patchje: kleur blijft constant */ + G.f |= G_PICKSEL; + + base= G.scene->set->base.first; + while(base) { + if(G.vd->lay & base->lay) { + where_is_object(base->object); + + cpack(0x404040); + draw_object(base); + + if(base->object->transflag & OB_DUPLI) { + extern ListBase duplilist; + Base tbase; + + tbase= *base; + + tbase.flag= OB_FROMDUPLI; + make_duplilist(G.scene->set, base->object); + ob= duplilist.first; + while(ob) { + tbase.object= ob; + draw_object(&tbase); + ob= ob->id.next; + } + free_duplilist(); + + } + } + base= base->next; + } + + G.f &= ~G_PICKSEL; + } + +/* SILLY CODE!!!! */ +/* See next silly code... why is the same code + * ~ duplicated twice, and then this silly if(FALSE) + * in part... wacky! and bad! + */ + + /* eerst niet selected en dupli's */ + base= G.scene->base.first; + while(base) { + + if(G.vd->lay & base->lay) { + + where_is_object(base->object); + + if(FALSE && base->object->transflag & OB_DUPLI) { + extern ListBase duplilist; + Base tbase; + + /* altijd eerst original tekenen vanwege make_displist */ + draw_object(base); + + /* patchje: kleur blijft constant */ + G.f |= G_PICKSEL; + cpack(0x404040); + + tbase.flag= OB_FROMDUPLI; + make_duplilist(G.scene, base->object); + + ob= duplilist.first; + while(ob) { + tbase.object= ob; + draw_object(&tbase); + ob= ob->id.next; + } + free_duplilist(); + + G.f &= ~G_PICKSEL; + } + else if((base->flag & SELECT)==0) { + draw_object(base); + } + + } + + base= base->next; + } + /* selected */ + base= G.scene->base.first; + while(base) { + + if ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) { + draw_object(base); + } + + base= base->next; + } + +/* SILLY CODE!!!! */ + /* dupli's, als laatste om zeker te zijn de displisten zijn ok */ + base= G.scene->base.first; + while(base) { + + if(G.vd->lay & base->lay) { + if(base->object->transflag & OB_DUPLI) { + extern ListBase duplilist; + Base tbase; + + /* patchje: kleur blijft constant */ + G.f |= G_PICKSEL; + cpack(0x404040); + + tbase.flag= OB_FROMDUPLI; + make_duplilist(G.scene, base->object); + + ob= duplilist.first; + while(ob) { + tbase.object= ob; + draw_object(&tbase); + ob= ob->id.next; + } + free_duplilist(); + + G.f &= ~G_PICKSEL; + } + } + base= base->next; + } + + + if(G.scene->radio) RAD_drawall(G.vd->drawtype>=OB_SOLID); + + persp(0); + + if(G.vd->persp>1) drawviewborder(); + drawcursor(); + draw_view_icon(); + + persp(1); + + curarea->win_swap= WIN_BACK_OK; + + if(G.zbuf) { + G.zbuf= FALSE; + glDisable(GL_DEPTH_TEST); + } + + if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) { + G.vd->flag |= V3D_NEEDBACKBUFDRAW; + addafterqueue(curarea->win, BACKBUFDRAW, 1); + } +} + + + /* Called back by rendering system, icky + */ +void drawview3d_render(struct View3D *v3d) +{ + extern short v3d_windowmode; + Base *base; + Object *ob; + + /* XXXXXXXX live and die by the hack */ + free_all_realtime_images(); + mywindow_build_and_set_renderwin(); + + v3d_windowmode= 1; + setwinmatrixview3d(0); + v3d_windowmode= 0; + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(R.winmat); + glMatrixMode(GL_MODELVIEW); + + setviewmatrixview3d(); + glLoadMatrixf(v3d->viewmat); + + Mat4MulMat4(v3d->persmat, v3d->viewmat, R.winmat); + Mat4Invert(v3d->persinv, v3d->persmat); + Mat4Invert(v3d->viewinv, v3d->viewmat); + + if(v3d->drawtype > OB_WIRE) { + G.zbuf= TRUE; + glEnable(GL_DEPTH_TEST); + } + + if (v3d->drawtype==OB_TEXTURE && G.scene->world) { + glClearColor(G.scene->world->horr, G.scene->world->horg, G.scene->world->horb, 0.0); + } else { + glClearColor(0.45, 0.45, 0.45, 0.0); + } + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glLoadIdentity(); + glLoadMatrixf(v3d->viewmat); + + /* abuse! to make sure it doesnt draw the helpstuff */ + G.f |= G_SIMULATION; + + do_all_ipos(); + BPY_do_all_scripts(SCRIPT_FRAMECHANGED); + do_all_keys(); + do_all_actions(); + do_all_ikas(); + + test_all_displists(); + + /* niet erg nette calc_ipo en where_is forceer */ + ob= G.main->object.first; + while(ob) { + ob->ctime= -123.456; + ob= ob->id.next; + } + + /* eerst set tekenen */ + if(G.scene->set) { + + /* patchje: kleur blijft constant */ + G.f |= G_PICKSEL; + + base= G.scene->set->base.first; + while(base) { + if(v3d->lay & base->lay) { + if ELEM3(base->object->type, OB_LAMP, OB_CAMERA, OB_LATTICE); + else { + where_is_object(base->object); + + cpack(0x404040); + draw_object(base); + + if(base->object->transflag & OB_DUPLI) { + extern ListBase duplilist; + Base tbase; + + tbase.flag= OB_FROMDUPLI; + make_duplilist(G.scene->set, base->object); + ob= duplilist.first; + while(ob) { + tbase.object= ob; + draw_object(&tbase); + ob= ob->id.next; + } + free_duplilist(); + } + } + } + base= base->next; + } + + G.f &= ~G_PICKSEL; + } + for (base = G.scene->base.first; base; base=base->next){ + clear_object_constraint_status(base->object); + } + /* eerst niet selected en dupli's */ + base= G.scene->base.first; + while(base) { + + if(v3d->lay & base->lay) { + if ELEM3(base->object->type, OB_LAMP, OB_CAMERA, OB_LATTICE); + else { + where_is_object(base->object); + + if(base->object->transflag & OB_DUPLI) { + extern ListBase duplilist; + Base tbase; + + /* altijd eerst original tekenen vanwege make_displist */ + draw_object(base); + + /* patchje: kleur blijft constant */ + G.f |= G_PICKSEL; + cpack(0x404040); + + tbase.flag= OB_FROMDUPLI; + make_duplilist(G.scene, base->object); + ob= duplilist.first; + while(ob) { + tbase.object= ob; + draw_object(&tbase); + ob= ob->id.next; + } + free_duplilist(); + + G.f &= ~G_PICKSEL; + } + else if((base->flag & SELECT)==0) { + draw_object(base); + } + } + } + + base= base->next; + } + + /* selected */ + base= G.scene->base.first; + while(base) { + + if ( ((base)->flag & SELECT) && ((base)->lay & v3d->lay) ) { + if ELEM3(base->object->type, OB_LAMP, OB_CAMERA, OB_LATTICE); + else draw_object(base); + } + + base= base->next; + } + + if(G.scene->radio) RAD_drawall(G.vd->drawtype>=OB_SOLID); + + if(G.zbuf) { + G.zbuf= FALSE; + glDisable(GL_DEPTH_TEST); + } + + G.f &= ~G_SIMULATION; + + glFinish(); + + glReadPixels(0, 0, R.rectx, R.recty, GL_RGBA, GL_UNSIGNED_BYTE, R.rectot); + glLoadIdentity(); + + free_all_realtime_images(); +} + + +double tottime = 0.0; + +int update_time(void) +{ + static double ltime; + double time; + + time = PIL_check_seconds_timer(); + + tottime += (time - ltime); + ltime = time; + return (tottime < 0.0); +} + +double speed_to_swaptime(int speed) +{ + switch(speed) { + case 1: + return 1.0/60.0; + case 2: + return 1.0/50.0; + case 3: + return 1.0/30.0; + case 4: + return 1.0/25.0; + case 5: + return 1.0/20.0; + case 6: + return 1.0/15.0; + case 7: + return 1.0/12.5; + case 8: + return 1.0/10.0; + case 9: + return 1.0/6.0; + } + return 1.0/4.0; +} + +double key_to_swaptime(int key) +{ + switch(key) { + case PAD1: + G.animspeed= 1; + tottime= 0; + return speed_to_swaptime(1); + case PAD2: + G.animspeed= 2; + tottime= 0; + return speed_to_swaptime(2); + case PAD3: + G.animspeed= 3; + tottime= 0; + return speed_to_swaptime(3); + case PAD4: + G.animspeed= 4; + tottime= 0; + return speed_to_swaptime(4); + case PAD5: + G.animspeed= 5; + tottime= 0; + return speed_to_swaptime(5); + case PAD6: + G.animspeed= 6; + tottime= 0; + return speed_to_swaptime(6); + case PAD7: + G.animspeed= 7; + tottime= 0; + return speed_to_swaptime(7); + case PAD8: + G.animspeed= 8; + tottime= 0; + return speed_to_swaptime(8); + case PAD9: + G.animspeed= 9; + tottime= 0; + return speed_to_swaptime(9); + } + + return speed_to_swaptime(G.animspeed); +} + +#ifdef NAN_LINEAR_PHYSICS + +void sumo_callback(void *obp) +{ + Object *ob= obp; + SM_Vector3 vec; + float matf[3][3]; + int i, j; + + SM_GetMatrixf(ob->sumohandle, ob->obmat[0]); + + VECCOPY(ob->loc, ob->obmat[3]); + + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + matf[i][j] = ob->obmat[i][j]; + } + } + Mat3ToEul(matf, ob->rot); +} + +void init_anim_sumo(void) +{ + extern Material defmaterial; + Base *base; + Mesh *me; + Object *ob; + Material *mat; + MFace *mface; + MVert *mvert; + float centre[3], size[3]; + int a; + SM_ShapeHandle shape; + SM_SceneHandle scene; + SM_Material material; + SM_MassProps massprops; + SM_Vector3 vec; + SM_Vector3 scaling; + + scene= SM_CreateScene(); + G.scene->sumohandle = scene; + + vec[0]= 0.0; + vec[1]= 0.0; + vec[2]= -9.8; + SM_SetForceField(scene, vec); + + /* ton: cylinders & cones are still Y-axis up, will be Z-axis later */ + /* ton: write location/rotation save and restore */ + + base= FIRSTBASE; + while (base) { + if (G.vd->lay & base->lay) { + ob= base->object; + + /* define shape, for now only meshes take part in physics */ + get_local_bounds(ob, centre, size); + + if (ob->type==OB_MESH) { + me= ob->data; + + if (ob->gameflag & OB_DYNAMIC) { + if (me->sumohandle) + shape= me->sumohandle; + else { + /* make new handle */ + switch(ob->boundtype) { + case OB_BOUND_BOX: + shape= SM_Box(2.0*size[0], 2.0*size[1], 2.0*size[2]); + break; + case OB_BOUND_SPHERE: + shape= SM_Sphere(size[0]); + break; + case OB_BOUND_CYLINDER: + shape= SM_Cylinder(size[0], 2.0*size[2]); + break; + case OB_BOUND_CONE: + shape= SM_Cone(size[0], 2.0*size[2]); + break; + } + + me->sumohandle= shape; + } + /* sumo material properties */ + mat= give_current_material(ob, 0); + if(mat==NULL) + mat= &defmaterial; + + material.restitution= mat->reflect; + material.static_friction= mat->friction; + material.dynamic_friction= mat->friction; + + /* sumo mass properties */ + massprops.mass= ob->mass; + massprops.center[0]= 0.0; + massprops.center[1]= 0.0; + massprops.center[2]= 0.0; + + massprops.inertia[0]= 0.5*ob->mass; + massprops.inertia[1]= 0.5*ob->mass; + massprops.inertia[2]= 0.5*ob->mass; + + massprops.orientation[0]= 0.0; + massprops.orientation[1]= 0.0; + massprops.orientation[2]= 0.0; + massprops.orientation[3]= 1.0; + + ob->sumohandle = SM_CreateObject(ob, shape, &material, + &massprops, sumo_callback); + SM_AddObject(scene, ob->sumohandle); + + scaling[0] = ob->size[0]; + scaling[1] = ob->size[1]; + scaling[2] = ob->size[2]; + SM_SetMatrixf(ob->sumohandle, ob->obmat[0]); + SM_SetScaling(ob->sumohandle, scaling); + + } + else { + if(me->sumohandle) shape= me->sumohandle; + else { + /* make new handle */ + shape= SM_NewComplexShape(); + + mface= me->mface; + mvert= me->mvert; + for(a=0; a<me->totface; a++,mface++) { + if(mface->v3) { + SM_Begin(); + SM_Vertex( (mvert+mface->v1)->co[0], (mvert+mface->v1)->co[1], (mvert+mface->v1)->co[2]); + SM_Vertex( (mvert+mface->v2)->co[0], (mvert+mface->v2)->co[1], (mvert+mface->v2)->co[2]); + SM_Vertex( (mvert+mface->v3)->co[0], (mvert+mface->v3)->co[1], (mvert+mface->v3)->co[2]); + if(mface->v4) + SM_Vertex( (mvert+mface->v4)->co[0], (mvert+mface->v4)->co[1], (mvert+mface->v4)->co[2]); + SM_End(); + } + } + + SM_EndComplexShape(); + + me->sumohandle= shape; + } + /* sumo material properties */ + mat= give_current_material(ob, 0); + if(mat==NULL) + mat= &defmaterial; + material.restitution= mat->reflect; + material.static_friction= mat->friction; + material.dynamic_friction= mat->friction; + + /* sumo mass properties */ + massprops.mass= ob->mass; + massprops.center[0]= 0.0; + massprops.center[1]= 0.0; + massprops.center[2]= 0.0; + + massprops.inertia[0]= 0.5*ob->mass; + massprops.inertia[1]= 0.5*ob->mass; + massprops.inertia[2]= 0.5*ob->mass; + + massprops.orientation[0]= 0.0; + massprops.orientation[1]= 0.0; + massprops.orientation[2]= 0.0; + massprops.orientation[3]= 1.0; + + ob->sumohandle= SM_CreateObject(ob, shape, &material, NULL, NULL); + SM_AddObject(scene, ob->sumohandle); + + scaling[0] = ob->size[0]; + scaling[1] = ob->size[1]; + scaling[2] = ob->size[2]; + SM_SetMatrixf(ob->sumohandle, ob->obmat[0]); + SM_SetScaling(ob->sumohandle, scaling); + } + } + } + base= base->next; + } +} + +/* update animated objects */ +void update_anim_sumo(void) +{ + SM_Vector3 scaling; + + Base *base; + Object *ob; + Mesh *me; + + base= FIRSTBASE; + while(base) { + if(G.vd->lay & base->lay) { + ob= base->object; + + if(ob->sumohandle) { + if((ob->gameflag & OB_DYNAMIC)==0) { + /* evt: optimise, check for anim */ + scaling[0] = ob->size[0]; + scaling[1] = ob->size[1]; + scaling[2] = ob->size[2]; + SM_SetMatrixf(ob->sumohandle, ob->obmat[0]); + SM_SetScaling(ob->sumohandle, scaling); + } + } + } + base= base->next; + } + +} + +void end_anim_sumo(void) +{ + Base *base; + Object *ob; + Mesh *me; + + base= FIRSTBASE; + while(base) { + if(G.vd->lay & base->lay) { + ob= base->object; + + if(ob->type==OB_MESH) { + if(ob->sumohandle) { + SM_RemoveObject(G.scene->sumohandle, ob->sumohandle); + SM_DeleteObject(ob->sumohandle); + ob->sumohandle= NULL; + } + me= ob->data; + if(me->sumohandle) { + SM_DeleteShape(me->sumohandle); + me->sumohandle= NULL; + } + } + } + base= base->next; + } + if(G.scene->sumohandle) { + SM_DeleteScene(G.scene->sumohandle); + G.scene->sumohandle= NULL; + } +} + +#endif + +void inner_play_anim_loop(int init, int mode) +{ + ScrArea *sa; + static ScrArea *oldsa; + static double swaptime; + static int curmode; + + /* init */ + if(init) { + oldsa= curarea; + swaptime= speed_to_swaptime(G.animspeed); + tottime= 0.0; + curmode= mode; +#ifdef NAN_LINEAR_PHYSICS + init_anim_sumo(); +#endif + return; + } + + set_timecursor(CFRA); + do_all_ipos(); + BPY_do_all_scripts(SCRIPT_FRAMECHANGED); + do_all_keys(); + do_all_actions(); + do_all_ikas(); + + + test_all_displists(); +#ifdef NAN_LINEAR_PHYSICS + update_anim_sumo(); + + SM_Proceed(G.scene->sumohandle, swaptime, 40, NULL); +#endif + sa= G.curscreen->areabase.first; + while(sa) { + if(sa==oldsa) { + scrarea_do_windraw(sa); + } + else if(curmode) { + if ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ) { + scrarea_do_windraw(sa); + } + } + + sa= sa->next; + } + + /* minimaal swaptime laten voorbijgaan */ + tottime -= swaptime; + while (update_time()) PIL_sleep_ms(1); + + if(CFRA==EFRA) { + if (tottime > 0.0) tottime = 0.0; + CFRA= SFRA; + } + else CFRA++; + +} + +int play_anim(int mode) +{ + ScrArea *sa, *oldsa; + int cfraont; + unsigned short event=0; + short val; + + /* patch voor zeer oude scenes */ + if(SFRA==0) SFRA= 1; + if(EFRA==0) EFRA= 250; + + if(SFRA>EFRA) return 0; + + update_time(); + + /* waitcursor(1); */ + G.f |= G_PLAYANIM; /* in sequence.c en view.c wordt dit afgevangen */ + + cfraont= CFRA; + oldsa= curarea; + + inner_play_anim_loop(1, mode); /* 1==init */ + + while(TRUE) { + + inner_play_anim_loop(0, 0); + + screen_swapbuffers(); + + while(qtest()) { + + event= extern_qread(&val); + if(event==ESCKEY) break; + else if(event==MIDDLEMOUSE) { + if(U.flag & VIEWMOVE) { + if(G.qual & LR_SHIFTKEY) viewmove(0); + else if(G.qual & LR_CTRLKEY) viewmove(2); + else viewmove(1); + } + else { + if(G.qual & LR_SHIFTKEY) viewmove(1); + else if(G.qual & LR_CTRLKEY) viewmove(2); + else viewmove(0); + } + } + else if(val) { + if(event==PAGEUPKEY) { + Group *group= G.main->group.first; + while(group) { + next_group_key(group); + group= group->id.next; + } + } + else if(event==PAGEDOWNKEY) { + Group *group= G.main->group.first; + while(group) { + prev_group_key(group); + group= group->id.next; + } + } + } + } + if(event==ESCKEY || event==SPACEKEY) break; + + if(mode==2 && CFRA==EFRA) break; + } + + if(event==SPACEKEY); + else CFRA= cfraont; + + do_all_ipos(); + do_all_keys(); + do_all_actions(); + do_all_ikas(); + + + if(oldsa!=curarea) areawinset(oldsa->win); + + /* restore all areas */ + sa= G.curscreen->areabase.first; + while(sa) { + if( (mode && sa->spacetype==SPACE_VIEW3D) || sa==curarea) addqueue(sa->win, REDRAW, 1); + + sa= sa->next; + } + + /* speed button */ + allqueue(REDRAWBUTSANIM, 0); + /* groups could have changed ipo */ + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWNLA, 0); + allqueue (REDRAWACTION, 0); + /* vooropig */ + update_for_newframe(); +#ifdef NAN_LINEAR_PHYSICS + end_anim_sumo(); +#endif + waitcursor(0); + G.f &= ~G_PLAYANIM; + + if (event==ESCKEY || event==SPACEKEY) return 1; + else return 0; +} diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c new file mode 100644 index 00000000000..a811f7fd7c3 --- /dev/null +++ b/source/blender/src/edit.c @@ -0,0 +1,830 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_armature_types.h" +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_meta_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_space_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_anim.h" +#include "BKE_object.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_lattice.h" +#include "BKE_mesh.h" + +#include "BIF_gl.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_interface.h" +#include "BIF_space.h" +#include "BIF_editview.h" +#include "BIF_glutil.h" + +#include "BSE_view.h" +#include "BSE_edit.h" +#include "BSE_trans_types.h" +#include "BSE_drawipo.h" + +#include "BDR_editobject.h" + +/* old stuff */ +#include "blendertimer.h" +#include "blendef.h" +#include "interface.h" +#include "mydevice.h" +/*#include "armature.h"*/ +/* #include "edit.h" */ +#include "nla.h" + +#ifdef __NLA +#include "BIF_editarmature.h" +#endif + +/* editmball.c */ +extern ListBase editelems; /* go away ! */ + + +/* from editobject */ +extern void make_trans_verts(float *min, float *max, int mode); + +/* circle selection callback */ +typedef void (*select_CBfunc)(short selecting, Object *editobj, short *mval, float rad); + +extern void obedit_selectionCB(short selecting, Object *editobj, + short *mval, float rad); +extern void uvedit_selectionCB(short selecting, Object *editobj, + short *mval, float rad); + +void circle_selectCB(select_CBfunc func); + +int get_border(rcti *rect, short col) +{ + float dvec[4], fac1, fac2; + int retval=1; + unsigned short event; + short mval[2], mvalo[4], val, x1, y1; + char str[64]; + + mywinset(G.curscreen->mainwin); + + /* pietsje groter, 1 pixel aan de rand */ + glReadBuffer(GL_FRONT); + glDrawBuffer(GL_FRONT); + + /* removed my_get_frontbuffer, this crashes when it gets a part outside the screen */ + /* solved it with just a redraw! */ + + mywinset(curarea->win); + + glDrawBuffer(GL_FRONT); + persp(0); + initgrabz(0.0, 0.0, 0.0); + + getmouseco_areawin(mvalo); + + /* draws the selection initial cross */ + sdrawXORline4(0, 0, mvalo[1], curarea->winx, mvalo[1]); + sdrawXORline4(1, mvalo[0], 0, mvalo[0], curarea->winy); + + while(TRUE) { + + /* als een renderwindow open is en de muis gaat erin */ + persp(1); + mywinset(curarea->win); + persp(0); + + /* selection loop while mouse pressed */ + getmouseco_areawin(mval); + + if(mvalo[0]!=mval[0] || mvalo[1]!=mval[1]) { + + /* aiming cross */ + sdrawXORline4(0, 0, mval[1], curarea->winx, mval[1]); + sdrawXORline4(1, mval[0], 0, mval[0], curarea->winy); + glFlush(); + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + } + event= extern_qread(&val); + + if(event && val) { + if(event==ESCKEY) { + retval= 0; + break; + } + else if(event==BKEY) { + /* b has been pressed twice: proceed with circle select */ + retval= 0; + break; + } + else if(event==LEFTMOUSE) break; + else if(event==MIDDLEMOUSE) break; + else if(event==RIGHTMOUSE) break; + } + } /* end while (TRUE) */ + + /* erase XORed lines */ + sdrawXORline4(-1, 0, 0, 0, 0); + + if(retval) { + /* box select */ + x1= mval[0]; + y1= mval[1]; + + getmouseco_areawin(mvalo); + + sdrawXORline4(0, x1, y1, x1, mvalo[1]); + sdrawXORline4(1, x1, mvalo[1], mvalo[0], mvalo[1]); + sdrawXORline4(2, mvalo[0], mvalo[1], mvalo[0], y1); + sdrawXORline4(3, mvalo[0], y1, x1, y1); + glFlush(); + + while(TRUE) { + getmouseco_areawin(mval); + if(mvalo[0]!=mval[0] || mvalo[1]!=mval[1]) { + + sdrawXORline4(0, x1, y1, x1, mval[1]); + sdrawXORline4(1, x1, mval[1], mval[0], mval[1]); + sdrawXORline4(2, mval[0], mval[1], mval[0], y1); + sdrawXORline4(3, mval[0], y1, x1, y1); + glFlush(); + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + } + + event= extern_qread(&val); + + /* still because of the renderwindow... */ + persp(1); + mywinset(curarea->win); + persp(0); + + if(val==0) { + if(event==ESCKEY) { + retval= 0; + break; + } + else if(event==LEFTMOUSE) break; + else if(event==MIDDLEMOUSE) break; + else if(event==RIGHTMOUSE) break; + } + + if(curarea->spacetype==SPACE_VIEW3D) { + glColor3f(0.4375, 0.4375, 0.4375); + glRecti(0, 10, 250, 20); + glColor3f(0.0, 0.0, 0.0); + + if(G.vd->persp==0) { + window_to_3d(dvec, mvalo[0]-x1, mvalo[1]-y1); + + glRasterPos2i(10, 10); + sprintf(str, "X %.4f Y %.4f Z %.4f Dia %.4f", dvec[0], dvec[1], dvec[2], sqrt(dvec[0]*dvec[0]+dvec[1]*dvec[1]+dvec[2]*dvec[2])); + BMF_DrawString(G.fonts, str); + } + else if(G.vd->persp==2) { + rcti vb; + + calc_viewborder(G.vd, &vb); + + fac1= (mvalo[0]-x1)/( (float) (vb.xmax-vb.xmin) ); + fac1*= 0.01*G.scene->r.size*G.scene->r.xsch; + + fac2= (mvalo[1]-y1)/( (float) (vb.ymax-vb.ymin) ); + fac2*= 0.01*G.scene->r.size*G.scene->r.ysch; + + glRasterPos2i(10, 10); + sprintf(str, "X %.1f Y %.1f Dia %.1f", fabs(fac1), fabs(fac2), sqrt(fac1*fac1 + fac2*fac2) ); + BMF_DrawString(G.fonts, str); + } + } + else if(curarea->spacetype==SPACE_IPO) { + SpaceIpo *sipo= curarea->spacedata.first; + + glColor3f(.40625, .40625, .40625); + glRecti(20, 30, 170, 40); + glColor3f(0.0, 0.0, 0.0); + + mvalo[2]= x1; + mvalo[3]= y1; + areamouseco_to_ipoco(&sipo->v2d, mval, dvec, dvec+1); + areamouseco_to_ipoco(&sipo->v2d, mvalo+2, dvec+2, dvec+3); + + glRasterPos2i(30, 30); + sprintf(str, "Time: %.4f Y %.4f", dvec[0]-dvec[2], dvec[1]-dvec[3]); + BMF_DrawString(G.fonts, str); + } + } /* end while (TRUE) */ + sdrawXORline4(-1, 0, 0, 0, 0); + + if(retval) { + rect->xmin= x1; + rect->ymin= y1; + rect->xmax= mval[0]; + rect->ymax= mval[1]; + retval= event; + + /* normaliseren */ + if(rect->xmin>rect->xmax) SWAP(int, rect->xmin, rect->xmax); + if(rect->ymin>rect->ymax) SWAP(int, rect->ymin, rect->ymax); + + if(rect->xmin==rect->xmax) retval= 0; + if(rect->ymin==rect->ymax) retval= 0; + } + } + + + /* wissen */ + if(event!=BKEY) { + if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_IPO) { + scrarea_queue_winredraw(curarea); + } + } + + glFlush(); + glReadBuffer(GL_BACK); + glDrawBuffer(GL_BACK); + + persp(1); + + /* pressed B again ? -> brush select */ + if(event==BKEY) { + switch (curarea->spacetype) { + case SPACE_VIEW3D: + if (G.obedit) + circle_selectCB(&obedit_selectionCB); + return 0; + case SPACE_IMAGE: // brush select in UV editor + circle_selectCB(&uvedit_selectionCB); + // this is a hack; we return 0 that the caller from get_border + // doesn't execute the selection code for border select.. + return 0; + } + } + return retval; +} + +void draw_sel_circle(short *mval, short *mvalo, float rad, float rado, int selecting) +{ + static short no_mvalo=0; + + if(mval==0 && mvalo==0) { /* signal */ + no_mvalo= 1; + return; + } + + persp(0); + glDrawBuffer(GL_FRONT); + + /* cirkel tekenen */ + + if(mvalo && no_mvalo==0) { + sdrawXORcirc(mvalo[0], mvalo[1], rado); + } + + if(mval) { + sdrawXORcirc(mval[0], mval[1], rad); + } + + glFlush(); + persp(1); + glDrawBuffer(GL_BACK); + + no_mvalo= 0; +} + +/** This function does the same as editview.c:circle_select(), + * but the selection actions are defined by a callback, making + * it (hopefully) reusable for other windows than the 3D view. + */ + +void circle_selectCB(select_CBfunc callback) +{ + static float rad= 40.0; + float rado; + int firsttime=1; + unsigned short event; + short mvalo[2], mval[2], val; + short selecting=0; + Object *obj; + + if(G.obedit) obj = G.obedit; + else obj = OBACT; + + + getmouseco_areawin(mvalo); + draw_sel_circle(mvalo, 0, rad, 0.0, selecting); + + rado= rad; + + while(TRUE) { + + /* als een renderwindow open is en de muis gaat erin */ + + mywinset(curarea->win); + + getmouseco_areawin(mval); + + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || rado!=rad || firsttime) { + firsttime= 0; + + draw_sel_circle(mval, mvalo, rad, rado, selecting); + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + rado= rad; + + if(selecting) { + callback(selecting, obj, mval, rad); + } + } + event= extern_qread(&val); + if (event) { + int afbreek= 0; + + switch(event) { + case LEFTMOUSE: + case MIDDLEMOUSE: + if(val) selecting= event; + else selecting= 0; + firsttime= 1; + + break; + case PADPLUSKEY: + if(val) if(rad<200.0) rad*= 1.2; + break; + case PADMINUS: + if(val) if(rad>5.0) rad/= 1.2; + break; + + case ESCKEY: case SPACEKEY: case RIGHTMOUSE: + case GKEY: case SKEY: case RKEY: case XKEY: case EKEY: case TABKEY: + afbreek= 1; + break; + + } + + if(afbreek) break; + } + } + + /* cirkel wissen */ + draw_sel_circle(0, mvalo, 0, rad, 1); + + countall(); + allqueue(REDRAWINFO, 0); +} + +void count_object(Object *ob, int sel) +{ + Mesh *me; + Curve *cu; + int tot=0, totf=0; + + switch(ob->type) { + case OB_MESH: + G.totmesh++; + me= get_mesh(ob); + if(me) { + G.totvert+= me->totvert; + G.totface+= me->totface; + if(sel) { + G.totvertsel+= me->totvert; + G.totfacesel+= me->totface; + } + } + break; + + case OB_LAMP: + G.totlamp++; + break; + case OB_SURF: + case OB_CURVE: + case OB_FONT: + G.totcurve++; + tot=totf= 0; + cu= ob->data; + if(cu->disp.first==0) makeDispList(ob); + count_displist( &cu->disp, &tot, &totf); + G.totvert+= tot; + G.totface+= totf; + if(sel) { + G.totvertsel+= tot; + G.totfacesel+= totf; + } + break; + case OB_MBALL: + count_displist( &ob->disp, &tot, &totf); + G.totvert+= tot; + G.totface+= totf; + if(sel) { + G.totvertsel+= tot; + G.totfacesel+= totf; + } + + break; + } + +} + +void countall() +{ +/* extern Lattice *editLatt; in BKE_lattice.h*/ + extern ListBase editNurb; + /* extern ListBase bpbase; */ + Base *base; + Object *ob; + Mesh *me; + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + MetaElem *ml; + /* struct BodyPoint *bop; */ + struct EditVert *eve; + struct EditVlak *evl; +#ifdef __NLA + struct EditBone *ebo; +#endif + int a; + + G.totvert= G.totvertsel= G.totfacesel= G.totface= G.totobj= + G.totmesh= G.totlamp= G.totcurve= G.totobjsel= 0; + + if(G.obedit) { + + if(G.obedit->type==OB_MESH) { + eve= G.edve.first; + while(eve) { + G.totvert++; + if(eve->f & 1) G.totvertsel++; + eve= eve->next; + } + evl= G.edvl.first; + while(evl) { + G.totface++; + if(evl->v1->f & 1) { + if(evl->v2->f & 1) { + if(evl->v3->f & 1) { + if(evl->v4) { + if(evl->v4->f & 1) G.totfacesel++; + } + else { + G.totfacesel++; + } + } + } + } + evl= evl->next; + } + } +#ifdef __NLA + else if (G.obedit->type==OB_ARMATURE){ + for (ebo=G.edbo.first;ebo;ebo=ebo->next){ + + /* Synch selection to parent for ik children */ + if ((ebo->flag & BONE_IK_TOPARENT) && ebo->parent){ + G.totvert--; + if (ebo->parent->flag & BONE_TIPSEL) + ebo->flag |= BONE_ROOTSEL; + else + ebo->flag &= ~BONE_ROOTSEL; + } + + if (ebo->flag & BONE_TIPSEL) + G.totvertsel++; + if (ebo->flag & BONE_ROOTSEL) + G.totvertsel++; + + if ((ebo->flag & BONE_TIPSEL) && (ebo->flag & BONE_ROOTSEL)) + ebo->flag |= BONE_SELECTED; + else + ebo->flag &= ~BONE_SELECTED; + + // If this is an IK child and it's parent is being moved, remove our root + if ((ebo->flag & BONE_IK_TOPARENT)&& (ebo->flag & BONE_ROOTSEL) && ebo->parent && (ebo->parent->flag & BONE_TIPSEL)){ + G.totvertsel--; + } + + G.totvert+=2; + G.totface++; + + + } + } +#endif + else if ELEM3(G.obedit->type, OB_CURVE, OB_SURF, OB_FONT) { + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + G.totvert+=3; + if(bezt->f1) G.totvertsel++; + if(bezt->f2) G.totvertsel++; + if(bezt->f3) G.totvertsel++; + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + G.totvert++; + if(bp->f1 & 1) G.totvertsel++; + bp++; + } + } + nu= nu->next; + } + } + else if(G.obedit->type==OB_MBALL) { + ml= editelems.first; + while(ml) { + G.totvert++; + if(ml->flag & SELECT) G.totvertsel++; + ml= ml->next; + } + } + else if(G.obedit->type==OB_LATTICE) { + bp= editLatt->def; + + a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + while(a--) { + G.totvert++; + if(bp->f1 & 1) G.totvertsel++; + bp++; + } + } + + allqueue(REDRAWINFO, 1); /* 1, want header->win==0! */ + return; + } + else if(G.f & (G_FACESELECT + G_VERTEXPAINT + G_TEXTUREPAINT +G_WEIGHTPAINT)) { + me= get_mesh((G.scene->basact) ? (G.scene->basact->object) : 0); + if(me) { + G.totface= me->totface; + G.totvert= me->totvert; + } + allqueue(REDRAWINFO, 1); /* 1, want header->win==0! */ + return; + } + + if(G.vd==0) return; + if(G.scene==0) return; + + base= (G.scene->base.first); + while(base) { + if(G.vd->lay & base->lay) { + + G.totobj++; + if(base->flag & SELECT) G.totobjsel++; + + count_object(base->object, base->flag & SELECT); + + if(base->object->transflag & OB_DUPLI) { + extern ListBase duplilist; + + make_duplilist(G.scene, base->object); + ob= duplilist.first; + while(ob) { + G.totobj++; + count_object(ob, base->flag & SELECT); + ob= ob->id.next; + } + free_duplilist(); + } + } + base= base->next; + } + allqueue(REDRAWINFO, 1); /* 1, want header->win==0! */ +} + +void snapmenu() +{ + extern TransVert *transvmain; + extern int tottrans; + extern float originmat[3][3]; /* object.c */ + TransVert *tv; + Base *base; + Object *ob; + float gridf, *curs, imat[3][3], bmat[3][3], vec[3], min[3], max[3], centroid[3]; + int count, a; + short event; + + event= pupmenu("SNAP %t|Sel -> Grid%x1|Sel -> Curs%x2|Curs-> Grid%x3|Curs-> Sel%x4"); + + gridf= G.vd->grid; + curs= give_cursor(); + + if(event== 1 || event==2) { /* sel->grid sel->curs */ + + if(G.obedit) { +#ifdef __NLA + if ELEM5(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) make_trans_verts(bmat[0], bmat[1], 0); +#else + if ELEM4(G.obedit->type, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) make_trans_verts(bmat[0], bmat[1], 0); +#endif + if(tottrans==0) return; + + Mat3CpyMat4(bmat, G.obedit->obmat); + Mat3Inv(imat, bmat); + + tv= transvmain; + for(a=0; a<tottrans; a++, tv++) { + + if(event==2) { + + vec[0]= curs[0]-G.obedit->obmat[3][0]; + vec[1]= curs[1]-G.obedit->obmat[3][1]; + vec[2]= curs[2]-G.obedit->obmat[3][2]; + } + else { + VECCOPY(vec, tv->loc); + Mat3MulVecfl(bmat, vec); + VecAddf(vec, vec, G.obedit->obmat[3]); + vec[0]= G.vd->grid*floor(.5+ vec[0]/gridf); + vec[1]= G.vd->grid*floor(.5+ vec[1]/gridf); + vec[2]= G.vd->grid*floor(.5+ vec[2]/gridf); + VecSubf(vec, vec, G.obedit->obmat[3]); + } + Mat3MulVecfl(imat, vec); + VECCOPY(tv->loc, vec); + + } + MEM_freeN(transvmain); + transvmain= 0; + + if ELEM(G.obedit->type, OB_SURF, OB_CURVE) makeDispList(G.obedit); + + if (G.obedit->type == OB_ARMATURE) + special_trans_update(0); + + allqueue(REDRAWVIEW3D, 0); + return; + } +#ifdef __NLA + if (G.obpose){ + allqueue(REDRAWVIEW3D, 0); + return; + } +#endif + base= (G.scene->base.first); + while(base) { + if( ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) && ((base)->object->id.lib==0))) { + ob= base->object; + + if(event==2) { + vec[0]= -ob->obmat[3][0] + curs[0]; + vec[1]= -ob->obmat[3][1] + curs[1]; + vec[2]= -ob->obmat[3][2] + curs[2]; + } + else { + vec[0]= -ob->obmat[3][0]+G.vd->grid*floor(.5+ ob->obmat[3][0]/gridf); + vec[1]= -ob->obmat[3][1]+G.vd->grid*floor(.5+ ob->obmat[3][1]/gridf); + vec[2]= -ob->obmat[3][2]+G.vd->grid*floor(.5+ ob->obmat[3][2]/gridf); + } + if(ob->parent) { + where_is_object(ob); + + Mat3Inv(imat, originmat); + Mat3MulVecfl(imat, vec); + ob->loc[0]+= vec[0]; + ob->loc[1]+= vec[1]; + ob->loc[2]+= vec[2]; + } + else { + ob->loc[0]+= vec[0]; + ob->loc[1]+= vec[1]; + ob->loc[2]+= vec[2]; + } + } + + base= base->next; + } + allqueue(REDRAWVIEW3D, 0); + } + else if(event==3) { /* curs to grid */ + curs[0]= G.vd->grid*floor(.5+curs[0]/gridf); + curs[1]= G.vd->grid*floor(.5+curs[1]/gridf); + curs[2]= G.vd->grid*floor(.5+curs[2]/gridf); + + allqueue(REDRAWVIEW3D, 0); + } + else if(event==4) { /* curs to sel */ + count= 0; + INIT_MINMAX(min, max); + centroid[0]= centroid[1]= centroid[2]= 0.0; + + if(G.obedit) { + tottrans=0; +#ifdef __NLA + if ELEM5(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) make_trans_verts(bmat[0], bmat[1], 0); +#else + if ELEM4(G.obedit->type, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) make_trans_verts(bmat[0], bmat[1], 0); +#endif + if(tottrans==0) return; + + Mat3CpyMat4(bmat, G.obedit->obmat); + + tv= transvmain; + for(a=0; a<tottrans; a++, tv++) { + VECCOPY(vec, tv->loc); + Mat3MulVecfl(bmat, vec); + VecAddf(vec, vec, G.obedit->obmat[3]); + VecAddf(centroid, centroid, vec); + DO_MINMAX(vec, min, max); + } + + if(G.vd->around==V3D_CENTROID) { + VecMulf(centroid, 1.0/(float)tottrans); + VECCOPY(curs, centroid); + } + else { + curs[0]= (min[0]+max[0])/2; + curs[1]= (min[1]+max[1])/2; + curs[2]= (min[2]+max[2])/2; + } + MEM_freeN(transvmain); + transvmain= 0; + } + else { + base= (G.scene->base.first); + while(base) { + if(((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) { + VECCOPY(vec, base->object->obmat[3]); + VecAddf(centroid, centroid, vec); + DO_MINMAX(vec, min, max); + count++; + } + base= base->next; + } + if(count) { + if(G.vd->around==V3D_CENTROID) { + VecMulf(centroid, 1.0/(float)count); + VECCOPY(curs, centroid); + } + else { + curs[0]= (min[0]+max[0])/2; + curs[1]= (min[1]+max[1])/2; + curs[2]= (min[2]+max[2])/2; + } + } + } + + allqueue(REDRAWVIEW3D, 0); + } +} diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c new file mode 100644 index 00000000000..f927bcf5264 --- /dev/null +++ b/source/blender/src/editaction.c @@ -0,0 +1,1414 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <string.h> +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "PIL_time.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_curve_types.h" +#include "DNA_ipo_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" +#include "DNA_constraint_types.h" + +#include "BKE_armature.h" +#include "BKE_constraint.h" +#include "BKE_displist.h" +#include "BKE_curve.h" +#include "BKE_ipo.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_action.h" + +#include "BIF_gl.h" +#include "BIF_mywindow.h" +#include "BIF_toolbox.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_buttons.h" +#include "BIF_interface.h" +#include "BIF_editview.h" +#include "BIF_poseobject.h" +#include "BIF_editarmature.h" + +#include "BSE_edit.h" +#include "BSE_drawipo.h" +#include "BSE_headerbuttons.h" +#include "BSE_editipo.h" +#include "BSE_editaction.h" +#include "BSE_trans_types.h" +#include "BSE_editaction_types.h" + +#include "BDR_editobject.h" + +#include "blendertimer.h" + +#include "interface.h" +#include "mydevice.h" +#include "blendef.h" +#include "nla.h" + +static bPose *g_posebuf=NULL; +extern int count_action_levels (bAction *act); + +#define BEZSELECTED(bezt) (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1)) + +/* Local Function prototypes */ + +static void insertactionkey(bAction *act, bActionChannel *achan, bPoseChannel *chan, int adrcode, short makecurve, float time); +static void flip_name (char *name); +static void mouse_actionchannels(bAction *act, short *mval); +static void borderselect_action(void); +static void mouse_action(void); +static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel, bConstraintChannel **conchan); +static void delete_actionchannels(void); +static void delete_actionchannel_keys(void); +static void duplicate_actionchannel_keys(void); +static void transform_actionchannel_keys(char mode); +static void select_poseelement_by_name (char *name, int select); +static void hilight_channel (bAction *act, bActionChannel *chan, short hilight); +static void set_action_key_time (bAction *act, bPoseChannel *chan, int adrcode, short makecurve, float time); + +/* Implementation */ + +static void select_poseelement_by_name (char *name, int select) +{ + /* Synchs selection of channels with selection of object elements in posemode */ + + Object *ob; + + ob = G.obpose; + if (!ob) + return; + + switch (ob->type){ + case OB_ARMATURE: + select_bone_by_name ((bArmature*)ob->data, name, select); + break; + default: + break; + } +} +#ifdef __NLA_BAKE +bAction* bake_action_with_client (bAction *act, Object *armob, float tolerance) +{ + bAction *result=NULL; + bActionChannel *achan; + float actlen; + int curframe; + char newname[64]; + bArmature *arm; + Bone *bone; + float oldframe; + bAction *temp; + bPoseChannel *pchan; + + if (!act) + return NULL; + + arm = get_armature(armob); + + + if (G.obedit){ + error ("Not in editmode"); + return NULL; + } + + if (!arm){ + error ("Must have an armature selected"); + return NULL; + } + /* Get a new action */ + result = add_empty_action(); + + /* Assign the new action a unique name */ + sprintf (newname, "%s.BAKED", act->id.name+2); + rename_id(&result->id, newname); + + actlen = calc_action_end(act); + + oldframe = G.scene->r.cfra; + + temp = armob->action; + armob->action = act; + + for (curframe=1; curframe<ceil(actlen+1); curframe++){ + + /* Apply the old action */ + + G.scene->r.cfra = curframe; + + /* Apply the object ipo */ + get_pose_from_action(&armob->pose, act, curframe); + apply_pose_armature(arm, armob->pose, 1); + clear_object_constraint_status(armob); + where_is_armature_time(armob, curframe); + + /* For each channel: set avail keys with current values */ + for (pchan=armob->pose->chanbase.first; pchan; pchan=pchan->next){ + + /* Copy the constraints from the armature (if any) */ + + bone = get_named_bone(arm, pchan->name); + if (bone){ + + Mat4ToQuat(pchan->obmat, pchan->quat); + Mat4ToSize(pchan->obmat, pchan->size); + VECCOPY(pchan->loc, pchan->obmat[3]); + + /* Apply to keys */ + set_action_key_time (result, pchan, AC_QUAT_X, 1, curframe); + set_action_key_time (result, pchan, AC_QUAT_Y, 1, curframe); + set_action_key_time (result, pchan, AC_QUAT_Z, 1, curframe); + set_action_key_time (result, pchan, AC_QUAT_W, 1, curframe); + set_action_key_time (result, pchan, AC_LOC_X, 1, curframe); + set_action_key_time (result, pchan, AC_LOC_Y, 1, curframe); + set_action_key_time (result, pchan, AC_LOC_Z, 1, curframe); + } + } + } + + /* Make another pass to ensure all keyframes are set to linear interpolation mode */ + for (achan = result->chanbase.first; achan; achan=achan->next){ + IpoCurve* icu; + for (icu = achan->ipo->curve.first; icu; icu=icu->next){ + icu->ipo= IPO_LIN; + } + } + + notice ("Made new action \"%s\"", newname); + G.scene->r.cfra = oldframe; + armob->action = temp; + return result; +} +#endif + +void select_actionchannel_by_name (bAction *act, char *name, int select) +{ + bActionChannel *chan; + + if (!act) + return; + + for (chan = act->chanbase.first; chan; chan=chan->next){ + if (!strcmp (chan->name, name)){ + act->achan = chan; + if (select){ + chan->flag |= ACHAN_SELECTED; + hilight_channel (act, chan, 1); + } + else{ + chan->flag &= ~ACHAN_SELECTED; + hilight_channel (act, chan, 0); + } + return; + } + } +} + +void remake_action_ipos(bAction *act) +{ + bActionChannel *chan; + bConstraintChannel *conchan; + IpoCurve *icu; + + for (chan= act->chanbase.first; chan; chan=chan->next){ + if (chan->ipo){ + for (icu = chan->ipo->curve.first; icu; icu=icu->next){ + sort_time_ipocurve(icu); + testhandles_ipocurve(icu); + } + } + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + if (conchan->ipo){ + for (icu = conchan->ipo->curve.first; icu; icu=icu->next){ + sort_time_ipocurve(icu); + testhandles_ipocurve(icu); + } + } + } + } +} + +static void duplicate_actionchannel_keys(void) +{ + bAction *act; + bActionChannel *chan; + bConstraintChannel *conchan; + + act=G.saction->action; + if (!act) + return; + + /* Find selected items */ + for (chan = act->chanbase.first; chan; chan=chan->next){ + duplicate_ipo_keys(chan->ipo); + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + duplicate_ipo_keys(conchan->ipo); + } + + transform_actionchannel_keys ('g'); +} + +static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel, bConstraintChannel **rchan){ + bAction *act; + bActionChannel *chan; + IpoCurve *icu; + bActionChannel *firstchan=NULL; + bConstraintChannel *conchan, *firstconchan=NULL; + int foundsel=0; + float firstvert=-1, foundx=-1; + int i; + short mval[2]; + float ymin, ymax; + rctf rectf; + *index=0; + + *rchan=NULL; + act=G.saction->action; /* We presume that we are only called during a valid action */ + + getmouseco_areawin (mval); + + mval[0]-=7; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + + mval[0]+=14; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + ymax = count_action_levels (act) * (CHANNELHEIGHT + CHANNELSKIP); + + *sel=0; + + for (chan=act->chanbase.first; chan; chan=chan->next){ + + /* Check action channel */ + ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){ + for (icu=chan->ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].vec[1][0] > rectf.xmin && icu->bezt[i].vec[1][0] <= rectf.xmax ){ + if (!firstchan){ + firstchan=chan; + firstvert=icu->bezt[i].vec[1][0]; + *sel = icu->bezt[i].f2 & 1; + } + + if (icu->bezt[i].f2 & 1){ + if (!foundsel){ + foundsel=1; + foundx = icu->bezt[i].vec[1][0]; + } + } + else if (foundsel && icu->bezt[i].vec[1][0] != foundx){ + *index=icu->bezt[i].vec[1][0]; + *sel = 0; + return chan; + } + } + } + } + } + ymax=ymin; + + /* Check constraint channels */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){ + for (icu=conchan->ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].vec[1][0] > rectf.xmin && icu->bezt[i].vec[1][0] <= rectf.xmax ){ + if (!firstchan){ + firstchan=chan; + firstconchan=conchan; + firstvert=icu->bezt[i].vec[1][0]; + *sel = icu->bezt[i].f2 & 1; + } + + if (icu->bezt[i].f2 & 1){ + if (!foundsel){ + foundsel=1; + foundx = icu->bezt[i].vec[1][0]; + } + } + else if (foundsel && icu->bezt[i].vec[1][0] != foundx){ + *index=icu->bezt[i].vec[1][0]; + *sel = 0; + *rchan = conchan; + return chan; + } + } + } + } + } + ymax=ymin; + } + } + + *rchan = firstconchan; + *index=firstvert; + return firstchan; +} + +static void mouse_action(void) +{ + bAction *act; + short sel; + float selx; + bActionChannel *chan; + bConstraintChannel *conchan; + short mval[2]; + + act=G.saction->action; + if (!act) + return; + + getmouseco_areawin (mval); + + chan=get_nearest_actionchannel_key(&selx, &sel, &conchan); + + if (chan){ + if (!(G.qual & LR_SHIFTKEY)){ + deselect_actionchannel_keys(act, 0); + deselect_actionchannels(act, 0); + act->achan = chan; + chan->flag |= ACHAN_SELECTED; + hilight_channel (act, chan, 1); + sel = 0; + } + + if (conchan) + select_ipo_key(conchan->ipo, selx, sel); + else + select_ipo_key(chan->ipo, selx, sel); + + allqueue(REDRAWIPO, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + + } +} + +static void borderselect_action(void) +{ + rcti rect; + rctf rectf; + int val; + short mval[2]; + bActionChannel *chan; + bConstraintChannel *conchan; + bAction *act; + float ymin, ymax; + + act=G.saction->action; + val= get_border (&rect, 3); + + if (!act) + return; + + if (val){ + mval[0]= rect.xmin; + mval[1]= rect.ymin+2; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + mval[0]= rect.xmax; + mval[1]= rect.ymax-2; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + ymax=count_action_levels(act) * (CHANNELHEIGHT+CHANNELSKIP); + for (chan=act->chanbase.first; chan; chan=chan->next){ + + /* Check action */ + ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) + borderselect_ipo_key(chan->ipo, rectf.xmin, rectf.xmax, val); + + ymax=ymin; + + /* Check constraints */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) + borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, val); + + ymax=ymin; + } + } + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + } +} + +bActionChannel* get_hilighted_action_channel(bAction* action) +{ + bActionChannel *chan; + + if (!action) + return NULL; + + for (chan=action->chanbase.first; chan; chan=chan->next){ + if (chan->flag & ACHAN_SELECTED && chan->flag & ACHAN_HILIGHTED) + return chan; + } + + return NULL; + +} + +void set_exprap_action(int mode) +{ + if(G.saction->action && G.saction->action->id.lib) return; + + error ("Not yet implemented!"); +} + +void free_posebuf(void) +{ + if (g_posebuf){ + clear_pose(g_posebuf); + MEM_freeN (g_posebuf); + } + g_posebuf=NULL; +} + +void copy_posebuf (void) +{ + Object *ob; + + free_posebuf(); + + ob=G.obpose; + if (!ob){ + error ("Copybuf is empty"); + return; + } + + filter_pose_keys(); + copy_pose(&g_posebuf, ob->pose, 0); + +} + +static void flip_name (char *name) +{ + + char prefix[128]={""}; /* The part before the facing */ + char suffix[128]={""}; /* The part after the facing */ + char replace[128]={""}; /* The replacement string */ + + char *index=NULL; + /* Find the last period */ + + strcpy (prefix, name); + + /* Check for an instance of .Right */ + if (!index){ + index = strstr (prefix, "Right"); + if (index){ + *index=0; + strcpy (replace, "Left"); + strcpy (suffix, index+6); + } + } + + /* Che ck for an instance of .RIGHT */ + if (!index){ + index = strstr (prefix, "RIGHT"); + if (index){ + *index=0; + strcpy (replace, "LEFT"); + strcpy (suffix, index+6); + } + } + + + /* Check for an instance of .right */ + if (!index){ + index = strstr (prefix, "right"); + if (index){ + *index=0; + strcpy (replace, "left"); + strcpy (suffix, index+6); + } + } + + /* Check for an instance of .left */ + if (!index){ + index = strstr (prefix, "left"); + if (index){ + *index=0; + strcpy (replace, "right"); + strcpy (suffix, index+5); + } + } + + /* Check for an instance of .LEFT */ + if (!index){ + index = strstr (prefix, "LEFT"); + if (index){ + *index=0; + strcpy (replace, "RIGHT"); + strcpy (suffix, index+5); + } + } + + /* Check for an instance of .Left */ + if (!index){ + index = strstr (prefix, "Left"); + if (index){ + *index=0; + strcpy (replace, "Right"); + strcpy (suffix, index+5); + } + } + + /* check for an instance of .L */ + if (!index){ + index = strstr (prefix, ".L"); + if (index){ + *index=0; + strcpy (replace, ".R"); + strcpy (suffix, index+2); + } + } + + /* check for an instance of .l */ + if (!index){ + index = strstr (prefix, ".l"); + if (index){ + *index=0; + strcpy (replace, ".r"); + strcpy (suffix, index+2); + } + } + + /* Checl for an instance of .R */ + if (!index){ + index = strstr (prefix, ".R"); + if (index){ + *index=0; + strcpy (replace, ".L"); + strcpy (suffix, index+2); + } + } + + /* Checl for an instance of .r */ + if (!index){ + index = strstr (prefix, ".r"); + if (index){ + *index=0; + strcpy (replace, ".l"); + strcpy (suffix, index+2); + } + } + + sprintf (name, "%s%s%s", prefix, replace, suffix); +} + +void paste_posebuf (int flip){ + Object *ob; + bPoseChannel *temp, *chan; + float eul[4]; + Base *base; + int newchan = 0; + + ob=G.obpose; + if (!ob) + return; + + if (!g_posebuf){ + error ("Copybuf is empty"); + return; + }; + + collect_pose_garbage(ob); + + /* Safely merge all of the channels in this pose into + any existing pose */ + if (ob->pose){ + if (U.flag & 0x01<<14){ + /* Display "Avail, all" dialog */ + } + for (chan=g_posebuf->chanbase.first; chan; chan=chan->next){ + if (chan->flag & POSE_KEY){ + temp = copy_pose_channel (chan); + if (flip){ + flip_name (temp->name); + temp->loc[0]*=-1; + + QuatToEul(temp->quat, eul); + eul[1]*=-1; + eul[2]*=-1; + EulToQuat(eul, temp->quat); + } + + temp = set_pose_channel (ob->pose, temp); + + if (U.flag & 0x01<<14){ + /* Set keys on pose */ + if (chan->flag & POSE_ROT){ + set_action_key(ob->action, temp, AC_QUAT_X, newchan); + set_action_key(ob->action, temp, AC_QUAT_Y, newchan); + set_action_key(ob->action, temp, AC_QUAT_Z, newchan); + set_action_key(ob->action, temp, AC_QUAT_W, newchan); + }; + if (chan->flag & POSE_SIZE){ + set_action_key(ob->action, temp, AC_SIZE_X, newchan); + set_action_key(ob->action, temp, AC_SIZE_Y, newchan); + set_action_key(ob->action, temp, AC_SIZE_Z, newchan); + }; + if (chan->flag & POSE_LOC){ + set_action_key(ob->action, temp, AC_LOC_X, newchan); + set_action_key(ob->action, temp, AC_LOC_Y, newchan); + set_action_key(ob->action, temp, AC_LOC_Z, newchan); + }; + } + } + } + + if (U.flag & 0x01<<14){ + remake_action_ipos(ob->action); + allqueue (REDRAWIPO, 0); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + + /* Update deformation children */ + if (G.obpose->type == OB_ARMATURE){ + for (base= FIRSTBASE; base; base= base->next){ + if (G.obpose==base->object->parent){ + if (base->object->partype==PARSKEL) + makeDispList(base->object); + } + } + } + } +} + +void set_action_key (struct bAction *act, struct bPoseChannel *chan, int adrcode, short makecurve) +{ + set_action_key_time (act, chan, adrcode, makecurve, frame_to_float(CFRA)); +} + +static void set_action_key_time (bAction *act, bPoseChannel *chan, int adrcode, short makecurve, float time) +{ + bActionChannel *achan; + char ipstr[256]; + + if (!act) + return; + + if (!chan) + return; + /* See if this action channel exists already */ + for (achan=act->chanbase.first; achan; achan=achan->next){ + if (!strcmp (chan->name, achan->name)) + break; + } + + if (!achan){ + if (!makecurve) + return; + achan = MEM_callocN (sizeof(bActionChannel), "actionChannel"); + strcpy (achan->name, chan->name); + BLI_addtail (&act->chanbase, achan); + } + + /* Ensure the channel appears selected in the action window */ + achan->flag |= ACHAN_SELECTED; + + /* Ensure this action channel has a valid Ipo */ + if (!achan->ipo){ + sprintf (ipstr, "%s.%s", act->id.name+2, chan->name); + ipstr[23]=0; + achan->ipo= add_ipo(ipstr, ID_AC); + } + + insertactionkey(act, achan, chan, adrcode, makecurve, time); + +} + +static void insertactionkey(bAction *act, bActionChannel *achan, bPoseChannel *chan, int adrcode, short makecurve, float cfra) +{ + IpoCurve *icu; + void *poin; + float curval; + int type; + ID *id; + + if (!act){ + return; + } + if (act->id.lib){ + error ("Can't pose libactions"); + return; + } + act->achan=achan; + act->pchan=chan; + + id=(ID*) act; + + /* First see if this curve exists */ + if (!makecurve){ + if (!achan->ipo) + return; + + for (icu = achan->ipo->curve.first; icu; icu=icu->next){ + if (icu->adrcode == adrcode) + break; + } + if (!icu) + return; + } + + + icu = get_ipocurve (id, GS(id->name), adrcode, achan->ipo); + + if(icu) { + poin= get_ipo_poin(id, icu, &type); + if(poin) { + curval= read_ipo_poin(poin, type); + // cfra= frame_to_float(CFRA); + insert_vert_ipo(icu, cfra, curval); + } + } + +} + +bAction *add_empty_action(void) +{ + bAction *act; + + act= alloc_libblock(&G.main->action, ID_AC, "Action"); + act->id.flag |= LIB_FAKEUSER; + act->id.us++; + return act; +} + +static void transform_actionchannel_keys(char mode) +{ + bAction *act; + TransVert *tv; + int /*sel=0,*/ i; + bActionChannel *chan; + short mvals[2], mvalc[2], cent[2]; + float sval[2], cval[2], lastcval[2]; + short cancel=0; + float fac=0.0F; + int loop=1; + int tvtot=0; + float deltax, startx; + float cenf[2]; + int invert=0, firsttime=1; + char str[256]; + bConstraintChannel *conchan; + + act=G.saction->action; + + /* Ensure that partial selections result in beztriple selections */ + for (chan=act->chanbase.first; chan; chan=chan->next){ + tvtot+=fullselect_ipo_keys(chan->ipo); + + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + tvtot+=fullselect_ipo_keys(conchan->ipo); + } + + /* If nothing is selected, bail out */ + if (!tvtot) + return; + + + /* Build the transvert structure */ + tv = MEM_callocN (sizeof(TransVert) * tvtot, "transVert"); + tvtot=0; + for (chan=act->chanbase.first; chan; chan=chan->next){ + /* Add the actionchannel */ + tvtot = add_trans_ipo_keys(chan->ipo, tv, tvtot); + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + tvtot = add_trans_ipo_keys(conchan->ipo, tv, tvtot); + } + + /* Do the event loop */ + cent[0] = curarea->winx + (G.saction->v2d.hor.xmax)/2; + cent[1] = curarea->winy + (G.saction->v2d.hor.ymax)/2; + areamouseco_to_ipoco(G.v2d, cent, &cenf[0], &cenf[1]); + + getmouseco_areawin (mvals); + areamouseco_to_ipoco(G.v2d, mvals, &sval[0], &sval[1]); + + startx=sval[0]; + while (loop) { + /* Get the input */ + /* If we're cancelling, reset transformations */ + /* Else calc new transformation */ + /* Perform the transformations */ + while (qtest()) { + short val; + unsigned short event= extern_qread(&val); + + if (val) { + switch (event) { + case LEFTMOUSE: + case SPACEKEY: + case RETKEY: + loop=0; + break; + case XKEY: + break; + case ESCKEY: + case RIGHTMOUSE: + cancel=1; + loop=0; + break; + default: + arrows_move_cursor(event); + break; + }; + } + } + + if (cancel) { + for (i=0; i<tvtot; i++) { + tv[i].loc[0]=tv[i].oldloc[0]; + tv[i].loc[1]=tv[i].oldloc[1]; + } + } else { + getmouseco_areawin (mvalc); + areamouseco_to_ipoco(G.v2d, mvalc, &cval[0], &cval[1]); + + if (!firsttime && lastcval[0]==cval[0] && lastcval[1]==cval[1]) { + PIL_sleep_ms(1); + } else { + for (i=0; i<tvtot; i++){ + tv[i].loc[0]=tv[i].oldloc[0]; + + switch (mode){ + case 'g': + deltax = cval[0]-sval[0]; + fac= deltax; + + apply_keyb_grid(&fac, 0.0, 1.0, 0.1, U.flag & AUTOGRABGRID); + + tv[i].loc[0]+=fac; + break; + case 's': + startx=mvals[0]-(ACTWIDTH/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2); + deltax=mvalc[0]-(ACTWIDTH/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2); + fac= fabs(deltax/startx); + + apply_keyb_grid(&fac, 0.0, 0.2, 0.1, U.flag & AUTOSIZEGRID); + + if (invert){ + if (i % 03 == 0){ + memcpy (tv[i].loc, tv[i].oldloc, sizeof(tv[i+2].oldloc)); + } + if (i % 03 == 2){ + memcpy (tv[i].loc, tv[i].oldloc, sizeof(tv[i-2].oldloc)); + } + + fac*=-1; + } + startx= (G.scene->r.cfra); + + tv[i].loc[0]-= startx; + tv[i].loc[0]*=fac; + tv[i].loc[0]+= startx; + + break; + } + } + } + + if (mode=='s'){ + sprintf(str, "sizeX: %.3f", fac); + headerprint(str); + } + else if (mode=='g'){ + sprintf(str, "deltaX: %.3f", fac); + headerprint(str); + } + + if (G.saction->lock){ + do_all_actions(); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWACTION, 0); + allqueue (REDRAWIPO, 0); + allqueue(REDRAWNLA, 0); + force_draw_all(); + } + else { + addqueue (curarea->win, REDRAWALL, 0); + force_draw (); + } + } + + lastcval[0]= cval[0]; + lastcval[1]= cval[1]; + firsttime= 0; + } + + /* Update the curve */ + /* Depending on the lock status, draw necessary views */ + + do_all_actions(); + remake_action_ipos(act); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue (REDRAWIPO, 0); + MEM_freeN (tv); +} + +void deselect_actionchannel_keys (bAction *act, int test) +{ + bActionChannel *chan; + bConstraintChannel *conchan; + int sel=1;; + + if (!act) + return; + + /* Determine if this is selection or deselection */ + + if (test){ + for (chan=act->chanbase.first; chan; chan=chan->next){ + /* Test the channel ipos */ + if (is_ipo_key_selected(chan->ipo)){ + sel = 0; + break; + } + + /* Test the constraint ipos */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + if (is_ipo_key_selected(conchan->ipo)){ + sel = 0; + break; + } + } + + if (sel == 0) + break; + } + } + else + sel=0; + + /* Set the flags */ + for (chan=act->chanbase.first; chan; chan=chan->next){ + set_ipo_key_selection(chan->ipo, sel); + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + set_ipo_key_selection(conchan->ipo, sel); + } +} + +void deselect_actionchannels (bAction *act, int test) +{ + bActionChannel *chan; + bConstraintChannel *conchan; + int sel=1; + + if (!act) + return; + + /* See if we should be selecting or deselecting */ + if (test){ + for (chan=act->chanbase.first; chan; chan=chan->next){ + if (!sel) + break; + + if (chan->flag & ACHAN_SELECTED){ + sel=0; + break; + } + if (sel){ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT){ + sel=0; + break; + } + } + } + } + } + else + sel=0; + + /* Now set the flags */ + for (chan=act->chanbase.first; chan; chan=chan->next){ + select_poseelement_by_name(chan->name, sel); + + if (sel) + chan->flag |= ACHAN_SELECTED; + else + chan->flag &= ~ACHAN_SELECTED; + + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + if (sel) + conchan->flag |= CONSTRAINT_CHANNEL_SELECT; + else + conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT; + } + } + +} + +static void hilight_channel (bAction *act, bActionChannel *chan, short select) +{ + bActionChannel *curchan; + + if (!act) + return; + + for (curchan=act->chanbase.first; curchan; curchan=curchan->next){ + if (curchan==chan && select) + curchan->flag |= ACHAN_HILIGHTED; + else + curchan->flag &= ~ACHAN_HILIGHTED; + } +} + +static void mouse_actionchannels(bAction *act, short *mval) +{ + bActionChannel *chan; + bConstraintChannel *clickconchan=NULL; + float click; + int wsize; + int sel; + bConstraintChannel *conchan; + + if (!act) + return; + + wsize = (count_action_levels (act)*(CHANNELHEIGHT+CHANNELSKIP)); + + + click = (wsize-(mval[1]+G.v2d->cur.ymin)); + click += CHANNELHEIGHT/2; + click /= (CHANNELHEIGHT+CHANNELSKIP); + + if (click<0) + return; + + for (chan = act->chanbase.first; chan; chan=chan->next){ + if ((int)click==0) + break; + + click--; + + /* Check for click in a constraint */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + if ((int)click==0){ + clickconchan=conchan; + chan=act->chanbase.last; + break; + } + click--; + } + } + + if (!chan){ + if (clickconchan){ + if (clickconchan->flag & CONSTRAINT_CHANNEL_SELECT) + sel = 0; + else + sel =1; + + /* Channel names clicking */ + if (G.qual & LR_SHIFTKEY){ + // select_poseelement_by_name(chan->name, !(chan->flag & ACHAN_SELECTED)); + if (clickconchan->flag & CONSTRAINT_CHANNEL_SELECT){ + clickconchan->flag &= ~CONSTRAINT_CHANNEL_SELECT; + // hilight_channel(act, chan, 0); + } + else{ + clickconchan->flag |= CONSTRAINT_CHANNEL_SELECT; + // hilight_channel(act, chan, 1); + } + } + else{ + deselect_actionchannels (act, 0); // Auto clear + clickconchan->flag |= CONSTRAINT_CHANNEL_SELECT; + // hilight_channel(act, chan, 1); + // act->achan = chan; + // select_poseelement_by_name(chan->name, 1); + } + + } + else + return; + } + else{ + /* Choose the mode */ + if (chan->flag & ACHAN_SELECTED) + sel = 0; + else + sel =1; + + /* Channel names clicking */ + if (G.qual & LR_SHIFTKEY){ + select_poseelement_by_name(chan->name, !(chan->flag & ACHAN_SELECTED)); + if (chan->flag & ACHAN_SELECTED){ + chan->flag &= ~ACHAN_SELECTED; + hilight_channel(act, chan, 0); + } + else{ + chan->flag |= ACHAN_SELECTED; + hilight_channel(act, chan, 1); + } + } + else{ + deselect_actionchannels (act, 0); // Auto clear + chan->flag |= ACHAN_SELECTED; + hilight_channel(act, chan, 1); + act->achan = chan; + select_poseelement_by_name(chan->name, 1); + } + + } + allqueue (REDRAWIPO, 0); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + +} + +static void delete_actionchannel_keys(void) +{ + bAction *act; + bActionChannel *chan; + bConstraintChannel *conchan; + + act = G.saction->action; + if (!act) + return; + + if (!okee("Erase selected keys")) + return; + + for (chan = act->chanbase.first; chan; chan=chan->next){ + + /* Check action channel keys*/ + delete_ipo_keys(chan->ipo); + + /* Delete constraint channel keys */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + delete_ipo_keys(conchan->ipo); + } + + remake_action_ipos (act); + allspace(REMAKEIPO, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWNLA, 0); + +} +static void delete_actionchannels (void) +{ + bConstraintChannel *conchan, *nextconchan; + bActionChannel *chan, *next; + bAction *act; + int freechan; + + act=G.saction->action; + + if (!act) + return; + + for (chan=act->chanbase.first; chan; chan=chan->next){ + if (chan->flag & ACHAN_SELECTED) + break; + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + { + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT){ + chan=act->chanbase.last; + break; + } + } + } + + if (!chan && !conchan) + return; + + if (!okee("Erase selected channels")) + return; + + for (chan=act->chanbase.first; chan; chan=next){ + freechan = 0; + next=chan->next; + + /* Remove action channels */ + if (chan->flag & ACHAN_SELECTED){ + if (chan->ipo) + chan->ipo->id.us--; /* Release the ipo */ + freechan = 1; + } + + /* Remove constraint channels */ + for (conchan=chan->constraintChannels.first; conchan; conchan=nextconchan){ + nextconchan=conchan->next; + if (freechan || conchan->flag & CONSTRAINT_CHANNEL_SELECT){ + if (conchan->ipo) + conchan->ipo->id.us--; + BLI_freelinkN(&chan->constraintChannels, conchan); + } + } + + if (freechan) + BLI_freelinkN (&act->chanbase, chan); + + } + + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + +} +void winqreadactionspace(unsigned short event, short val, char ascii) +{ + SpaceAction *saction; + bAction *act; + int doredraw= 0; + short mval[2]; + float dx,dy; + int cfra; + + if(curarea->win==0) return; + + saction= curarea->spacedata.first; + if (!saction) + return; + + act=saction->action; + if(val) { + + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + getmouseco_areawin(mval); + + switch(event) { + case UI_BUT_EVENT: + do_blenderbuttons(val); + break; + case HOMEKEY: + do_action_buttons(B_ACTHOME); + break; + case DKEY: + if (G.qual & LR_SHIFTKEY && mval[0]>ACTWIDTH){ + duplicate_actionchannel_keys(); + remake_action_ipos(act); + } + break; + case DELKEY: + case XKEY: + if (mval[0]<ACTWIDTH) + delete_actionchannels (); + else + delete_actionchannel_keys (); + break; + case GKEY: + if (mval[0]>=ACTWIDTH) + transform_actionchannel_keys ('g'); + break; + case SKEY: + if (mval[0]>=ACTWIDTH) + transform_actionchannel_keys ('s'); + break; + case AKEY: + if (mval[0]<ACTWIDTH){ + deselect_actionchannels (act, 1); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue (REDRAWIPO, 0); + } + else{ + deselect_actionchannel_keys (act, 1); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue (REDRAWIPO, 0); + } + break; + case BKEY: + borderselect_action(); + break; + case RIGHTMOUSE: + if (mval[0]<ACTWIDTH) + mouse_actionchannels(act, mval); + else + mouse_action(); + break; + case LEFTMOUSE: + if (mval[0]>ACTWIDTH){ + do { + getmouseco_areawin(mval); + + areamouseco_to_ipoco(G.v2d, mval, &dx, &dy); + + cfra= (int)dx; + if(cfra< 1) cfra= 1; + + if( cfra!=CFRA ) { + CFRA= cfra; + update_for_newframe(); + force_draw_plus(SPACE_VIEW3D); + force_draw_plus(SPACE_IPO); + force_draw_plus(SPACE_BUTS); + } + + } while(get_mbut()&L_MOUSE); + } + + break; + case MIDDLEMOUSE: + view2dmove(); /* in drawipo.c */ + break; + } + } + + if(doredraw) addqueue(curarea->win, REDRAW, 1); + +} + diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c new file mode 100644 index 00000000000..31c9c94fa6f --- /dev/null +++ b/source/blender/src/editarmature.c @@ -0,0 +1,2574 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * editarmature.c: Interface for creating and posing armature objects + */ + +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_action.h" +#include "BKE_armature.h" +#include "BKE_constraint.h" +#include "BKE_global.h" +#include "BKE_object.h" + +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_interface.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_toolbox.h" +#include "BIF_editarmature.h" +#include "BIF_poseobject.h" +#include "BIF_mywindow.h" + +#include "BDR_editobject.h" +#include "BDR_drawobject.h" + +#include "BSE_edit.h" +#include "BSE_view.h" +#include "BSE_trans_types.h" +#include "BSE_editaction.h" + +#include "mydevice.h" +#include "interface.h" +#include "blendef.h" +#include "nla.h" + +/* >>>>> FIXME: ARG! Colours should be defined in a header somewhere! */ +/* Note, these came from drawobject.c They really should be in a nice header file somewhere */ +#define B_YELLOW 0x77FFFF +#define B_PURPLE 0xFF70FF + +#define B_CYAN 0xFFFF00 +#define B_AQUA 0xFFBB55 /* 0xFF8833*/ + +extern int tottrans; /* Originally defined in editobject.c */ +extern struct TransOb *transmain; /* Originally defined in editobject.c */ +extern float centre[3], centroid[3]; /* Originally defined in editobject.c */ + +/* Macros */ +#define TEST_EDITARMATURE {if(G.obedit==0) return; if( (G.vd->lay & G.obedit->lay)==0 ) return;} + +/* Local Function Prototypes */ +static void editbones_to_armature (ListBase *bones, Object *ob); +static int editbone_to_parnr (EditBone *bone); + +static void validate_editbonebutton(EditBone *bone); +static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist); +static int select_bonechildren_by_name (struct Bone *bone, char *name, int select); +static void build_bonestring (char *string, struct EditBone *bone); +static void draw_boneverti (float x, float y, float z, float size, int flag); +static void draw_bone (int armflag, int boneflag, unsigned int id, char *name, float length); +static void draw_bonechildren (struct Bone *bone, int flag, unsigned int *index); +static void add_bone_input (struct Object *ob); +static void make_boneList(struct ListBase* list, struct ListBase *bones, struct EditBone *parent); +static void make_bone_menu_children (struct Bone *bone, char *str, int *index); +static void delete_bone(struct EditBone* exBone); +static void clear_armature_children (struct Bone *bone, struct bPose *pose, char mode); +static void parnr_to_editbone(EditBone *bone); + +static int count_bones (struct bArmature *arm, int flagmask, int allbones); + +static int count_bonechildren (struct Bone *bone, int incount, int flagmask, int allbones); +static int add_trans_bonechildren (struct Object* ob, struct Bone* bone, struct TransOb* buffer, int index, char mode); +static void deselect_bonechildren (struct Bone *bone, int mode); +static void selectconnected_posebonechildren (struct Bone *bone); + +static int editbone_name_exists (char* name); +static void unique_editbone_name (char* name); +static void *get_nearest_bone (int findunsel); +static EditBone * get_nearest_editbonepoint (int findunsel, int *selmask); + +static void attach_bone_to_parent(EditBone *bone); +static Bone *get_first_selected_bonechildren (Bone *bone); + + +/* Functions */ + + + +void apply_rot_armature (Object *ob, float mat[3][3]){ + ListBase list; + EditBone *ebone; + bArmature *arm; + + arm = get_armature(ob); + + if (!arm) + return; + + /* Put the armature into editmode */ + list.first= list.last = NULL; + make_boneList(&list, &arm->bonebase, NULL); + + /* Do the rotations */ + for (ebone = list.first; ebone; ebone=ebone->next){ + + { + + /* Fixme: This is essentially duplicated from join_armature */ + + float premat[4][4]; + float postmat[4][4]; + float difmat[4][4]; + float imat[4][4]; + float temp[4][4]; + float delta[3]; + float rmat[4][4]; + + Mat4CpyMat3 (rmat, mat); + /* Get the premat */ + VecSubf (delta, ebone->tail, ebone->head); + make_boneMatrixvr(temp, delta, ebone->roll); + Mat4MulMat4 (premat, temp, rmat); + + Mat4MulVecfl(rmat, ebone->head); + Mat4MulVecfl(rmat, ebone->tail); + + /* Get the postmat */ + VecSubf (delta, ebone->tail, ebone->head); + make_boneMatrixvr(postmat, delta, ebone->roll); + + /* Find the roll */ + Mat4Invert (imat, premat); + Mat4MulMat4 (difmat, postmat, imat); + +#if 0 + printmatrix4 ("Difmat", difmat); +#endif + ebone->roll -=atan(difmat[2][0]/difmat[2][2]); + + if (difmat[0][0]<0) + ebone->roll +=M_PI; + + } + + + } + + /* Turn the list into an armature */ + editbones_to_armature(&list, ob); + + /* Free the editbones */ + if (list.first){ + BLI_freelistN (&list); + } + +} + + + +static Bone *get_first_selected_bonechildren (Bone *bone) +{ + Bone *curbone, *result; + + if (bone->flag & BONE_SELECTED) + return bone; + + for (curbone = bone->childbase.first; curbone; curbone=curbone->next){ + result = get_first_selected_bonechildren(curbone); + if (result) + return result; + }; + + return NULL; +} + +Bone *get_first_selected_bone (void) +{ + Bone *curbone, *result; + bArmature *arm; + + arm = get_armature(OBACT); + if (!arm) + return NULL; + + for (curbone = arm->bonebase.first; curbone; curbone=curbone->next){ + result = get_first_selected_bonechildren(curbone); + if (result) + return result; + } + + return NULL; +} + +void clever_numbuts_posearmature (void) +{ + bArmature *arm; + Bone *bone; + bPoseChannel *chan; + + arm = get_armature(OBACT); + if (!arm) + return; + + bone = get_first_selected_bone(); + + if (!bone) + return; + + add_numbut(0, NUM|FLO, "Loc X:", -G.vd->far, G.vd->far, bone->loc, 0); + add_numbut(1, NUM|FLO, "Loc Y:", -G.vd->far, G.vd->far, bone->loc+1, 0); + add_numbut(2, NUM|FLO, "Loc Z:", -G.vd->far, G.vd->far, bone->loc+2, 0); + + add_numbut(3, NUM|FLO, "Quat X:", -G.vd->far, G.vd->far, bone->quat, 0); + add_numbut(4, NUM|FLO, "Quat Y:", -G.vd->far, G.vd->far, bone->quat+1, 0); + add_numbut(5, NUM|FLO, "Quat Z:", -G.vd->far, G.vd->far, bone->quat+2, 0); + add_numbut(6, NUM|FLO, "Quat W:", -G.vd->far, G.vd->far, bone->quat+3, 0); + + add_numbut(7, NUM|FLO, "Size X:", -G.vd->far, G.vd->far, bone->size, 0); + add_numbut(8, NUM|FLO, "Size Y:", -G.vd->far, G.vd->far, bone->size+1, 0); + add_numbut(9, NUM|FLO, "Size Z:", -G.vd->far, G.vd->far, bone->size+2, 0); + + do_clever_numbuts("Active Bone", 10, REDRAW); + + /* This is similar to code in special_trans_update */ + + if (!G.obpose->pose) G.obpose->pose= MEM_callocN(sizeof(bPose), "pose"); + chan = MEM_callocN (sizeof (bPoseChannel), "transPoseChannel"); + + chan->flag |= POSE_LOC|POSE_ROT|POSE_SIZE; + memcpy (chan->loc, bone->loc, sizeof (chan->loc)); + memcpy (chan->quat, bone->quat, sizeof (chan->quat)); + memcpy (chan->size, bone->size, sizeof (chan->size)); + strcpy (chan->name, bone->name); + + set_pose_channel (G.obpose->pose, chan); + +} + +void clever_numbuts_armature (void) +{ + EditBone *ebone, *child; + + ebone= G.edbo.first; + + for (ebone = G.edbo.first; ebone; ebone=ebone->next){ + if (ebone->flag & BONE_SELECTED) + break; + } + + if (!ebone) + return; + + add_numbut(0, NUM|FLO, "Root X:", -G.vd->far, G.vd->far, ebone->head, 0); + add_numbut(1, NUM|FLO, "Root Y:", -G.vd->far, G.vd->far, ebone->head+1, 0); + add_numbut(2, NUM|FLO, "Root Z:", -G.vd->far, G.vd->far, ebone->head+2, 0); + + add_numbut(3, NUM|FLO, "Tip X:", -G.vd->far, G.vd->far, ebone->tail, 0); + add_numbut(4, NUM|FLO, "Tip Y:", -G.vd->far, G.vd->far, ebone->tail+1, 0); + add_numbut(5, NUM|FLO, "Tip Z:", -G.vd->far, G.vd->far, ebone->tail+2, 0); + + /* Convert roll to degrees */ + ebone->roll *= (180.0F/M_PI); + add_numbut(6, NUM|FLO, "Roll:", -G.vd->far, G.vd->far, &ebone->roll, 0); + + do_clever_numbuts("Active Bone", 7, REDRAW); + + /* Convert roll to radians */ + ebone->roll /= (180.0F/M_PI); + + // Update our parent + if (ebone->parent && ebone->flag & BONE_IK_TOPARENT){ + VECCOPY (ebone->parent->tail, ebone->head); + } + + // Update our children if necessary + for (child = G.edbo.first; child; child=child->next){ + if (child->parent == ebone && child->flag & BONE_IK_TOPARENT){ + VECCOPY (child->head, ebone->tail); + } + } +} + +void select_bone_by_name (bArmature *arm, char *name, int select) +{ + Bone *bone; + + if (!arm) + return; + + for (bone=arm->bonebase.first; bone; bone=bone->next) + if (select_bonechildren_by_name (bone, name, select)) + break; +} + +static int select_bonechildren_by_name (Bone *bone, char *name, int select) +{ + Bone *curBone; + + if (!strcmp (bone->name, name)){ + if (select) + bone->flag |= BONE_SELECTED; + else + bone->flag &= ~BONE_SELECTED; + return 1; + } + + for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ + if (select_bonechildren_by_name (curBone, name, select)) + return 1; + } + + return 0; +} +void selectconnected_armature(void) +{ + EditBone *bone, *curBone, *next; + + if (G.qual & LR_SHIFTKEY) + bone= get_nearest_bone(0); + else + bone= get_nearest_bone(1); + + if (!bone) + return; + + /* Select parents */ + for (curBone=bone; curBone; curBone=next){ + if (G.qual & LR_SHIFTKEY){ + curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + } + else{ + curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + } + + if (curBone->flag & BONE_IK_TOPARENT) + next=curBone->parent; + else + next=NULL; + } + + /* Select children */ + while (bone){ + for (curBone=G.edbo.first; curBone; curBone=next){ + next = curBone->next; + if (curBone->parent == bone){ + if (curBone->flag & BONE_IK_TOPARENT){ + if (G.qual & LR_SHIFTKEY) + curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + else + curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + bone=curBone; + break; + } + else{ + bone=NULL; + break; + } + } + } + if (!curBone) + bone=NULL; + + } + + countall(); + allqueue (REDRAWVIEW3D, 0); + +} + +void selectconnected_posearmature(void) +{ + Bone *bone, *curBone, *next; + + if (G.qual & LR_SHIFTKEY) + bone= get_nearest_bone(0); + else + bone = get_nearest_bone(1); + + if (!bone) + return; + + /* Select parents */ + for (curBone=bone; curBone; curBone=next){ + select_actionchannel_by_name (G.obpose->action, curBone->name, !(G.qual & LR_SHIFTKEY)); + if (G.qual & LR_SHIFTKEY) + curBone->flag &= ~BONE_SELECTED; + else + curBone->flag |= BONE_SELECTED; + + if (curBone->flag & BONE_IK_TOPARENT) + next=curBone->parent; + else + next=NULL; + } + + /* Select children */ + for (curBone=bone->childbase.first; curBone; curBone=next){ + selectconnected_posebonechildren (curBone); + } + + countall(); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWACTION, 0); +} + +static void selectconnected_posebonechildren (Bone *bone) +{ + Bone *curBone; + + if (!(bone->flag & BONE_IK_TOPARENT)) + return; + + select_actionchannel_by_name (G.obpose->action, bone->name, !(G.qual & LR_SHIFTKEY)); + + if (G.qual & LR_SHIFTKEY) + bone->flag &= ~BONE_SELECTED; + else + bone->flag |= BONE_SELECTED; + + for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ + selectconnected_posebonechildren (curBone); + } +} + + +char *make_bone_menu (bArmature *arm) +{ + char *menustr=NULL; + Bone *curBone; + int size; + int index=0; + + + // Count the bones + size = (count_bones (arm, 0xFFFFFFFF, 1)*48) + 256; + menustr = MEM_callocN(size, "bonemenu"); + + sprintf (menustr, "Select Bone%%t"); + + for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ + make_bone_menu_children (curBone, menustr, &index); + } + + return menustr; +} + +static void make_bone_menu_children (Bone *bone, char *str, int *index) +{ + Bone *curBone; + + sprintf (str, "%s|%s%%x%d", str, bone->name, *index); + (*index) ++; + + for (curBone=bone->childbase.first; curBone; curBone=curBone->next) + make_bone_menu_children (curBone, str, index); +} + +void free_editArmature(void) +{ + + /* Clear the editbones list */ + if (G.edbo.first){ + BLI_freelistN (&G.edbo); + } +} + +static EditBone * get_nearest_editbonepoint (int findunsel, int *selmask){ + EditBone *ebone; + GLuint buffer[MAXPICKBUF]; + short hits; + int i, takeNext=0; + int sel; + unsigned int hitresult, hitbone, firstunSel=-1; + + glInitNames(); + hits=selectprojektie(buffer, 0, 0, 0, 0); + + /* See if there are any selected bones in this group */ + if (hits){ + for (i=0; i< hits; i++){ + hitresult = buffer[3+(i*4)]; + if (!(hitresult&BONESEL_NOSEL)){ + + /* Determine which points are selected */ + hitbone = hitresult & ~(BONESEL_ROOT|BONESEL_TIP); + + /* Determine what the current bone is */ + ebone = BLI_findlink(&G.edbo, hitbone); + + /* See if it is selected */ + sel = 0; + if ((hitresult & (BONESEL_TIP|BONESEL_ROOT)) == (BONESEL_TIP|BONESEL_ROOT)) + sel = (ebone->flag & (BONE_TIPSEL| BONE_ROOTSEL)) == (BONE_TIPSEL|BONE_ROOTSEL) ? 1 : 0; + else if (hitresult & BONESEL_TIP) + sel |= ebone->flag & BONE_TIPSEL; + else if (hitresult & BONESEL_ROOT) + sel |= ebone->flag & BONE_ROOTSEL; + if (!findunsel) + sel = !sel; + + if (sel) + takeNext=1; + else{ + if (firstunSel == -1) + firstunSel = hitresult; + if (takeNext){ + *selmask =0; + if (hitresult & BONESEL_ROOT) + *selmask |= BONE_ROOTSEL; + if (hitresult & BONESEL_TIP) + *selmask |= BONE_TIPSEL; + return ebone; + } + } + } + } + + if (firstunSel != -1){ + *selmask = 0; + if (firstunSel & BONESEL_ROOT) + *selmask |= BONE_ROOTSEL; + if (firstunSel & BONESEL_TIP) + *selmask |= BONE_TIPSEL; + return BLI_findlink(&G.edbo, firstunSel & ~(BONESEL_ROOT|BONESEL_TIP)); + } +#if 1 + else{ + *selmask = 0; + if (buffer[3] & BONESEL_ROOT) + *selmask |= BONE_ROOTSEL; + if (buffer[3] & BONESEL_TIP) + *selmask |= BONE_TIPSEL; +#if 1 + return BLI_findlink(&G.edbo, buffer[3] & ~(BONESEL_ROOT|BONESEL_TIP)); +#else + return NULL; +#endif + } +#endif + } + + *selmask = 0; + return NULL; +} + +static void * get_nearest_bone (int findunsel){ + void *firstunSel=NULL, *data; + GLuint buffer[MAXPICKBUF]; + short hits; + int i, takeNext=0; + int sel; + unsigned int hitresult; + Bone *bone; + EditBone *ebone; + + glInitNames(); + hits=selectprojektie(buffer, 0, 0, 0, 0); + + + /* See if there are any selected bones in this group */ + if (hits){ + for (i=0; i< hits; i++){ + hitresult = buffer[3+(i*4)]; + if (!(hitresult&BONESEL_NOSEL)){ + + /* Determine which points are selected */ + hitresult &= ~(BONESEL_ROOT|BONESEL_TIP); + + /* Determine what the current bone is */ + if (!G.obedit){ + bone = get_indexed_bone(OBACT->data, hitresult); + if (findunsel) + sel = (bone->flag & BONE_SELECTED); + else + sel = !(bone->flag & BONE_SELECTED); + data = bone; + } + else{ + ebone = BLI_findlink(&G.edbo, hitresult); + if (findunsel) + sel = (ebone->flag & BONE_SELECTED); + else + sel = !(ebone->flag & BONE_SELECTED); + + data = ebone; + } + + if (sel) + takeNext=1; + else{ + if (!firstunSel) + firstunSel=data; + if (takeNext) + return data; + } + } + } + + if (firstunSel) + return firstunSel; +#if 1 + else{ +#if 1 + if (G.obedit) + return BLI_findlink(&G.edbo, buffer[3] & ~(BONESEL_ROOT|BONESEL_TIP)); + else + return get_indexed_bone(OBACT->data, buffer[3] & ~(BONESEL_ROOT|BONESEL_TIP)); +#else + return NULL; +#endif + } +#endif + } + + return NULL; +} + +void delete_armature(void) +{ + EditBone *curBone, *next; + + TEST_EDITARMATURE; + if(okee("Erase selected")==0) return; + + for (curBone=G.edbo.first;curBone;curBone=next){ + next=curBone->next; + if (curBone->flag&BONE_SELECTED) + delete_bone(curBone); + } + + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSCONSTRAINT, 0); + countall(); +} + + +static void delete_bone(EditBone* exBone) +{ + EditBone *curBone; + bPoseChannel *chan; + + /* Find any bones that refer to this bone */ + for (curBone=G.edbo.first;curBone;curBone=curBone->next){ + if (curBone->parent==exBone){ + curBone->parent=exBone->parent; + curBone->flag &= ~BONE_IK_TOPARENT; + } + } + + /* Erase any associated pose channel */ + if (G.obedit->pose){ + for (chan=G.obedit->pose->chanbase.first; chan; chan=chan->next){ + if (!strcmp (chan->name, exBone->name)){ + free_constraints(&chan->constraints); + BLI_freelinkN (&G.obedit->pose->chanbase, chan); + break; + } + } + } + + + allqueue(REDRAWBUTSCONSTRAINT, 0); + allqueue(REDRAWBUTSEDIT, 0); + + BLI_freelinkN (&G.edbo,exBone); +} + +void remake_editArmature(void) +{ + if(okee("Reload Original data")==0) return; + + make_editArmature(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSCONSTRAINT, 0); + allqueue(REDRAWBUTSEDIT, 0); +} + +void mouse_armature(void) +{ + EditBone* nearBone = NULL; + int selmask; + + nearBone=get_nearest_editbonepoint(1, &selmask); + + if (nearBone){ + if ((G.qual & LR_SHIFTKEY) && (nearBone->flag & selmask)) + nearBone->flag &= ~selmask; + else + nearBone->flag |= selmask; + + if (!(G.qual & LR_SHIFTKEY)){ + deselectall_armature(); + nearBone->flag |= selmask; + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSCONSTRAINT, 0); + }; + countall(); + rightmouse_transform(); +} + +void make_editArmature(void) +{ + bArmature *arm; + + if (G.obedit==0) + return; + + free_editArmature(); + + arm= get_armature(G.obedit); + if (!arm) + return; + + make_boneList (&G.edbo, &arm->bonebase,NULL); +} + +static void editbones_to_armature (ListBase *list, Object *ob) +{ + bArmature *arm; + EditBone *eBone; + Bone *newBone; + + arm = get_armature(ob); + if (!list) + return; + if (!arm) + return; + + free_bones(arm); + + + /* Copy the bones from the editData into the armature*/ + for (eBone=list->first;eBone;eBone=eBone->next){ + newBone=MEM_callocN (sizeof(Bone), "bone"); + eBone->temp= newBone; /* Associate the real Bones with the EditBones */ + + strcpy (newBone->name, eBone->name); + memcpy (newBone->head, eBone->head, sizeof(float)*3); + memcpy (newBone->tail, eBone->tail, sizeof(float)*3); + newBone->flag=eBone->flag &~(BONE_SELECTED|BONE_HILIGHTED); +// newBone->roll=eBone->roll; + newBone->roll = 0.0F; + + /* >>>>> FIXME: This isn't a very good system: a lot of + pointless copying involved. To be investigated + once things are working better. + */ + + newBone->weight = eBone->weight; + newBone->dist = eBone->dist; + memcpy (newBone->loc, eBone->loc, sizeof(eBone->loc)); + memcpy (newBone->dloc, eBone->dloc, sizeof(eBone->dloc)); +/* memcpy (newBone->orig, eBone->orig, sizeof(eBone->orig));*/ + memcpy (newBone->size, eBone->size, sizeof(eBone->size)); + memcpy (newBone->dsize, eBone->dsize, sizeof(eBone->dsize)); + memcpy (newBone->quat, eBone->quat, sizeof(eBone->quat)); + memcpy (newBone->dquat, eBone->dquat, sizeof(eBone->dquat)); + memcpy (newBone->obmat, eBone->obmat, sizeof(eBone->obmat)); + } + + /* Fix parenting in a separate pass to ensure ebone->bone connections + are valid at this point */ + for (eBone=list->first;eBone;eBone=eBone->next){ + newBone= (Bone*) eBone->temp; + if (eBone->parent){ + newBone->parent=(Bone*) eBone->parent->temp; + BLI_addtail (&newBone->parent->childbase,newBone); + + { + float M_boneRest[4][4]; + float M_parentRest[4][4]; + float iM_parentRest[4][4]; + float delta[3]; + + /* Get the parent's global matrix (rotation only)*/ + VecSubf (delta, eBone->parent->tail, eBone->parent->head); + make_boneMatrixvr(M_parentRest, delta, eBone->parent->roll); + + /* Get this bone's global matrix (rotation only)*/ + VecSubf (delta, eBone->tail, eBone->head); + make_boneMatrixvr(M_boneRest, delta, eBone->roll); + + /* Invert the parent matrix */ + Mat4Invert (iM_parentRest, M_parentRest); + + /* Get the new head and tail */ + VecSubf (newBone->head, eBone->head, eBone->parent->tail); + VecSubf (newBone->tail, eBone->tail, eBone->parent->tail); + + Mat4MulVecfl(iM_parentRest, newBone->head); + Mat4MulVecfl(iM_parentRest, newBone->tail); + + + } + + } + /* ...otherwise add this bone to the armature's bonebase */ + else + BLI_addtail (&arm->bonebase,newBone); + } + + /* Make a pass through the new armature to fix rolling */ + fix_bonelist_roll (&arm->bonebase, list); + /* Get rid of pose channels that may have belonged to deleted bones */ + collect_pose_garbage(ob); + /* Ensure all bones have channels */ + apply_pose_armature(arm, ob->pose, 0); + + /* Calculate and cache the inverse restposition matrices (needed for deformation)*/ + precalc_bonelist_irestmats(&arm->bonebase); +} + + +void load_editArmature(void) +{ + bArmature *arm; + + arm=get_armature(G.obedit); + if (!arm) + return; + +#if 1 + editbones_to_armature(&G.edbo, G.obedit); +#else + free_bones(arm); + + + /* Copy the bones from the editData into the armature*/ + for (eBone=G.edbo.first;eBone;eBone=eBone->next){ + newBone=MEM_callocN (sizeof(Bone), "bone"); + eBone->temp= newBone; /* Associate the real Bones with the EditBones */ + + strcpy (newBone->name, eBone->name); + memcpy (newBone->head, eBone->head, sizeof(float)*3); + memcpy (newBone->tail, eBone->tail, sizeof(float)*3); + newBone->flag=eBone->flag &~(BONE_SELECTED|BONE_HILIGHTED); + // newBone->roll=eBone->roll; + newBone->roll = 0.0F; + + /* >>>>> FIXME: This isn't a very good system: a lot of + pointless copying involved. To be investigated + once things are working better. + */ + + newBone->weight = eBone->weight; + newBone->dist = eBone->dist; + memcpy (newBone->loc, eBone->loc, sizeof(eBone->loc)); + memcpy (newBone->dloc, eBone->dloc, sizeof(eBone->dloc)); +/* memcpy (newBone->orig, eBone->orig, sizeof(eBone->orig));*/ + memcpy (newBone->size, eBone->size, sizeof(eBone->size)); + memcpy (newBone->dsize, eBone->dsize, sizeof(eBone->dsize)); + memcpy (newBone->quat, eBone->quat, sizeof(eBone->quat)); + memcpy (newBone->dquat, eBone->dquat, sizeof(eBone->dquat)); + memcpy (newBone->obmat, eBone->obmat, sizeof(eBone->obmat)); + } + + /* Fix parenting in a separate pass to ensure ebone->bone connections + are valid at this point */ + for (eBone=G.edbo.first;eBone;eBone=eBone->next){ + newBone= (Bone*) eBone->temp; + if (eBone->parent){ + newBone->parent=(Bone*) eBone->parent->temp; + BLI_addtail (&newBone->parent->childbase,newBone); + + { + float M_boneRest[4][4]; + float M_parentRest[4][4]; + float M_relativeBone[4][4]; + float iM_parentRest[4][4]; + float delta[3]; + + /* Get the parent's global matrix (rotation only)*/ + VecSubf (delta, eBone->parent->tail, eBone->parent->head); + make_boneMatrixvr(M_parentRest, delta, eBone->parent->roll); + + /* Get this bone's global matrix (rotation only)*/ + VecSubf (delta, eBone->tail, eBone->head); + make_boneMatrixvr(M_boneRest, delta, eBone->roll); + + /* Invert the parent matrix */ + Mat4Invert (iM_parentRest, M_parentRest); + + /* Get the new head and tail */ + VecSubf (newBone->head, eBone->head, eBone->parent->tail); + VecSubf (newBone->tail, eBone->tail, eBone->parent->tail); + + Mat4MulVecfl(iM_parentRest, newBone->head); + Mat4MulVecfl(iM_parentRest, newBone->tail); + + + } + + } + /* ...otherwise add this bone to the armature's bonebase */ + else + BLI_addtail (&arm->bonebase,newBone); + } + + /* Make a pass through the new armature to fix rolling */ + fix_bonelist_roll (&arm->bonebase, &G.edbo); + + /* Get rid of pose channels that may have belonged to deleted bones */ + collect_pose_garbage(G.obedit); +#endif +} + +static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist) +{ + Bone *curBone; + EditBone *ebone; + + for (curBone=bonelist->first; curBone; curBone=curBone->next){ + + /* Fix this bone's roll */ +#if 1 + { + float premat[4][4]; + float postmat[4][4]; + float difmat[4][4]; + float imat[4][4]; + float delta[3]; + + /* Find the associated editbone */ + for (ebone = editbonelist->first; ebone; ebone=ebone->next) + if ((Bone*)ebone->temp == curBone) + break; + + if (ebone){ + /* Get the premat */ + VecSubf (delta, ebone->tail, ebone->head); + make_boneMatrixvr(premat, delta, ebone->roll); + + /* Get the postmat */ + get_objectspace_bone_matrix(curBone, postmat, 1, 0); + postmat[3][0]=postmat[3][1]=postmat[3][2]=0.0F; +#if 1 + Mat4Invert (imat, premat); + Mat4MulMat4 (difmat, postmat, imat); +#else + Mat4Invert (imat, postmat); + Mat4MulMat4 (difmat, premat, imat); +#endif +#if 0 + printf ("Bone %s\n", curBone->name); + printmatrix4 ("premat", premat); + printmatrix4 ("postmat", postmat); + printmatrix4 ("difmat", difmat); + printf ("Roll = %f\n", (-atan(difmat[2][0]/difmat[2][2]) * (180.0/M_PI))); +#endif + curBone->roll = -atan(difmat[2][0]/difmat[2][2]); + + if (difmat[0][0]<0) + curBone->roll +=M_PI; + + } + } +#endif + + fix_bonelist_roll (&curBone->childbase, editbonelist); + } +} + +void make_bone_parent(void) +{ +/* error ("Bone Parenting not yet implemented"); */ + return; +} + +static void make_boneList(ListBase* list, ListBase *bones, EditBone *parent) +{ + EditBone *eBone; + Bone *curBone; + + for (curBone=bones->first; curBone; curBone=curBone->next){ + eBone=MEM_callocN(sizeof(EditBone),"make_editbone"); + + /* Copy relevant data from bone to eBone */ + eBone->parent=parent; + strcpy (eBone->name, curBone->name); + eBone->flag = curBone->flag & ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + + /* Print bone matrix before and after */ + + get_bone_root_pos(curBone, eBone->head, 0); + get_bone_tip_pos(curBone, eBone->tail, 0); +// eBone->roll=curBone->roll; + eBone->roll=0; + +#if 1 + { + float delta[3]; + float premat[4][4]; + float postmat[4][4]; + float imat[4][4]; + float difmat[4][4]; + + VecSubf (delta, eBone->tail, eBone->head); + make_boneMatrixvr(postmat, delta, eBone->roll); + + get_objectspace_bone_matrix(curBone, premat, 1, 0); + +#if 0 + Mat4Invert (imat, premat); + Mat4MulMat4 (difmat, postmat, imat); +#else + Mat4Invert (imat, postmat); + Mat4MulMat4 (difmat, premat, imat); +#endif +#if 0 + printf ("Bone %s\n", curBone->name); + printmatrix4 ("diffmat", difmat); + printf ("Roll : atan of %f / %f = %f\n", difmat[2][0], difmat[2][2], (float)atan(difmat[2][0]/difmat[2][2])*(180.0F/M_PI)); +#endif + eBone->roll = atan(difmat[2][0]/difmat[2][2]); + + if (difmat[0][0]<0) + eBone->roll +=M_PI; + } +#endif + eBone->dist= curBone->dist; + eBone->weight= curBone->weight; + memcpy (eBone->loc, curBone->loc, sizeof(curBone->loc)); + memcpy (eBone->dloc, curBone->dloc, sizeof(curBone->dloc)); + /* memcpy (eBone->orig, curBone->orig, sizeof(curBone->orig));*/ + memcpy (eBone->size, curBone->size, sizeof(curBone->size)); + memcpy (eBone->dsize, curBone->dsize, sizeof(curBone->dsize)); + memcpy (eBone->quat, curBone->quat, sizeof(curBone->quat)); + memcpy (eBone->dquat, curBone->dquat, sizeof(curBone->dquat)); + memcpy (eBone->obmat, curBone->obmat, sizeof(curBone->obmat)); + + + BLI_addtail (list, eBone); + + /* Add children if necessary */ + if (curBone->childbase.first) + make_boneList (list, &curBone->childbase, eBone); + } + + +} + +#if 0 +static EditVert* add_armatureVert (float *loc) +{ + EditVert* vert=NULL; + + vert = MEM_callocN (sizeof (EditVert), "armaturevert"); + if (vert){ + VECCOPY (vert->co, loc); + BLI_addtail (&G.edve,vert); + } + + return vert; + +} + +static EditVert* get_armatureVert (float *loc) +{ + EditVert* vert; + + for (vert=G.edve.first;vert;vert=vert->next){ + if ((vert->co[0]==loc[0])&&(vert->co[1]==loc[1])&&(vert->co[2]==loc[2])){ + return (vert); + } + } + + return add_armatureVert (loc); +} +#endif + +void draw_armature(Object *ob) +{ + bArmature *arm; + Bone *bone; + EditBone *eBone; + unsigned int index; + float delta[3],offset[3]; + float bmat[4][4]; + float length; + + if (ob==NULL) return; + + arm= ob->data; + if (arm==NULL) return; + + if (!(ob->lay & G.vd->lay)) + return; + + /* If we're in editmode, draw the Global edit data */ + if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) { + cpack (0x000000); + + arm->flag |= ARM_EDITMODE; + for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){ + if (ob==G.obedit){ + // if ((eBone->flag&(BONE_TIPSEL | BONE_ROOTSEL))==(BONE_TIPSEL|BONE_ROOTSEL)) + // cpack (B_YELLOW); + // else + cpack (B_PURPLE); + } + else cpack (0x000000); + + glPushMatrix(); + + /* Compose the parent transforms (i.e. their translations) */ + VECCOPY (offset,eBone->head); + + glTranslatef (offset[0],offset[1],offset[2]); + + delta[0]=eBone->tail[0]-eBone->head[0]; + delta[1]=eBone->tail[1]-eBone->head[1]; + delta[2]=eBone->tail[2]-eBone->head[2]; + + length = sqrt (delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]); + + make_boneMatrixvr(bmat, delta, eBone->roll); + glMultMatrixf (bmat); + draw_bone (arm->flag, eBone->flag, index, eBone->name, length); + + glPopMatrix(); + if (eBone->parent){ + glLoadName (-1); + setlinestyle(3); + + glBegin(GL_LINES); + glVertex3fv(eBone->parent->tail); + glVertex3fv(eBone->head); + glEnd(); + + setlinestyle(0); + } + }; + arm->flag &= ~ARM_EDITMODE; + cpack (B_YELLOW); + + } + else{ + /* Draw hierarchical bone list (non-edit data) */ + + /* Ensure we're using the mose recent pose */ + if (!ob->pose) + ob->pose=MEM_callocN (sizeof(bPose), "pose"); + +#if 1 /* Activate if there are problems with action lag */ + apply_pose_armature(arm, ob->pose, 0); + where_is_armature (ob); +#endif + + if (G.obpose == ob){ + arm->flag |= ARM_POSEMODE; +#if 0 /* Depreciated interactive ik goal drawing */ + if (arm->chainbase.first){ + glPushMatrix(); + glTranslatef(((PoseChain*)arm->chainbase.first)->goal[0], + ((PoseChain*)arm->chainbase.first)->goal[1], + ((PoseChain*)arm->chainbase.first)->goal[2]); + drawaxes(1.0); + glPopMatrix(); + } +#endif + } + index = 0; + for (bone=arm->bonebase.first; bone; bone=bone->next) { + glPushMatrix(); + draw_bonechildren(bone, arm->flag, &index); + glPopMatrix(); + if (arm->flag & ARM_POSEMODE) + cpack (B_CYAN); + } + + arm->flag &= ~ARM_POSEMODE; + } +} + +static void draw_boneverti (float x, float y, float z, float size, int flag) +{ + GLUquadricObj *qobj; + + size*=0.05; + +/* + Ultimately dots should be drawn in screenspace + For now we'll just draw them any old way. +*/ + glPushMatrix(); + + glTranslatef(x, y, z); + + qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); + gluPartialDisk( qobj, 0, 1.0F*size, 32, 1, 360.0, 360.0); + + glRotatef (90, 0, 1, 0); + gluPartialDisk( qobj, 0, 1.0F*size, 32, 1, 360.0, 360.0); + + glRotatef (90, 1, 0, 0); + gluPartialDisk( qobj, 0, 1.0F*size, 32, 1, 360.0, 360.0); + + gluDeleteQuadric(qobj); + + glPopMatrix(); +} + +static void draw_bonechildren (Bone *bone, int flag, unsigned int *index) +{ + Bone *cbone; + float delta[3]; + float length; + float M_objectspacemat[4][4]; + + if (bone==NULL) return; + + if (flag & ARM_POSEMODE){ + if (bone->flag & BONE_SELECTED) + cpack (B_CYAN); + else + cpack (B_AQUA); + } + + // Draw a line from our root to the parent's tip + if (bone->parent && !(bone->flag & (BONE_IK_TOPARENT|BONE_HIDDEN)) ){ + float childMat[4][4]; + float boneMat[4][4]; + float tip[3], root[3]; + get_objectspace_bone_matrix(bone->parent, boneMat, 0, 1); + get_objectspace_bone_matrix(bone, childMat, 1, 1); + + VECCOPY (tip, boneMat[3]); + VECCOPY (root, childMat[3]); + + if (flag & ARM_POSEMODE) + glLoadName (-1); + setlinestyle(3); + glBegin(GL_LINES); + glVertex3fv(tip); + glVertex3fv(root); + glEnd(); + setlinestyle(0); + } + + + /* Draw this bone in objectspace */ + delta[0]=bone->tail[0]-bone->head[0]; + delta[1]=bone->tail[1]-bone->head[1]; + delta[2]=bone->tail[2]-bone->head[2]; + length = sqrt (delta[0]*delta[0] + delta[1]*delta[1] + delta[2]*delta[2] ); + + /* Incorporates offset, rest rotation, user rotation and parent coordinates*/ + get_objectspace_bone_matrix(bone, M_objectspacemat, 1, 1); + + if (!(bone->flag & BONE_HIDDEN)){ + glPushMatrix(); + glMultMatrixf(M_objectspacemat); + + + if (flag & ARM_POSEMODE) + draw_bone(flag, (bone->parent && bone->parent->flag & BONE_HIDDEN) ? (bone->flag & ~BONE_IK_TOPARENT) : (bone->flag), *index, bone->name, length); + else + draw_bone(flag, (bone->parent && bone->parent->flag & BONE_HIDDEN) ? (bone->flag & ~BONE_IK_TOPARENT) : (bone->flag), -1, bone->name, length); + glPopMatrix(); + } + (*index)++; + + /* Draw the children */ + for (cbone= bone->childbase.first; cbone; cbone=cbone->next){ + draw_bonechildren (cbone, flag, index); + } +} + +static void draw_bone (int armflag, int boneflag, unsigned int id, char *name, float length) +{ + float vec[2]; + float bulge; + float pointsize; + /* + FIXME: This routine should probably draw the bones in screenspace using + the projected start & end points of the transformed bone + */ + + pointsize = length; + if (pointsize<0.1) + pointsize=0.1; + + /* Draw a 3d octahedral bone */ + + bulge=length*0.1; + + if (id!=-1) + glLoadName((GLuint) id ); + + glPushMatrix(); + + /* Draw root point if we have no IK parent */ + if (!(boneflag & BONE_IK_TOPARENT)){ + if (id != -1) + glLoadName (id | BONESEL_ROOT); + if (armflag & ARM_EDITMODE){ + if (boneflag & BONE_ROOTSEL) + cpack (B_YELLOW); + else + cpack (B_PURPLE); + } + draw_boneverti (0, 0, 0, pointsize, 0); + } + + /* Draw tip point (for selection only )*/ + + if (id != -1) + glLoadName (id | BONESEL_TIP); + + if (armflag & ARM_EDITMODE){ + if (boneflag & BONE_TIPSEL) + cpack (B_YELLOW); + else + cpack (B_PURPLE); + } + + draw_boneverti (0, length, 0, pointsize, 0); + + if (id != -1){ + if (armflag & ARM_POSEMODE) + glLoadName((GLuint) id); + else{ +#if 1 /* Bones not selectable in editmode */ + glLoadName((GLuint) -1); +#else + glLoadName ((GLuint) id|BONESEL_TIP|BONESEL_ROOT); +#endif + } + } + + + if (armflag & ARM_EDITMODE){ + if (boneflag & BONE_SELECTED) + cpack (B_YELLOW); + else + cpack (B_PURPLE); + } + + /* Draw additional axes */ + if (armflag & ARM_DRAWAXES){ + drawaxes(length*0.25F); + } + + /* Section 1*/ + glBegin(GL_LINE_STRIP); + vec[0]= vec[1]= 0; + glVertex2fv(vec); + + vec[0]= -bulge; vec[1]= bulge; + glVertex2fv(vec); + + vec[0]= 0; vec[1]= length; + glVertex2fv(vec); + + vec[0]= bulge; vec[1]= bulge; + glVertex2fv(vec); + + vec[0]= 0; vec[1]= 0; + glVertex2fv(vec); + glEnd(); + + /* Section 2*/ + glRotatef(90,0,1,0); + glBegin(GL_LINE_STRIP); + vec[0]= vec[1]= 0; + glVertex2fv(vec); + + vec[0]= -bulge; vec[1]= bulge; + glVertex2fv(vec); + + vec[0]= 0; vec[1]= length; + glVertex2fv(vec); + + vec[0]= bulge; vec[1]= bulge; + glVertex2fv(vec); + + vec[0]= 0; vec[1]= 0; + glVertex2fv(vec); + glEnd(); + + /* Square*/ + glTranslatef (0,bulge,0); + glRotatef(45,0,1,0); + glRotatef(90,1,0,0); + glBegin(GL_LINE_STRIP); + + vec[0]= -bulge*.707;vec[1]=-bulge*.707; + glVertex2fv(vec); + + vec[0]= bulge*.707;vec[1]= -bulge*.707; + glVertex2fv(vec); + + vec[0]= bulge*.707;vec[1]= bulge*.707; + glVertex2fv(vec); + + vec[0]= -bulge*.707;vec[1]= bulge*.707; + glVertex2fv(vec); + + vec[0]= vec[1]= -bulge*.707; + glVertex2fv(vec); + glEnd(); + + + glPopMatrix(); + + /* Draw the bone name */ + if (armflag & ARM_DRAWNAMES){ + glRasterPos3f(0, length/2.0, 0); + BMF_DrawString(G.font, " "); + BMF_DrawString(G.font, name); + } +} + + + +void add_primitiveArmature(int type) +{ + if(G.scene->id.lib) return; + + /* this function also comes from an info window */ + if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return; + if(G.vd==NULL) return; + + check_editmode(OB_ARMATURE); + + /* If we're not the "obedit", make a new object and enter editmode */ + if(G.obedit==NULL) { + add_object(OB_ARMATURE); + base_init_from_view3d(BASACT, G.vd); + G.obedit= BASACT->object; + + where_is_object(G.obedit); + + make_editArmature(); + setcursor_space(SPACE_VIEW3D, CURSOR_EDIT); + } + + switch (type){ + default: + add_bone_input (G.obedit); + break; + }; + + countall(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSCONSTRAINT, 0); + allqueue(REDRAWNLA, 0); +} + +static void add_bone_input (Object *ob) +/* + FUNCTION: + Creates a bone chain under user input. + As the user clicks to accept each bone, + a new bone is started as the child and IK + child of the previous bone. Pressing ESC + cancels the current bone and leaves bone + adding mode. + +*/ +{ + float *cursLoc, cent[3], dx, dy; + float mat[3][3], curs[3], cmat[3][3], imat[3][3], rmat[4][4], itmat[4][4]; + short xo, yo, mval[2], afbreek=0; + short val; + float restmat[4][4], tempVec[4]; + EditBone *bone; + EditBone *parent; + unsigned short event; + float angle, scale; + float length, lengths; + float newEnd[4]; + int addbones=1; + float dvec[3], dvecp[3]; + + cursLoc= give_cursor(); + + VECCOPY (curs,cursLoc); + + while (addbones>0){ + afbreek=0; + /* Create an inverse matrix */ + Mat3CpyMat4(mat, G.obedit->obmat); + VECCOPY(cent, curs); + cent[0]-= G.obedit->obmat[3][0]; + cent[1]-= G.obedit->obmat[3][1]; + cent[2]-= G.obedit->obmat[3][2]; + + Mat3CpyMat4(imat, G.vd->viewmat); + Mat3MulVecfl(imat, cent); + + Mat3MulMat3(cmat, imat, mat); + Mat3Inv(imat,cmat); + + /* Create a temporary bone */ + bone= MEM_callocN(sizeof(EditBone), "eBone"); + + /* If we're the child of something, set that up now */ + if (addbones>1){ + parent=G.edbo.last; + bone->parent=parent; + bone->flag|=BONE_IK_TOPARENT; + } + + strcpy (bone->name,"Bone"); + unique_editbone_name (bone->name); + + BLI_addtail(&G.edbo, bone); + + bone->flag |= BONE_QUATROT; + bone->flag |= (BONE_SELECTED); + deselectall_armature(); + bone->flag |= BONE_SELECTED|BONE_HILIGHTED|BONE_TIPSEL|BONE_ROOTSEL; + + bone->weight= 1.0F; + bone->dist= 1.0F; + + /* Project cursor center to screenspace. */ + getmouseco_areawin(mval); + xo= mval[0]; + yo= mval[1]; + window_to_3d(dvecp, xo, yo); + + while (1) { + + getmouseco_areawin(mval); + window_to_3d(dvec, mval[0], mval[1]); + + scale=1000; + + dx= ((float)mval[0]-(float)xo)*scale; + dy= ((float)mval[1]-(float)yo)*scale; + + /* Calc bone length*/ + lengths= sqrt((dx*dx)+(dy*dy)); + length = sqrt(((dvec[0]-dvecp[0])*(dvec[0]-dvecp[0]))+((dvec[1]-dvecp[1])*(dvec[1]-dvecp[1]))+((dvec[2]-dvecp[2])*(dvec[2]-dvecp[2]))); + + /* Find rotation around screen normal */ + if (lengths>0.0F) { + angle= acos(dy/lengths); + if (dx<0.0F) + angle*= -1.0F; + } + else angle= 0.0F; + + /* FIXME: Is there a blender-defined way of making rot and trans matrices? */ + rmat[0][0]= cos (angle); + rmat[0][1]= -sin (angle); + rmat[0][2]= 0.0F; + rmat[0][3]= 0.0F; + rmat[1][0]= sin (angle); + rmat[1][1]= cos (angle); + rmat[1][2]= 0.0F; + rmat[1][3]= 0.0F; + rmat[2][0]= 0.0F; + rmat[2][1]= 0.0F; + rmat[2][2]= 1.0F; + rmat[2][3]= 0.0F; + rmat[3][0]= cent[0]; + rmat[3][1]= cent[1]; + rmat[3][2]= cent[2]; + rmat[3][3]= 1.0F; + + /* Rotate object's inversemat by the bone's rotation + to get the coordinate space of the bone */ + Mat4CpyMat3 (itmat, imat); + Mat4MulMat4 (restmat, rmat, itmat); + + /* Find the bone head */ + tempVec[0]=0; tempVec[1]=0.0F; tempVec[2]=0.0F; tempVec[3]=1.0F; + Mat4MulVec4fl (restmat, tempVec); + VECCOPY (bone->head, tempVec); + + /* Find the bone tail */ + tempVec[0]=0; tempVec[1]=length; tempVec[2]=0.0F; tempVec[3]=1.0F; + Mat4MulVec4fl (restmat, tempVec); + VECCOPY (bone->tail, tempVec); + + /* IF we're a child of something, add the parents' translates */ + + /* Offset of child is new cursor*/ + + VECCOPY (newEnd,bone->tail); newEnd[3]=1; + + /* Set the bone's transformations */ + Mat4One (bone->obmat); + bone->size[0]=bone->size[1]=bone->size[2]=1.0F; + + force_draw(); + while(qtest()) { + event= extern_qread(&val); + if(val) { + switch(event) { + case ESCKEY: + case RIGHTMOUSE: + BLI_freelinkN (&G.edbo,bone); + afbreek=1; + addbones=0; + break; + case LEFTMOUSE: + case MIDDLEMOUSE: + case SPACEKEY: + case RETKEY: + afbreek= 1; + + Mat4MulVec4fl (G.obedit->obmat,newEnd); + + curs[0]=newEnd[0]; + curs[1]=newEnd[1]; + curs[2]=newEnd[2]; + addbones++; + break; + } /* End of case*/ + } /* End of if (val)*/ + if(afbreek) break; + } /* Endd of Qtest loop */ + + if(afbreek) break; + }/* End of positioning loop (while)*/ + } /* End of bone adding loop*/ + + countall(); + +} + +static void validate_editbonebutton_cb(void *bonev, void *arg2_unused) +{ + EditBone *curBone= bonev; + validate_editbonebutton(curBone); +} +static void parnr_to_editbone_cb(void *bonev, void *arg2_unused) +{ + EditBone *curBone= bonev; + parnr_to_editbone(curBone); +} +static void attach_bone_to_parent_cb(void *bonev, void *arg2_unused) +{ + EditBone *curBone= bonev; + attach_bone_to_parent(curBone); +} + +void armaturebuts(void) +{ + bArmature *arm=NULL; + Object *ob=NULL; + uiBlock *block=NULL; + char str[64]; + int bx=148, by=100; + EditBone *curBone; + uiBut *but; + char *boneString=NULL; + int index; + + ob= OBACT; + if (ob==NULL) return; + + sprintf(str, "editbuttonswin %d", curarea->win); + block= uiNewBlock (&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win); + + arm= ob->data; + if (arm==NULL) return; + + uiBlockSetCol(block, BUTGREEN); + uiDefButI(block, TOG|BIT|ARM_RESTPOSBIT,REDRAWVIEW3D, "Rest Pos", bx,by,97,20, &arm->flag, 0, 0, 0, 0, "Disable all animation for this object"); + uiDefButI(block, TOG|BIT|ARM_DRAWAXESBIT,REDRAWVIEW3D, "Draw Axes", bx,by-46,97,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes"); + uiDefButI(block, TOG|BIT|ARM_DRAWNAMESBIT,REDRAWVIEW3D, "Draw Names", bx,by-69,97,20, &arm->flag, 0, 0, 0, 0, "Draw bone names"); + + uiBlockSetCol(block, BUTGREY); + + /* Draw the bone name block */ + + bx+=400; by=200; + + if (G.obedit==ob){ + uiDefBut(block, LABEL, 0, "Selected Bones", bx,by,128,18, 0, 0, 0, 0, 0, ""); + by-=20; + for (curBone=G.edbo.first, index=0; curBone; curBone=curBone->next, index++){ + if (curBone->flag & (BONE_SELECTED)){ + + /* Hide in posemode flag */ + uiBlockSetCol(block, BUTGREEN); + uiDefButI(block, TOG|BIT|BONE_HIDDENBIT, REDRAWVIEW3D, "Hide", bx-50,by,48,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in posemode"); + + /* Bone naming button */ + uiBlockSetCol(block, BUTGREY); + strcpy (curBone->oldname, curBone->name); + but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", bx,by,97,18, &curBone->name, 0, 24, 0, 0, "Change the bone name"); + uiButSetFunc(but, validate_editbonebutton_cb, curBone, NULL); + + uiDefBut(block, LABEL, 0, "child of", bx+106,by,100,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); + + boneString = malloc((BLI_countlist(&G.edbo) * 64)+64); + build_bonestring (boneString, curBone); + + curBone->parNr = editbone_to_parnr(curBone->parent); + but = uiDefButI(block, MENU,REDRAWVIEW3D, boneString, bx+164,by,97,18, &curBone->parNr, 0.0, 0.0, 0.0, 0.0, "Parent"); + uiButSetFunc(but, parnr_to_editbone_cb, curBone, NULL); + + free(boneString); + + /* IK to parent flag */ + if (curBone->parent){ + uiBlockSetCol(block, BUTGREEN); + but=uiDefButI(block, TOG|BIT|BONE_IK_TOPARENTBIT, REDRAWVIEW3D, "IK", bx+275,by,32,18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "IK link to parent"); + uiButSetFunc(but, attach_bone_to_parent_cb, curBone, NULL); + } + + /* Dist and weight buttons */ + uiBlockSetCol(block, BUTGREY); + uiDefButF(block, NUM,REDRAWVIEW3D, "Dist:", bx+320, by, 110, 18, &curBone->dist, 0.0, 1000.0, 10.0, 0.0, "Bone deformation distance"); + uiDefButF(block, NUM,REDRAWVIEW3D, "Weight:", bx+438, by, 110, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight"); + + by-=19; + } + } + } + + uiDrawBlock (block); + +} + +static int editbone_to_parnr (EditBone *bone) +{ + EditBone *ebone; + int index; + + for (ebone=G.edbo.first, index=0; ebone; ebone=ebone->next, index++){ + if (ebone==bone) + return index; + } + + return -1; +} + +static void parnr_to_editbone(EditBone *bone) +{ + if (bone->parNr == -1){ + bone->parent = NULL; + bone->flag &= ~BONE_IK_TOPARENT; + } + else{ + bone->parent = BLI_findlink(&G.edbo, bone->parNr); + attach_bone_to_parent(bone); + } +} + +static void attach_bone_to_parent(EditBone *bone) +{ + EditBone *curbone; + + if (bone->flag & BONE_IK_TOPARENT) { + + /* See if there are any other bones that refer to the same parent and disconnect them */ + for (curbone = G.edbo.first; curbone; curbone=curbone->next){ + if (curbone!=bone){ + if (curbone->parent && (curbone->parent == bone->parent) && (curbone->flag & BONE_IK_TOPARENT)) + curbone->flag &= ~BONE_IK_TOPARENT; + } + } + + /* Attach this bone to its parent */ + VECCOPY(bone->head, bone->parent->tail); + } + +} + +static void build_bonestring (char *string, EditBone *bone){ + EditBone *curBone; + EditBone *pBone; + int skip=0; + int index; + + sprintf (string, "Parent%%t| %%x%d", -1); /* That space is there for a reason */ + + for (curBone = G.edbo.first, index=0; curBone; curBone=curBone->next, index++){ + /* Make sure this is a valid child */ + if (curBone != bone){ + skip=0; + for (pBone=curBone->parent; pBone; pBone=pBone->parent){ + if (pBone==bone){ + skip=1; + break; + } + } + + if (skip) + continue; + + sprintf (string, "%s|%s%%x%d", string, curBone->name, index); + } + } +} + +static void validate_editbonebutton(EditBone *eBone){ + EditBone *prev; + bAction *act; + bActionChannel *chan; + Base *base; + + /* Separate the bone from the G.edbo */ + prev=eBone->prev; + BLI_remlink (&G.edbo, eBone); + + /* Validate the name */ + unique_editbone_name (eBone->name); + + /* Re-insert the bone */ + if (prev) + BLI_insertlink(&G.edbo, prev, eBone); + else + BLI_addhead (&G.edbo, eBone); + + /* Rename channel if necessary */ + if (G.obedit) + act = G.obedit->action; + + if (act && !act->id.lib){ + // Find the appropriate channel + for (chan = act->chanbase.first; chan; chan=chan->next){ + if (!strcmp (chan->name, eBone->oldname)){ + strcpy (chan->name, eBone->name); + } + } + allqueue(REDRAWACTION, 0); + } + + /* Update the parenting info of any users */ + /* Yes, I know this is the worst thing you have ever seen. */ + + for (base = G.scene->base.first; base; base=base->next){ + Object *ob = base->object; + + /* See if an object is parented to this armature */ + if (ob->parent && ob->partype==PARBONE && (ob->parent->type==OB_ARMATURE) && (ob->parent->data == G.obedit->data)){ + if (!strcmp(ob->parsubstr, eBone->oldname)) + strcpy(ob->parsubstr, eBone->name); + } + } + + exit_editmode(0); /* To ensure new names make it to the edit armature */ + +} + +void deselectall_armature(void) +/* Actually, it toggles selection, deselecting + everything if anything is selected */ +{ + EditBone *eBone; + int sel=1; + + + /* Determine if there are any selected bones + And therefore whether we are selecting or deselecting */ + for (eBone=G.edbo.first;eBone;eBone=eBone->next){ + if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)){ + sel=0; + break; + }; + }; + + /* Set the flags */ + for (eBone=G.edbo.first;eBone;eBone=eBone->next){ + if (sel) + eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + else + eBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + }; + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSCONSTRAINT, 0); + countall(); +} + +void join_armature(void) +{ + + Object *ob; + Base *base, *nextbase; + ListBase eblist; + EditBone *curbone, *next; + float mat[4][4], imat[4][4]; + + /* Ensure we're not in editmode and that the active object is an armature*/ + if(G.obedit) return; + + ob= OBACT; + if(ob->type!=OB_ARMATURE) return; + + /* Make sure the user wants to continue*/ + if(okee("Join selected Armatures")==0) return; + + /* Put the active armature into editmode and join the bones from the other one*/ +#if 1 + enter_editmode(); +#else + baselist.first=baselist.last=0; + make_boneList(&baselist, &((bArmature*)ob->data)->bonebase, NULL); +#endif + + for (base=FIRSTBASE; base; base=nextbase) { + nextbase = base->next; + if (TESTBASE(base)){ + if ((base->object->type==OB_ARMATURE) && (base->object!=ob)){ + /* Make a list of editbones */ + eblist.first=eblist.last=0; + make_boneList (&eblist, &((bArmature*)base->object->data)->bonebase,NULL); + /* Find the difference matrix */ + Mat4Invert(imat, ob->obmat); + Mat4MulMat4(mat, base->object->obmat, imat); + + /* Copy bones from the object to the edit armature */ + for (curbone=eblist.first; curbone; curbone=next){ + next = curbone->next; + + /* Blank out tranformation data */ + curbone->loc[0]=curbone->loc[1]=curbone->loc[2]=0.0F; + curbone->size[0]=curbone->size[1]=curbone->size[2]=1.0F; + curbone->quat[0]=curbone->quat[1]=curbone->quat[2]=curbone->quat[3]=0.0F; + + unique_editbone_name (curbone->name); + + /* Transform the bone */ + { + float premat[4][4]; + float postmat[4][4]; + float difmat[4][4]; + float imat[4][4]; + float temp[4][4]; + float delta[3]; + + /* Get the premat */ + VecSubf (delta, curbone->tail, curbone->head); + make_boneMatrixvr(temp, delta, curbone->roll); + Mat4MulMat4 (premat, temp, mat); + + Mat4MulVecfl(mat, curbone->head); + Mat4MulVecfl(mat, curbone->tail); + + /* Get the postmat */ + VecSubf (delta, curbone->tail, curbone->head); + make_boneMatrixvr(postmat, delta, curbone->roll); + + /* Find the roll */ + Mat4Invert (imat, premat); + Mat4MulMat4 (difmat, postmat, imat); + + curbone->roll -=atan(difmat[2][0]/difmat[2][2]); + + if (difmat[0][0]<0) + curbone->roll +=M_PI; + + } +#if 1 + BLI_remlink(&eblist, curbone); + BLI_addtail(&G.edbo, curbone); +#else + BLI_remlink(&eblist, curbone); + BLI_addtail(&baselist, curbone); +#endif + } + + free_and_unlink_base(base); + } + } + } + +#if 1 + exit_editmode(1); +#else + editbones_to_armature(&baselist, ob); + if (baselist.first){ + BLI_freelistN (&baselist); + } +#endif + allqueue(REDRAWVIEW3D, 0); + +} + + +static int editbone_name_exists (char *name){ + EditBone *eBone; + + for (eBone=G.edbo.first; eBone; eBone=eBone->next){ + if (!strcmp (name, eBone->name)) + return 1; + } + + return 0; + +} + +static void unique_editbone_name (char *name){ + char tempname[64]; + int number; + char *dot; + + + if (editbone_name_exists(name)){ + /* Strip off the suffix */ + dot=strchr(name, '.'); + if (dot) + *dot=0; + + for (number = 1; number <=999; number++){ + sprintf (tempname, "%s.%03d", name, number); + if (!editbone_name_exists(tempname)){ + strcpy (name, tempname); + return; + } + } + } +} + +void extrude_armature(void) +{ + EditBone *newbone, *curbone, *first=NULL, *partest; + + TEST_EDITARMATURE; + + + if(okee("Extrude Bone Segments")==0) return; + + /* Duplicate the necessary bones */ + for (curbone = G.edbo.first; ((curbone) && (curbone!=first)); curbone=curbone->next){ + if (curbone->flag & (BONE_TIPSEL|BONE_SELECTED)){ + newbone = MEM_callocN(sizeof(EditBone), "extrudebone"); + + + VECCOPY (newbone->head, curbone->tail); + VECCOPY (newbone->tail, newbone->head); + newbone->parent = curbone; + newbone->flag = BONE_TIPSEL; + newbone->flag |= BONE_QUATROT; + newbone->weight= curbone->weight; + newbone->dist= curbone->dist; + Mat4One(newbone->obmat); + + /* See if there are any ik children of the parent */ + for (partest = G.edbo.first; partest; partest=partest->next){ + if ((partest->parent == curbone) && (partest->flag & BONE_IK_TOPARENT)) + break; + } + + if (!partest) + newbone->flag |= BONE_IK_TOPARENT; + + strcpy (newbone->name, curbone->name); + unique_editbone_name(newbone->name); + + /* Add the new bone to the list */ + BLI_addtail(&G.edbo, newbone); + if (!first) + first = newbone; + } + + /* Deselect the old bone */ + curbone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL); + + } + + /* Transform the endpoints */ + countall(); + transform('g'); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSCONSTRAINT, 0); +} + +void addvert_armature(void) +{ +/* + I haven't decided if it will be possible to add bones in this way. + For the moment, we'll use Extrude, or explicit parenting. + */ +} + + + + + +void adduplicate_armature(void) +{ + EditBone *eBone = NULL; + EditBone *curBone; + EditBone *firstDup=NULL; /* The beginning of the duplicated bones in the edbo list */ + + countall(); + + /* Find the selected bones and duplicate them as needed */ + for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){ + if (curBone->flag & BONE_SELECTED){ + + eBone=MEM_callocN(sizeof(EditBone), "addup_editbone"); + eBone->flag |= BONE_SELECTED; + + /* Copy data from old bone to new bone */ + memcpy (eBone, curBone, sizeof(EditBone)); + + /* Blank out tranformation data */ + eBone->loc[0]=eBone->loc[1]=eBone->loc[2]=0.0F; + eBone->size[0]=eBone->size[1]=eBone->size[2]=1.0F; + eBone->quat[0]=eBone->quat[1]=eBone->quat[2]=eBone->quat[3]=0.0F; + + curBone->temp = eBone; + eBone->temp = curBone; + + unique_editbone_name (eBone->name); + BLI_addtail (&G.edbo, eBone); + if (!firstDup) + firstDup=eBone; + } + } + + if (eBone){ + /* Fix the head and tail */ + if (eBone->parent && !eBone->parent->flag & BONE_SELECTED){ + VecSubf (eBone->tail, eBone->tail, eBone->head); + VecSubf (eBone->head, eBone->head, eBone->head); + } + } + + /* Run though the list and fix the pointers */ + for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){ + + if (curBone->flag & BONE_SELECTED){ + eBone=(EditBone*) curBone->temp; + + /* If this bone has no parent, + Set the duplicate->parent to NULL + */ + if (!curBone->parent){ + eBone->parent = NULL; + } + /* If this bone has a parent that IS selected, + Set the duplicate->parent to the curBone->parent->duplicate + */ + else if (curBone->parent->flag & BONE_SELECTED){ + eBone->parent=(EditBone*) curBone->parent->temp; + } + /* If this bone has a parent that IS not selected, + Set the duplicate->parent to the curBone->parent + */ + else { + eBone->parent=(EditBone*) curBone->parent; + eBone->flag &= ~BONE_IK_TOPARENT; + } + + } + } + + /* Deselect the old bones and select the new ones */ + + for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){ + curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + } + + + transform('g'); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSCONSTRAINT, 0); +} + +/* + * + * POSING FUNCTIONS: Maybe move these to a separate file at some point + * + * + */ + + +void clear_armature(Object *ob, char mode){ + Bone *curBone; + bArmature *arm; + + arm=get_armature(ob); + + if (!arm) + return; + + for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ + clear_armature_children (curBone, ob->pose, mode); + } + + where_is_armature (ob); + +} + +static void clear_armature_children (Bone *bone, bPose *pose, char mode){ + Bone *curBone; + bPoseChannel *chan; + if (!bone) + return; + + verify_pose_channel (pose, bone->name); + chan=get_pose_channel (pose, bone->name); + + if (!chan) + return; + + if (bone->flag & BONE_SELECTED){ + switch (mode){ + case 'r': + chan->quat[1]=chan->quat[2]=chan->quat[3]=0.0F; chan->quat[0]=1.0F; + break; + case 'g': + chan->loc[0]=chan->loc[1]=chan->loc[2]=0.0F; + break; + case 's': + chan->size[0]=chan->size[1]=chan->size[2]=1.0F; + break; + + } + } + + for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ + clear_armature_children (curBone, pose, mode); + } + +} + +void mousepose_armature(void) +/* + Handles right-clicking for selection + of bones in armature pose modes. +*/ +{ + Bone *nearBone; + + if (!G.obpose) + return; + + nearBone = get_nearest_bone(1); + + if (nearBone){ + if (!(G.qual & LR_SHIFTKEY)){ + deselectall_posearmature(0); + nearBone->flag|=BONE_SELECTED; + select_actionchannel_by_name(G.obpose->action, nearBone->name, 1); + } + else { + if (nearBone->flag & BONE_SELECTED){ + nearBone->flag &= ~BONE_SELECTED; + select_actionchannel_by_name(G.obpose->action, nearBone->name, 0); + } + else{ + nearBone->flag |= BONE_SELECTED; + select_actionchannel_by_name(G.obpose->action, nearBone->name, 1); + } + }; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); /* To force action ipo update */ + allqueue(REDRAWBUTSCONSTRAINT, 0); + +// countall(); + rightmouse_transform(); + +} + +void make_trans_bones (char mode) +/* Used in pose mode */ +{ + bArmature *arm; + Bone *curBone; + int count=0; + + transmain=NULL; + + arm=get_armature (G.obpose); + if (!arm) + return; + + if (arm->flag & ARM_RESTPOS){ + notice ("Transformation not possible while Rest Position is enabled"); + return; + } + + + if (!(G.obpose->lay & G.vd->lay)) + return; + + + centroid[0]=centroid[1]=centroid[2]=0; + + apply_pose_armature(arm, G.obpose->pose, 0); + where_is_armature (G.obpose); + + /* Allocate memory for the transformation record */ + tottrans= count_bones (arm, BONE_SELECTED, 0); + + if (!tottrans) + return; + + transmain= MEM_callocN(tottrans*sizeof(TransOb), "bonetransmain"); + + for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ + count = add_trans_bonechildren (G.obpose, curBone, transmain, count, mode); + } + + tottrans=count; + + if (tottrans){ + centroid[0]/=tottrans; + centroid[1]/=tottrans; + centroid[2]/=tottrans; + Mat4MulVecfl (G.obpose->obmat, centroid); + } + else{ + MEM_freeN (transmain); + } + return; + +} + +static int count_bones (bArmature *arm, int flagmask, int allbones) +{ + int count=0; + Bone *curBone; + + if (!arm) + return 0; + + for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ + count = count_bonechildren (curBone, count, flagmask, allbones); + } + + return count; + +} + +static int count_bonechildren (Bone *bone, int incount, int flagmask, int allbones){ + + Bone *curBone; + + if (!bone) + return incount; + + if (bone->flag & flagmask || flagmask == 0xFFFFFFFF){ + incount++; + if (!allbones) + return incount; + } + + for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ + incount=count_bonechildren (curBone, incount, flagmask, allbones); + } + + return incount; +} + + +static int add_trans_bonechildren (Object* ob, Bone* bone, TransOb* buffer, int index, char mode) +{ + Bone *curBone; + TransOb *curOb; + float parmat[4][4], tempmat[4][4]; + float tempobmat[4][4]; + float vec[3]; + if (!bone) + return index; + + + + /* We don't let IK children get "grabbed" */ + if (bone->flag & BONE_SELECTED){ + if (!((mode=='g' || mode=='G') && (bone->flag & BONE_IK_TOPARENT))){ + + get_bone_root_pos (bone, vec, 1); + + VecAddf (centroid, centroid, vec); + + curOb=&buffer[index]; + + curOb->ob = ob; + curOb->rot=NULL; + + curOb->quat= bone->quat; + curOb->size= bone->size; + curOb->loc = bone->loc; + + curOb->data = bone; // FIXME: Dangerous + + memcpy (curOb->oldquat, bone->quat, sizeof (bone->quat)); + memcpy (curOb->oldsize, bone->size, sizeof (bone->size)); + memcpy (curOb->oldloc, bone->loc, sizeof (bone->loc)); + +#if 0 + if (bone->parent) + get_objectspace_bone_matrix(bone->parent, tempmat, 1, 1); + else + Mat4One (tempmat); +#else + /* Get the matrix of this bone minus the usertransform */ + Mat4CpyMat4 (tempobmat, bone->obmat); + Mat4One (bone->obmat); + get_objectspace_bone_matrix(bone, tempmat, 1, 1); + Mat4CpyMat4 (bone->obmat, tempobmat); + + +#endif + +#if 1 + Mat4MulMat4 (parmat, tempmat, ob->obmat); /* Original */ + + /* Get world transform */ + get_objectspace_bone_matrix(bone, tempmat, 1, 1); + if (ob->parent){ + where_is_object(ob->parent); + Mat4MulSerie (tempobmat, ob->parent->obmat, ob->obmat, tempmat, NULL, NULL, NULL, NULL, NULL); + } + else + Mat4MulSerie (tempobmat, ob->obmat, tempmat, NULL, NULL, NULL, NULL, NULL, NULL); + Mat3CpyMat4 (curOb->axismat, tempobmat); + Mat3Ortho(curOb->axismat); + +#else + Mat4MulMat4 (parmat, ob->obmat, tempmat); +#endif + Mat3CpyMat4 (curOb->parmat, parmat); + Mat3Inv (curOb->parinv, curOb->parmat); + + Mat3CpyMat4 (curOb->obmat, bone->obmat); + Mat3Inv (curOb->obinv, curOb->obmat); + + index++; + return index; + } + + } + + /* Recursively search */ + for (curBone = bone->childbase.first; curBone; curBone=curBone->next){ + index=add_trans_bonechildren (ob, curBone, buffer, index, mode); + } + + return index; +} + +static void deselect_bonechildren (Bone *bone, int mode) +{ + Bone *curBone; + + if (!bone) + return; + + if (mode==0) + bone->flag &= ~BONE_SELECTED; + else if (!(bone->flag & BONE_HIDDEN)) + bone->flag |= BONE_SELECTED; + + select_actionchannel_by_name(G.obpose->action, bone->name, mode); + + for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ + deselect_bonechildren(curBone, mode); + } +} + + +void deselectall_posearmature (int test){ + int selectmode = 0; + Bone* curBone; + + /* Determine if we're selecting or deselecting */ + if (test){ + if (!count_bones (get_armature(G.obpose), BONE_SELECTED, 0)) + selectmode = 1; + } + + /* Set the flags accordingly */ + for (curBone=get_armature(G.obpose)->bonebase.first; curBone; curBone=curBone->next) + deselect_bonechildren (curBone, selectmode); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION, 0); + +} + +void auto_align_armature(void) +/* Sets the roll value of selected bones so that their zaxes point upwards */ +{ + EditBone *ebone; + float xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0}, ytest[3]={0.0, -1.0, 0.0}; + float targetmat[4][4], imat[4][4]; + float curmat[4][4], diffmat[4][4]; + float delta[3]; + + for (ebone = G.edbo.first; ebone; ebone=ebone->next){ + if (ebone->flag & BONE_SELECTED){ + /* Find the current bone matrix */ + VecSubf(delta, ebone->tail, ebone->head); + make_boneMatrixvr (curmat, delta, 0.0); + + /* Make new matrix based on y axis & z-up */ + VECCOPY (yaxis, curmat[1]); + + Mat4One(targetmat); + VECCOPY (targetmat[0], xaxis); + VECCOPY (targetmat[1], yaxis); + VECCOPY (targetmat[2], zaxis); + Mat4Ortho(targetmat); + + /* Find the difference between the two matrices */ + + Mat4Invert (imat, targetmat); + Mat4MulMat4(diffmat, curmat, imat); + + ebone->roll = atan(diffmat[2][0]/diffmat[2][2]); + + } + } +}
\ No newline at end of file diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c new file mode 100644 index 00000000000..17d59a18192 --- /dev/null +++ b/source/blender/src/editconstraint.c @@ -0,0 +1,753 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdio.h> +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" + +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_constraint_types.h" +#include "DNA_curve_types.h" + +#include "BKE_utildefines.h" +#include "BKE_action.h" +#include "BKE_armature.h" +#include "BKE_object.h" +#include "BKE_global.h" +#include "BKE_constraint.h" +#include "BKE_ipo.h" + +#include "BIF_editarmature.h" +#include "BIF_editconstraint.h" +#include "BIF_interface.h" +#include "BIF_screen.h" +#include "BIF_toolbox.h" + +#include "BSE_editaction.h" + +#include "interface.h" +#include "blendef.h" +#include "nla.h" + +static short add_constraint_element (Object *owner, const char *substring, Object *parent, const char *parentstring); +static short detect_constraint_loop (Object *owner, const char* substring, int disable); +static void test_bonelist_constraints (Object *owner, ListBase *list); +static void clear_object_constraint_loop_flags(Object *ob); +//static int is_child_of(struct Object *owner, struct Object *parent); +//static int is_bonechild_of(struct Bone *bone, struct Bone *parent); +static int is_child_of_ex(Object *owner, const char *ownersubstr, Object *parent, const char *parsubstr); + +ListBase g_conBase; +const char *g_conString; +Object *g_conObj; + + +void unique_constraint_name (bConstraint *con, ListBase *list){ + char tempname[64]; + int number; + char *dot; + int exists = 0; + bConstraint *curcon; + + /* See if we even need to do this */ + for (curcon = list->first; curcon; curcon=curcon->next){ + if (curcon!=con){ + if (!strcmp(curcon->name, con->name)){ + exists = 1; + break; + } + } + } + + if (!exists) + return; + + /* Strip off the suffix */ + dot=strchr(con->name, '.'); + if (dot) + *dot=0; + + for (number = 1; number <=999; number++){ + sprintf (tempname, "%s.%03d", con->name, number); + + exists = 0; + for (curcon=list->first; curcon; curcon=curcon->next){ + if (con!=curcon){ + if (!strcmp (curcon->name, tempname)){ + exists = 1; + break; + } + } + } + if (!exists){ + strcpy (con->name, tempname); + return; + } + } +} + +static int is_child_of_ex(Object *owner, const char *ownersubstr, Object *parent, const char *parsubstr) +{ + Object *curob; + int working = 1; + Bone *bone = NULL; + Bone *parbone= NULL; + + curob=owner; + + /* If this is a bone */ + if (strlen(ownersubstr)) + bone = get_named_bone(get_armature(owner->parent), ownersubstr); + + if (strlen(parsubstr)) + parbone = get_named_bone(get_armature(parent), parsubstr); + + + /* Traverse the scene graph */ + while (curob && !bone){ + switch (curob->partype){ + case PARBONE: + if (strlen(parsubstr)){ + bone = get_named_bone(get_armature(curob->parent), curob->parsubstr); + break; + } + /* The break is supposed to be missing */ + default: + if (curob==parent){ + if (parbone) + return 0; + else + return 1; + } + curob=curob->parent; + } + } + + + /* Descend into the armature scene graph */ + while (bone){ + if (bone==parbone) + return 1; + bone=bone->parent; + } + + return 0; +} +/* +static int is_child_of(Object *owner, Object *parent) +{ + Object *curpar; + + for (curpar = owner->parent; curpar; curpar=curpar->parent){ + if (curpar==parent) + return 1; + } + + return 0; +} + + +static int is_bonechild_of(Bone *bone, Bone *parent) +{ + Bone *curpar; + + if (!bone) + return 0; + + for (curpar = bone->parent; curpar; curpar=curpar->parent){ + if (curpar==parent) + return 1; + } + return 0; +} +*/ +static short add_constraint_element (Object *owner, const char *substring, Object *parent, const char *parentstring) +{ + + if (!owner) + return 0; + + /* See if this is the original object */ + if (parent == owner){ + if (!strcmp (parentstring, substring)) + return 1; + } + + if (owner == g_conObj){ + if (!strcmp (g_conString, substring)) + return 1; + } + + /* See if this is a child of the adding object */ + if (parent){ +// if (is_child_of (owner, parent)) + if (is_child_of_ex (owner, substring, parent, parentstring)) + return 1; + /* Parent is a bone */ +/* if ((owner==parent) && (owner->type == OB_ARMATURE)){ + if (strlen (substring) && strlen(parentstring)){ + if (is_bonechild_of(get_named_bone(owner->data, substring), get_named_bone(parent->data, parentstring))) + return 1; + } + } + */ + } + return 0; +} + +static void test_bonelist_constraints (Object *owner, ListBase *list) +{ + Bone *bone; + Base *base1; + + + for (bone = list->first; bone; bone=bone->next){ + for (base1 = G.scene->base.first; base1; base1=base1->next){ + clear_object_constraint_loop_flags(base1->object); + } + test_constraints(owner, bone->name, 1); + test_bonelist_constraints (owner, &bone->childbase); + } +} + + +static void clear_object_constraint_loop_flags(Object *ob) +{ + bConstraint *con; + + if (!ob) + return; + + /* Test object constraints */ + for (con = ob->constraints.first; con; con=con->next){ + con->flag &= ~CONSTRAINT_LOOPTESTED; + } + + switch (ob->type){ + case OB_ARMATURE: + if (ob->pose){ + bPoseChannel *pchan; + for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){ + for (con = pchan->constraints.first; con; con=con->next){ + con->flag &= ~CONSTRAINT_LOOPTESTED; + } + } + } + break; + default: + break; + } +} +void test_scene_constraints (void) +{ + Base *base, *base1; + +/* Clear the "done" flags of all constraints */ + + for (base = G.scene->base.first; base; base=base->next){ + clear_object_constraint_loop_flags(base->object); + } + + /* Test all constraints */ + for (base = G.scene->base.first; base; base=base->next){ + /* Test the object */ + + for (base1 = G.scene->base.first; base1; base1=base1->next) + clear_object_constraint_loop_flags(base1->object); + + + test_constraints (base->object, "", 1); + + + /* Test the subobject constraints */ + switch (base->object->type){ + case OB_ARMATURE: + { + bArmature *arm; + arm = get_armature(base->object); + if (arm) + test_bonelist_constraints (base->object, &arm->bonebase); + } + break; + default: + break; + } + + + } +} + +int test_constraints (Object *owner, const char *substring, int disable) +{ +/* init_constraint_elements();*/ + g_conObj = owner; + g_conString = substring; + + if (detect_constraint_loop (owner, substring, disable)) + return 1; + else + return 0; + +/* free_constraint_elements(); */ +} + +static short detect_constraint_loop (Object *owner, const char* substring, int disable) +{ + + bConstraint *curcon; + ListBase *conlist; + int type; + int result = 0; + + if (!owner) + return result; + + /* Check parents */ + /* Get the constraint list for this object */ + + if (strlen (substring)){ + switch (owner->type){ + case OB_ARMATURE: + type = TARGET_BONE; + break; + default: + type = TARGET_OBJECT; + break; + } + } + else + type = TARGET_OBJECT; + + + switch (type){ + case TARGET_OBJECT: + conlist = &owner->constraints; + /* Check parents */ +#if 0 + if (owner->parent && (ELEM (owner->partype, PAROBJECT, PARBONE))){ + if (add_constraint_element (owner->parent, "", NULL, NULL)){ + return 1; + } + /* if (detect_constraint_loop (owner->parent, "", disable)){ + return 1; + } + */ + } + /* Check tracking */ + if (owner->track && (ELEM (owner->partype, PAROBJECT, PARBONE))){ + if (add_constraint_element (owner->track, "", NULL, NULL)){ + return 1; + } + /* if (detect_constraint_loop (owner->track, "", disable)){ + return 1; + } + */ + } +#else + if (owner->parent && (owner->partype==PAROBJECT)) + if (add_constraint_element (owner->parent, "", NULL, NULL)) + return 1; + + if (owner->parent && (owner->partype==PARBONE)) + if (add_constraint_element (owner->parent, owner->parsubstr, NULL, NULL)) + return 1; + + /* Check tracking */ + if (owner->track) + if (add_constraint_element (owner->track, "", NULL, NULL)) + return 1; +#endif + + break; + case TARGET_BONE: + { + Bone *bone; + bPoseChannel *chan; + + bone = get_named_bone(((bArmature*)owner->data), substring); + chan = get_pose_channel (owner->pose, substring); + if (bone){ + conlist = &chan->constraints; + if (bone->parent){ + if (add_constraint_element (owner, bone->parent->name, NULL, NULL)) + return 1; + if (detect_constraint_loop (owner, bone->parent->name, disable)) + return 1; + } + else{ + if (add_constraint_element (owner, "", NULL, NULL)) + return 1; + if (detect_constraint_loop (owner, "", disable)) + return 1; + } + } + else + conlist = NULL; + } + break; + default: + conlist = NULL; + break; + } + + /* Cycle constraints */ + if (conlist){ + for (curcon = conlist->first; curcon; curcon=curcon->next){ + + /* Clear the disable flag */ + + if (curcon->flag & CONSTRAINT_LOOPTESTED){ + return 0; + } + else { + curcon->flag &= ~CONSTRAINT_DISABLE; + curcon->flag |= CONSTRAINT_LOOPTESTED; + switch (curcon->type){ + case CONSTRAINT_TYPE_ACTION: + { + bActionConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + + if (add_constraint_element (data->tar, data->subtarget, owner, substring)){ + curcon->flag |= CONSTRAINT_DISABLE; + result = 1; + break; + // return 1; + } + if (detect_constraint_loop (data->tar, data->subtarget, disable)){ + curcon->flag |= CONSTRAINT_DISABLE; + result = 1; + break; + // return 1; + } + } + break; + case CONSTRAINT_TYPE_LOCLIKE: + { + bLocateLikeConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + + if (add_constraint_element (data->tar, data->subtarget, owner, substring)){ + curcon->flag |= CONSTRAINT_DISABLE; + result = 1; + break; + // return 1; + } + if (detect_constraint_loop (data->tar, data->subtarget, disable)){ + curcon->flag |= CONSTRAINT_DISABLE; + result = 1; + break; + // return 1; + } + } + break; + case CONSTRAINT_TYPE_ROTLIKE: + { + bRotateLikeConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + + if (add_constraint_element (data->tar, data->subtarget, owner, substring)){ + curcon->flag |= CONSTRAINT_DISABLE; + result = 1; + break; + // return 1; + } + if (detect_constraint_loop (data->tar, data->subtarget, disable)){ + curcon->flag |= CONSTRAINT_DISABLE; + result = 1; + break; + // return 1; + } + } + break; + case CONSTRAINT_TYPE_KINEMATIC: + { + bKinematicConstraint *data = curcon->data; + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + + if (add_constraint_element (data->tar, data->subtarget, owner, substring)){ + curcon->flag |= CONSTRAINT_DISABLE; + result = 1; + break; + // return 1; + } + if (detect_constraint_loop (data->tar, data->subtarget, disable)){ + curcon->flag |= CONSTRAINT_DISABLE; + result = 1; + break; + // return 1; + } + } + break; + case CONSTRAINT_TYPE_TRACKTO: + { + bTrackToConstraint *data = curcon->data; + if (!exist_object(data->tar)) data->tar = NULL; + + if (add_constraint_element (data->tar, data->subtarget, owner, substring)){ + curcon->flag |= CONSTRAINT_DISABLE; + result = 1; + break; + // return 1; + } + if (detect_constraint_loop (data->tar, data->subtarget, disable)){ + curcon->flag |= CONSTRAINT_DISABLE; + result = 1; + break; + // return 1; + } + } + break; + } + } + } + } + + return result; +} + +ListBase *get_constraint_client_channels (int forcevalid) +{ + + Object *ob; + char ipstr[64]; + + ob=OBACT; + + if (!ob) + return NULL; + + /* See if we are a bone constraint */ + if (G.obpose){ + switch (G.obpose->type){ + case OB_ARMATURE: + { + bActionChannel *achan; + Bone *bone; + + bone = get_first_selected_bone(); + if (!bone) break; + + /* Make sure we have an action */ + if (!G.obpose->action){ + if (!forcevalid) + return NULL; + + G.obpose->action=add_empty_action(); + } + + /* Make sure we have an actionchannel */ + achan = get_named_actionchannel(G.obpose->action, bone->name); + if (!achan){ + if (!forcevalid) + return NULL; + + achan = MEM_callocN (sizeof(bActionChannel), "actionChannel"); + + strcpy (achan->name, bone->name); + sprintf (ipstr, "%s.%s", G.obpose->action->id.name+2, achan->name); + ipstr[23]=0; + achan->ipo= add_ipo(ipstr, ID_AC); + + BLI_addtail (&G.obpose->action->chanbase, achan); + } + + return &achan->constraintChannels; + } + } + } + + return &ob->constraintChannels; +} + +ListBase *get_constraint_client(char *name, short *clientType, void **clientdata) +{ + Object *ob; + ListBase *list; + + ob=OBACT; + if (clientType) + *clientType = -1; + + if (!ob) + return NULL; + + list = &ob->constraints; + + /* Prep the object's constraint channels */ + if (clientType) + *clientType = TARGET_OBJECT; + + if (name) + strcpy (name, ob->id.name+2); + + if (G.obpose){ + switch (G.obpose->type){ + case OB_ARMATURE: + { + Bone *bone; + + bone = get_first_selected_bone(); + if (!bone) break; + + { + bPoseChannel *chan; + + /* Is the bone the client? */ + if (clientType) + *clientType = TARGET_BONE; + if (clientdata) + *clientdata = bone; + if (name) + sprintf (name, "%s>>%s", name, bone->name); + verify_pose_channel(G.obpose->pose, bone->name); + chan = get_pose_channel (G.obpose->pose, bone->name); + list = &chan->constraints; + + } + } + break; + } + } + + return list; +} + +void *new_constraint_data (short type) +{ + void *result; + + switch (type){ + case CONSTRAINT_TYPE_KINEMATIC: + { + bKinematicConstraint *data; + data = MEM_callocN(sizeof(bKinematicConstraint), "kinematicConstraint"); + + data->tolerance = 0.001; + data->iterations = 500; + + result = data; + } + break; + case CONSTRAINT_TYPE_NULL: + { + result = NULL; + } + break; + case CONSTRAINT_TYPE_TRACKTO: + { + bTrackToConstraint *data; + data = MEM_callocN(sizeof(bTrackToConstraint), "tracktoConstraint"); + + result = data; + + } + break; + case CONSTRAINT_TYPE_ROTLIKE: + { + bRotateLikeConstraint *data; + data = MEM_callocN(sizeof(bRotateLikeConstraint), "rotlikeConstraint"); + + result = data; + } + break; + case CONSTRAINT_TYPE_LOCLIKE: + { + bLocateLikeConstraint *data; + data = MEM_callocN(sizeof(bLocateLikeConstraint), "loclikeConstraint"); + + data->flag |= LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z; + result = data; + } + break; + case CONSTRAINT_TYPE_ACTION: + { + bActionConstraint *data; + data = MEM_callocN(sizeof(bActionConstraint), "actionConstraint"); + + result = data; + } + break; + default: + result = NULL; + break; + } + + return result; +} + +bConstraint * add_new_constraint(void) +{ + bConstraint *con; + + con = MEM_callocN(sizeof(bConstraint), "constraint"); + + /* Set up a generic constraint datablock */ + con->type = CONSTRAINT_TYPE_TRACKTO; + con->flag |= CONSTRAINT_EXPAND; + con->enforce=1.0F; + /* Load the data for it */ + con->data = new_constraint_data(con->type); + strcpy (con->name, "Const"); + return con; +} + +bConstraintChannel *add_new_constraint_channel(const char* name) +{ + bConstraintChannel *chan = NULL; + + chan = MEM_callocN(sizeof(bConstraintChannel), "constraintChannel"); + strcpy(chan->name, name); + + return chan; +}
\ No newline at end of file diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c new file mode 100644 index 00000000000..023fa1bba27 --- /dev/null +++ b/source/blender/src/editcurve.c @@ -0,0 +1,3979 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif +#include <stdlib.h> +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_curve_types.h" +#include "DNA_ipo_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_library.h" +#include "BKE_ipo.h" +#include "BKE_displist.h" +#include "BKE_curve.h" +#include "BKE_global.h" +#include "BKE_object.h" +#include "BKE_main.h" + +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_screen.h" +#include "BIF_toolbox.h" +#include "BIF_space.h" +#include "BIF_editkey.h" +#include "BIF_mywindow.h" +#include "BIF_interface.h" + +#include "BSE_view.h" /* For persp... */ +#include "BSE_edit.h" + +#include "BDR_drawobject.h" +#include "BDR_editcurve.h" +#include "BDR_editobject.h" + +/* #include "graphics.h" */ +#include "interface.h" /* MAART: for NUM and FLO types, + pupmenu */ +/* #include "edit.h" */ +#include "mydevice.h" +#include "blendef.h" + + +#include "BDR_editcurve.h" +/* still need to eradicate a few :( */ +#define callocstructN(x,y,name) (x*)MEM_callocN((y)* sizeof(x),name) +/* only used sparingly: */ +#define BEZSELECTED(bezt) (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1)) + + +ListBase editNurb; +BPoint *lastselbp; +Nurb *lastnu; /* voor selected */ + + +/* void freeNurblist(ListBase *lb); already declared in the kernel */ + +float nurbcircle[8][2]= { + {0.0, -1.0}, {-1.0, -1.0}, {-1.0, 0.0}, {-1.0, 1.0}, + {0.0, 1.0}, { 1.0, 1.0}, { 1.0, 0.0}, { 1.0, -1.0} +}; + +short isNurbsel(Nurb *nu) +{ + BezTriple *bezt; + BPoint *bp; + int a; + + if((nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if( (bezt->f1 & 1) || (bezt->f2 & 1) || (bezt->f3 & 1) ) return 1; + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if( (bp->f1 & 1) ) return 1; + bp++; + } + } + return 0; +} + +int isNurbsel_count(Nurb *nu) +{ + BezTriple *bezt; + BPoint *bp; + int a, sel=0; + + if((nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if( (bezt->f1 & 1) || (bezt->f2 & 1) || (bezt->f3 & 1) ) sel++; + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if( (bp->f1 & 1) ) sel++; + bp++; + } + } + return sel; +} + + +void printknots() +{ + Nurb *nu; + int a, num; + + nu= editNurb.first; + while(nu) { + if(isNurbsel(nu) && (nu->type & 7)==CU_NURBS) { + if(nu->knotsu) { + num= KNOTSU(nu); + for(a=0;a<num;a++) printf("knotu %d: %f\n", a, nu->knotsu[a]); + } + if(nu->knotsv) { + num= KNOTSV(nu); + for(a=0;a<num;a++) printf("knotv %d: %f\n", a, nu->knotsv[a]); + } + } + nu= nu->next; + } +} + +#if 0 +static void printweightsNurb(void) +{ + Nurb *nu; + BPoint *bp; + int a; + char str[30]; + + if(G.obedit==0) return; + + persp(0); + + glDrawBuffer(GL_FRONT); + + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_NURBS) { + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a--) { + if(bp->f1 & 1) { + if(bp->s[0]!= 3200) { + sprintf(str,"%2.2f", bp->vec[3]); + + cpack(0x737373); + glRasterPos2i(bp->s[0]-1, bp->s[1]-1); + BMF_DrawString(G.font, str); + + glRasterPos2i(bp->s[0]+1, bp->s[1]+1); + BMF_DrawString(G.font, str); + + cpack(0xFFFFFF); + glRasterPos2i(bp->s[0], bp->s[1]); + BMF_DrawString(G.font, str); + } + } + bp++; + } + } + nu= nu->next; + } + + glDrawBuffer(GL_BACK); + persp(1); +} +#endif + + +/* ********************* LOAD EN MAKE *************** */ + +void load_editNurb() +{ + /* laad editNurb in object */ + Curve *cu= 0; + Nurb *nu, *newnu; + KeyBlock *actkey=0; + + if(G.obedit==0) return; + + if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + + G.totvert= count_curveverts(&editNurb); + + cu= G.obedit->data; + + /* zijn er keys? */ + if(cu->key) { + actkey= cu->key->block.first; + while(actkey) { + if(actkey->flag & SELECT) break; + actkey= actkey->next; + } + + if(actkey) { + /* aktieve key: de vertices */ + + if(G.totvert) { + if(actkey->data) MEM_freeN(actkey->data); + + actkey->data= MEM_callocN(cu->key->elemsize*G.totvert, "actkey->data"); + actkey->totelem= G.totvert; + + curve_to_key(cu, actkey, &editNurb); + } + } + } + + if(cu->key && actkey!=cu->key->refkey) { + /* er zijn keys, alleen veranderingen in verts schrijven */ + /* als aantal vertices verschillen, beetje onvoorspelbaar */ + + /* vertex -> vertex copy! */ + if(actkey) key_to_curve(actkey, cu, &cu->nurb); + } + else { + freeNurblist(&(cu->nurb)); + + nu= editNurb.first; + while(nu) { + newnu= duplicateNurb(nu); + newnu->hide= 0; + BLI_addtail(&(cu->nurb), newnu); + + if((nu->type & 7)==CU_NURBS) { + if(nu->pntsu < nu->orderu) nu->orderu= nu->pntsu; + } + + nu= nu->next; + } + } + + } + + lastnu= 0; /* voor selected */ + +} + +void make_editNurb() +{ + /* maak kopie van baseNurb in editNurb */ + Curve *cu=0; + Nurb *nu, *newnu; + BezTriple *bezt; + BPoint *bp; + KeyBlock *actkey=0; + int a, tot=0; + + if(G.obedit==0) return; + + lastselbp= 0; /* global voor select row */ + + if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + freeNurblist(&editNurb); + + cu= G.obedit->data; + nu= cu->nurb.first; + + while(nu) { + newnu= duplicateNurb(nu); + BLI_addtail(&editNurb, newnu); + /* flags op nul */ + newnu->hide= 0; + if((nu->type & 7)==CU_BEZIER) { + a= nu->pntsu; + bezt= newnu->bezt; + while(a--) { + bezt->f1= bezt->f2= bezt->f3= bezt->hide= 0; + bezt++; + tot+= 3; + } + } + else { + a= nu->pntsu*nu->pntsv; + bp= newnu->bp; + while(a--) { + bp->f1= bp->hide= 0; + bp++; + tot++; + } + } + nu= nu->next; + } + + if(cu->key) { + actkey= cu->key->block.first; + while(actkey) { + if(actkey->flag & SELECT) break; + actkey= actkey->next; + } + + if(actkey) { + key_to_curve(actkey, cu, &editNurb); + } + } + makeDispList(G.obedit); + } + else G.obedit= 0; + + countall(); + + lastnu= 0; /* voor selected */ +} + +void remake_editNurb() +{ + + if(okee("Reload Original data")==0) return; + + make_editNurb(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); +} + + +void separate_nurb() +{ + Nurb *nu, *nu1; + Object *oldob; + Base *base, *oldbase; + Curve *cu; + ListBase editnurbo; + float trans[9]; + + if( (G.vd->lay & G.obedit->lay)==0 ) return; + + if(okee("Separate")==0) return; + + waitcursor(1); + + cu= G.obedit->data; + if(cu->key) { + error("Can't separate with vertex keys"); + return; + } + + /* we gaan de zaak als volgt neppen: + * 1. duplicate base: dit wordt de nieuwe, oude pointer onthouden + * 2. alle NIET geselecteerde curves/nurbs apart zetten + * 3. load_ebaseNurb(): dit is de nieuwe base + * 4. freelist en oude nurbs weer terughalen + */ + + /* alleen ebase geselecteerd */ + base= FIRSTBASE; + while(base) { + if(base->lay & G.vd->lay) { + if(base->object==G.obedit) base->flag |= 1; + else base->flag &= ~1; + } + base= base->next; + } + + /* apart zetten: alles wat maar enigszins NIET select is */ + editnurbo.first= editnurbo.last= 0; + nu= editNurb.first; + while(nu) { + nu1= nu->next; + if(isNurbsel(nu)==0) { + BLI_remlink(&editNurb, nu); + BLI_addtail(&editnurbo, nu); + } + nu= nu1; + } + + oldob= G.obedit; + oldbase= BASACT; + + trans[0]=trans[1]=trans[2]=trans[3]=trans[4]=trans[5]= 0.0; + trans[6]=trans[7]=trans[8]= 1.0; + G.qual |= LR_ALTKEY; /* patch om zeker te zijn van gelinkte dupli */ + adduplicate(trans); + G.qual &= ~LR_ALTKEY; + + G.obedit= BASACT->object; /* basact wordt in adduplicate() gezet */ + + G.obedit->data= copy_curve(cu); + /* omdat nieuwe curve een kopie is: aantal users verlagen */ + cu->id.us--; + + load_editNurb(); + + BASACT->flag &= ~SELECT; + + if(editNurb.first) freeNurblist(&editNurb); + + editNurb= editnurbo; + + G.obedit= 0; /* displisten doen anders in editmode */ + makeDispList(OBACT); /* de gesepareerde */ + + G.obedit= oldob; + BASACT= oldbase; + BASACT->flag |= SELECT; + + waitcursor(0); + + countall(); + allqueue(REDRAWVIEW3D, 0); + + lastnu= 0; /* voor selected */ +} + +/* ******************* FLAGS ********************* */ + + +short isNurbselUV(Nurb *nu, int *u, int *v, int flag) +/* +Nurb *nu; +int *u, *v, flag; +*/ +{ + /* return u!=-1: 1 rij in u-richting geselecteerd. U heeft de waarde tussen 0-pntsv + * return v!=-1: 1 kolom in v-richting geselecteerd. V heeft de waarde tussen 0-pntsu + */ + BPoint *bp; + int a, b, sel; + + *u= *v= -1; + + bp= nu->bp; + for(b=0; b<nu->pntsv; b++) { + sel= 0; + for(a=0; a<nu->pntsu; a++, bp++) { + if(bp->f1 & flag) sel++; + } + if(sel==nu->pntsu) { + if(*u== -1) *u= b; + else return 0; + } + else if(sel>1) return 0; /* want sel==1 is nog goed */ + } + + for(a=0; a<nu->pntsu; a++) { + sel= 0; + bp= nu->bp+a; + for(b=0; b<nu->pntsv; b++, bp+=nu->pntsu) { + if(bp->f1 & flag) sel++; + } + if(sel==nu->pntsv) { + if(*v== -1) *v= a; + else return 0; + } + else if(sel>1) return 0; + } + + if(*u==-1 && *v>-1) return 1; + if(*v==-1 && *u>-1) return 1; + return 0; +} + +void setflagsNurb(short flag) +/* short flag; */ +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a; + + nu= editNurb.first; + while(nu) { + if( (nu->type & 7)==CU_BEZIER) { + a= nu->pntsu; + bezt= nu->bezt; + while(a--) { + bezt->f1= bezt->f2= bezt->f3= flag; + bezt++; + } + } + else { + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a--) { + bp->f1= flag; + bp++; + } + } + nu= nu->next; + } +} + +void rotateflagNurb(short flag, float *cent, float rotmat[][3]) +{ + /* alle verts met (flag & 'flag') rotate */ + Nurb *nu; + BPoint *bp; + int a; + + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_NURBS) { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + + while(a--) { + if(bp->f1 & flag) { + bp->vec[0]-=cent[0]; + bp->vec[1]-=cent[1]; + bp->vec[2]-=cent[2]; + Mat3MulVecfl(rotmat, bp->vec); + bp->vec[0]+=cent[0]; + bp->vec[1]+=cent[1]; + bp->vec[2]+=cent[2]; + } + bp++; + } + } + nu= nu->next; + } +} + + +void translateflagNurb(short flag, float *vec) +{ + /* alle verts met (->f & flag) translate */ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a; + + nu= editNurb.first; + while(nu) { + if( (nu->type & 7)==CU_BEZIER) { + a= nu->pntsu; + bezt= nu->bezt; + while(a--) { + if(bezt->f1 & flag) VecAddf(bezt->vec[0], bezt->vec[0], vec); + if(bezt->f2 & flag) VecAddf(bezt->vec[1], bezt->vec[1], vec); + if(bezt->f3 & flag) VecAddf(bezt->vec[2], bezt->vec[2], vec); + bezt++; + } + } + else { + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a--) { + if(bp->f1 & flag) VecAddf(bp->vec, bp->vec, vec); + bp++; + } + } + + test2DNurb(nu); + + nu= nu->next; + } +} + +void weightflagNurb(short flag, float w, int mode) /* mode==0: vervangen, mode==1: vermenigvuldigen */ +{ + Nurb *nu; + BPoint *bp; + int a; + + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_NURBS) { + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a--) { + if(bp->f1 & flag) { + if(mode==1) bp->vec[3]*= w; + else bp->vec[3]= w; + } + bp++; + } + } + nu= nu->next; + } +} + +void deleteflagNurb(short flag) +{ + Nurb *nu, *next; + BPoint *bp, *bpn, *newbp; + int a, b, newu, newv, sel; + + if(G.obedit && G.obedit->type==OB_SURF); + else return; + + lastselbp= 0; + + nu= editNurb.first; + while(nu) { + next= nu->next; + + /* is de hele nurb geselecteerd */ + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a) { + a--; + if(bp->f1 & flag); + else break; + bp++; + } + if(a==0) { + BLI_remlink(&editNurb, nu); + freeNurb(nu); + } + else { + /* is de nurb in U richting geselecteerd */ + newv= nu->pntsv; + bp= nu->bp; + for(b=0; b<nu->pntsv; b++) { + sel= 0; + for(a=0; a<nu->pntsu; a++, bp++) { + if(bp->f1 & flag) sel++; + } + if(sel==nu->pntsu) { + newv--; + } + else if(sel>=1) { + /* don't delete */ + break; + } + } + if(newv!=nu->pntsv && b==nu->pntsv) { + /* deleten */ + bp= nu->bp; + bpn = newbp = + (BPoint*) MEM_mallocN(newv * nu->pntsu * sizeof(BPoint), "deleteNurb"); + for(b=0; b<nu->pntsv; b++) { + if((bp->f1 & flag)==0) { + memcpy(bpn, bp, nu->pntsu*sizeof(BPoint)); + bpn+= nu->pntsu; + } + bp+= nu->pntsu; + } + nu->pntsv= newv; + MEM_freeN(nu->bp); + nu->bp= newbp; + if(nu->orderv>nu->pntsv) nu->orderv= nu->pntsv; + + makeknots(nu, 2, nu->flagv>>1); + } + else { + /* is de nurb in V richting geselecteerd */ + newu= nu->pntsu; + for(a=0; a<nu->pntsu; a++) { + bp= nu->bp+a; + sel= 0; + for(b=0; b<nu->pntsv; b++, bp+=nu->pntsu) { + if(bp->f1 & flag) sel++; + } + if(sel==nu->pntsv) { + newu--; + } + else if(sel>=1) { + /* don't delete */ + break; + } + } + if(newu!=nu->pntsu && a==nu->pntsu) { + /* deleten */ + bp= nu->bp; + bpn = newbp = + (BPoint*) MEM_mallocN(newu * nu->pntsv * sizeof(BPoint), "deleteNurb"); + for(b=0; b<nu->pntsv; b++) { + for(a=0; a<nu->pntsu; a++, bp++) { + if((bp->f1 & flag)==0) { + *bpn= *bp; + bpn++; + } + } + } + MEM_freeN(nu->bp); + nu->bp= newbp; + if(newu==1 && nu->pntsv>1) { /* maak een U spline */ + nu->pntsu= nu->pntsv; + nu->pntsv= 1; + SWAP(short, nu->orderu, nu->orderv); + if(nu->orderu>nu->pntsu) nu->orderu= nu->pntsu; + if(nu->knotsv) MEM_freeN(nu->knotsv); + nu->knotsv= 0; + } + else { + nu->pntsu= newu; + if(nu->orderu>nu->pntsu) nu->orderu= nu->pntsu; + } + makeknots(nu, 1, nu->flagu>>1); + } + } + } + nu= next; + } +} + +short extrudeflagNurb(int flag) +/* int flag; */ +{ + Nurb *nu; + BPoint *bp, *bpn, *newbp; + int ok= 0, a, u, v, len; + + if(G.obedit && G.obedit->type==OB_SURF); + else return 0; + + nu= editNurb.first; + while(nu) { + + if(nu->pntsv==1) { + bp= nu->bp; + a= nu->pntsu; + while(a) { + if(bp->f1 & flag); + else break; + bp++; + a--; + } + if(a==0) { + ok= 1; + newbp = + (BPoint*)MEM_mallocN(2 * nu->pntsu * sizeof(BPoint), "extrudeNurb1"); + memcpy(newbp, nu->bp, nu->pntsu*sizeof(BPoint) ); + bp= newbp+ nu->pntsu; + memcpy(bp, nu->bp, nu->pntsu*sizeof(BPoint) ); + MEM_freeN(nu->bp); + nu->bp= newbp; + a= nu->pntsu; + while(a--) { + bp->f1 |= flag; + newbp->f1 &= ~flag; + bp++; + newbp++; + } + + nu->pntsv= 2; + nu->orderv= 2; + makeknots(nu, 2, nu->flagv>>1); + } + } + else { + /* welke rij of kolom is geselecteerd */ + + if( isNurbselUV(nu, &u, &v, flag) ) { + + /* alles deselecteren */ + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + bp->f1 &= ~flag; + bp++; + } + + if(u==0 || u== nu->pntsv-1) { /* rij in u-richting geselecteerd */ + ok= 1; + newbp = + (BPoint*) MEM_mallocN(nu->pntsu*(nu->pntsv + 1) + * sizeof(BPoint), "extrudeNurb1"); + if(u==0) { + len= nu->pntsv*nu->pntsu; + memcpy(newbp+nu->pntsu, nu->bp, len*sizeof(BPoint) ); + memcpy(newbp, nu->bp, nu->pntsu*sizeof(BPoint) ); + bp= newbp; + } + else { + len= nu->pntsv*nu->pntsu; + memcpy(newbp, nu->bp, len*sizeof(BPoint) ); + memcpy(newbp+len, nu->bp+len-nu->pntsu, nu->pntsu*sizeof(BPoint) ); + bp= newbp+len; + } + + a= nu->pntsu; + while(a--) { + bp->f1 |= flag; + bp++; + } + + MEM_freeN(nu->bp); + nu->bp= newbp; + nu->pntsv++; + if(nu->resolv<3) nu->resolv++; + makeknots(nu, 2, nu->flagv>>1); + } + else if(v==0 || v== nu->pntsu-1) { /* kolom in v-richting geselecteerd */ + ok= 1; + bpn = newbp = + (BPoint*) MEM_mallocN((nu->pntsu + 1) * nu->pntsv * sizeof(BPoint), "extrudeNurb1"); + bp= nu->bp; + + for(a=0; a<nu->pntsv; a++) { + if(v==0) { + *bpn= *bp; + bpn->f1 |= flag; + bpn++; + } + memcpy(bpn, bp, nu->pntsu*sizeof(BPoint)); + bp+= nu->pntsu; + bpn+= nu->pntsu; + if(v== nu->pntsu-1) { + *bpn= *(bp-1); + bpn->f1 |= flag; + bpn++; + } + } + + MEM_freeN(nu->bp); + nu->bp= newbp; + nu->pntsu++; + if(nu->resolu<3) nu->resolu++; + makeknots(nu, 1, nu->flagu>>1); + } + } + } + nu= nu->next; + } + + return ok; +} + + +void adduplicateflagNurb(short flag) +/* short flag; */ +{ + Nurb *nu, *newnu; + BezTriple *bezt, *bezt1; + BPoint *bp, *bp1; + int a, b, starta, enda, newu, newv; + char *usel; + + nu= editNurb.last; + while(nu) { + if( (nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + for(a=0; a<nu->pntsu; a++) { + enda= -1; + starta= a; + while( (bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag) ) { + bezt->f1 &= ~flag; + bezt->f2 &= ~flag; + bezt->f3 &= ~flag; + enda=a; + if(a>=nu->pntsu-1) break; + a++; + bezt++; + } + if(enda>=starta) { + newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN"); + memcpy(newnu, nu, sizeof(Nurb)); + BLI_addtail(&editNurb, newnu); + lastnu= newnu; + newnu->pntsu= enda-starta+1; + newnu->bezt= + (BezTriple*)MEM_mallocN((enda - starta + 1) * sizeof(BezTriple), "adduplicateN"); + memcpy(newnu->bezt, nu->bezt+starta, newnu->pntsu*sizeof(BezTriple)); + + b= newnu->pntsu; + bezt1= newnu->bezt; + while(b--) { + bezt1->f1 |= flag; + bezt1->f2 |= flag; + bezt1->f3 |= flag; + bezt1++; + } + + if(nu->flagu & 1) { + if(starta!=0 || enda!=nu->pntsu-1) newnu->flagu--; + } + } + bezt++; + } + } + else if(nu->pntsv==1) { /* want UV Nurb heeft andere duplimethode */ + bp= nu->bp; + for(a=0; a<nu->pntsu; a++) { + enda= -1; + starta= a; + while(bp->f1 & flag) { + bp->f1 &= ~flag; + enda= a; + if(a>=nu->pntsu-1) break; + a++; + bp++; + } + if(enda>=starta) { + newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN3"); + memcpy(newnu, nu, sizeof(Nurb)); + lastnu= newnu; + BLI_addtail(&editNurb, newnu); + newnu->pntsu= enda-starta+1; + newnu->bp = (BPoint*)MEM_mallocN((enda-starta+1) * sizeof(BPoint), "adduplicateN4"); + memcpy(newnu->bp, nu->bp+starta, newnu->pntsu*sizeof(BPoint)); + + b= newnu->pntsu; + bp1= newnu->bp; + while(b--) { + bp1->f1 |= flag; + bp1++; + } + + if(nu->flagu & 1) { + if(starta!=0 || enda!=nu->pntsu-1) newnu->flagu--; + } + + /* knots */ + newnu->knotsu= 0; + makeknots(newnu, 1, newnu->flagu>>1); + } + bp++; + } + } + else { + /* een rechthoekig gebied in de nurb moet geselecteerd zijn */ + if(isNurbsel(nu)) { + usel= MEM_callocN(nu->pntsu, "adduplicateN4"); + bp= nu->bp; + for(a=0; a<nu->pntsv; a++) { + for(b=0; b<nu->pntsu; b++, bp++) { + if(bp->f1 & flag) usel[b]++; + } + } + newu= 0; + newv= 0; + for(a=0; a<nu->pntsu; a++) { + if(usel[a]) { + if(newv==0 || usel[a]==newv) { + newv= usel[a]; + newu++; + } + else { + newv= 0; + break; + } + } + } + if(newu==0 || newv==0) { + printf("Can't duplicate Nurb\n"); + } + else { + + if(newu==1) SWAP(short, newu, newv); + + newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN5"); + memcpy(newnu, nu, sizeof(Nurb)); + BLI_addtail(&editNurb, newnu); + lastnu= newnu; + newnu->pntsu= newu; + newnu->pntsv= newv; + newnu->bp = + (BPoint*)MEM_mallocN(newu * newv * sizeof(BPoint), "adduplicateN6"); + newnu->orderu= MIN2(nu->orderu, newu); + newnu->orderv= MIN2(nu->orderv, newv); + + bp= newnu->bp; + bp1= nu->bp; + for(a=0; a<nu->pntsv; a++) { + for(b=0; b<nu->pntsu; b++, bp1++) { + if(bp1->f1 & flag) { + memcpy(bp, bp1, sizeof(BPoint)); + bp1->f1 &= ~flag; + bp++; + } + } + } + if(nu->pntsu==newnu->pntsu) { + newnu->knotsu= MEM_mallocN(sizeof(float)*KNOTSU(nu), "adduplicateN6"); + memcpy(newnu->knotsu, nu->knotsu, sizeof(float)*KNOTSU(nu)); + } + else { + newnu->knotsu= 0; + makeknots(newnu, 1, newnu->flagu>>1); + } + if(nu->pntsv==newnu->pntsv) { + newnu->knotsv= MEM_mallocN(sizeof(float)*KNOTSV(nu), "adduplicateN7"); + memcpy(newnu->knotsv, nu->knotsv, sizeof(float)*KNOTSV(nu)); + } + else { + newnu->knotsv= 0; + makeknots(newnu, 2, newnu->flagv>>1); + } + + } + MEM_freeN(usel); + } + } + + nu= nu->prev; + } + + /* lastnu changed */ + allqueue(REDRAWBUTSEDIT, 0); +} + + +void switchdirectionNurb2(void) +{ + Nurb *nu; + + if(G.obedit->lay & G.vd->lay); + else return; + + nu= editNurb.first; + while(nu) { + if( isNurbsel(nu) ) switchdirectionNurb(nu); + nu= nu->next; + } + + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); +} + +void switchdirection_knots(float *base, int tot) +{ + float *fp1, *fp2, *tempf; + int a; + + if(base==NULL || tot==0) return; + + /* de knots omkeren */ + a= tot; + fp1= base; + fp2= fp1+(a-1); + a/= 2; + while(fp1!=fp2 && a>0) { + SWAP(float, *fp1, *fp2); + a--; + fp1++; + fp2--; + } + /* en weer in stijgende lijn maken */ + a= tot; + fp1= base; + fp2=tempf= MEM_mallocN(sizeof(float)*a, "switchdirect"); + while(a--) { + fp2[0]= fabs(fp1[1]-fp1[0]); + fp1++; + fp2++; + } + + a= tot-1; + fp1= base; + fp2= tempf; + fp1[0]= 0.0; + fp1++; + while(a--) { + fp1[0]= fp1[-1]+fp2[0]; + fp1++; + fp2++; + } + MEM_freeN(tempf); +} + +/* **************** EDIT ************************ */ + +void deselectall_nurb() +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a, b; + + if(G.obedit->lay & G.vd->lay); + else return; + + a= 0; + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + b= nu->pntsu; + bezt= nu->bezt; + while(b--) { + if(bezt->hide==0) { + if(bezt->f1 & 1) { + a=1; + break; + } + if(bezt->f2 & 1) { + a=1; + break; + } + if(bezt->f3 & 1) { + a=1; + break; + } + } + bezt++; + } + } + else { + b= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(b--) { + if(bp->hide==0) { + if(bp->f1 & 1) { + a=1; + break; + } + } + bp++; + } + } + if(a) break; + nu= nu->next; + } + + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==1) { + b= nu->pntsu; + bezt= nu->bezt; + while(b--) { + if(bezt->hide==0) { + if(a) { + bezt->f1 &= ~1; + bezt->f2 &= ~1; + bezt->f3 &= ~1; + } + else { + bezt->f1 |= 1; + bezt->f2 |= 1; + bezt->f3 |= 1; + } + } + bezt++; + } + } + else { + b= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(b--) { + if(bp->hide==0) { + if(a) bp->f1 &= ~ 1; + else bp->f1 |= 1; + } + bp++; + } + } + nu= nu->next; + } + countall(); + allqueue(REDRAWVIEW3D, 0); +} + +void hideNurb(int swap) +{ + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + int a, sel; + + if(G.obedit==0) return; + + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + sel= 0; + while(a--) { + if(BEZSELECTED(bezt)) { + sel++; + bezt->f1 &= ~1; + bezt->f2 &= ~1; + bezt->f3 &= ~1; + bezt->hide= 1; + } + bezt++; + } + if(sel==nu->pntsu) nu->hide= 1; + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + sel= 0; + while(a--) { + if(swap==0 && (bp->f1 & 1)) { + bp->f1 &= ~1; + bp->hide= 1; + sel++; + } + else if(swap && (bp->f1 & 1)==0) { + bp->f1 &= ~1; + bp->hide= 1; + sel++; + } + bp++; + } + if(sel==nu->pntsu*nu->pntsv) nu->hide= 1; + } + nu= nu->next; + } + + makeDispList(G.obedit); + countall(); + allqueue(REDRAWVIEW3D, 0); +} + +void revealNurb() +{ + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + int a; + + if(G.obedit==0) return; + + nu= editNurb.first; + while(nu) { + nu->hide= 0; + if((nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(bezt->hide) { + bezt->f1 |= 1; + bezt->f2 |= 1; + bezt->f3 |= 1; + bezt->hide= 0; + } + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->hide) { + bp->f1 |= 1; + bp->hide= 0; + } + bp++; + } + } + nu= nu->next; + } + + makeDispList(G.obedit); + countall(); + allqueue(REDRAWVIEW3D, 0); +} + +void selectswapNurb() +{ + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + int a; + + if(G.obedit==0) return; + + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(bezt->hide==0) { + if(bezt->f1 & 1) bezt->f1 &= ~1; + else bezt->f1 |= 1; + if(bezt->f2 & 1) bezt->f2 &= ~1; + else bezt->f2 |= 1; + if(bezt->f3 & 1) bezt->f3 &= ~1; + else bezt->f3 |= 1; + } + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->hide==0) { + if(bp->f1 & 1) bp->f1 &= ~1; + else bp->f1 |= 1; + } + bp++; + } + } + nu= nu->next; + } + + countall(); + allqueue(REDRAWVIEW3D, 0); +} + +/** Divide the line segments associated with the currently selected + * curve nodes (Bezier or NURB). If there are no valid segment + * selections within the current selection, nothing happens. + * + * @deffunc subdividenurb subdivideNurb(void) + * @return Nothing + * @param None +*/ +void subdivideNurb() +{ + Nurb *nu; + BezTriple *prevbezt, *bezt, *beztnew, *beztn; + BPoint *bp, *prevbp, *bpnew, *bpn; + float vec[12]; + int a, b, sel, aantal, *usel, *vsel; + + // printf("*** subdivideNurb: entering subdivide\n"); + + nu= editNurb.first; + while(nu) { + aantal= 0; + if((nu->type & 7)==CU_BEZIER) { + /* + Insert a point into a 2D Bezier curve. + Endpoints are preserved. Otherwise, all selected and inserted points are + newly created. Old points are discarded. + */ + /* tellen */ + if(nu->flagu & 1) { + a= nu->pntsu; + bezt= nu->bezt; + prevbezt= bezt+(a-1); + } + else { + a= nu->pntsu-1; + prevbezt= nu->bezt; + bezt= prevbezt+1; + } + while(a--) { + if( BEZSELECTED(prevbezt) && BEZSELECTED(bezt) ) aantal++; + prevbezt= bezt; + bezt++; + } + + if(aantal) { + /* inserten */ + beztnew = + /* I have some severe doubt about the original + * formulation... I stick to the upper bound to be + * on the safe side */ + (BezTriple*)MEM_mallocN((aantal + nu->pntsu) * sizeof(BezTriple), "subdivNurb"); +/* mallocstructN(BezTriple, aantal+nu->pntsu, "subdivNurb"); */ + beztn= beztnew; + if(nu->flagu & 1) { + a= nu->pntsu; + bezt= nu->bezt; + prevbezt= bezt+(a-1); + } + else { + a= nu->pntsu-1; + prevbezt= nu->bezt; + bezt= prevbezt+1; + } + while(a--) { + memcpy(beztn, prevbezt, sizeof(BezTriple)); + beztn++; + // printf("*** subdivideNurb: insert Bezier point\n"); + + if( BEZSELECTED(prevbezt) && BEZSELECTED(bezt) ) { + memcpy(beztn, bezt, sizeof(BezTriple)); + maakbez(prevbezt->vec[1][0],prevbezt->vec[2][0], + bezt->vec[0][0],bezt->vec[1][0],vec,2); + maakbez(prevbezt->vec[1][1],prevbezt->vec[2][1], + bezt->vec[0][1],bezt->vec[1][1],vec+1,2); + maakbez(prevbezt->vec[1][2],prevbezt->vec[2][2], + bezt->vec[0][2],bezt->vec[1][2],vec+2,2); + VECCOPY(beztn->vec[1], vec+3); + beztn->h1= beztn->h2= HD_AUTO; + beztn++; + } + + prevbezt= bezt; + bezt++; + } + /* laatste punt */ + if((nu->flagu & 1)==0) memcpy(beztn, prevbezt, sizeof(BezTriple)); + + MEM_freeN(nu->bezt); + nu->bezt= beztnew; + nu->pntsu+= aantal; + + calchandlesNurb(nu); + } + } /* End of 'if((nu->type & 7)==CU_BEZIER)' */ + else if (nu->pntsv==1) { + /* + All flat lines (ie. co-planar), except flat Nurbs. Flat NURB curves + are handled together with the regular NURB plane division, as it + should be. I split it off just now, let's see if it is + stable... nzc 30-5-'00 + */ + /* tellen */ + if(nu->flagu & 1) { + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + prevbp= bp+(a-1); + } + else { + a= nu->pntsu-1; + prevbp= nu->bp; + bp= prevbp+1; + } + while(a--) { + if( (bp->f1 & 1) && (prevbp->f1 & 1) ) aantal++; + prevbp= bp; + bp++; + } + + if(aantal) { + /* inserten */ + bpnew = + (BPoint*)MEM_mallocN((aantal + nu->pntsu) * sizeof(BPoint), "subdivNurb2"); + bpn= bpnew; + + if(nu->flagu & 1) { + a= nu->pntsu; + bp= nu->bp; + prevbp= bp+(a-1); + } + else { + a= nu->pntsu-1; + prevbp= nu->bp; + bp= prevbp+1; + } + while(a--) { + memcpy(bpn, prevbp, sizeof(BPoint)); + bpn++; + + if( (bp->f1 & 1) && (prevbp->f1 & 1) ) { + // printf("*** subdivideNurb: insert 'linear' point\n"); + memcpy(bpn, bp, sizeof(BPoint)); + bpn->vec[0]= (prevbp->vec[0]+bp->vec[0])/2.0; + bpn->vec[1]= (prevbp->vec[1]+bp->vec[1])/2.0; + bpn->vec[2]= (prevbp->vec[2]+bp->vec[2])/2.0; + bpn->vec[3]= (prevbp->vec[3]+bp->vec[3])/2.0; + bpn++; + + } + prevbp= bp; + bp++; + } + if((nu->flagu & 1)==0) memcpy(bpn, prevbp, sizeof(BPoint)); /* laatste punt */ + + MEM_freeN(nu->bp); + nu->bp= bpnew; + nu->pntsu+= aantal; + + if(nu->type & 4) { + makeknots(nu, 1, nu->flagu>>1); + } + } + } /* End of 'else if(nu->pntsv==1)' */ + else if((nu->type & 7)==CU_NURBS) { + /* This is a very strange test ... */ + /** + Subdivide NURB surfaces - nzc 30-5-'00 - + + Subdivision of a NURB curve can be effected by adding a + control point (insertion of a knot), or by raising the + degree of the functions used to build the NURB. The + expression + + degree = #knots - #controlpoints + 1 (J Walter piece) + degree = #knots - #controlpoints (Blender + implementation) + ( this is confusing.... what is true? Another concern + is that the JW piece allows the curve to become + explicitly 1st order derivative discontinuous, while + this is not what we want here... ) + + is an invariant for a single NURB curve. Raising the degree + of the NURB is done elsewhere; the degree is assumed + constant during this opration. Degree is a property shared + by all controlpoints in a curve (even though it is stored + per control point - this can be misleading). + Adding a knot is done by searching for the place in the + knot vector where a certain knot value must be inserted, or + by picking an appropriate knot value between two existing + ones. The number of controlpoints that is influenced by the + insertion depends on the order of the curve. A certain + minimum number of knots is needed to form high-order + curves, as can be seen from the equation above. In Blender, + currently NURBs may be up to 6th order, so we modify at + most 6 points. One point is added. For an n-degree curve, + n points are discarded, and n+1 points inserted + (so effectively, n points are modified). (that holds for + the JW piece, but it seems not for our NURBs) + In practice, the knot spacing is copied, but the tail + (the points following the insertion point) need to be + offset to keep the knot series ascending. The knot series + is always a series of monotonically ascending integers in + Blender. When not enough control points are available to + fit the order, duplicates of the endpoints are added as + needed. + */ + /* selecteer-arrays aanleggen */ + usel= MEM_callocN(sizeof(int)*nu->pntsu, "subivideNurb3"); + vsel= MEM_callocN(sizeof(int)*nu->pntsv, "subivideNurb3"); + sel= 0; + + /* Count the number of selected points. */ + bp= nu->bp; + for(a=0; a<nu->pntsv; a++) { + for(b=0; b<nu->pntsu; b++) { + if(bp->f1 & 1) { + usel[b]++; + vsel[a]++; + sel++; + } + bp++; + } + } + if( sel == (nu->pntsu*nu->pntsv) ) { /* hele nurb subdividen */ + /* Global subdivision is a special case of partial + subdivision. Strange it is considered separately... */ + bpn=bpnew= MEM_mallocN( (2*nu->pntsu-1)*(2*nu->pntsv-1)*sizeof(BPoint), "subdivideNurb4"); + bp= nu->bp; + /* eerst de rijen subdividen */ + for(a=0; a<nu->pntsv; a++) { + for(b=0; b<nu->pntsu; b++) { + *bpn= *bp; + bpn++; + bp++; + if(b<nu->pntsu-1) { + *bpn= *bp; + prevbp= bp-1; + bpn->vec[0]= (prevbp->vec[0]+bp->vec[0])/2.0; + bpn->vec[1]= (prevbp->vec[1]+bp->vec[1])/2.0; + bpn->vec[2]= (prevbp->vec[2]+bp->vec[2])/2.0; + bpn->vec[3]= (prevbp->vec[3]+bp->vec[3])/2.0; + bpn++; + } + } + bpn+= (2*nu->pntsu-1); + } + /* nu nieuwe invoegen */ + bpn= bpnew+(2*nu->pntsu-1); + bp= bpnew+(4*nu->pntsu-2); + prevbp= bpnew; + for(a=1; a<nu->pntsv; a++) { + + for(b=0; b<2*nu->pntsu-1; b++) { + *bpn= *bp; + bpn->vec[0]= (prevbp->vec[0]+bp->vec[0])/2.0; + bpn->vec[1]= (prevbp->vec[1]+bp->vec[1])/2.0; + bpn->vec[2]= (prevbp->vec[2]+bp->vec[2])/2.0; + bpn->vec[3]= (prevbp->vec[3]+bp->vec[3])/2.0; + bpn++; + bp++; + prevbp++; + } + bp+= (2*nu->pntsu-1); + bpn+= (2*nu->pntsu-1); + prevbp+= (2*nu->pntsu-1); + } + MEM_freeN(nu->bp); + nu->bp= bpnew; + nu->pntsu= 2*nu->pntsu-1; + nu->pntsv= 2*nu->pntsv-1; + makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 2, nu->flagv>>1); + } /* End of 'if(sel== nu->pntsu*nu->pntsv)' (subdivide entire NURB) */ + else { + /* in v richting subdividen? */ + sel= 0; + for(a=0; a<nu->pntsv-1; a++) { + if(vsel[a]==nu->pntsu && vsel[a+1]==nu->pntsu) sel++; + } + + if(sel) { /* V ! */ + bpn=bpnew= MEM_mallocN( (sel+nu->pntsv)*nu->pntsu*sizeof(BPoint), "subdivideNurb4"); + bp= nu->bp; + for(a=0; a<nu->pntsv; a++) { + for(b=0; b<nu->pntsu; b++) { + *bpn= *bp; + bpn++; + bp++; + } + if( (a<nu->pntsv-1) && vsel[a]==nu->pntsu && vsel[a+1]==nu->pntsu ) { + prevbp= bp- nu->pntsu; + for(b=0; b<nu->pntsu; b++) { + /* + This simple bisection must be replaces by a + subtle resampling of a number of points. Our + task is made slightly easier because each + point in our curve is a separate data + node. (is it?) + */ + *bpn= *prevbp; + bpn->vec[0]= (prevbp->vec[0]+bp->vec[0])/2.0; + bpn->vec[1]= (prevbp->vec[1]+bp->vec[1])/2.0; + bpn->vec[2]= (prevbp->vec[2]+bp->vec[2])/2.0; + bpn->vec[3]= (prevbp->vec[3]+bp->vec[3])/2.0; + bpn++; + prevbp++; + bp++; + } + bp-= nu->pntsu; + } + } + MEM_freeN(nu->bp); + nu->bp= bpnew; + nu->pntsv+= sel; + makeknots(nu, 2, nu->flagv>>1); + } + else { + /* of in u richting? */ + sel= 0; + for(a=0; a<nu->pntsu-1; a++) { + if(usel[a]==nu->pntsv && usel[a+1]==nu->pntsv) sel++; + } + + if(sel) { /* U ! */ + /* Inserting U points is sort of 'default' Flat curves only get */ + /* U points inserted in them. */ + bpn=bpnew= MEM_mallocN( (sel+nu->pntsu)*nu->pntsv*sizeof(BPoint), "subdivideNurb4"); + bp= nu->bp; + for(a=0; a<nu->pntsv; a++) { + for(b=0; b<nu->pntsu; b++) { + *bpn= *bp; + bpn++; + bp++; + if( (b<nu->pntsu-1) && usel[b]==nu->pntsv && usel[b+1]==nu->pntsv ) { + /* + One thing that bugs me here is that the + orders of things are not the same as in + the JW piece. Also, this implies that we + handle at most 3rd order curves? I miss + some symmetry here... + */ + prevbp= bp- 1; + *bpn= *prevbp; + bpn->vec[0]= (prevbp->vec[0]+bp->vec[0])/2.0; + bpn->vec[1]= (prevbp->vec[1]+bp->vec[1])/2.0; + bpn->vec[2]= (prevbp->vec[2]+bp->vec[2])/2.0; + bpn->vec[3]= (prevbp->vec[3]+bp->vec[3])/2.0; + bpn++; + } + } + } + MEM_freeN(nu->bp); + nu->bp= bpnew; + nu->pntsu+= sel; + makeknots(nu, 1, nu->flagu>>1); /* shift knots + forward */ + } + } + } + MEM_freeN(usel); + MEM_freeN(vsel); + // printf("*** subdivideNurb: end of NURB splitting part\n"); + } /* End of 'if((nu->type & 7)==CU_NURBS)' */ + nu= nu->next; + } + + /* Sync flushing */ + // printf("*** subdivideNurb: subdivide done\n"); + + makeDispList(G.obedit); + countall(); + allqueue(REDRAWVIEW3D, 0); +} + + +short findnearestNurbvert(short sel, Nurb **nurb, BezTriple **bezt, BPoint **bp) +/* +short sel; +Nurb **nurb; +BezTriple **bezt; +BPoint **bp; +*/ +{ + /* sel==1: selected krijgen een nadeel */ + /* in nurb en bezt of bp wordt nearest weggeschreven */ + /* return 0 1 2: handlepunt */ + Nurb *nu; + BezTriple *bezt1; + BPoint *bp1; + short dist= 100, temp, mval[2], a, hpoint=0; + + *nurb= 0; + *bezt= 0; + *bp= 0; + + /* projektie doen */ + calc_nurbverts_ext(); /* drawobject.c */ + + getmouseco_areawin(mval); + + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + bezt1= nu->bezt; + a= nu->pntsu; + while(a--) { + if(bezt1->hide==0) { + temp= abs(mval[0]- bezt1->s[0][0])+ abs(mval[1]- bezt1->s[0][1]); + if( (bezt1->f1 & 1)==sel) temp+=5; + if(temp<dist) { + hpoint=0; + *bezt=bezt1; + dist= temp; + *nurb= nu; + *bp= 0; + } + + /* middelste punten een klein nadeel */ + temp= 3+abs(mval[0]- bezt1->s[1][0])+ abs(mval[1]- bezt1->s[1][1]); + if( (bezt1->f2 & 1)==sel) temp+=5; + if(temp<dist) { + hpoint=1; + *bezt=bezt1; + dist= temp; + *nurb= nu; + *bp= 0; + } + + temp= abs(mval[0]- bezt1->s[2][0])+ abs(mval[1]- bezt1->s[2][1]); + if( (bezt1->f3 & 1)==sel) temp+=5; + if(temp<dist) { + hpoint=2; + *bezt=bezt1; + dist= temp; + *nurb= nu; + *bp= 0; + } + } + bezt1++; + } + } + else { + bp1= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp1->hide==0) { + temp= abs(mval[0]- bp1->s[0])+ abs(mval[1]- bp1->s[1]); + if( (bp1->f1 & 1)==sel) temp+=5; + if(temp<dist) { + hpoint=0; + *bp=bp1; + dist= temp; + *nurb= nu; + *bezt= 0; + } + } + bp1++; + } + } + nu= nu->next; + } + + return hpoint; +} + + +void findselectedNurbvert(Nurb **nu, BezTriple **bezt, BPoint **bp) +{ + /* in nu en (bezt of bp) wordt selected weggeschreven als er 1 sel. is */ + /* als er meer punten in 1 spline selected: alleen nu terug, bezt en bp zijn 0 */ + Nurb *nu1; + BezTriple *bezt1; + BPoint *bp1; + int a; + + *nu= 0; + *bezt= 0; + *bp= 0; + nu1= editNurb.first; + while(nu1) { + if((nu1->type & 7)==CU_BEZIER) { + bezt1= nu1->bezt; + a= nu1->pntsu; + while(a--) { + if( (bezt1->f1 & 1) || (bezt1->f2 & 1) || (bezt1->f3 & 1) ) { + if(*nu!=0 && *nu!= nu1) { + *nu= 0; + *bp= 0; + *bezt= 0; + return; + } + else if(*bezt || *bp) { + *bp= 0; + *bezt= 0; + } + else { + *bezt= bezt1; + *nu= nu1; + } + } + bezt1++; + } + } + else { + bp1= nu1->bp; + a= nu1->pntsu*nu1->pntsv; + while(a--) { + if( bp1->f1 & 1 ) { + if(*nu!=0 && *nu!= nu1) { + *bp= 0; + *bezt= 0; + *nu= 0; + return; + } + else if(*bezt || *bp) { + *bp= 0; + *bezt= 0; + } + else { + *bp= bp1; + *nu= nu1; + } + } + bp1++; + } + } + nu1= nu1->next; + } +} + +void setsplinetype(short type) +/* +short type; +*/ +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a, c, nr; + + if(type==CU_CARDINAL || type==CU_BSPLINE) { + error("Not implemented yet"); + return; + } + + nu= editNurb.first; + while(nu) { + if(isNurbsel(nu)) { + + if((nu->type & 7)==0) { /* Poly */ + if(type==CU_BEZIER) { /* naar Bezier met vecthandles */ + nr= nu->pntsu; + bezt = + (BezTriple*)MEM_callocN(nr * sizeof(BezTriple), "setsplinetype2"); + nu->bezt= bezt; + a= nr; + bp= nu->bp; + while(a--) { + VECCOPY(bezt->vec[1], bp->vec); + bezt->f1=bezt->f2=bezt->f3= bp->f1; + bezt->h1= bezt->h2= HD_VECT; + bp++; + bezt++; + } + MEM_freeN(nu->bp); + nu->bp= 0; + nu->pntsu= nr; + nu->type &= ~7; + nu->type |= 1; + calchandlesNurb(nu); + } + else if(type==4) { /* naar Nurb */ + nu->type &= ~7; + nu->type+= 4; + nu->orderu= 4; + nu->flagu &= 1; + nu->flagu += 4; + makeknots(nu, 1, nu->flagu>>1); + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a--) { + bp->vec[3]= 1.0; + bp++; + } + } + } + else if((nu->type & 7)==CU_BEZIER) { /* Bezier */ + if(type==0 || type==4) { /* naar Poly of Nurb */ + nr= 3*nu->pntsu; + nu->bp = + (BPoint*)MEM_callocN(nr * sizeof(BPoint), "setsplinetype"); + a= nu->pntsu; + bezt= nu->bezt; + bp= nu->bp; + while(a--) { + if(type==0 && bezt->h1==HD_VECT && bezt->h2==HD_VECT) { + /* vectorhandle wordt 1 polyvert */ + VECCOPY(bp->vec, bezt->vec[1]); + bp->vec[3]= 1.0; + bp->f1= bezt->f2; + nr-= 2; + bp++; + } + else { + for(c=0;c<3;c++) { + VECCOPY(bp->vec, bezt->vec[c]); + bp->vec[3]= 1.0; + if(c==0) bp->f1= bezt->f1; + else if(c==1) bp->f1= bezt->f2; + else bp->f1= bezt->f3; + bp++; + } + } + bezt++; + } + MEM_freeN(nu->bezt); + nu->bezt= 0; + nu->pntsu= nr; + nu->pntsv= 1; + nu->orderu= 4; + nu->orderv= 1; + nu->type &= ~7; + nu->type+= type; + if(nu->flagu & 1) c= nu->orderu-1; + else c= 0; + if(type== 4) { + nu->flagu &= 1; + nu->flagu += 4; + makeknots(nu, 1, nu->flagu>>1); + } + } + } + else if( (nu->type & 7)==CU_NURBS && G.obedit->type==OB_CURVE) { + if(type==0) { /* naar Poly */ + nu->type &= ~7; + MEM_freeN(nu->knotsu); + nu->knotsu= 0; + if(nu->knotsv) MEM_freeN(nu->knotsv); + nu->knotsv= 0; + } + else if(type==CU_BEZIER) { /* naar Bezier */ + nr= nu->pntsu/3; + bezt = + (BezTriple*)MEM_callocN(nr * sizeof(BezTriple), "setsplinetype2"); + nu->bezt= bezt; + a= nr; + bp= nu->bp; + while(a--) { + VECCOPY(bezt->vec[0], bp->vec); + bezt->f1= bp->f1; + bp++; + VECCOPY(bezt->vec[1], bp->vec); + bezt->f2= bp->f1; + bp++; + VECCOPY(bezt->vec[2], bp->vec); + bezt->f3= bp->f1; + bp++; + bezt++; + } + MEM_freeN(nu->bp); + nu->bp= 0; + MEM_freeN(nu->knotsu); + nu->knotsu= 0; + nu->pntsu= nr; + nu->type &= ~7; + nu->type+= 1; + } + } + } + nu= nu->next; + } +} + +/* ******************** SKINNING LOFTING!!! ******************** */ + +void rotate_direction_nurb(Nurb *nu) +{ + BPoint *bp1, *bp2, *temp; + int u, v; + + SWAP(short, nu->pntsu, nu->pntsv); + SWAP(short, nu->orderu, nu->orderv); + SWAP(short, nu->resolu, nu->resolv); + SWAP(short, nu->flagu, nu->flagv); + + SWAP(float *, nu->knotsu, nu->knotsv); + switchdirection_knots(nu->knotsv, KNOTSV(nu) ); + + temp= MEM_dupallocN(nu->bp); + bp1= nu->bp; + for(v=0; v<nu->pntsv; v++) { + for(u=0; u<nu->pntsu; u++, bp1++) { + bp2= temp + (nu->pntsu-u-1)*(nu->pntsv) + v; + *bp1= *bp2; + } + } + + MEM_freeN(temp); +} + +int is_u_selected(Nurb *nu, int u) +{ + BPoint *bp; + int v; + + /* what about resolu == 2? */ + bp= nu->bp+u; + for(v=0; v<nu->pntsv-1; v++, bp+=nu->pntsu) { + if(v) if(bp->f1 & 1) return 1; + } + + return 0; +} + +/* ******************************** */ + +typedef struct NurbSort { + struct NurbSort *next, *prev; + Nurb *nu; + float vec[3]; +} NurbSort; + +static ListBase nsortbase= {0, 0}; +/* static NurbSort *nusmain; */ /* this var seems to go unused... at least in this file */ + +void make_selection_list_nurb() +{ + ListBase nbase= {0, 0}; + NurbSort *nus, *nustest, *headdo, *taildo; + Nurb *nu; + BPoint *bp; + float dist, headdist, taildist; + int a; + + nu= editNurb.first; + while(nu) { + if( isNurbsel(nu) ) { + + nus = (NurbSort*)MEM_callocN(sizeof(NurbSort), "sort"); + BLI_addhead(&nbase, nus); + nus->nu= nu; + + bp= nu->bp; + a= nu->pntsu; + while(a--) { + VecAddf(nus->vec, nus->vec, bp->vec); + bp++; + } + VecMulf(nus->vec, 1.0/(float)nu->pntsu); + + + } + nu= nu->next; + } + + /* just add the first one */ + nus= nbase.first; + BLI_remlink(&nbase, nus); + BLI_addtail( &nsortbase, nus); + + /* now add, either at head or tail, the closest one */ + while(nbase.first) { + + headdist= taildist= 1.0e30; + headdo= taildo= 0; + + nustest= nbase.first; + while(nustest) { + dist= VecLenf(nustest->vec, ((NurbSort *)nsortbase.first)->vec); + + if(dist<headdist) { + headdist= dist; + headdo= nustest; + } + dist= VecLenf(nustest->vec, ((NurbSort *)nsortbase.last)->vec); + + if(dist<taildist) { + taildist= dist; + taildo= nustest; + } + nustest= nustest->next; + } + + if(headdist<taildist) { + BLI_remlink(&nbase, headdo); + BLI_addhead(&nsortbase, headdo); + } + else { + BLI_remlink(&nbase, taildo); + BLI_addtail(&nsortbase, taildo); + } + } +} + +void merge_2_nurb(Nurb *nu1, Nurb *nu2) +{ + BPoint *bp, *bp1, *bp2, *temp; + float len1, len2; + int origu, u, v; + + /* first nurbs will be changed to make u = resolu-1 selected */ + /* 2nd nurbs will be changed to make u = 0 selected */ + + /* first nurbs: u = resolu-1 selected */ + + if( is_u_selected(nu1, nu1->pntsu-1) ); + else { + rotate_direction_nurb(nu1); + if( is_u_selected(nu1, nu1->pntsu-1) ); + else { + rotate_direction_nurb(nu1); + if( is_u_selected(nu1, nu1->pntsu-1) ); + else { + rotate_direction_nurb(nu1); + if( is_u_selected(nu1, nu1->pntsu-1) ); + else { + /* rotate again, now its OK! */ + if(nu1->pntsv!=1) rotate_direction_nurb(nu1); + return; + } + } + } + } + + /* 2nd nurbs: u = 0 selected */ + if( is_u_selected(nu2, 0) ); + else { + rotate_direction_nurb(nu2); + if( is_u_selected(nu2, 0) ); + else { + rotate_direction_nurb(nu2); + if( is_u_selected(nu2, 0) ); + else { + rotate_direction_nurb(nu2); + if( is_u_selected(nu2, 0) ); + else { + /* rotate again, now its OK! */ + if(nu1->pntsu==1) rotate_direction_nurb(nu1); + if(nu2->pntsv!=1) rotate_direction_nurb(nu2); + return; + } + } + } + } + + if( nu1->pntsv != nu2->pntsv ) { + error("resolution doesn't match"); + return; + } + + /* ok, now nu1 has the rightmost collumn and nu2 the leftmost collumn selected */ + /* maybe we need a 'v' flip of nu2? */ + + bp1= nu1->bp+nu1->pntsu-1; + bp2= nu2->bp; + len1= 0.0; + + for(v=0; v<nu1->pntsv; v++, bp1+=nu1->pntsu, bp2+=nu2->pntsu) { + len1+= VecLenf(bp1->vec, bp2->vec); + } + + bp1= nu1->bp + nu1->pntsu-1; + bp2= nu2->bp + nu2->pntsu*(nu2->pntsv-1); + len2= 0.0; + + for(v=0; v<nu1->pntsv; v++, bp1+=nu1->pntsu, bp2-=nu2->pntsu) { + len2+= VecLenf(bp1->vec, bp2->vec); + } + + /* merge */ + origu= nu1->pntsu; + nu1->pntsu+= nu2->pntsu; + nu1->resolu+= nu2->pntsu; + if(nu1->resolv < nu2->resolv) nu1->resolv= nu2->resolv; + if(nu1->orderu<3) nu1->orderu++; + if(nu1->orderv<3) nu1->orderv++; + temp= nu1->bp; + nu1->bp= MEM_mallocN(nu1->pntsu*nu1->pntsv*sizeof(BPoint), "mergeBP"); + + bp= nu1->bp; + bp1= temp; + + for(v=0; v<nu1->pntsv; v++) { + + /* switch direction? */ + if(len1<len2) bp2= nu2->bp + v*nu2->pntsu; + else bp2= nu2->bp + (nu1->pntsv-v-1)*nu2->pntsu; + + for(u=0; u<nu1->pntsu; u++, bp++) { + if(u<origu) { + *bp= *bp1; bp1++; + bp->f1 &= ~SELECT; + } + else { + *bp= *bp2; bp2++; + } + } + } + + /* merge knots */ + makeknots(nu1, 1, nu1->flagu>>1); + + /* make knots, for merged curved for example */ + makeknots(nu1, 2, nu1->flagv>>1); + + MEM_freeN(temp); + BLI_remlink(&editNurb, nu2); + freeNurb(nu2); +} + +void merge_nurb() +{ + NurbSort *nus1, *nus2; + int ok= 1; + + make_selection_list_nurb(); + + if(nsortbase.first == nsortbase.last) { + BLI_freelistN(&nsortbase); + error("Too few selections"); + return; + } + + nus1= nsortbase.first; + nus2= nus1->next; + + /* resolution match, to avoid uv rotations */ + if(nus1->nu->pntsv==1) { + if(nus1->nu->pntsu==nus2->nu->pntsu || nus1->nu->pntsu==nus2->nu->pntsv); + else ok= 0; + } + else if(nus2->nu->pntsv==1) { + if(nus2->nu->pntsu==nus1->nu->pntsu || nus2->nu->pntsu==nus1->nu->pntsv); + else ok= 0; + } + else if( nus1->nu->pntsu==nus2->nu->pntsu || nus1->nu->pntsv==nus2->nu->pntsv); + else if( nus1->nu->pntsu==nus2->nu->pntsv || nus1->nu->pntsv==nus2->nu->pntsu); + else { + ok= 0; + } + + if(ok==0) { + error("resolution doesn't match"); + BLI_freelistN(&nsortbase); + return; + } + + while(nus2) { + merge_2_nurb(nus1->nu, nus2->nu); + nus2= nus2->next; + } + + BLI_freelistN(&nsortbase); + + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + +} + + +void addsegment_nurb() +{ + /* voegt twee curves samen */ + Nurb *nu, *nu1=0, *nu2=0; + BezTriple *bezt; + BPoint *bp; + float *fp, offset; + int a; + + /* first decide if this is a surface merge! */ + if(G.obedit->type==OB_SURF) nu= editNurb.first; + else nu= 0; + + while(nu) { + if( isNurbsel(nu) ) { + + if(nu->pntsu>1 && nu->pntsv>1) break; + if(isNurbsel_count(nu)>1) break; + if(isNurbsel_count(nu)==1) { + /* only 1 selected, not first or last, a little complex, but intuitive */ + if(nu->pntsv==1) { + if( (nu->bp->f1 & 1) || ((nu->bp+nu->pntsu-1)->f1 & 1)); + else break; + } + } + } + nu= nu->next; + } + if(nu) { + merge_nurb(); + return; + } + + /* vind de beide nurben en punten, nu1 wordt achter nu2 gezet */ + nu= editNurb.first; + while(nu) { + if((nu->flagu & 1)==0) { /* niet cyclic */ + if( (nu->type & 7)==CU_BEZIER ) { + bezt= nu->bezt; + if(nu1==0) { + if( BEZSELECTED(bezt) ) nu1= nu; + else { + bezt= bezt+(nu->pntsu-1); + if( BEZSELECTED(bezt) ) { + nu1= nu; + switchdirectionNurb(nu); + } + } + } + else if(nu2==0) { + if( BEZSELECTED(bezt) ) { + nu2= nu; + switchdirectionNurb(nu); + } + else { + bezt= bezt+(nu->pntsu-1); + if( BEZSELECTED(bezt) ) { + nu2= nu; + } + } + } + else break; + } + else if(nu->pntsv==1) { + bp= nu->bp; + if(nu1==0) { + if( bp->f1 & 1) nu1= nu; + else { + bp= bp+(nu->pntsu-1); + if( bp->f1 & 1 ) { + nu1= nu; + switchdirectionNurb(nu); + } + } + } + else if(nu2==0) { + if( bp->f1 & 1) { + nu2= nu; + switchdirectionNurb(nu); + } + else { + bp= bp+(nu->pntsu-1); + if( bp->f1 & 1 ) { + nu2= nu; + } + } + } + else break; + } + } + nu= nu->next; + } + + if((nu1 && nu2) && (nu1!=nu2)) { + if( nu1->type==nu2->type) { + if((nu1->type & 7)==CU_BEZIER) { + bezt = + (BezTriple*)MEM_mallocN((nu1->pntsu+nu2->pntsu) * sizeof(BezTriple), "addsegmentN"); + memcpy(bezt, nu2->bezt, nu2->pntsu*sizeof(BezTriple)); + memcpy(bezt+nu2->pntsu, nu1->bezt, nu1->pntsu*sizeof(BezTriple)); + MEM_freeN(nu1->bezt); + nu1->bezt= bezt; + nu1->pntsu+= nu2->pntsu; + BLI_remlink(&editNurb, nu2); + freeNurb(nu2); + calchandlesNurb(nu1); + } + else { + bp = + (BPoint*)MEM_mallocN((nu1->pntsu+nu2->pntsu) * sizeof(BPoint), "addsegmentN2"); + memcpy(bp, nu2->bp, nu2->pntsu*sizeof(BPoint) ); + memcpy(bp+nu2->pntsu, nu1->bp, nu1->pntsu*sizeof(BPoint)); + MEM_freeN(nu1->bp); + nu1->bp= bp; + + a= nu1->pntsu+nu1->orderu; + + nu1->pntsu+= nu2->pntsu; + BLI_remlink(&editNurb, nu2); + + /* en de knots aaneenrijgen */ + if((nu1->type & 7)==4) { + fp= MEM_mallocN(sizeof(float)*KNOTSU(nu1), "addsegment3"); + memcpy(fp, nu1->knotsu, sizeof(float)*a); + MEM_freeN(nu1->knotsu); + nu1->knotsu= fp; + + + offset= nu1->knotsu[a-1] +1.0; + fp= nu1->knotsu+a; + for(a=0; a<nu2->pntsu; a++, fp++) { + if(nu2->knotsu) + *fp= offset+nu2->knotsu[a+1]; + else + *fp = offset; + } + } + freeNurb(nu2); + } + } + makeDispList(G.obedit); + countall(); + allqueue(REDRAWVIEW3D, 0); + } + else error("Can't make segment"); +} + +void mouse_nurb() +{ + Nurb *nu; + BezTriple *bezt=0; + BPoint *bp=0; + short hand; + + hand= findnearestNurbvert(1, &nu, &bezt, &bp); + + if(bezt || bp) { + if((G.qual & LR_SHIFTKEY)==0) { + + setflagsNurb(0); + + if(bezt) { + + if(hand==1) { + bezt->f1|= 1; + bezt->f2|= 1; + bezt->f3|= 1; + } + else if(hand==0) bezt->f1|= 1; + else bezt->f3|= 1; + } + else { + lastselbp= bp; + bp->f1 |= 1; + } + + allqueue(REDRAWVIEW3D, 0); + } + else { + if(bezt) { + if(hand==1) { + if(bezt->f2 & 1) { + bezt->f1 &= ~1; + bezt->f2 &= ~1; + bezt->f3 &= ~1; + } + else { + bezt->f1 |= 1; + bezt->f2 |= 1; + bezt->f3 |= 1; + } + } + else if(hand==0) { + if(bezt->f1 & 1) { + bezt->f1 &= ~1; + } + else { + bezt->f1 |= 1; + } + } + else { + if(bezt->f3 & 1) { + bezt->f3 &= ~1; + } + else { + bezt->f3 |= 1; + } + } + } + else { + if(bp->f1 & 1) bp->f1 &= ~1; + else { + bp->f1 |= 1; + lastselbp= bp; + } + } + + allqueue(REDRAWVIEW3D, 0); + + } + + countall(); + } + + rightmouse_transform(); + + if(nu!=lastnu) { + lastnu= nu; + allqueue(REDRAWBUTSEDIT, 0); + } + +} + +void spinNurb(float *dvec, short mode) +/* float *dvec; */ +/* short mode; */ /* 0 is extrude, 1 is duplicate */ +{ + Nurb *nu; + float *curs, si,phi,n[3],q[4],cmat[3][3],tmat[3][3],imat[3][3]; + float cent[3],bmat[3][3], rotmat[3][3], scalemat1[3][3], scalemat2[3][3]; + float persmat[3][3], persinv[3][3]; + short a,ok; + + if(G.obedit==0 || G.obedit->type!=OB_SURF) return; + if( (G.vd->lay & G.obedit->lay)==0 ) return; + + Mat3CpyMat4(persmat, G.vd->viewmat); + Mat3Inv(persinv, persmat); + + /* imat en centrum en afmeting */ + Mat3CpyMat4(bmat, G.obedit->obmat); + Mat3Inv(imat, bmat); + + curs= give_cursor(); + VECCOPY(cent, curs); + VecSubf(cent, cent, G.obedit->obmat[3]); + Mat3MulVecfl(imat,cent); + + if(dvec) { + n[0]=n[1]= 0.0; + n[2]= 1.0; + } else { + n[0]= G.vd->viewinv[2][0]; + n[1]= G.vd->viewinv[2][1]; + n[2]= G.vd->viewinv[2][2]; + Normalise(n); + } + + phi= M_PI/8.0; + q[0]= cos(phi); + si= sin(phi); + q[1]= n[0]*si; + q[2]= n[1]*si; + q[3]= n[2]*si; + QuatToMat3(q, cmat); + Mat3MulMat3(tmat, cmat, bmat); + Mat3MulMat3(rotmat, imat, tmat); + + Mat3One(scalemat1); + scalemat1[0][0]= sqrt(2.0); + scalemat1[1][1]= sqrt(2.0); + + Mat3MulMat3(tmat,persmat,bmat); + Mat3MulMat3(cmat,scalemat1,tmat); + Mat3MulMat3(tmat,persinv,cmat); + Mat3MulMat3(scalemat1,imat,tmat); + + Mat3One(scalemat2); + scalemat2[0][0]/= sqrt(2.0); + scalemat2[1][1]/= sqrt(2.0); + + Mat3MulMat3(tmat,persmat,bmat); + Mat3MulMat3(cmat,scalemat2,tmat); + Mat3MulMat3(tmat,persinv,cmat); + Mat3MulMat3(scalemat2,imat,tmat); + + ok= 1; + + for(a=0;a<7;a++) { + if(mode==0) ok= extrudeflagNurb(1); + else adduplicateflagNurb(1); + if(ok==0) { + error("Can't spin"); + break; + } + rotateflagNurb(1,cent,rotmat); + + if(mode==0) { + if( (a & 1)==0 ) { + rotateflagNurb(1,cent,scalemat1); + weightflagNurb(1, 0.25*sqrt(2.0), 1); + } + else { + rotateflagNurb(1,cent,scalemat2); + weightflagNurb(1, 4.0/sqrt(2.0), 1); + } + } + if(dvec) { + Mat3MulVecfl(bmat,dvec); + translateflagNurb(1,dvec); + } + } + + if(ok) { + nu= editNurb.first; + while(nu) { + if(isNurbsel(nu)) { + nu->orderv= 4; + nu->flagv |= 1; + makeknots(nu, 2, nu->flagv>>1); + } + nu= nu->next; + } + } +} + +void addvert_Nurb(int mode) +{ + Nurb *nu; + BezTriple *bezt, *newbezt = NULL; + BPoint *bp, *newbp = NULL; + float *curs, mat[3][3],imat[3][3], temp[3]; + + if(G.obedit==0) return; + if( (G.vd->lay & G.obedit->lay)==0 ) return; + + if(mode=='e' && okee("Extrude")==0) return; + + Mat3CpyMat4(mat, G.obedit->obmat); + Mat3Inv(imat,mat); + + findselectedNurbvert(&nu, &bezt, &bp); + if(bezt==0 && bp==0) return; + + if((nu->type & 7)==CU_BEZIER) { + /* welk bezpoint? */ + if(bezt== nu->bezt) { /* eerste */ + bezt->f1= bezt->f2= bezt->f3= 0; + newbezt = + (BezTriple*)MEM_callocN((nu->pntsu+1) * sizeof(BezTriple), "addvert_Nurb"); + memcpy(newbezt+1, bezt, nu->pntsu*sizeof(BezTriple)); + *newbezt= *bezt; + newbezt->f1= newbezt->f2= newbezt->f3= 1; + if(bezt->h1 & 1) newbezt->h1= newbezt->h2= HD_AUTO; + else newbezt->h1= newbezt->h2= HD_VECT; + VECCOPY(temp, bezt->vec[1]); + MEM_freeN(nu->bezt); + nu->bezt= newbezt; + bezt= newbezt+1; + } + else if(bezt== (nu->bezt+nu->pntsu-1)) { /* laatste */ + bezt->f1= bezt->f2= bezt->f3= 0; + newbezt = + (BezTriple*)MEM_callocN((nu->pntsu+1) * sizeof(BezTriple), "addvert_Nurb"); + memcpy(newbezt, nu->bezt, nu->pntsu*sizeof(BezTriple)); + *(newbezt+nu->pntsu)= *bezt; + VECCOPY(temp, bezt->vec[1]); + MEM_freeN(nu->bezt); + nu->bezt= newbezt; + newbezt+= nu->pntsu; + newbezt->f1= newbezt->f2= newbezt->f3= 1; + if(newbezt->h2 & 1) newbezt->h1= newbezt->h2= HD_AUTO; + else newbezt->h1= newbezt->h2= HD_VECT; + bezt= nu->bezt+nu->pntsu-1; + } + else bezt= 0; + + if(bezt) { + nu->pntsu++; + newbezt->s[1][0]= G.vd->mx; + newbezt->s[1][1]= G.vd->my; + + if(mode=='e') { + VECCOPY(newbezt->vec[0], bezt->vec[0]); + VECCOPY(newbezt->vec[1], bezt->vec[1]); + VECCOPY(newbezt->vec[2], bezt->vec[2]); + } + else { + curs= give_cursor(); + + VECCOPY(newbezt->vec[1], curs); + VecSubf(newbezt->vec[1],newbezt->vec[1],G.obedit->obmat[3]); + Mat3MulVecfl(imat,newbezt->vec[1]); + VecSubf(temp, newbezt->vec[1],temp); + VecAddf(newbezt->vec[0], bezt->vec[0],temp); + VecAddf(newbezt->vec[2], bezt->vec[2],temp); + calchandlesNurb(nu); + } + } + } + else if(nu->pntsv==1) { + /* welk b-point? */ + if(bp== nu->bp) { /* eerste */ + bp->f1= 0; + newbp = + (BPoint*)MEM_callocN((nu->pntsu+1) * sizeof(BPoint), "addvert_Nurb3"); + memcpy(newbp+1, bp, nu->pntsu*sizeof(BPoint)); + *newbp= *bp; + newbp->f1= 1; + MEM_freeN(nu->bp); + nu->bp= newbp; + } + else if(bp== (nu->bp+nu->pntsu-1)) { /* laatste */ + bp->f1= 0; + newbp = + (BPoint*)MEM_callocN((nu->pntsu+1) * sizeof(BPoint), "addvert_Nurb4"); + memcpy(newbp, nu->bp, nu->pntsu*sizeof(BPoint)); + *(newbp+nu->pntsu)= *bp; + MEM_freeN(nu->bp); + nu->bp= newbp; + newbp+= nu->pntsu; + newbp->f1= 1; + } + else bp= 0; + + if(bp) { + nu->pntsu++; + newbp->s[0]= G.vd->mx; + newbp->s[1]= G.vd->my; + + if(nu->resolu<3) nu->resolu++; + makeknots(nu, 1, nu->flagu>>1); + + if(mode=='e') { + VECCOPY(newbp->vec, bp->vec); + } + else { + curs= give_cursor(); + + VECCOPY(newbp->vec, curs); + VecSubf(newbp->vec, newbp->vec, G.obedit->obmat[3]); + Mat3MulVecfl(imat,newbp->vec); + newbp->vec[3]= 1.0; + } + } + } + + test2DNurb(nu); + makeDispList(G.obedit); + countall(); + allqueue(REDRAWVIEW3D, 0); + + if(mode=='e') transform('d'); + else while(get_mbut()&R_MOUSE) BIF_wait_for_statechange(); +} + +void extrude_nurb() +{ + Nurb *nu; + int ok= 0; + + if(G.obedit && G.obedit->type==OB_SURF) { + + /* first test: curve? */ + nu= editNurb.first; + while(nu) { + if(nu->pntsv==1 && isNurbsel_count(nu)==1 ) break; + nu= nu->next; + } + if(nu) { + addvert_Nurb('e'); + } + else { + + if(okee("Extrude")==0) return; + ok= extrudeflagNurb(1); /* '1'= flag */ + + if(ok) { + makeDispList(G.obedit); + countall(); + transform('d'); + } + } + } +} + + + +void makecyclicNurb() +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + float *fp; + int a, b, cyclmode=0; + + nu= editNurb.first; + while(nu) { + if( nu->pntsu>1 || nu->pntsv>1) { + if( (nu->type & 7)==0 ) { + a= nu->pntsu; + bp= nu->bp; + while(a--) { + if( bp->f1 & 1 ) { + if(nu->flagu & 1) nu->flagu--; + else nu->flagu++; + break; + } + bp++; + } + } + else if( (nu->type & 7)==CU_BEZIER ) { + a= nu->pntsu; + bezt= nu->bezt; + while(a--) { + if( BEZSELECTED(bezt) ) { + if(nu->flagu & 1) nu->flagu--; + else nu->flagu++; + break; + } + bezt++; + } + calchandlesNurb(nu); + } + else if(nu->pntsv==1 && (nu->type & 7)==CU_NURBS) { + a= nu->pntsu; + bp= nu->bp; + while(a--) { + if( bp->f1 & 1 ) { + if(nu->flagu & 1) nu->flagu--; + else { + nu->flagu++; + fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN"); + b= (nu->orderu+nu->pntsu); + memcpy(fp, nu->knotsu, sizeof(float)*b); + MEM_freeN(nu->knotsu); + nu->knotsu= fp; + + makeknots(nu, 1, 0); /* 1==u 0==uniform */ + + } + break; + } + bp++; + } + } + else if(nu->type==CU_NURBS) { + if(cyclmode==0) { + cyclmode= pupmenu("Toggle %t|cyclic U%x1|cyclic V%x2"); + if(cyclmode < 1) return; + } + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a--) { + + if( bp->f1 & 1) { + if(cyclmode==1 && nu->pntsu>1) { + if(nu->flagu & 1) nu->flagu--; + else { + nu->flagu++; + fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN"); + b= (nu->orderu+nu->pntsu); + memcpy(fp, nu->knotsu, sizeof(float)*b); + MEM_freeN(nu->knotsu); + nu->knotsu= fp; + + makeknots(nu, 1, 0); /* 1==u 0==uniform */ + } + } + if(cyclmode==2 && nu->pntsv>1) { + if(nu->flagv & 1) nu->flagv--; + else { + nu->flagv++; + fp= MEM_mallocN(sizeof(float)*KNOTSV(nu), "makecyclicN"); + b= (nu->orderv+nu->pntsv); + memcpy(fp, nu->knotsv, sizeof(float)*b); + MEM_freeN(nu->knotsv); + nu->knotsv= fp; + + makeknots(nu, 2, 0); /* 2==v 0==uniform */ + } + } + break; + } + bp++; + } + + } + } + nu= nu->next; + } + makeDispList(G.obedit); +} + +void selectconnected_nurb() +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a; + + findnearestNurbvert(1, &nu, &bezt, &bp); + if(bezt) { + a= nu->pntsu; + bezt= nu->bezt; + while(a--) { + if(bezt->hide==0) { + if(G.qual & LR_SHIFTKEY) { + bezt->f1 &= ~1; + bezt->f2 &= ~1; + bezt->f3 &= ~1; + } + else { + bezt->f1 |= 1; + bezt->f2 |= 1; + bezt->f3 |= 1; + } + } + bezt++; + } + } + else if(bp) { + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a--) { + if(bp->hide==0) { + if(G.qual & LR_SHIFTKEY) { + bp->f1 &= ~1; + } + else { + bp->f1 |= 1; + } + } + bp++; + } + } + + countall(); + allqueue(REDRAWVIEW3D, 0); +} + +void selectrow_nurb() +{ + static BPoint *last=0; + static int direction=0; + Nurb *nu; + BPoint *bp; + int u = 0, v = 0, a, b, ok=0; + + if(editNurb.first==0) return; + if(G.obedit==0 || G.obedit->type!=OB_SURF) return; + if(lastselbp==0) return; + + /* zoek de juiste nurb en toggle met u of v */ + nu= editNurb.first; + while(nu) { + bp= nu->bp; + for(v=0; v<nu->pntsv; v++) { + for(u=0; u<nu->pntsu; u++, bp++) { + if(bp==lastselbp) { + if(bp->f1 & 1) { + ok= 1; + break; + } + } + } + if(ok) break; + } + if(ok) { + if(last==lastselbp) { + direction= 1-direction; + setflagsNurb(0); + } + last= lastselbp; + + bp= nu->bp; + for(a=0; a<nu->pntsv; a++) { + for(b=0; b<nu->pntsu; b++, bp++) { + if(direction) { + if(a==v) if(bp->hide==0) bp->f1 |= 1; + } + else { + if(b==u) if(bp->hide==0) bp->f1 |= 1; + } + } + } + countall(); + allqueue(REDRAWVIEW3D, 0); + return; + } + nu= nu->next; + } +} + +void adduplicate_nurb() +{ + + if( (G.vd->lay & G.obedit->lay)==0 ) return; + + adduplicateflagNurb(1); + + countall(); + transform('d'); +} + +void delNurb() +{ + Nurb *nu, *next, *nu1; + BezTriple *bezt, *bezt1, *bezt2; + BPoint *bp, *bp1, *bp2; + int a; + short event, cut = 0; + + if(G.obedit==0 ) return; + if( (G.vd->lay & G.obedit->lay)==0 ) return; + + if(G.obedit->type==OB_SURF) event= pupmenu("ERASE %t|Selected%x0|All%x2"); + else event= pupmenu("ERASE %t|Selected%x0|Segment%x1|All%x2"); + + if(event== -1) return; + + if(G.obedit->type==OB_SURF) { + if(event==0) deleteflagNurb(1); + else freeNurblist(&editNurb); + + countall(); + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + return; + } + + if(event==0) { + /* eerste doorloop, kunnen hele stukken weg? */ + nu= editNurb.first; + while(nu) { + next= nu->next; + if( (nu->type & 7)==CU_BEZIER ) { + bezt= nu->bezt; + a= nu->pntsu; + if(a) { + while(a) { + if( BEZSELECTED(bezt) ); + else break; + a--; + bezt++; + } + if(a==0) { + BLI_remlink(&editNurb, nu); + freeNurb(nu); + } + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + if(a) { + while(a) { + if(bp->f1 & 1 ); + else break; + a--; + bp++; + } + if(a==0) { + BLI_remlink(&editNurb, nu); + freeNurb(nu); + } + } + } + nu= next; + } + /* tweede doorloop, kleine stukken weg: alleen curves */ + nu= editNurb.first; + while(nu) { + next= nu->next; + event= 0; + if( (nu->type & 7)==CU_BEZIER ) { + bezt= nu->bezt; + for(a=0;a<nu->pntsu;a++) { + if( BEZSELECTED(bezt) ) { + memcpy(bezt, bezt+1, (nu->pntsu-a-1)*sizeof(BezTriple)); + nu->pntsu--; + a--; + event= 1; + } + else bezt++; + } + if(event) { + bezt1 = + (BezTriple*)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb"); + memcpy(bezt1, nu->bezt, (nu->pntsu)*sizeof(BezTriple) ); + MEM_freeN(nu->bezt); + nu->bezt= bezt1; + calchandlesNurb(nu); + } + } + else if(nu->pntsv==1) { + bp= nu->bp; + + for(a=0;a<nu->pntsu;a++) { + if( bp->f1 & 1 ) { + memcpy(bp, bp+1, (nu->pntsu-a-1)*sizeof(BPoint)); + nu->pntsu--; + a--; + event= 1; + } + else { + bp++; + } + } + if(event) { + bp1 = (BPoint*)MEM_mallocN(nu->pntsu * sizeof(BPoint), "delNurb2"); + memcpy(bp1, nu->bp, (nu->pntsu)*sizeof(BPoint) ); + MEM_freeN(nu->bp); + nu->bp= bp1; + } + makeknots(nu, 1, nu->flagu>>1); + } + nu= next; + } + } + else if(event==1) { /* erase segment */ + /* vind de twee geselecteerde punten */ + bezt1= bezt2= 0; + bp1= bp2= 0; + nu= editNurb.first; + nu1= 0; + while(nu) { + next= nu->next; + if( (nu->type & 7)==CU_BEZIER ) { + bezt= nu->bezt; + for(a=0; a<nu->pntsu-1; a++) { + if( BEZSELECTED(bezt) ) { + bezt1= bezt; + bezt2= bezt+1; + if( (bezt2->f1 & 1) || (bezt2->f2 & 1) || (bezt2->f3 & 1) ) ; + else { /* misschien niet cyclic maken */ + if(a==0 && (nu->flagu & 1) ) { + bezt2= bezt+(nu->pntsu-1); + if( (bezt2->f1 & 1) || (bezt2->f2 & 1) || (bezt2->f3 & 1) ) { + nu->flagu--; + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + } + } + return; + } + cut= a; + nu1= nu; + break; + } + bezt++; + } + } + else if(nu->pntsv==1) { + bp= nu->bp; + for(a=0; a<nu->pntsu-1; a++) { + if( bp->f1 & 1 ) { + bp1= bp; + bp2= bp+1; + if( bp2->f1 & 1 ) ; + else { /* misschien niet cyclic maken */ + if(a==0 && (nu->flagu & 1) ) { + bp2= bp+(nu->pntsu-1); + if( bp2->f1 & 1 ) { + nu->flagu--; + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + } + } + return; + } + cut= a; + nu1= nu; + break; + } + bp++; + } + } + if(nu1) break; + + nu= nu->next; + } + if(nu1) { + if(bezt1) { + if(nu1->pntsu==2) { /* helemaal weg */ + BLI_remlink(&editNurb, nu); + freeNurb(nu); + } + else if(nu1->flagu & 1) { /* cyclic */ + bezt = + (BezTriple*)MEM_mallocN((cut+1) * sizeof(BezTriple), "delNurb1"); + memcpy(bezt, nu1->bezt,(cut+1)*sizeof(BezTriple)); + a= nu1->pntsu-cut-1; + memcpy(nu1->bezt, bezt2, a*sizeof(BezTriple)); + memcpy(nu1->bezt+a, bezt, (cut+1)*sizeof(BezTriple)); + nu1->flagu--; + MEM_freeN(bezt); + calchandlesNurb(nu); + } + else { /* nieuwe curve erbij */ + +/* hier zit een fout in... maar waar? (a kan nul worden) */ + + nu = + (Nurb*)MEM_mallocN(sizeof(Nurb), "delNurb2"); + memcpy(nu, nu1, sizeof(Nurb)); + BLI_addtail(&editNurb, nu); + nu->bezt = + (BezTriple*)MEM_mallocN((cut+1) * sizeof(BezTriple), "delNurb3"); + memcpy(nu->bezt, nu1->bezt,(cut+1)*sizeof(BezTriple)); + a= nu1->pntsu-cut-1; + + bezt = + (BezTriple*)MEM_mallocN(a * sizeof(BezTriple), "delNurb4"); + memcpy(bezt, nu1->bezt+cut+1,a*sizeof(BezTriple)); + MEM_freeN(nu1->bezt); + nu1->bezt= bezt; + nu1->pntsu= a; + nu->pntsu= cut+1; + + + calchandlesNurb(nu); + calchandlesNurb(nu1); + } + } + else if(bp1) { + if(nu1->pntsu==2) { /* helemaal weg */ + BLI_remlink(&editNurb, nu); + freeNurb(nu); + } + else if(nu1->flagu & 1) { /* cyclic */ + bp = + (BPoint*)MEM_mallocN((cut+1) * sizeof(BPoint), "delNurb5"); + memcpy(bp, nu1->bp,(cut+1)*sizeof(BPoint)); + a= nu1->pntsu-cut-1; + memcpy(nu1->bp, bp2, a*sizeof(BPoint)); + memcpy(nu1->bp+a, bp, (cut+1)*sizeof(BPoint)); + nu1->flagu--; + MEM_freeN(bp); + } + else { /* nieuwe curve erbij */ + nu = (Nurb*)MEM_mallocN(sizeof(Nurb), "delNurb6"); + memcpy(nu, nu1, sizeof(Nurb)); + BLI_addtail(&editNurb, nu); + nu->bp = + (BPoint*)MEM_mallocN((cut+1) * sizeof(BPoint), "delNurb7"); + memcpy(nu->bp, nu1->bp,(cut+1)*sizeof(BPoint)); + a= nu1->pntsu-cut-1; + bp = + (BPoint*)MEM_mallocN(a * sizeof(BPoint), "delNurb8"); + memcpy(bp, nu1->bp+cut+1,a*sizeof(BPoint)); + MEM_freeN(nu1->bp); + nu1->bp= bp; + nu1->pntsu= a; + nu->pntsu= cut+1; + } + } + } + } + else if(event==2) { + freeNurblist(&editNurb); + } + + countall(); + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); +} + + +void join_curve(int type) +{ + Base *base, *nextb; + Object *ob; + Curve *cu; + Nurb *nu, *newnu; + BezTriple *bezt; + BPoint *bp; + ListBase tempbase; + float imat[4][4], cmat[4][4]; + int a; + + if(G.obedit) return; + + ob= OBACT; + if(ob->type!=type) return; + if(ob->lay & G.vd->lay); else return; + tempbase.first= tempbase.last= 0; + + if(type==OB_SURF) { + if(okee("Join selected Nurbs")==0) return; + } + else if(okee("Join selected Curves")==0) return; + + /* alle geselecteerde curves invers transformen in obact */ + Mat4Invert(imat, ob->obmat); + + base= FIRSTBASE; + while(base) { + nextb= base->next; + if TESTBASE(base) { + if(base->object->type==type) { + if(base->object != ob) { + + cu= base->object->data; + + if(cu->nurb.first) { + /* let op: matmul omkeren is ECHT fout */ + Mat4MulMat4(cmat, base->object->obmat, imat); + + nu= cu->nurb.first; + while(nu) { + newnu= duplicateNurb(nu); + BLI_addtail(&tempbase, newnu); + + if( (bezt= newnu->bezt) ) { + a= newnu->pntsu; + while(a--) { + Mat4MulVecfl(cmat, bezt->vec[0]); + Mat4MulVecfl(cmat, bezt->vec[1]); + Mat4MulVecfl(cmat, bezt->vec[2]); + bezt++; + } + } + if( (bp= newnu->bp) ) { + a= newnu->pntsu*nu->pntsv; + while(a--) { + Mat4MulVecfl(cmat, bp->vec); + bp++; + } + } + nu= nu->next; + } + } + + free_and_unlink_base(base); + } + } + } + base= nextb; + } + + cu= ob->data; + addlisttolist(&cu->nurb, &tempbase); + + enter_editmode(); + exit_editmode(1); + + allqueue(REDRAWVIEW3D, 0); +} + + + +Nurb *addNurbprim(int type, int stype, int newname) +/* type: &8= 2D; 0=poly,1 bez, 4 nurb + * stype: 0: 2/4 punts curve + * 1: 8 punts cirkel + * 2: 4x4 patch Nurb + * 3: tube 4:sphere 5:donut + * 6: 5 punts, 5e order rechte lijn (pad) alleen nurbspline! + */ +{ + static int xzproj= 0; + Nurb *nu = NULL; + BezTriple *bezt; + BPoint *bp; + float *curs, cent[3],vec[3],imat[3][3],mat[3][3]; + float fac,cmat[3][3]; + int a, b; + + /* imat en centrum en afmeting */ + if(G.obedit) { + + Mat3CpyMat4(mat, G.obedit->obmat); + curs= give_cursor(); + VECCOPY(cent, curs); + cent[0]-= G.obedit->obmat[3][0]; + cent[1]-= G.obedit->obmat[3][1]; + cent[2]-= G.obedit->obmat[3][2]; + + Mat3CpyMat4(imat, G.vd->viewmat); + Mat3MulVecfl(imat, cent); + Mat3MulMat3(cmat, imat, mat); + Mat3Inv(imat, cmat); + setflagsNurb(0); + } + else { + Mat3One(imat); + cent[0]= cent[1]= cent[2]= 0.0; + } + + if ELEM5(stype, 0, 1, 2, 4, 6) { + nu = (Nurb*)MEM_callocN(sizeof(Nurb), "addNurbprim"); + nu->type= type; + nu->resolu= 12; + nu->resolv= 12; + /* if(G.obedit && (G.mainb==5 || G.mainb==9)) nu->col= 0; */ + } + + switch(stype) { + case 0: /* curve */ + if(newname) { + rename_id((ID *)G.obedit, "Curve"); + rename_id((ID *)G.obedit->data, "Curve"); + } + if((type & 7)==CU_BEZIER) { + nu->pntsu= 2; + nu->bezt = + (BezTriple*)MEM_callocN(2 * sizeof(BezTriple), "addNurbprim1"); + bezt= nu->bezt; + bezt->h1= bezt->h2= HD_ALIGN; + bezt->f1= bezt->f2= bezt->f3= 1; + + for(a=0;a<3;a++) { + VECCOPY(bezt->vec[a], cent); + } + bezt->vec[1][0]+= -G.vd->grid; + bezt->vec[0][0]+= -1.5*G.vd->grid; + bezt->vec[0][1]+= -0.5*G.vd->grid; + bezt->vec[2][0]+= -0.5*G.vd->grid; + bezt->vec[2][1]+= 0.5*G.vd->grid; + for(a=0;a<3;a++) Mat3MulVecfl(imat, bezt->vec[a]); + + bezt++; + bezt->h1= bezt->h2= HD_ALIGN; + bezt->f1= bezt->f2= bezt->f3= 1; + + for(a=0;a<3;a++) { + VECCOPY(bezt->vec[a], cent); + } + bezt->vec[1][0]+= G.vd->grid; + for(a=0;a<3;a++) Mat3MulVecfl(imat, bezt->vec[a]); + + calchandlesNurb(nu); + } + else { + nu->pntsu= 4; + nu->pntsv= 1; + nu->orderu= 4; + nu->bp= callocstructN(BPoint, 4, "addNurbprim3"); + + bp= nu->bp; + for(a=0;a<4;a++, bp++) { + VECCOPY(bp->vec, cent); + bp->vec[3]= 1.0; + bp->f1= 1; + } + + bp= nu->bp; + bp->vec[0]+= -1.5*G.vd->grid; + bp++; + bp->vec[0]+= -G.vd->grid; + bp->vec[1]+= G.vd->grid; + bp++; + bp->vec[0]+= G.vd->grid; + bp->vec[1]+= G.vd->grid; + bp++; + bp->vec[0]+= 1.5*G.vd->grid; + + bp= nu->bp; + for(a=0;a<4;a++, bp++) Mat3MulVecfl(imat,bp->vec); + + if((type & 7)==4) { + nu->knotsu= 0; /* makeknots alloceert */ + makeknots(nu, 1, nu->flagu>>1); + } + + } + break; + case 6: /* 5 punts pad */ + nu->pntsu= 5; + nu->pntsv= 1; + nu->orderu= 5; + nu->flagu= 2; /* endpoint */ + nu->resolu= 32; + nu->bp= callocstructN(BPoint, 5, "addNurbprim3"); + + bp= nu->bp; + for(a=0;a<5;a++, bp++) { + VECCOPY(bp->vec, cent); + bp->vec[3]= 1.0; + bp->f1= 1; + } + + bp= nu->bp; + bp->vec[0]+= -2.0*G.vd->grid; + bp++; + bp->vec[0]+= -G.vd->grid; + bp++; bp++; + bp->vec[0]+= G.vd->grid; + bp++; + bp->vec[0]+= 2.0*G.vd->grid; + + bp= nu->bp; + for(a=0;a<5;a++, bp++) Mat3MulVecfl(imat,bp->vec); + + if((type & 7)==4) { + nu->knotsu= 0; /* makeknots alloceert */ + makeknots(nu, 1, nu->flagu>>1); + } + + break; + case 1: /* cirkel */ + if(newname) { + rename_id((ID *)G.obedit, "CurveCircle"); + rename_id((ID *)G.obedit->data, "CurveCircle"); + } + if((type & 7)==CU_BEZIER) { + nu->pntsu= 4; + nu->bezt= callocstructN(BezTriple, 4, "addNurbprim1"); + nu->flagu= 1; + bezt= nu->bezt; + + for(a=0;a<3;a++) { + VECCOPY(bezt->vec[a], cent); + } + bezt->h1= bezt->h2= HD_AUTO; + bezt->f1= bezt->f2= bezt->f3= 1; + bezt->vec[1][0]+= -G.vd->grid; + for(a=0;a<3;a++) Mat3MulVecfl(imat,bezt->vec[a]); + + bezt++; + for(a=0;a<3;a++) { + VECCOPY(bezt->vec[a], cent); + } + bezt->h1= bezt->h2= HD_AUTO; + bezt->f1= bezt->f2= bezt->f3= 1; + bezt->vec[1][1]+= G.vd->grid; + for(a=0;a<3;a++) Mat3MulVecfl(imat,bezt->vec[a]); + + bezt++; + for(a=0;a<3;a++) { + VECCOPY(bezt->vec[a], cent); + } + bezt->h1= bezt->h2= HD_AUTO; + bezt->f1= bezt->f2= bezt->f3= 1; + bezt->vec[1][0]+= G.vd->grid; + for(a=0;a<3;a++) Mat3MulVecfl(imat,bezt->vec[a]); + + bezt++; + for(a=0;a<3;a++) { + VECCOPY(bezt->vec[a], cent); + } + bezt->h1= bezt->h2= HD_AUTO; + bezt->f1= bezt->f2= bezt->f3= 1; + bezt->vec[1][1]+= -G.vd->grid; + for(a=0;a<3;a++) Mat3MulVecfl(imat,bezt->vec[a]); + + calchandlesNurb(nu); + } + else if( (type & 7)==CU_NURBS ) { /* nurb */ + nu->pntsu= 8; + nu->pntsv= 1; + nu->orderu= 4; + nu->bp= callocstructN(BPoint, 8, "addNurbprim6"); + nu->flagu= 1; + bp= nu->bp; + + for(a=0; a<8; a++) { + bp->f1= 1; + VECCOPY(bp->vec, cent); + + if(xzproj==0) { + bp->vec[0]+= nurbcircle[a][0]*G.vd->grid; + bp->vec[1]+= nurbcircle[a][1]*G.vd->grid; + } + else { + bp->vec[0]+= 0.25*nurbcircle[a][0]*G.vd->grid-.75*G.vd->grid; + bp->vec[2]+= 0.25*nurbcircle[a][1]*G.vd->grid; + } + if(a & 1) bp->vec[3]= 0.25*sqrt(2.0); + else bp->vec[3]= 1.0; + Mat3MulVecfl(imat,bp->vec); + bp++; + } + + makeknots(nu, 1, nu->flagu>>1); + } + break; + case 2: /* 4x4 patch */ + if( (type & 7)==CU_NURBS ) { /* nurb */ + if(newname) { + rename_id((ID *)G.obedit, "Surf"); + rename_id((ID *)G.obedit->data, "Surf"); + } + + nu->pntsu= 4; + nu->pntsv= 4; + nu->orderu= 4; + nu->orderv= 4; + nu->flag= ME_SMOOTH; + nu->bp= callocstructN(BPoint, 4*4, "addNurbprim6"); + nu->flagu= 0; + nu->flagv= 0; + bp= nu->bp; + + for(a=0; a<4; a++) { + for(b=0; b<4; b++) { + VECCOPY(bp->vec, cent); + bp->f1= 1; + fac= (float)a -1.5; + bp->vec[0]+= fac*G.vd->grid; + fac= (float)b -1.5; + bp->vec[1]+= fac*G.vd->grid; + if(a==1 || a==2) if(b==1 || b==2) { + bp->vec[2]+= G.vd->grid; + } + Mat3MulVecfl(imat,bp->vec); + bp->vec[3]= 1.0; + bp++; + } + } + + makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 2, nu->flagv>>1); + } + break; + case 3: /* tube */ + if( (type & 7)==CU_NURBS ) { + if(newname) { + rename_id((ID *)G.obedit, "SurfTube"); + rename_id((ID *)G.obedit->data, "SurfTube"); + } + + nu= addNurbprim(4, 1, 0); /* cirkel */ + nu->resolu= 32; + nu->flag= ME_SMOOTH; + BLI_addtail(&editNurb, nu); /* tijdelijk voor extrude en translate */ + vec[0]=vec[1]= 0.0; + vec[2]= -G.vd->grid; + Mat3MulVecfl(imat, vec); + translateflagNurb(1, vec); + extrudeflagNurb(1); + vec[0]= -2*vec[0]; + vec[1]= -2*vec[1]; + vec[2]= -2*vec[2]; + translateflagNurb(1, vec); + + BLI_remlink(&editNurb, nu); + + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a-- >0) { + bp->f1 |= 1; + bp++; + } + } + break; + case 4: /* sphere */ + if( (type & 7)==CU_NURBS ) { + if(newname) { + rename_id((ID *)G.obedit, "SurfSphere"); + rename_id((ID *)G.obedit->data, "SurfSphere"); + } + + nu->pntsu= 5; + nu->pntsv= 1; + nu->orderu= 3; + nu->resolu= 24; + nu->resolv= 32; + nu->flag= ME_SMOOTH; + nu->bp= callocstructN(BPoint, 5, "addNurbprim6"); + nu->flagu= 0; + bp= nu->bp; + + for(a=0; a<5; a++) { + bp->f1= 1; + VECCOPY(bp->vec, cent); + bp->vec[0]+= nurbcircle[a][0]*G.vd->grid; + bp->vec[2]+= nurbcircle[a][1]*G.vd->grid; + if(a & 1) bp->vec[3]= 0.5*sqrt(2.0); + else bp->vec[3]= 1.0; + Mat3MulVecfl(imat,bp->vec); + bp++; + } + nu->flagu= 4; + makeknots(nu, 1, nu->flagu>>1); + + BLI_addtail(&editNurb, nu); /* tijdelijk voor spin */ + spinNurb(0, 0); + + makeknots(nu, 2, nu->flagv>>1); + + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a-- >0) { + bp->f1 |= 1; + bp++; + } + BLI_remlink(&editNurb, nu); + } + break; + case 5: /* donut */ + if( (type & 7)==CU_NURBS ) { + if(newname) { + rename_id((ID *)G.obedit, "SurfDonut"); + rename_id((ID *)G.obedit->data, "SurfDonut"); + } + + xzproj= 1; + nu= addNurbprim(4, 1, 0); /* cirkel */ + xzproj= 0; + nu->resolu= 24; + nu->resolv= 32; + nu->flag= ME_SMOOTH; + BLI_addtail(&editNurb, nu); /* tijdelijk voor extrude en translate */ + spinNurb(0, 0); + + BLI_remlink(&editNurb, nu); + + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a-- >0) { + bp->f1 |= 1; + bp++; + } + + } + break; + } + + /* altijd doen: */ + nu->flag= ME_SMOOTH; + + test2DNurb(nu); + + return nu; +} + +void default_curve_ipo(Curve *cu) +{ + IpoCurve *icu; + BezTriple *bezt; + + if(cu->ipo) return; + + cu->ipo= add_ipo("CurveIpo", ID_CU); + + icu= MEM_callocN(sizeof(IpoCurve), "ipocurve"); + + icu->blocktype= ID_CU; + icu->adrcode= CU_SPEED; + icu->flag= IPO_VISIBLE+IPO_SELECT; + set_icu_vars(icu); + + BLI_addtail( &(cu->ipo->curve), icu); + + icu->bezt= bezt= MEM_callocN(2*sizeof(BezTriple), "defaultipo"); + icu->totvert= 2; + + bezt->hide= IPO_BEZ; + bezt->f1=bezt->f2= bezt->f3= SELECT; + bezt->h1= bezt->h2= HD_AUTO; + bezt++; + bezt->vec[1][0]= 100.0; + bezt->vec[1][1]= 1.0; + bezt->hide= IPO_BEZ; + bezt->f1=bezt->f2= bezt->f3= SELECT; + bezt->h1= bezt->h2= HD_AUTO; + + calchandles_ipocurve(icu); +} + +void add_primitiveCurve(int stype) +{ + Nurb *nu; + Curve *cu; + int type, newname= 0; + + if(G.scene->id.lib) return; + + /* this function also comes from an info window */ + if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return; + if(G.vd==0) return; + + if(stype>=10 && stype<20) type= CU_2D+1; + else if(stype>=20 && stype<30) type= CU_2D+2; + else if(stype>=30 && stype<40) type= CU_2D+3; + else if(stype>=40 && stype<50) { + if(stype==46) type= 4; + else type= CU_2D+4; + } + else type= CU_2D; + + check_editmode(OB_CURVE); + + /* als geen obedit: nieuw object en in editmode gaan */ + if(G.obedit==0) { + add_object(OB_CURVE); + base_init_from_view3d(BASACT, G.vd); + G.obedit= BASACT->object; + + where_is_object(G.obedit); + + make_editNurb(); + setcursor_space(SPACE_VIEW3D, CURSOR_EDIT); + newname= 1; + + cu= G.obedit->data; + if(stype==46) { + cu->flag |= (CU_3D+CU_PATH); + + default_curve_ipo(cu); + } + } + else cu= G.obedit->data; + + if(cu->flag & CU_3D) type &= ~CU_2D; + + stype= (stype % 10); + + nu= addNurbprim(type, stype, newname); /* 2D */ + + BLI_addtail(&editNurb, nu); + makeDispList(G.obedit); + + allqueue(REDRAWBUTSEDIT, 0); + + countall(); + allqueue(REDRAWVIEW3D, 0); +} + +void add_primitiveNurb(int type) +{ + Nurb *nu; + int newname= 0; + + if(G.scene->id.lib) return; + if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return; + + check_editmode(OB_SURF); + + /* als geen obedit: nieuw object en in editmode gaan */ + if(G.obedit==0) { + add_object(OB_SURF); + base_init_from_view3d(BASACT, G.vd); + G.obedit= BASACT->object; + + where_is_object(G.obedit); + + make_editNurb(); + setcursor_space(SPACE_VIEW3D, CURSOR_EDIT); + newname= 1; + } + + nu= addNurbprim(4, type, newname); + BLI_addtail(&editNurb,nu); + makeDispList(G.obedit); + + allqueue(REDRAWBUTSEDIT, 0); + + countall(); + allqueue(REDRAWVIEW3D, 0); +} + + + +void clear_tilt() +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a; + + if(okee("Clear tilt")==0) return; + + nu= editNurb.first; + while(nu) { + if( nu->bezt ) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(BEZSELECTED(bezt)) bezt->alfa= 0.0; + bezt++; + } + } + else if(nu->bp) { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->f1 & 1) bp->alfa= 0.0; + bp++; + } + } + nu= nu->next; + } + + makeBevelList(G.obedit); + allqueue(REDRAWVIEW3D, 0); +} + +void clever_numbuts_curve() +{ + BPoint *bp; + BezTriple *bezt; + float old[3], delta[3]; + int a; + + if(lastnu==0) return; + if(lastnu->bp) { + bp= lastnu->bp; + a= lastnu->pntsu*lastnu->pntsv; + while(a--) { + if(bp->f1 & 1) break; + bp++; + } + if(bp==0) return; + + add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, bp->vec, 0); + add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, bp->vec+1, 0); + add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, bp->vec+2, 0); + add_numbut(3, NUM|FLO, " W:", 0.0, 100.0, bp->vec+3, 0); + + do_clever_numbuts("Active BPoint", 4, REDRAW); + makeDispList(G.obedit); + } + else if(lastnu->bezt) { + bezt= lastnu->bezt; + a= lastnu->pntsu; + while(a--) { + if(BEZSELECTED(bezt)) break; + bezt++; + } + if(bezt==0) return; + + if(bezt->f2 & 1) { + add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, bezt->vec[1], 0); + add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, bezt->vec[1]+1, 0); + add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, bezt->vec[1]+2, 0); + VECCOPY(old, bezt->vec[1]); + do_clever_numbuts("Active BezierPoint", 3, REDRAW); + + VecSubf(delta, bezt->vec[1], old); + VecAddf(bezt->vec[0], bezt->vec[0], delta); + VecAddf(bezt->vec[2], bezt->vec[2], delta); + makeDispList(G.obedit); + } + else if(bezt->f1 & 1) { + add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, bezt->vec[0], 0); + add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, bezt->vec[0]+1, 0); + add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, bezt->vec[0]+2, 0); + + do_clever_numbuts("Active HandlePoint", 3, REDRAW); + } + else if(bezt->f3 & 1) { + add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, bezt->vec[0], 0); + add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, bezt->vec[2]+1, 0); + add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, bezt->vec[2]+2, 0); + + do_clever_numbuts("Active HandlePoint", 3, REDRAW); + } + } + +} + +int bezt_compare (const void *e1, const void *e2) +{ + BezTriple *b1 = *((BezTriple**)e1); + BezTriple *b2 = *((BezTriple**)e2); + + /* Check numerical values */ + float val = b1->vec[1][0] - b2->vec[1][0]; + + if (val<0) + return -1; + + if (val>0) + return 1; + + /* Check selected flags : Ensures that selected keys will be listed first */ + + if ((b1->f2 & 1) && !(b2->f2 & 1)) + return -1; + if (!(b1->f2 & 1) && (b2->f2 & 1)) + return 1; + + return 0; +} diff --git a/source/blender/src/editdeform.c b/source/blender/src/editdeform.c new file mode 100644 index 00000000000..7bce1aaa695 --- /dev/null +++ b/source/blender/src/editdeform.c @@ -0,0 +1,345 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * Creator-specific support for vertex deformation groups + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_editVert.h" + +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" + +#include "BKE_global.h" +#include "BKE_deform.h" +#include "BKE_mesh.h" + +#include "BIF_editdeform.h" +#include "BIF_toolbox.h" + +void sel_verts_defgroup (int select) +{ + EditVert *eve; + Object *ob; + int i; + + ob=G.obedit; + + if (!ob) + return; + + switch (ob->type){ + case OB_MESH: + for (eve=G.edve.first; eve; eve=eve->next){ + if (eve->totweight){ + for (i=0; i<eve->totweight; i++){ + if (eve->dw[i].def_nr == (ob->actdef-1)){ + if (select) eve->f |= 1; + else eve->f &= ~1; + break; + } + } + } + } + break; + default: + break; + } + +} + +MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup) +/* Ensures that mv has a deform weight entry for +the specified defweight group */ +{ + int i; + MDeformWeight *newdw; + + if (!dv) + return NULL; + + for (i=0; i<dv->totweight; i++){ + if (dv->dw[i].def_nr == defgroup) + return dv->dw+i; + } + + newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight"); + if (dv->dw){ + memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); + MEM_freeN (dv->dw); + } + dv->dw=newdw; + + dv->dw[dv->totweight].weight=0; + dv->dw[dv->totweight].def_nr=defgroup; + /* Group index */ + + dv->totweight++; + + return dv->dw+(dv->totweight-1); +} + +void add_defgroup (Object *ob) +{ + bDeformGroup *defgroup; + + if (!ob) + return; + + defgroup = MEM_callocN (sizeof(bDeformGroup), "deformGroup"); + strcpy (defgroup->name, "Group"); + + BLI_addtail(&ob->defbase, defgroup); + unique_vertexgroup_name(defgroup, ob); + + ob->actdef = BLI_countlist(&ob->defbase); +} + +void del_defgroup (Object *ob) +{ + bDeformGroup *defgroup; + EditVert *eve; + int i; + + + if (!ob) + return; + + if (!ob->actdef) + return; + + defgroup = BLI_findlink(&ob->defbase, ob->actdef-1); + if (!defgroup) + return; + + /* Make sure that no verts are using this group */ + remove_verts_defgroup(1); + + /* Make sure that any verts with higher indices are adjusted accordingly */ + for (eve=G.edve.first; eve; eve=eve->next){ + for (i=0; i<eve->totweight; i++){ + if (eve->dw[i].def_nr > (ob->actdef-1)) + eve->dw[i].def_nr--; + } + } + + /* Update the active material index if necessary */ + if (ob->actdef==BLI_countlist(&ob->defbase)) + ob->actdef--; + + /* Remove the group */ + BLI_freelinkN (&ob->defbase, defgroup); +} + +void assign_verts_defgroup (void) +/* Only available in editmode */ +{ + Object *ob; + EditVert *eve; + bDeformGroup *dg, *eg; + extern float editbutvweight; /* buttons.c */ + int i, done; + MDeformWeight *newdw; + + ob=G.obedit; + + if (!ob) + return; + + dg=BLI_findlink(&ob->defbase, ob->actdef-1); + if (!dg){ + error ("No vertex group active"); + return; + } + + switch (ob->type){ + case OB_MESH: + /* Go through the list of editverts and assign them */ + for (eve=G.edve.first; eve; eve=eve->next){ + if (eve->f & 1){ + done=0; + /* See if this vert already has a reference to this group */ + /* If so: Change its weight */ + done=0; + for (i=0; i<eve->totweight; i++){ + eg = BLI_findlink (&ob->defbase, eve->dw[i].def_nr); + /* Find the actual group */ + if (eg==dg){ + eve->dw[i].weight=editbutvweight; + done=1; + break; + } + } + /* If not: Add the group and set its weight */ + if (!done){ + newdw = MEM_callocN (sizeof(MDeformWeight)*(eve->totweight+1), "deformWeight"); + if (eve->dw){ + memcpy (newdw, eve->dw, sizeof(MDeformWeight)*eve->totweight); + MEM_freeN (eve->dw); + } + eve->dw=newdw; + + eve->dw[eve->totweight].weight=editbutvweight; + eve->dw[eve->totweight].def_nr=ob->actdef-1; + + eve->totweight++; + + } + } + } + break; + default: + printf ("Assigning deformation groups to unknown object type: Warn <reevan@blender.nl>\n"); + break; + } + +} + +void remove_verts_defgroup (int allverts) +/* Only available in editmode */ +{ + Object *ob; + EditVert *eve; + MDeformWeight *newdw; + bDeformGroup *dg, *eg; + int i; + + ob=G.obedit; + + if (!ob) + return; + + dg=BLI_findlink(&ob->defbase, ob->actdef-1); + if (!dg){ + error ("No vertex group active"); + return; + } + + switch (ob->type){ + case OB_MESH: + for (eve=G.edve.first; eve; eve=eve->next){ + if (eve->dw && ((eve->f & 1) || allverts)){ + for (i=0; i<eve->totweight; i++){ + /* Find group */ + eg = BLI_findlink (&ob->defbase, eve->dw[i].def_nr); + if (eg == dg){ + eve->totweight--; + if (eve->totweight){ + newdw = MEM_mallocN (sizeof(MDeformWeight)*(eve->totweight), "deformWeight"); + + if (eve->dw){ + memcpy (newdw, eve->dw, sizeof(MDeformWeight)*i); + memcpy (newdw+i, eve->dw+i+1, sizeof(MDeformWeight)*(eve->totweight-i)); + MEM_freeN (eve->dw); + } + eve->dw=newdw; + } + else{ + MEM_freeN (eve->dw); + eve->dw=NULL; + } + } + } + } + } + break; + default: + printf ("Removing deformation groups from unknown object type: Warn <reevan@blender.nl>\n"); + break; + } +} + +void verify_defgroups (Object *ob) +{ + /* Ensure the defbase & the dverts match */ + switch (ob->type){ + case OB_MESH: + if (!ob->defbase.first){ + if (((Mesh*)ob->data)->dvert){ + free_dverts(((Mesh*)ob->data)->dvert, ((Mesh*)ob->data)->totvert); + ((Mesh*)ob->data)->dvert=NULL; + } + } + break; + default: + break; + } +} + +void unique_vertexgroup_name (bDeformGroup *dg, Object *ob) +{ + char tempname[64]; + int number; + char *dot; + int exists = 0; + bDeformGroup *curdef; + + if (!ob) + return; + /* See if we even need to do this */ + for (curdef = ob->defbase.first; curdef; curdef=curdef->next){ + if (dg!=curdef){ + if (!strcmp(curdef->name, dg->name)){ + exists = 1; + break; + } + } + } + + if (!exists) + return; + + /* Strip off the suffix */ + dot=strchr(dg->name, '.'); + if (dot) + *dot=0; + + for (number = 1; number <=999; number++){ + sprintf (tempname, "%s.%03d", dg->name, number); + + exists = 0; + for (curdef=ob->defbase.first; curdef; curdef=curdef->next){ + if (dg!=curdef){ + if (!strcmp (curdef->name, tempname)){ + exists = 1; + break; + } + } + } + if (!exists){ + strcpy (dg->name, tempname); + return; + } + } +} diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c new file mode 100644 index 00000000000..8ae3b2a7035 --- /dev/null +++ b/source/blender/src/editface.c @@ -0,0 +1,1338 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + + +#include <math.h> +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "MTC_matrixops.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "DNA_image_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_space_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_mesh.h" +#include "BKE_texture.h" + +#include "BSE_view.h" +#include "BSE_edit.h" +#include "BSE_drawview.h" /* for backdrawview3d */ + +#include "BIF_interface.h" +#include "BIF_mywindow.h" +#include "BIF_toolbox.h" +#include "BIF_screen.h" +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_space.h" /* for allqueue */ + +#include "BDR_drawmesh.h" +#include "BDR_editface.h" +#include "BDR_vpaint.h" + +#include "BDR_editface.h" +#include "BDR_vpaint.h" + +#include "mydevice.h" +#include "blendef.h" +#include "render.h" + +/* #include "graphics.h" */ +// #include "blendef.h" +#include "interface.h" +#include "TPT_DependKludge.h" + +#ifdef NAN_TPT +#include "../img/IMG_Api.h" +#include "BSE_trans_types.h" +#endif /* NAN_TPT */ + +TFace *lasttface=0; + +void set_lasttface() +{ + Mesh *me; + TFace *tface; + int a; + + lasttface= 0; + + me= get_mesh(OBACT); + if(me==0 || me->tface==0) return; + + tface= me->tface; + a= me->totface; + while(a--) { + if(tface->flag & TF_ACTIVE) { + lasttface= tface; + return; + } + tface++; + } + + tface= me->tface; + a= me->totface; + while(a--) { + if(tface->flag & TF_SELECT) { + lasttface= tface; + return; + } + tface++; + } + + tface= me->tface; + a= me->totface; + while(a--) { + if((tface->flag & TF_HIDE)==0) { + lasttface= tface; + return; + } + tface++; + } +} + +void default_uv(float uv[][2], float size) +{ + int dy; + + if(size>1.0) size= 1.0; + + dy= 1.0-size; + + uv[0][0]= 0; + uv[0][1]= size+dy; + + uv[1][0]= 0; + uv[1][1]= dy; + + uv[2][0]= size; + uv[2][1]= dy; + + uv[3][0]= size; + uv[3][1]= size+dy; + + +} + +void default_tface(TFace *tface) +{ + default_uv(tface->uv, 1.0); + + tface->col[0]= tface->col[1]= tface->col[2]= tface->col[3]= vpaint_get_current_col(); + + tface->mode= TF_TEX; + tface->mode= 0; + tface->flag= TF_SELECT; + tface->tpage= 0; + tface->mode |= TF_DYNAMIC; +} + +void make_tfaces(Mesh *me) +{ + TFace *tface; + int a; + + a= me->totface; + if(a==0) return; + tface= me->tface= MEM_callocN(a*sizeof(TFace), "tface"); + while(a--) { + default_tface(tface); + tface++; + } + if(me->mcol) { + mcol_to_tface(me, 1); + } +} + +void reveal_tface() +{ + Mesh *me; + TFace *tface; + int a; + + me= get_mesh(OBACT); + if(me==0 || me->tface==0 || me->totface==0) return; + + tface= me->tface; + a= me->totface; + while(a--) { + if(tface->flag & TF_HIDE) { + tface->flag |= TF_SELECT; + tface->flag -= TF_HIDE; + } + tface++; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); +} + + + +void hide_tface() +{ + Mesh *me; + TFace *tface; + int a; + + me= get_mesh(OBACT); + if(me==0 || me->tface==0 || me->totface==0) return; + + if(G.qual & LR_ALTKEY) { + reveal_tface(); + return; + } + + tface= me->tface; + a= me->totface; + while(a--) { + if(tface->flag & TF_HIDE); + else { + if(G.qual & LR_SHIFTKEY) { + if( (tface->flag & TF_SELECT)==0) tface->flag |= TF_HIDE; + } + else { + if( (tface->flag & TF_SELECT)) tface->flag |= TF_HIDE; + } + } + if(tface->flag & TF_HIDE) tface->flag &= ~TF_SELECT; + + tface++; + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + +} + +void select_linked_tfaces() +{ + Mesh *me; + TFace *tface; + MFace *mface; + int a, doit=1; + char *cpmain; + + me= get_mesh(OBACT); + if(me==0 || me->tface==0 || me->totface==0) return; + + cpmain= MEM_callocN(me->totvert, "cpmain"); + + while(doit) { + doit= 0; + + /* select connected: array vullen */ + tface= me->tface; + mface= me->mface; + a= me->totface; + while(a--) { + if(tface->flag & TF_HIDE); + else if(tface->flag & TF_SELECT) { + if( mface->v3) { + cpmain[mface->v1]= 1; + cpmain[mface->v2]= 1; + cpmain[mface->v3]= 1; + if(mface->v4) cpmain[mface->v4]= 1; + } + } + tface++; mface++; + } + + /* omgekeerd: vanuit array vlakken selecteren */ + + tface= me->tface; + mface= me->mface; + a= me->totface; + while(a--) { + if(tface->flag & TF_HIDE); + else if((tface->flag & TF_SELECT)==0) { + if( mface->v3) { + if(mface->v4) { + if(cpmain[mface->v4]) { + tface->flag |= TF_SELECT; + doit= 1; + } + } + if( cpmain[mface->v1] || cpmain[mface->v2] || cpmain[mface->v3] ) { + tface->flag |= TF_SELECT; + doit= 1; + } + } + } + tface++; mface++; + } + + } + MEM_freeN(cpmain); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + +} + +void deselectall_tface() +{ + Mesh *me; + TFace *tface; + int a, sel; + + me= get_mesh(OBACT); + if(me==0 || me->tface==0) return; + + tface= me->tface; + a= me->totface; + sel= 0; + while(a--) { + if(tface->flag & TF_HIDE); + else if(tface->flag & TF_SELECT) sel= 1; + tface++; + } + + tface= me->tface; + a= me->totface; + while(a--) { + if(tface->flag & TF_HIDE); + else { + if(sel) tface->flag &= ~TF_SELECT; + else tface->flag |= TF_SELECT; + } + tface++; + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + +} + +void rotate_uv_tface() +{ + Mesh *me; + TFace *tface; + MFace *mface; + short mode; + int a; + + me= get_mesh(OBACT); + if(me==0 || me->tface==0) return; + + mode= pupmenu("OK? %t|Rot UV %x1|Rot VertexCol %x2"); + + if(mode<1) return; + + tface= me->tface; + mface= me->mface; + a= me->totface; + while(a--) { + if(tface->flag & TF_SELECT) { + if(mode==1) { + float u1= tface->uv[0][0]; + float v1= tface->uv[0][1]; + + tface->uv[0][0]= tface->uv[1][0]; + tface->uv[0][1]= tface->uv[1][1]; + + tface->uv[1][0]= tface->uv[2][0]; + tface->uv[1][1]= tface->uv[2][1]; + + if(mface->v4) { + tface->uv[2][0]= tface->uv[3][0]; + tface->uv[2][1]= tface->uv[3][1]; + + tface->uv[3][0]= u1; + tface->uv[3][1]= v1; + } + else { + tface->uv[2][0]= u1; + tface->uv[2][1]= v1; + } + } + else if(mode==2) { + unsigned int tcol= tface->col[0]; + + tface->col[0]= tface->col[1]; + tface->col[1]= tface->col[2]; + + if(mface->v4) { + tface->col[2]= tface->col[3]; + tface->col[3]= tcol; + } + else { + tface->col[2]= tcol; + } + } + } + tface++; + mface++; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); +} + +/** + * Returns the face under the give position in screen coordinates. + * Code extracted from face_select routine. + * Question: why is all of the backbuffer drawn? + * We're only interested in one pixel! + * @author Maarten Gribnau + * @param me the mesh with the faces to be picked + * @param x the x-coordinate to pick at + * @param y the y-coordinate to pick at + * @return the face under the cursor (0 if there was no face found) + */ +TFace* face_pick(Mesh *me, short x, short y) +{ + unsigned int col; + int index; + TFace *ret = 0; + + if (me==0 || me->tface==0) { + return ret; + } + + /* Have OpenGL draw in the back buffer with color coded face indices */ + if (curarea->win_swap==WIN_EQUAL) { + G.vd->flag |= V3D_NEEDBACKBUFDRAW; + } + if (G.vd->flag & V3D_NEEDBACKBUFDRAW) { + backdrawview3d(0); + } + /* Read the pixel under the cursor */ + glReadPixels(x+curarea->winrct.xmin, y+curarea->winrct.ymin, 1, 1, + GL_RGBA, GL_UNSIGNED_BYTE, &col); + /* Unbelievable! */ + if (G.order==B_ENDIAN) { + SWITCH_INT(col); + } + /* Convert the color back to a face index */ + index = framebuffer_to_index(col); + if (col==0 || index<=0 || index>me->totface) { + return ret; + } + /* Return the face */ + ret = ((TFace*)me->tface) + (index-1); + return ret; +} + +void face_select() +{ + Object *ob; + Mesh *me; + TFace *tface, *tsel; + short mval[2]; + int a; + + /* Get the face under the cursor */ + ob = OBACT; + if (!(ob->lay & G.vd->lay)) { + error("Active object not in this layer!"); + } + me = get_mesh(ob); + getmouseco_areawin(mval); + tsel = face_pick(me, mval[0], mval[1]); + if (!tsel) return; + + if (tsel->flag & TF_HIDE) return; + + /* clear flags */ + tface = me->tface; + a = me->totface; + while (a--) { + if (G.qual & LR_SHIFTKEY) { + tface->flag &= ~TF_ACTIVE; + } + else { + tface->flag &= ~(TF_ACTIVE+TF_SELECT); + } + tface++; + } + + tsel->flag |= TF_ACTIVE; + + if (G.qual & LR_SHIFTKEY) { + if (tsel->flag & TF_SELECT) { + tsel->flag &= ~TF_SELECT; + } + else { + tsel->flag |= TF_SELECT; + } + } + else { + tsel->flag |= TF_SELECT; + } + + lasttface = tsel; + + /* image window redraw */ + allqueue(REDRAWIMAGE, 0); + allqueue(REDRAWBUTSGAME, 0); + allqueue(REDRAWVIEW3D, 0); +} + + +void face_borderselect() +{ + Mesh *me; + TFace *tface; + rcti rect; + unsigned int *rectm, *rt; + int a, sx, sy, index, val; + char *selar; + + me= get_mesh(OBACT); + if(me==0 || me->tface==0) return; + if(me->totface==0) return; + + val= get_border(&rect, 3); + + /* why readbuffer here? shouldn't be necessary */ + glReadBuffer(GL_BACK); + + if(val) { + selar= MEM_callocN(me->totface+1, "selar"); + + sx= (rect.xmax-rect.xmin+1); + sy= (rect.ymax-rect.ymin+1); + if(sx*sy<=0) return; + + rt=rectm= MEM_mallocN(sizeof(int)*sx*sy, "selrect"); + glReadPixels(rect.xmin+curarea->winrct.xmin, rect.ymin+curarea->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, rectm); + if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(sx*sy, rectm); + + a= sx*sy; + while(a--) { + if(*rt) { + index= framebuffer_to_index(*rt); + if(index<=me->totface) selar[index]= 1; + } + rt++; + } + + tface= me->tface; + for(a=1; a<=me->totface; a++, tface++) { + if(selar[a]) { + if(tface->flag & TF_HIDE); + else { + if(val==LEFTMOUSE) tface->flag |= TF_SELECT; + else tface->flag &= ~TF_SELECT; + } + } + } + + MEM_freeN(rectm); + MEM_freeN(selar); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + } +} + +#define TEST_STRUBI 1 +#ifdef TEST_STRUBI +float CalcNormUV(float *a, float *b, float *c) +{ + float d1[3], d2[3]; + + d1[0] = a[0] - b[0]; + d1[1] = a[1] - b[1]; + d2[0] = b[0] - c[0]; + d2[1] = b[1] - c[1]; + return (d1[0] * d2[1] - d1[1] * d2[0]); +} +#endif + + +/* Pupmenu codes: */ +#define UV_CUBE_MAPPING 2 +#define UV_CYL_MAPPING 3 +#define UV_SPHERE_MAPPING 4 +#define UV_BOUNDS4_MAPPING 65 +#define UV_BOUNDS2_MAPPING 66 +#define UV_BOUNDS1_MAPPING 67 +#define UV_STD4_MAPPING 130 +#define UV_STD2_MAPPING 129 +#define UV_STD1_MAPPING 128 +#define UV_WINDOW_MAPPING 5 + +/* Some macro tricks to make pupmenu construction look nicer :-) + Sorry, just did it for fun. */ + +#define _STR(x) " " #x +#define STRING(x) _STR(x) + +#define MENUSTRING(string, code) string " %x" STRING(code) +#define MENUTITLE(string) string " %t|" + +void uv_autocalc_tface() +{ + Mesh *me; + TFace *tface; + MFace *mface; + MVert *mv; + Object *ob; + extern float cumapsize; /* buttons.c */ + float dx, dy, min[3], cent[3], max[3], no[3], *loc, mat[4][4]; + float fac = 1.0; + + int i, n, mi; /* strubi */ + int a, b; + short cox, coy, mode, adr[2]; + + me= get_mesh(ob=OBACT); + if(me==0 || me->tface==0) return; + if(me->totface==0) return; + + mode= pupmenu(MENUTITLE("UV Calculation") + MENUSTRING("Cube", UV_CUBE_MAPPING) "|" + MENUSTRING("Cylinder", UV_CYL_MAPPING) "|" + MENUSTRING("Bounds to 1/4", UV_BOUNDS4_MAPPING) "|" + MENUSTRING("Bounds to 1/2", UV_BOUNDS2_MAPPING) "|" + MENUSTRING("Bounds to 1/1", UV_BOUNDS1_MAPPING) "|" + MENUSTRING("Standard 1/4", UV_STD4_MAPPING) "|" + MENUSTRING("Standard 1/2", UV_STD2_MAPPING) "|" + MENUSTRING("Standard 1/1", UV_STD1_MAPPING) "|" + MENUSTRING("From Window", UV_WINDOW_MAPPING) ); + + switch(mode) { + case UV_CUBE_MAPPING: + tface= me->tface; + mface= me->mface; + mv= me->mvert; + loc= ob->obmat[3]; + + fbutton(&cumapsize, 0.0001, 100.0, "Cubemap size"); + + for(a=0; a<me->totface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT) { + if(mface->v3==0) continue; + + CalcNormFloat((mv+mface->v1)->co, (mv+mface->v2)->co, (mv+mface->v3)->co, no); + + no[0]= fabs(no[0]); + no[1]= fabs(no[1]); + no[2]= fabs(no[2]); + + cox=0; coy= 1; + if(no[2]>=no[0] && no[2]>=no[1]); + else if(no[1]>=no[0] && no[1]>=no[2]) coy= 2; + else { cox= 1; coy= 2;} + + tface->uv[0][0]= 0.5+0.5*cumapsize*(loc[cox] + (mv+mface->v1)->co[cox]); + tface->uv[0][1]= 0.5+0.5*cumapsize*(loc[coy] + (mv+mface->v1)->co[coy]); + dx = floor(tface->uv[0][0]); + dy = floor(tface->uv[0][1]); + tface->uv[0][0] -= dx; + tface->uv[0][1] -= dy; + tface->uv[1][0]= 0.5+0.5*cumapsize*(loc[cox] + (mv+mface->v2)->co[cox]); + tface->uv[1][1]= 0.5+0.5*cumapsize*(loc[coy] + (mv+mface->v2)->co[coy]); + tface->uv[1][0] -= dx; + tface->uv[1][1] -= dy; + tface->uv[2][0]= 0.5+0.5*cumapsize*(loc[cox] + (mv+mface->v3)->co[cox]); + tface->uv[2][1]= 0.5+0.5*cumapsize*(loc[coy] + (mv+mface->v3)->co[coy]); + tface->uv[2][0] -= dx; + tface->uv[2][1] -= dy; + if(mface->v4) { + tface->uv[3][0]= 0.5+0.5*cumapsize*(loc[cox] + (mv+mface->v4)->co[cox]); + tface->uv[3][1]= 0.5+0.5*cumapsize*(loc[coy] + (mv+mface->v4)->co[coy]); + tface->uv[3][0] -= dx; + tface->uv[3][1] -= dy; + } + + } + } + + case UV_BOUNDS4_MAPPING: + fac = 0.25; + goto bounds_mapping; + case UV_BOUNDS2_MAPPING: + fac = 0.5; + goto bounds_mapping; + case UV_BOUNDS1_MAPPING: + // fac = 1.0; was already initialized as 1.0 + case UV_WINDOW_MAPPING: + bounds_mapping: + mymultmatrix(ob->obmat); + MTC_Mat4SwapMat4(G.vd->persmat, mat); + mygetsingmatrix(G.vd->persmat); + + tface= me->tface; + mface= me->mface; + + dx = curarea->winx; + dy = curarea->winy; + + if (dx > dy) dy = dx; + else dx = dy; + + for(a=0; a<me->totface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT) { + + if(mface->v3==0) continue; + + project_short( (me->mvert+mface->v1)->co, adr); + if(adr[0]!=3200) { + tface->uv[0][0]= ((float)adr[0])/dx; + tface->uv[0][1]= ((float)adr[1])/dy; + } + project_short( (me->mvert+mface->v2)->co, adr); + if(adr[0]!=3200) { + tface->uv[1][0]= ((float)adr[0])/dx; + tface->uv[1][1]= ((float)adr[1])/dy; + } + project_short( (me->mvert+mface->v3)->co, adr); + if(adr[0]!=3200) { + tface->uv[2][0]= ((float)adr[0])/dx; + tface->uv[2][1]= ((float)adr[1])/dy; + } + if(mface->v4) { + project_short( (me->mvert+mface->v4)->co, adr); + if(adr[0]!=3200) { + tface->uv[3][0]= ((float)adr[0])/dx; + tface->uv[3][1]= ((float)adr[1])/dy; + } + } + } + } + + //stop here if WINDOW_MAPPING: + if (mode == UV_WINDOW_MAPPING) break; + + /* minmax */ + min[0]= min[1]= 1.0; + max[0]= max[1]= 0.0; + tface= me->tface; + mface= me->mface; + for(a=0; a<me->totface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT) { + if(mface->v3==0) continue; + + if(mface->v4) b= 3; else b= 2; + for(; b>=0; b--) { + min[0]= MIN2(tface->uv[b][0], min[0]); + min[1]= MIN2(tface->uv[b][1], min[1]); + max[0]= MAX2(tface->uv[b][0], max[0]); + max[1]= MAX2(tface->uv[b][1], max[1]); + } + } + } + + dx= max[0]-min[0]; + dy= max[1]-min[1]; + + tface= me->tface; + mface= me->mface; + for(a=0; a<me->totface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT) { + if(mface->v3==0) continue; + + if(mface->v4) b= 3; else b= 2; + for(; b>=0; b--) { + tface->uv[b][0]= ((tface->uv[b][0] - min[0])* fac) / dx; + tface->uv[b][1]= 1.0 - fac + ((tface->uv[b][1] - min[1]) * fac) /dy; + } + } + } + break; + + case UV_STD4_MAPPING: + fac = 0.25; + goto standard_mapping; + case UV_STD2_MAPPING: + fac = 0.5; + goto standard_mapping; + case UV_STD1_MAPPING: + fac = 1.0; + + standard_mapping: + tface= me->tface; + for(a=0; a<me->totface; a++, tface++) { + if(tface->flag & TF_SELECT) { + default_uv(tface->uv, fac); + } + } + break; + + case UV_SPHERE_MAPPING: + case UV_CYL_MAPPING: + + /* calc centre */ + + INIT_MINMAX(min, max); + + tface= me->tface; + mface= me->mface; + for(a=0; a<me->totface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT) { + if(mface->v3==0) continue; + + DO_MINMAX( (me->mvert+mface->v1)->co, min, max); + DO_MINMAX( (me->mvert+mface->v2)->co, min, max); + DO_MINMAX( (me->mvert+mface->v3)->co, min, max); + if(mface->v4) DO_MINMAX( (me->mvert+mface->v3)->co, min, max); + } + } + + VecMidf(cent, min, max); + + tface= me->tface; + mface= me->mface; + for(a=0; a<me->totface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT) { + if(mface->v3==0) continue; + + VecSubf(no, (me->mvert+mface->v1)->co, cent); + if(mode==UV_CYL_MAPPING) tubemap(no[0], no[1], no[2], tface->uv[0], &tface->uv[0][1]); + else spheremap(no[0], no[1], no[2], tface->uv[0], &tface->uv[0][1]); + + VecSubf(no, (me->mvert+mface->v2)->co, cent); + if(mode==UV_CYL_MAPPING) tubemap(no[0], no[1], no[2], tface->uv[1], &tface->uv[1][1]); + else spheremap(no[0], no[1], no[2], tface->uv[1], &tface->uv[1][1]); + + VecSubf(no, (me->mvert+mface->v3)->co, cent); + if(mode==UV_CYL_MAPPING) tubemap(no[0], no[1], no[2], tface->uv[2], &tface->uv[2][1]); + else spheremap(no[0], no[1], no[2], tface->uv[2], &tface->uv[2][1]); + n = 3; + + if(mface->v4) { + VecSubf(no, (me->mvert+mface->v4)->co, cent); + if(mode==3) tubemap(no[0], no[1], no[2], tface->uv[3], &tface->uv[3][1]); + else spheremap(no[0], no[1], no[2], tface->uv[3], &tface->uv[3][1]); + n = 4; + } + mi = 0; + for (i = 1; i < n; i++) + { + if (tface->uv[i][0] > tface->uv[mi][0]) mi = i; + } + for (i = 0; i < n; i++) + { + if (i != mi) { + dx = tface->uv[mi][0] - tface->uv[i][0]; + if (dx > 0.5) { + tface->uv[i][0] += 1.0; + } + } + } + } + } + break; + default: + return; + } // end switch + + /* clipping and wrapping */ + if(G.sima && G.sima->flag & SI_CLIP_UV) { + tface= me->tface; + mface= me->mface; + for(a=0; a<me->totface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT) { + if(mface->v3==0) continue; + + dx= dy= 0; + if(mface->v4) b= 3; else b= 2; + for(; b>=0; b--) { + while(tface->uv[b][0] + dx < 0.0) dx+= 0.5; + while(tface->uv[b][0] + dx > 1.0) dx-= 0.5; + while(tface->uv[b][1] + dy < 0.0) dy+= 0.5; + while(tface->uv[b][1] + dy > 1.0) dy-= 0.5; + } + + if(mface->v4) b= 3; else b= 2; + for(; b>=0; b--) { + tface->uv[b][0]+= dx; + CLAMP(tface->uv[b][0], 0.0, 1.0); + + tface->uv[b][1]+= dy; + CLAMP(tface->uv[b][1], 0.0, 1.0); + } + } + } + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + myloadmatrix(G.vd->viewmat); + MTC_Mat4SwapMat4(G.vd->persmat, mat); + +} + +void set_faceselect() /* toggle */ +{ + Object *ob = OBACT; + Mesh *me = 0; + + scrarea_queue_headredraw(curarea); + + if(G.f & G_FACESELECT) G.f &= ~G_FACESELECT; + else { + if (ob && ob->type == OB_MESH) G.f |= G_FACESELECT; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSGAME, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWIMAGE, 0); + + ob= OBACT; + me= get_mesh(ob); + if(me && me->tface==NULL) make_tfaces(me); + + if(G.f & G_FACESELECT) { + setcursor_space(SPACE_VIEW3D, CURSOR_FACESEL); + if(me) set_lasttface(); + } + else if((G.f & (G_WEIGHTPAINT|G_VERTEXPAINT|G_TEXTUREPAINT))==0) { + if(me) reveal_tface(); + setcursor_space(SPACE_VIEW3D, CURSOR_STD); + makeDispList(ob); + } + countall(); +} + + +#ifdef NAN_TPT +/** + * Get the view ray through the screen point. + * Uses the OpenGL settings of the active view port. + * The coordinates should be given in viewport coordinates. + * @author Maarten Gribnau + * @param x the x-coordinate of the screen point. + * @param y the y-coordinate of the screen point. + * @param org origin of the view ray. + * @param dir direction of the view ray. + */ +void get_pick_ray(short x, short y, float org[3], float dir[3]) +{ + double mvmatrix[16]; + double projmatrix[16]; + GLint viewport[4]; + double px, py, pz; + float l; + + /* Get the matrices needed for gluUnProject */ + glGetIntegerv(GL_VIEWPORT, viewport); + glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix); + glGetDoublev(GL_PROJECTION_MATRIX, projmatrix); + + /* Set up viewport so that gluUnProject will give correct values */ + viewport[0] = 0; + viewport[1] = 0; + /* printf("viewport = (%4d, %4d, %4d, %4d)\n", viewport[0], viewport[1], viewport[2], viewport[3]); */ + /* printf("cursor = (%4d, %4d)\n", x, y); */ + + gluUnProject((GLdouble) x, (GLdouble) y, 0.0, mvmatrix, projmatrix, viewport, &px, &py, &pz); + org[0] = (float)px; org[1] = (float)py; org[2] = (float)pz; + /* printf("world point at z=0.0 is (%f, %f, %f)\n", org[0], org[1], org[2]); */ + gluUnProject((GLdouble) x, (GLdouble) y, 1.0, mvmatrix, projmatrix, viewport, &px, &py, &pz); + /* printf("world point at z=1.0 is (%f, %f, %f)\n", px, py, pz); */ + dir[0] = ((float)px) - org[0]; + dir[1] = ((float)py) - org[1]; + dir[2] = ((float)pz) - org[2]; + l = (float)sqrt(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]); + if (!l) return; + l = 1. / l; + dir[0] *= l; dir[1] *= l; dir[2] *= l; + /* printf("ray org. is (%f, %f, %f)\n", org[0], org[1], org[2]); */ + /* printf("ray dir. is (%f, %f, %f)\n", dir[0], dir[1], dir[2]); */ +} + + +int triangle_ray_intersect(float tv0[3], float tv1[3], float tv2[3], float org[3], float dir[3], float uv[2]) +{ + float v1v0[3]; + float v2v0[3]; + float n[3], an[3]; + float t, d, l; + float p[3]; + double u0, v0, u1, v1, u2, v2, uvtemp; + unsigned int iu, iv; + + /* Calculate normal of the plane (cross, normalize) + * Could really use moto here... + */ + v1v0[0] = tv1[0] - tv0[0]; + v1v0[1] = tv1[1] - tv0[1]; + v1v0[2] = tv1[2] - tv0[2]; + v2v0[0] = tv2[0] - tv0[0]; + v2v0[1] = tv2[1] - tv0[1]; + v2v0[2] = tv2[2] - tv0[2]; + n[0] = (v1v0[1] * v2v0[2]) - (v1v0[2] * v2v0[1]); + n[1] = (v1v0[2] * v2v0[0]) - (v1v0[0] * v2v0[2]); + n[2] = (v1v0[0] * v2v0[1]) - (v1v0[1] * v2v0[0]); + l = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]); + if (!l) return 0; + l = 1. / l; + n[0] *= l; n[1] *= l; n[2] *= l; + + /* Calculate intersection point */ + t = n[0]*dir[0] + n[1]*dir[1] + n[2]*dir[2]; + if (fabs(t) < 1.0e-6) return 0; + d = -(n[0]*tv0[0] + n[1]*tv0[1] + n[2]*tv0[2]); + t = -(((n[0]*org[0] + n[1]*org[1] + n[2]*org[2]) + d) / t); + if (t < 0) return 0; + p[0] = org[0] + dir[0]*t; + p[1] = org[1] + dir[1]*t; + p[2] = org[2] + dir[2]*t; + /*printf("intersection at (%f, %f, %f)\n", p[0], p[1], p[2]);*/ + + /* Calculate the largest component of the normal */ + an[0] = fabs(n[0]); an[1] = fabs(n[1]); an[2] = fabs(n[2]); + if ((an[0] > an[1]) && (an[0] > an[2])) { + iu = 1; iv = 2; + } + else if ((an[1] > an[0]) && (an[1] > an[2])) { + iu = 2; iv = 0; + } + else { + iu = 0; iv = 1; + } + /* printf("iu, iv = (%d, %d)\n", iu, iv); */ + + /* Calculate (u,v) */ + u0 = p[iu] - tv0[iu]; + v0 = p[iv] - tv0[iv]; + u1 = tv1[iu] - tv0[iu]; + v1 = tv1[iv] - tv0[iv]; + u2 = tv2[iu] - tv0[iu]; + v2 = tv2[iv] - tv0[iv]; + /* printf("u0, v0, u1, v1, u2, v2 = (%f, %f, %f, %f, %f, %f)\n", u0, v0, u1, v1, u2, v2); */ + + /* These calculations should be in double precision. + * On windows we get inpredictable results in single precision + */ + if (u1 == 0) { + uvtemp = u0/u2; + uv[1] = (float)uvtemp; + /* if ((uv[1] >= 0.) && (uv[1] <= 1.)) { */ + uv[0] = (float)((v0 - uvtemp*v2) / v1); + /* } */ + } + else { + uvtemp = (v0*u1 - u0*v1)/(v2*u1-u2*v1); + uv[1] = (float)uvtemp; + /* if ((uv[1] >= 0) && (uv[1] <= 1)) { */ + uv[0] = (float)((u0 - uvtemp*u2) / u1); + /* } */ + } + /* printf("uv[0], uv[1] = (%f, %f)\n", uv[0], uv[1]); */ + return ((uv[0] >= 0) && (uv[1] >= 0) && ((uv[0]+uv[1]) <= 1)) ? 2 : 1; +} + +/** + * Returns the vertex (local) coordinates of a face. + * No bounds checking! + * @author Maarten Gribnau + * @param mesh the mesh with the face. + * @param face the face. + * @param v1 vertex 1 coordinates. + * @param v2 vertex 2 coordinates. + * @param v3 vertex 3 coordinates. + * @param v4 vertex 4 coordinates. + * @return number of vertices of this face + */ +int face_get_vertex_coordinates(Mesh* mesh, TFace* face, float v1[3], float v2[3], float v3[3], float v4[3]) +{ + int num_vertices; + MVert *mv; + MFace *mf = (MFace *) (((MFace *)mesh->mface) + (face - (TFace *) mesh->tface)); + + num_vertices = mf->v4 == 0 ? 3 : 4; + mv = mesh->mvert + mf->v1; + v1[0] = mv->co[0]; v1[1] = mv->co[1]; v1[2] = mv->co[2]; + mv = mesh->mvert + mf->v2; + v2[0] = mv->co[0]; v2[1] = mv->co[1]; v2[2] = mv->co[2]; + mv = mesh->mvert + mf->v3; + v3[0] = mv->co[0]; v3[1] = mv->co[1]; v3[2] = mv->co[2]; + if (num_vertices == 4) { + mv = mesh->mvert + mf->v4; + v4[0] = mv->co[0]; v4[1] = mv->co[1]; v4[2] = mv->co[2]; + } + + return num_vertices; +} + +/** + * Finds texture coordinates from face edge interpolation values. + * @author Maarten Gribnau + * @param face the face. + * @param v1 vertex 1 index. + * @param v2 vertex 2 index. + * @param v3 vertex 3 index. + * @param a interpolation value of edge v2-v1. + * @param b interpolation value of edge v3-v1. + * @param u (u,v) coordinate. + * @param v (u,v) coordinate. + */ +void face_get_uv(TFace* face, int v1, int v2, int v3, float a, float b, float* u, float* v) +{ + float uv01[2], uv21[2]; + + /* Pin a,b inside [0,1] range */ +#if 0 + a = (float)fmod(a, 1.); + b = (float)fmod(b, 1.); +#else + if (a < 0.f) a = 0.f; + else if (a > 1.f) a = 1.f; + if (b < 0.f) b = 0.f; + else if (b > 1.f) b = 1.f; +#endif + + /* Convert to texture coordinates */ + uv01[0] = face->uv[v2][0] - face->uv[v1][0]; + uv01[1] = face->uv[v2][1] - face->uv[v1][1]; + uv21[0] = face->uv[v3][0] - face->uv[v1][0]; + uv21[1] = face->uv[v3][1] - face->uv[v1][1]; + uv01[0] *= a; + uv01[1] *= a; + uv21[0] *= b; + uv21[1] *= b; + *u = face->uv[v1][0] + (uv01[0] + uv21[0]); + *v = face->uv[v1][1] + (uv01[1] + uv21[1]); +} + +/** + * Get the (u,v) coordinates on a face from a point in screen coordinates. + * The coordinates should be given in viewport coordinates. + * @author Maarten Gribnau + * @param object the object with the mesh + * @param mesh the mesh with the face to be picked. + * @param face the face to be picked. + * @param x the x-coordinate to pick at. + * @param y the y-coordinate to pick at. + * @param u the u-coordinate calculated. + * @param v the v-coordinate calculated. + * @return intersection result: + * 0 == no intersection, (u,v) invalid + * 1 == intersection, (u,v) valid + */ +int face_pick_uv(Object* object, Mesh* mesh, TFace* face, short x, short y, float* u, float* v) +{ + float org[3], dir[3]; + float ab[2]; + float v1[3], v2[3], v3[3], v4[3]; + int result; + int num_verts; + + /* Get a view ray to intersect with the face */ + get_pick_ray(x, y, org, dir); + + /* Convert local vertex coordinates to world */ + num_verts = face_get_vertex_coordinates(mesh, face, v1, v2, v3, v4); + /* Convert local vertex coordinates to world */ + Mat4MulVecfl(object->obmat, v1); + Mat4MulVecfl(object->obmat, v2); + Mat4MulVecfl(object->obmat, v3); + if (num_verts > 3) { + Mat4MulVecfl(object->obmat, v4); + } + + /* Get (u,v) values (local face coordinates) of intersection point + * If face is a quad, there are two triangles to check. + */ + result = triangle_ray_intersect(v2, v1, v3, org, dir, ab); + if ((num_verts == 3) || (num_verts == 4) && (result > 1)) { + /* Face is a triangle or a quad with a hit on the first triangle */ + face_get_uv(face, 1, 0, 2, ab[0], ab[1], u, v); + /* printf("triangle 1, texture (u,v)=(%f, %f)\n", *u, *v); */ + } + else { + /* Face is a quad and no intersection with first triangle */ + result = triangle_ray_intersect(v4, v3, v1, org, dir, ab); + face_get_uv(face, 3, 2, 0, ab[0], ab[1], u, v); + /* printf("triangle 2, texture (u,v)=(%f, %f)\n", *u, *v); */ + } + return result > 0; +} + +/** + * First attempt at drawing in the texture of a face. + * @author Maarten Gribnau + */ +void face_draw() +{ + Object *ob; + Mesh *me; + TFace *face, *face_old = 0; + short xy[2], xy_old[2]; + //int a, index; + Image *img, *img_old; + IMG_BrushPtr brush; + IMG_CanvasPtr canvas = 0; + int rowBytes; + char *warn_packed_file = 0; + float uv[2], uv_old[2]; + extern VPaint Gvp; + + ob = OBACT; + if (!ob) { + error("No active object"); return; + } + if (!(ob->lay & G.vd->lay)) { + error("Active object not in this layer"); return; + } + me = get_mesh(ob); + if (!me) { + error("Active object does not have a mesh"); return; + } + + brush = IMG_BrushCreate(Gvp.size, Gvp.size, Gvp.r, Gvp.g, Gvp.b, Gvp.a); + if (!brush) { + error("Can not create brush"); return; + } + + getmouseco_areawin(xy_old); + while (get_mbut() & L_MOUSE) { + getmouseco_areawin(xy); + /* Check if cursor has moved */ + if ((xy[0] != xy_old[0]) || (xy[1] != xy_old[1])) { + + /* Get face to draw on */ + face = face_pick(me, xy[0], xy[1]); + + /* Check if this is another face. */ + if (face != face_old) { + /* The active face changed, check the texture */ + if (face) { + img = face->tpage; + } + else { + img = 0; + } + + if (img != img_old) { + /* Faces have different textures. Finish drawing in the old face. */ + if (face_old && canvas) { + face_pick_uv(ob, me, face_old, xy[0], xy[1], &uv[0], &uv[1]); + IMG_CanvasDrawLineUV(canvas, brush, uv_old[0], uv_old[1], uv[0], uv[1]); + img_old->ibuf->userflags |= IB_BITMAPDIRTY; + /* Delete old canvas */ + IMG_CanvasDispose(canvas); + canvas = 0; + } + + /* Create new canvas and start drawing in the new face. */ + if (img) { + if (img->ibuf && img->packedfile == 0) { + /* MAART: skipx is not set most of the times. Make a guess. */ + rowBytes = img->ibuf->skipx ? img->ibuf->skipx : img->ibuf->x * 4; + canvas = IMG_CanvasCreateFromPtr(img->ibuf->rect, img->ibuf->x, img->ibuf->y, rowBytes); + if (canvas) { + face_pick_uv(ob, me, face, xy_old[0], xy_old[1], &uv_old[0], &uv_old[1]); + face_pick_uv(ob, me, face, xy[0], xy[1], &uv[0], &uv[1]); + IMG_CanvasDrawLineUV(canvas, brush, uv_old[0], uv_old[1], uv[0], uv[1]); + img->ibuf->userflags |= IB_BITMAPDIRTY; + } + } + else { + /* TODO: should issue warning that no texture is assigned */ + if (img->packedfile) { + warn_packed_file = img->id.name + 2; + img = 0; + } + } + } + } + else { + /* Face changed and faces have the same texture. */ + if (canvas) { + /* Finish drawing in the old face. */ + if (face_old) { + face_pick_uv(ob, me, face_old, xy[0], xy[1], &uv[0], &uv[1]); + IMG_CanvasDrawLineUV(canvas, brush, uv_old[0], uv_old[1], uv[0], uv[1]); + img_old->ibuf->userflags |= IB_BITMAPDIRTY; + } + + /* Start drawing in the new face. */ + if (face) { + face_pick_uv(ob, me, face, xy_old[0], xy_old[1], &uv_old[0], &uv_old[1]); + face_pick_uv(ob, me, face, xy[0], xy[1], &uv[0], &uv[1]); + IMG_CanvasDrawLineUV(canvas, brush, uv_old[0], uv_old[1], uv[0], uv[1]); + img->ibuf->userflags |= IB_BITMAPDIRTY; + } + } + } + } + else { + /* Same face, continue drawing */ + if (face && canvas) { + /* Get the new (u,v) coordinates */ + face_pick_uv(ob, me, face, xy[0], xy[1], &uv[0], &uv[1]); + IMG_CanvasDrawLineUV(canvas, brush, uv_old[0], uv_old[1], uv[0], uv[1]); + img->ibuf->userflags |= IB_BITMAPDIRTY; + } + } + + if (face && img) { + /* Make OpenGL aware of a change in the texture */ + free_realtime_image(img); + /* Redraw the view */ + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } + + xy_old[0] = xy[0]; + xy_old[1] = xy[1]; + uv_old[0] = uv[0]; + uv_old[1] = uv[1]; + face_old = face; + img_old = img; + } + } + + IMG_BrushDispose(brush); + if (canvas) { + IMG_CanvasDispose(canvas); + canvas = 0; + } + + if (warn_packed_file) { + error("Painting in packed images not supported: %s", warn_packed_file); + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + allqueue(REDRAWHEADERS, 0); +} +#endif /* NAN_TPT */ diff --git a/source/blender/src/editfont.c b/source/blender/src/editfont.c new file mode 100644 index 00000000000..fb39c33976f --- /dev/null +++ b/source/blender/src/editfont.c @@ -0,0 +1,537 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <string.h> + +#include <fcntl.h> +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_editVert.h" + +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_vfont_types.h" +#include "DNA_scene_types.h" + +#include "BKE_displist.h" +#include "BKE_font.h" +#include "BKE_object.h" +#include "BKE_global.h" +#include "BKE_main.h" + +#include "BIF_editfont.h" +#include "BIF_toolbox.h" +#include "BIF_space.h" +#include "BIF_mywindow.h" + +#include "BDR_editobject.h" + +#include "mydevice.h" + +#include "blendef.h" + +#define MAXTEXT 1000 + +int textediting=0; + +static char findaccent(char char1, char code) +{ + char new= 0; + + if(char1=='a') { + if(code=='`') new= 224; + else if(code==39) new= 225; + else if(code=='^') new= 226; + else if(code=='~') new= 227; + else if(code=='"') new= 228; + else if(code=='o') new= 229; + else if(code=='e') new= 230; + else if(code=='-') new= 170; + } + else if(char1=='c') { + if(code==',') new= 231; + if(code=='|') new= 162; + } + else if(char1=='e') { + if(code=='`') new= 232; + else if(code==39) new= 233; + else if(code=='^') new= 234; + else if(code=='"') new= 235; + } + else if(char1=='i') { + if(code=='`') new= 236; + else if(code==39) new= 237; + else if(code=='^') new= 238; + else if(code=='"') new= 239; + } + else if(char1=='n') { + if(code=='~') new= 241; + } + else if(char1=='o') { + if(code=='`') new= 242; + else if(code==39) new= 243; + else if(code=='^') new= 244; + else if(code=='~') new= 245; + else if(code=='"') new= 246; + else if(code=='/') new= 248; + else if(code=='-') new= 186; + else if(code=='e') new= 143; + } + else if(char1=='s') { + if(code=='s') new= 167; + } + else if(char1=='u') { + if(code=='`') new= 249; + else if(code==39) new= 250; + else if(code=='^') new= 251; + else if(code=='"') new= 252; + } + else if(char1=='y') { + if(code==39) new= 253; + else if(code=='"') new= 255; + } + else if(char1=='A') { + if(code=='`') new= 192; + else if(code==39) new= 193; + else if(code=='^') new= 194; + else if(code=='~') new= 195; + else if(code=='"') new= 196; + else if(code=='o') new= 197; + else if(code=='e') new= 198; + } + else if(char1=='C') { + if(code==',') new= 199; + } + else if(char1=='E') { + if(code=='`') new= 200; + else if(code==39) new= 201; + else if(code=='^') new= 202; + else if(code=='"') new= 203; + } + else if(char1=='I') { + if(code=='`') new= 204; + else if(code==39) new= 205; + else if(code=='^') new= 206; + else if(code=='"') new= 207; + } + else if(char1=='N') { + if(code=='~') new= 209; + } + else if(char1=='O') { + if(code=='`') new= 210; + else if(code==39) new= 211; + else if(code=='^') new= 212; + else if(code=='~') new= 213; + else if(code=='"') new= 214; + else if(code=='/') new= 216; + else if(code=='e') new= 141; + } + else if(char1=='U') { + if(code=='`') new= 217; + else if(code==39) new= 218; + else if(code=='^') new= 219; + else if(code=='"') new= 220; + } + else if(char1=='Y') { + if(code==39) new= 221; + } + else if(char1=='1') { + if(code=='4') new= 188; + if(code=='2') new= 189; + } + else if(char1=='3') { + if(code=='4') new= 190; + } + else if(char1==':') { + if(code=='-') new= 247; + } + else if(char1=='-') { + if(code==':') new= 247; + if(code=='|') new= 135; + if(code=='+') new= 177; + } + else if(char1=='|') { + if(code=='-') new= 135; + if(code=='=') new= 136; + } + else if(char1=='=') { + if(code=='|') new= 136; + } + else if(char1=='+') { + if(code=='-') new= 177; + } + + if(new) return new; + else return char1; +} + +static char *textbuf=0; +static char *oldstr; + +static int insert_into_textbuf(Curve *cu, char c) +{ + if (cu->len<MAXTEXT-1) { + int x; + + for(x= cu->len; x>cu->pos; x--) textbuf[x]= textbuf[x-1]; + textbuf[cu->pos]= c; + + cu->pos++; + cu->len++; + textbuf[cu->len]='\0'; + + return 1; + } else { + return 0; + } +} + +void do_textedit(unsigned short event, short val, char ascii) +{ + Curve *cu; + static int accentcode= 0; + int x, doit=0, cursmove=0; + + cu= G.obedit->data; + + if(ascii) { + + /* o.a. afvangen van TAB (TAB==9) */ + if( (ascii > 31 && ascii < 200 && ascii != 127) || (ascii==13) || (ascii==10) || (ascii==8)) { + + if(accentcode) { + if(cu->pos>0) textbuf[cu->pos-1]= findaccent(textbuf[cu->pos-1], ascii); + accentcode= 0; + } + else if(cu->len<MAXTEXT-1) { + if(G.qual & LR_ALTKEY ) { + if(ascii=='t') ascii= 137; + else if(ascii=='c') ascii= 169; + else if(ascii=='f') ascii= 164; + else if(ascii=='g') ascii= 176; + else if(ascii=='l') ascii= 163; + else if(ascii=='r') ascii= 174; + else if(ascii=='s') ascii= 223; + else if(ascii=='v') ascii= 1001; + else if(ascii=='y') ascii= 165; + else if(ascii=='.') ascii= 138; + else if(ascii=='1') ascii= 185; + else if(ascii=='2') ascii= 178; + else if(ascii=='3') ascii= 179; + else if(ascii=='%') ascii= 139; + else if(ascii=='?') ascii= 191; + else if(ascii=='!') ascii= 161; + else if(ascii=='x') ascii= 215; + else if(ascii=='>') ascii= 187; + else if(ascii=='<') ascii= 171; + } + + if(ascii==1001) { + int file, filelen; + char *strp; + +/* this should be solved by clipboard support */ +#ifdef __WIN32_DISABLED + file= open("C:\\windows\\temp\\cutbuf", O_BINARY|O_RDONLY); +#else + file= open("/tmp/.cutbuffer", O_BINARY|O_RDONLY); +#endif + if(file>0) { + + filelen = BLI_filesize(file); + + strp= MEM_mallocN(filelen+1, "tempstr"); + read(file, strp, filelen); + close(file); + strp[filelen]= 0; + if(cu->len+filelen<MAXTEXT) { + strcat( textbuf, strp); + cu->len= strlen(textbuf); + cu->pos= cu->len; + } + MEM_freeN(strp); + } + } + else { + insert_into_textbuf(cu, ascii); + } + } + + doit= 1; + } + } + else if(val) { + cursmove= 0; + + switch(event) { + case RETKEY: + insert_into_textbuf(cu, '\n'); + doit= 1; + break; + + case RIGHTARROWKEY: + if(G.qual & LR_SHIFTKEY) { + while(cu->pos<cu->len) { + if( textbuf[cu->pos]==0) break; + if( textbuf[cu->pos]=='\n') break; + cu->pos++; + } + } + else { + cu->pos++; + } + cursmove= FO_CURS; + break; + + case LEFTARROWKEY: + + if(G.qual & LR_SHIFTKEY) { + while(cu->pos>0) { + if( textbuf[cu->pos-1]=='\n') break; + cu->pos--; + } + } + else { + cu->pos--; + } + cursmove=FO_CURS; + break; + + case UPARROWKEY: + if(G.qual & LR_SHIFTKEY) { + cu->pos= 0; + cursmove= FO_CURS; + } + else if(G.qual & LR_ALTKEY) { + if (cu->pos && textbuf[cu->pos - 1] < 255) { + textbuf[cu->pos - 1]++; + doit= 1; + } + } + else cursmove=FO_CURSUP; + break; + + case DOWNARROWKEY: + if(G.qual & LR_SHIFTKEY) { + cu->pos= cu->len; + cursmove= FO_CURS; + } + else if(G.qual & LR_ALTKEY) { + if (cu->pos && textbuf[cu->pos - 1] > 1) { + textbuf[cu->pos - 1]--; + doit= 1; + } + } + else cursmove= FO_CURSDOWN; + break; + + case BACKSPACEKEY: + if(cu->len!=0) { + if(G.qual & LR_ALTKEY) { + if(cu->pos>0) accentcode= 1; + } + else if(G.qual & LR_SHIFTKEY) { + cu->pos= 0; + textbuf[0]= 0; + cu->len= 0; + } + else if(cu->pos>0) { + for(x=cu->pos;x<=cu->len;x++) textbuf[x-1]= textbuf[x]; + cu->pos--; + textbuf[--cu->len]='\0'; + } + } + doit= 1; + break; + } + + if(cursmove) { + if(cu->pos>cu->len) cu->pos= cu->len; + else if(cu->pos>=MAXTEXT) cu->pos= MAXTEXT; + else if(cu->pos<0) cu->pos= 0; + } + } + if(doit || cursmove) { + text_to_curve(G.obedit, cursmove); + if(cursmove==0) makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + } +} + +void make_editText(void) +{ + Curve *cu; + + cu= G.obedit->data; + if(textbuf==0) textbuf= MEM_mallocN(MAXTEXT, "texteditbuf"); + BLI_strncpy(textbuf, cu->str, MAXTEXT); + oldstr= cu->str; + cu->str= textbuf; + + cu->len= strlen(textbuf); + if(cu->pos>cu->len) cu->pos= cu->len; + + text_to_curve(G.obedit, 0); + makeDispList(G.obedit); + + textediting= 1; +} + +void load_editText(void) +{ + Curve *cu; + + cu= G.obedit->data; + + MEM_freeN(oldstr); + oldstr= 0; + + cu->str= MEM_mallocN(cu->len+1, "tekstedit"); + strcpy(cu->str, textbuf); + + /* this memory system is weak... */ + MEM_freeN(textbuf); + textbuf= 0; + + cu->len= strlen(cu->str); + textediting= 0; +} + +void remake_editText(void) +{ + Curve *cu; + + if(okee("Reload Original text")==0) return; + + BLI_strncpy(textbuf, oldstr, MAXTEXT); + cu= G.obedit->data; + cu->len= strlen(textbuf); + if(cu->pos>cu->len) cu->pos= cu->len; + + text_to_curve(G.obedit, 0); + makeDispList(G.obedit); + + allqueue(REDRAWVIEW3D, 0); +} + +void free_editText(void) +{ + if(oldstr) MEM_freeN(oldstr); + textbuf= oldstr= 0; + textediting= 0; +} + +static VFont *get_builtin_font(void) +{ + VFont *vf; + + for (vf= G.main->vfont.first; vf; vf= vf->id.next) + if (BLI_streq(vf->name, "<builtin>")) + return vf; + + return load_vfont("<builtin>"); +} + +void add_primitiveFont(int dummy_argument) +{ + Curve *cu; + + if (G.obedit && G.obedit->type==OB_FONT) return; + check_editmode(OB_FONT); + + add_object(OB_FONT); + base_init_from_view3d(BASACT, G.vd); + G.obedit= BASACT->object; + where_is_object(G.obedit); + + cu= G.obedit->data; + + cu->vfont= get_builtin_font(); + cu->vfont->id.us++; + cu->str= MEM_mallocN(12, "str"); + strcpy(cu->str, "Text"); + cu->pos= 4; + + make_editText(); + allqueue(REDRAWVIEW3D, 0); +} + +void to_upper(void) +{ + Curve *cu; + int len, ok; + char *str; + + if(G.obedit==0) { + return; + } + + ok= 0; + cu= G.obedit->data; + + len= strlen(cu->str); + str= cu->str; + while(len) { + if( *str>=97 && *str<=122) { + ok= 1; + *str-= 32; + } + len--; + str++; + } + + if(ok==0) { + len= strlen(cu->str); + str= cu->str; + while(len) { + if( *str>=65 && *str<=90) { + *str+= 32; + } + len--; + str++; + } + } + text_to_curve(G.obedit, 0); + makeDispList(G.obedit); + + allqueue(REDRAWVIEW3D, 0); + +} + + diff --git a/source/blender/src/editgroup.c b/source/blender/src/editgroup.c new file mode 100644 index 00000000000..e72fb33e9b8 --- /dev/null +++ b/source/blender/src/editgroup.c @@ -0,0 +1,251 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_group_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_group.h" +#include "BKE_global.h" +#include "BKE_main.h" + +#include "BIF_space.h" +#include "BIF_interface.h" +#include "BIF_toolbox.h" +#include "BIF_editgroup.h" + +#include "interface.h" +#include "blendef.h" +#include "mydevice.h" + +void set_active_group(void) +{ + /* with active object, find active group */ + Group *group; + GroupObject *go; + + G.scene->group= NULL; + + if(BASACT) { + group= G.main->group.first; + while(group) { + go= group->gobject.first; + while(go) { + if(go->ob == OBACT) { + G.scene->group= group; + return; + } + go= go->next; + } + group= group->id.next; + } + } +} + + +void add_selected_to_group(void) +{ + Base *base= FIRSTBASE; + Group *group; + + if(BASACT==NULL) { + error("No active object"); + return; + } + + if(okee("Add selected to group")==0) return; + + if(G.scene->group==NULL) G.scene->group= add_group(); + + while(base) { + if TESTBASE(base) { + + /* each object only in one group */ + group= find_group(base->object); + if(group==G.scene->group); + else { + if(group) { + rem_from_group(group, base->object); + } + add_to_group(G.scene->group, base->object); + base->object->flag |= OB_FROMGROUP; + base->flag |= OB_FROMGROUP; + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSANIM, 0); +} + +void rem_selected_from_group(void) +{ + Base *base=FIRSTBASE; + Group *group; + + if(okee("Remove selected from group")==0) return; + + while(base) { + if TESTBASE(base) { + + group= find_group(base->object); + if(group) { + rem_from_group(group, base->object); + + base->object->flag &= ~OB_FROMGROUP; + base->flag &= ~OB_FROMGROUP; + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSANIM, 0); +} + +void group_menu(void) +{ + Base *base; + GroupObject *go; + GroupKey *gk; + short nr, len; + char *str, tstr[40]; + + if(G.scene->group==NULL) return; + + /* make menu string */ + len= 60; + gk= G.scene->group->gkey.first; + while(gk) { + len+= 36; + gk= gk->next; + } + + str= MEM_mallocN(len, "groupmenu"); + strcpy(str, "Group options%t|Select members %x1"); + + if(G.scene->group->active) + strcat(str, "|Overwrite active key %x2|%l"); + + nr= 3; + gk= G.scene->group->gkey.first; + while(gk) { + sprintf(tstr, "|Load: %s %%x%d", gk->name, nr++); + strcat(str, tstr); + gk= gk->next; + } + + /* here we go */ + + nr= pupmenu(str); + MEM_freeN(str); + + if(nr==1) { + go= G.scene->group->gobject.first; + while(go) { + go->ob->flag |= SELECT; + go= go->next; + } + + /* nasty thing... that should be solved someday */ + base= FIRSTBASE; + while(base) { + base->flag= base->object->flag; + base= base->next; + } + + } + else if(nr==2) { + go= G.scene->group->gobject.first; + while(go) { + add_object_key(go, G.scene->group->active); + go= go->next; + } + + } + else if(nr>2) { + nr-= 2; + gk= G.scene->group->gkey.first; + while(gk) { + nr--; + if(nr==0) break; + gk= gk->next; + } + + G.scene->group->active= gk; + set_group_key(G.scene->group); + + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSANIM, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); +} + + +void prev_group_key(Group *group) +{ + GroupKey *gk= group->active; + + if(gk) gk= gk->prev; + + if(gk==NULL) group->active= group->gkey.last; + else group->active= gk; + + set_group_key(group); +} + +void next_group_key(Group *group) +{ + GroupKey *gk= group->active; + + if(gk) gk= gk->next; + + if(gk==NULL) group->active= group->gkey.first; + else group->active= gk; + + set_group_key(group); + +} + + diff --git a/source/blender/src/editika.c b/source/blender/src/editika.c new file mode 100644 index 00000000000..1c4cde7a247 --- /dev/null +++ b/source/blender/src/editika.c @@ -0,0 +1,422 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_ika_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_object.h" +#include "BKE_ika.h" +#include "BKE_global.h" +#include "BKE_displist.h" + +#include "BIF_gl.h" +#include "BIF_toolbox.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_editika.h" + +#include "BSE_view.h" +#include "BSE_drawview.h" + +#include "mydevice.h" +#include "blendef.h" + +static void draw_limb(Limb *li, float small) +{ + float vec[2]; + + glRotatef(( li->alpha*180.0/M_PI), 0.0, 0.0, 1.0); + + { GLUquadricObj *qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); + gluPartialDisk( qobj, small, small, 32, 1, 180.0, 180.0); + gluDeleteQuadric(qobj); + }; + + vec[0]= 0.0; vec[1]= small; + glBegin(GL_LINE_STRIP); + glVertex2fv(vec); + vec[0]= li->len; vec[1]= 0.0; + glVertex2fv(vec); + vec[0]= 0.0; vec[1]= -small; + glVertex2fv(vec); + glEnd(); + + small*= 0.25; + + if(li->next) circf(li->len, 0.0, small); + else circf(li->len, 0.0, small); + + glTranslatef(li->len, 0.0, 0.0); +} + +void draw_ika(Object *ob, int sel) +{ + Ika *ika; + Limb *li; + float col[4]; + float small= 0.15; + + ika= ob->data; + li= ika->limbbase.first; + if(li==0) return; + + /* we zijn al in objectspace */ + glPushMatrix(); + + glGetFloatv(GL_CURRENT_COLOR, col); + + if((ika->flag & IK_GRABEFF)==0) { + if(sel) cpack(0xFFFF); + circf(0.0, 0.0, 0.05*li->len); + + glColor3f(col[0], col[1], col[2]); + } + + while(li) { + small= 0.10*li->len; + draw_limb(li, small); + li= li->next; + } + + if(ika->flag & IK_GRABEFF) { + if(sel) { + if(ika->def) cpack(0xFFFF00); + else cpack(0xFFFF); + } + circf(0.0, 0.0, 0.25*small); + glColor3f(col[0], col[1], col[2]); + } + + glPopMatrix(); +} + +/* type 0: verts, type 1: limbs */ +void draw_ika_nrs(Object *ob, int type) +{ + Ika *ika; + Limb *li; + int nr=0; + char str[12]; + + if(curarea->spacetype!=SPACE_VIEW3D) return; + mywinset(curarea->win); + + glDrawBuffer(GL_FRONT); + myloadmatrix(G.vd->viewmat); + mymultmatrix(ob->obmat); + + ika= ob->data; + li= ika->limbbase.first; + + /* we zijn al in objectspace */ + glPushMatrix(); + cpack(0xFFFFFF); + + if(type==0) { + sprintf(str, " %d", nr++); + glRasterPos3f(0.0, 0.0, 0.0); + BMF_DrawString(G.font, str); + + while(li) { + + glRotatef(( li->alpha*180.0/M_PI), 0.0, 0.0, 1.0); + glTranslatef(li->len, 0.0, 0.0); + sprintf(str, " %d", nr++); + glRasterPos3f(0.0, 0.0, 0.0); + BMF_DrawString(G.font, str); + + li= li->next; + } + } + else { + while(li) { + + glRotatef(( li->alpha*180.0/M_PI), 0.0, 0.0, 1.0); + glTranslatef( 0.7*li->len, 0.0, 0.0); + sprintf(str, " %d", nr++); + glRasterPos3f(0.0, 0.0, 0.0); + BMF_DrawString(G.font, str); + glTranslatef( 0.3*li->len, 0.0, 0.0); + + li= li->next; + } + + } + + glDrawBuffer(GL_BACK); + glPopMatrix(); +} + + + +int extrude_ika(Object *ob, int add) +{ + Ika *ika; + Limb *li; + float dvec[3], dvecp[3], oldeul[3], mat[3][3], imat[3][3]; + int firsttime= 1; + unsigned short event = 0; + short val, afbreek=0, mval[2], xo, yo; + + /* init */ + VECCOPY(oldeul, ob->rot); + initgrabz(ob->obmat[3][0], ob->obmat[3][1], ob->obmat[3][2]); + + Mat3CpyMat4(mat, ob->obmat); + Mat3Inv(imat, mat); + + getmouseco_areawin(mval); + xo= mval[0]; + yo= mval[1]; + + /* het laatste punt van de ika */ + ika= ob->data; + + if(add) { + /* een erbij: */ + li= MEM_callocN(sizeof(Limb), "limb"); + BLI_addtail(&ika->limbbase, li); + if(li->prev) { + li->eff[0]= li->prev->eff[0]; + li->eff[1]= li->prev->eff[1]; + } + li->eff[0]+= 0.5; + } + li= ika->limbbase.last; + if(li==0) return 0; + + while(TRUE) { + + getmouseco_areawin(mval); + if(mval[0]!=xo || mval[1]!=yo || firsttime) { + firsttime= 0; + + window_to_3d(dvec, mval[0]-xo, mval[1]-yo); + VECCOPY(dvecp, dvec); + + /* apply */ + Mat3MulVecfl(imat, dvecp); + li->eff[0]+= dvecp[0]; + li->eff[1]+= dvecp[1]; + + calc_limb(li); + + if(li->prev==0) { + VECCOPY(ob->rot, oldeul); + euler_rot(ob->rot, li->alpha, 'z'); + li->alpha= li->alphao= 0.0; + } + + xo= mval[0]; + yo= mval[1]; + + force_draw(); + } + + while(qtest()) { + event= extern_qread(&val); + if(val) { + switch(event) { + case ESCKEY: + case LEFTMOUSE: + case MIDDLEMOUSE: + case SPACEKEY: + case RETKEY: + afbreek= 1; + break; + } + } + if(afbreek) break; + } + + if(afbreek) break; + } + + if(event==ESCKEY) { + if(ika->limbbase.first!=ika->limbbase.last) { + li= ika->limbbase.last; + BLI_remlink(&ika->limbbase, li); + MEM_freeN(li); + } + } + else if(add) init_defstate_ika(ob); + + allqueue(REDRAWVIEW3D, 0); + + if(event==LEFTMOUSE) return 0; + return 1; +} + +void delete_skeleton(void) +{ + Object *ob; + Ika *ika; + + ob= OBACT; + if(ob==0 || ob->type!=OB_IKA || (ob->flag & SELECT)==0) return; + + ika= ob->data; + + if(!ika->def) return; + if(!okee("Delete Skeleton")) return; + + if(ika->def) MEM_freeN(ika->def); + ika->def= 0; + ika->totdef= 0; + + allqueue(REDRAWVIEW3D, 0); +} + +static void copy_deform(int tot, Deform *defbase, Deform *def) +{ + /* defbase is the old one, *def is new. When they match, + the deform data is copied */ + + while(tot--) { + if(defbase->ob==def->ob && defbase->par1==def->par1) { + def->fac= defbase->fac; + def->dist= defbase->dist; + return; + } + defbase++; + } +} + +void make_skeleton(void) +{ + Object *ob; + Base *base; + Ika *ika; + Deform *def, *defbase; + Limb *li; + int a, totdef=0; + + ob= OBACT; + if(ob==0 || ob->type!=OB_IKA || (ob->flag & SELECT)==0) return; + + if(!okee("Make Skeleton")) return; + + ika= ob->data; + + /* per selected ob, per limb, de obmat en imat berekenen */ + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + if(base->object->type==OB_IKA) totdef+= count_limbs(base->object); + else totdef++; + } + base= base->next; + } + + if(totdef==0) { + error("Nothing selected"); + return; + } + + def=defbase= MEM_callocN(totdef*sizeof(Deform), "deform"); + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + + if(base->object->type==OB_IKA) { + + li= ( (Ika *)(base->object->data) )->limbbase.first; + a= 0; + while(li) { + what_does_parent1(base->object, PARLIMB, a, 0, 0); + def->ob= base->object; + def->partype= PARLIMB; + def->par1= a; + + Mat4Invert(def->imat, workob.obmat); + def->vec[0]= li->len; + def->fac= 1.0; + + copy_deform(ika->totdef, ika->def, def); + + def++; + a++; + li= li->next; + } + } + else { + what_does_parent1(base->object, PAROBJECT, 0, 0, 0); + def->ob= base->object; + def->partype= PAROBJECT; + + def->vec[0]= 0.0; + def->fac= 1.0; + def->dist= 0.0; + + copy_deform(ika->totdef, ika->def, def); + + Mat4Invert(def->imat, workob.obmat); + def++; + } + } + base= base->next; + } + + if(ika->def) MEM_freeN(ika->def); + ika->def= defbase; + ika->totdef= totdef; + + /* Recalculate the deformation on any object + * that was parented to the old skeleton. + */ + for (base= FIRSTBASE; base; base= base->next) + if (base->object->parent==ob) + makeDispList(base->object); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); +} diff --git a/source/blender/src/editimasel.c b/source/blender/src/editimasel.c new file mode 100644 index 00000000000..f96491b1a6f --- /dev/null +++ b/source/blender/src/editimasel.c @@ -0,0 +1,383 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#else +#include <sys/times.h> +#endif + +#include "PIL_time.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_screen_types.h" +#include "DNA_space_types.h" + +#include "BKE_global.h" + +#include "BIF_fsmenu.h" +#include "BIF_screen.h" +#include "BIF_interface.h" +#include "BIF_imasel.h" + +#include "BSE_filesel.h" +#include "BSE_drawimasel.h" + +#include "BDR_editcurve.h" + +#include "blendef.h" +#include "mydevice.h" +#include "interface.h" + +/* locals */ +void draw_icon_imasel(void); +void winqreadimasel(unsigned short event, short val, char ascii); + +#define XIC 20 +#define YIC 21 + +/* GLOBALS */ +extern char *fsmenu; + + +void draw_icon_imasel(void) +{ + scrarea_queue_winredraw(curarea); +} + +void winqreadimasel(unsigned short event, short val, char ascii) +{ + SpaceImaSel *simasel; + + short mval[2]; + short area_event; + short queredraw = 0; + char name[256]; + char *selname; + static double prevtime=0; + + + if(val==0) return; + simasel= curarea->spacedata.first; + + area_event = 0; + getmouseco_areawin(mval); + simasel->mx= mval[0]; + simasel->my= mval[1]; + + if (simasel->desx > 0){ + if ( (mval[0] > simasel->dssx) && (mval[0] < simasel->dsex) && (mval[1] > simasel->dssy) && (mval[1] < simasel->dsey) ) area_event = IMS_INDIRSLI; + if ( (mval[0] > simasel->desx) && (mval[0] < simasel->deex) && (mval[1] > simasel->desy) && (mval[1] < simasel->deey) ) area_event = IMS_INDIR; + } + if (simasel->fesx > 0){ + if ( (mval[0] > simasel->fssx) && (mval[0] < simasel->fsex) && (mval[1] > simasel->fssy) && (mval[1] < simasel->fsey) ) area_event = IMS_INFILESLI; + if ( (mval[0] > simasel->fesx) && (mval[0] < simasel->feex) && (mval[1] > simasel->fesy) && (mval[1] < simasel->feey) ) area_event = IMS_INFILE; + } + + if( event!=RETKEY && event!=PADENTER) + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) { + case AFTERPIBREAD: + get_pib_file(simasel); + queredraw = 1; + break; + + case AFTERIMASELIMA: + if (bitset(simasel->fase, IMS_DOTHE_INF)){ + get_file_info(simasel); + + if (!bitset(simasel->fase, IMS_KNOW_INF)){ + addafterqueue(curarea->win, AFTERIMASELIMA, 1); + + }else{ + simasel->subfase = 0; + simasel->imafase = 0; + simasel->fase |= IMS_DOTHE_IMA; + addafterqueue(curarea->win, AFTERIMASELGET, 1); + } + } + break; + case AFTERIMASELGET: + if (bitset(simasel->fase, IMS_DOTHE_IMA)){ + get_next_image(simasel); + if (simasel->ima_redraw > 0){ + double newtime = PIL_check_seconds_timer(); + if ((newtime - prevtime) > 0.03) { + simasel->ima_redraw = 0; + queredraw = 1; + prevtime = newtime; + } + + } + if (!bitset(simasel->fase, IMS_KNOW_IMA)){ + addafterqueue(curarea->win, AFTERIMASELGET, 1); + }else{ + simasel->ima_redraw = 0; + simasel->subfase = 0; + simasel->imafase = 0; + addqueue(curarea->win, AFTERIMAWRITE, 1); + queredraw = 1; + } + } + break; + case AFTERIMAWRITE: + if (bitset(simasel->fase, IMS_KNOW_IMA)){ + write_new_pib(simasel); + queredraw = 1; + } + break; + + case RIGHTMOUSE: + if ((area_event == IMS_INFILE) && (simasel->hilite_ima)){ + select_ima_files(simasel); + queredraw = 1; + } + break; + case UI_BUT_EVENT: + + /* bug: blender's interface kit also returns a '4'... what is it! */ + + switch(val) { + case 13: /* 'P' */ + imadir_parent(simasel); + queredraw = 1; + + case 1: /* dir entry */ + checkdir(simasel->dir); + clear_ima_dir(simasel); + queredraw = 1; + break; + + case 3: /* fsmenu */ + selname= fsmenu_get_entry(simasel->fileselmenuitem-1); + if (selname) { + strcpy(simasel->dir, selname); + checkdir(simasel->dir); + clear_ima_dir(simasel); + queredraw = 1; + } + break; + + case 5: + if (simasel->returnfunc) { + char name[256]; + strcpy(name, simasel->dir); + strcat(name, simasel->file); + simasel->returnfunc(name); + filesel_prevspace(); + } + break; + case 6: + filesel_prevspace(); + break; + + } + break; + + case LEFTMOUSE: + case MIDDLEMOUSE: + + /* No button pressed */ + switch (area_event){ + case IMS_INDIRSLI: + move_imadir_sli(simasel); + queredraw = 1; + break; + case IMS_INFILESLI: + move_imafile_sli(simasel); + queredraw = 1; + break; + case IMS_INDIR: + if (simasel->hilite > -1){ + change_imadir(simasel); + queredraw = 1; + } + break; + case IMS_INFILE: + if (simasel->hilite_ima){ + strcpy(simasel->fole, simasel->hilite_ima->file_name); + strcpy(simasel->file, simasel->hilite_ima->file_name); + + if (event == LEFTMOUSE) addqueue(curarea->win, IMALEFTMOUSE, 1); + + if ((event == MIDDLEMOUSE)&&(simasel->returnfunc)){ + strcpy(name, simasel->dir); + strcat(name, simasel->file); + + if(simasel->mode & IMS_STRINGCODE) BLI_makestringcode(G.sce, name); + + simasel->returnfunc(name); + filesel_prevspace(); + } + queredraw = 1; + } + break; + } + break; + + case MOUSEX: + case MOUSEY: + getmouseco_areawin(mval); /* lokaal screen */ + calc_hilite(simasel); + if (simasel->mouse_move_redraw ){ + simasel->mouse_move_redraw = 0; + queredraw = 1; + } + break; + + case PAGEUPKEY: + case PAGEDOWNKEY: + switch(area_event){ + case IMS_INDIRSLI: + case IMS_INDIR: + if (simasel->dirsli){ + if (event == PAGEUPKEY) simasel->topdir -= (simasel->dirsli_lines - 1); + if (event == PAGEDOWNKEY) simasel->topdir += (simasel->dirsli_lines - 1); + queredraw = 1; + } + break; + case IMS_INFILESLI: + case IMS_INFILE: + if(simasel->imasli){ + if (event == PAGEUPKEY) simasel->image_slider -= simasel->slider_height; + if (event == PAGEDOWNKEY) simasel->image_slider += simasel->slider_height; + + if(simasel->image_slider < 0.0) simasel->image_slider = 0.0; + if(simasel->image_slider > 1.0) simasel->image_slider = 1.0; + queredraw = 1; + } + break; + } + break; + + case HOMEKEY: + simasel->image_slider = 0.0; + queredraw = 1; + break; + + case ENDKEY: + simasel->image_slider = 1.0; + queredraw = 1; + break; + + case AKEY: + if (G.qual == 0){ + ima_select_all(simasel); + queredraw = 1; + } + break; + + case PKEY: + if(G.qual & LR_SHIFTKEY) { + extern char bprogname[]; /* usiblender.c */ + + sprintf(name, "%s -a \"%s%s\"", bprogname, simasel->dir, simasel->file); + system(name); + } + if(G.qual & LR_CTRLKEY) { + if(bitset(simasel->fase, IMS_KNOW_IMA)) pibplay(simasel); + } + if (G.qual == 0){ + imadir_parent(simasel); + checkdir(simasel->dir); + clear_ima_dir(simasel); + queredraw = 1; + } + break; + + case IKEY: + if ((G.qual == 0)&&(simasel->file)){ + sprintf(name, "$IMAGEEDITOR %s%s", simasel->dir, simasel->file); + system(name); + queredraw = 1; + } + + break; + + case PADPLUSKEY: + case EQUALKEY: + BLI_newname(simasel->file, +1); + queredraw = 1; + break; + + case PADMINUS: + case MINUSKEY: + BLI_newname(simasel->file, -1); + queredraw = 1; + break; + + case BACKSLASHKEY: + case SLASHKEY: +#ifdef WIN32 + strcpy(simasel->dir, "\\"); +#else + strcpy(simasel->dir, "/"); +#endif + clear_ima_dir(simasel); + simasel->image_slider = 0.0; + queredraw = 1; + break; + + case PERIODKEY: + clear_ima_dir(simasel); + queredraw = 1; + break; + + case ESCKEY: + filesel_prevspace(); + break; + + case PADENTER: + case RETKEY: + if (simasel->returnfunc){ + strcpy(name, simasel->dir); + strcat(name, simasel->file); + simasel->returnfunc(name); + filesel_prevspace(); + } + break; + } + + + if (queredraw) scrarea_queue_winredraw(curarea); +} + + diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c new file mode 100644 index 00000000000..163bf0132c8 --- /dev/null +++ b/source/blender/src/editipo.c @@ -0,0 +1,5212 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <string.h> +#include <math.h> +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" +#include "PIL_time.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_constraint_types.h" +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_object_types.h" +#include "DNA_lamp_types.h" +#include "DNA_sequence_types.h" +#include "DNA_sound_types.h" +#include "DNA_camera_types.h" +#include "DNA_material_types.h" +#include "DNA_key_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_ipo_types.h" +#include "DNA_curve_types.h" +#include "DNA_space_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view3d_types.h" +#include "DNA_group_types.h" +#include "DNA_ika_types.h" + +#include "BKE_utildefines.h" +#include "BKE_action.h" +#include "BKE_anim.h" +#include "BKE_material.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_ika.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_group.h" + +#include "BIF_buttons.h" +#include "BIF_editkey.h" +#include "BIF_editseq.h" +#include "BIF_editview.h" +#include "BIF_interface.h" +#include "BIF_mywindow.h" +#include "BIF_poseobject.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_toolbox.h" +#include "BIF_poseobject.h" + +#include "BDR_drawobject.h" +#include "BDR_editobject.h" + +#include "BSE_trans_types.h" +#include "BSE_editipo_types.h" +#include "BSE_drawipo.h" +#include "BSE_editipo.h" +#include "BSE_editaction.h" +#include "BSE_edit.h" +#include "BSE_drawview.h" +#include "BSE_headerbuttons.h" + +#include "blendef.h" +#include "mydevice.h" +#include "interface.h" +#include "render.h" + +/* forwards */ +#define BEZSELECTED(bezt) (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1)) + +#define IPOTHRESH 0.9 +#define ISPOIN(a, b, c) ( (a->b) && (a->c) ) +#define ISPOIN3(a, b, c, d) ( (a->b) && (a->c) && (a->d) ) +#define ISPOIN4(a, b, c, d, e) ( (a->b) && (a->c) && (a->d) && (a->e) ) + +extern int ob_ar[]; +extern int ma_ar[]; +extern int seq_ar[]; +extern int cu_ar[]; +extern int key_ar[]; +extern int wo_ar[]; +extern int la_ar[]; +extern int cam_ar[]; +extern int snd_ar[]; +extern int ac_ar[]; +extern int co_ar[]; + +void getname_ac_ei(int nr, char *str) +{ + switch(nr) { + case AC_LOC_X: + strcpy(str, "LocX"); break; + case AC_LOC_Y: + strcpy(str, "LocY"); break; + case AC_LOC_Z: + strcpy(str, "LocZ"); break; + case AC_SIZE_X: + strcpy(str, "SizeX"); break; + case AC_SIZE_Y: + strcpy(str, "SizeY"); break; + case AC_SIZE_Z: + strcpy(str, "SizeZ"); break; + case AC_QUAT_X: + strcpy(str, "QuatX"); break; + case AC_QUAT_Y: + strcpy(str, "QuatY"); break; + case AC_QUAT_Z: + strcpy(str, "QuatZ"); break; + case AC_QUAT_W: + strcpy(str, "QuatW"); break; + default: + str[0]= 0; + } +} + +void getname_co_ei(int nr, char *str) +{ + switch(nr){ + case CO_ENFORCE: + strcpy(str, "Inf"); break; + } +} + +void getname_ob_ei(int nr, char *str, int colipo) +{ + switch(nr) { + case OB_LOC_X: + strcpy(str, "LocX"); break; + case OB_LOC_Y: + strcpy(str, "LocY"); break; + case OB_LOC_Z: + strcpy(str, "LocZ"); break; + case OB_DLOC_X: + strcpy(str, "dLocX"); break; + case OB_DLOC_Y: + strcpy(str, "dLocY"); break; + case OB_DLOC_Z: + strcpy(str, "dLocZ"); break; + + case OB_ROT_X: + strcpy(str, "RotX"); break; + case OB_ROT_Y: + strcpy(str, "RotY"); break; + case OB_ROT_Z: + strcpy(str, "RotZ"); break; + case OB_DROT_X: + strcpy(str, "dRotX"); break; + case OB_DROT_Y: + strcpy(str, "dRotY"); break; + case OB_DROT_Z: + strcpy(str, "dRotZ"); break; + + case OB_SIZE_X: + strcpy(str, "SizeX"); break; + case OB_SIZE_Y: + strcpy(str, "SizeY"); break; + case OB_SIZE_Z: + strcpy(str, "SizeZ"); break; + case OB_DSIZE_X: + strcpy(str, "dSizeX"); break; + case OB_DSIZE_Y: + strcpy(str, "dSizeY"); break; + case OB_DSIZE_Z: + strcpy(str, "dSizeZ"); break; + + case OB_LAY: + strcpy(str, "Layer"); break; + + case OB_TIME: + strcpy(str, "Time"); break; + case OB_EFF_X: + if(colipo) strcpy(str, "ColR"); + else strcpy(str, "EffX"); + break; + case OB_EFF_Y: + if(colipo) strcpy(str, "ColG"); + else strcpy(str, "EffY"); + break; + case OB_EFF_Z: + if(colipo) strcpy(str, "ColB"); + else strcpy(str, "EffZ"); + break; + case OB_COL_A: + strcpy(str, "ColA"); + break; + default: + str[0]= 0; + } +} + +void getname_tex_ei(int nr, char *str) +{ + switch(nr) { + case MAP_OFS_X: + strcpy(str, "OfsX"); break; + case MAP_OFS_Y: + strcpy(str, "OfsY"); break; + case MAP_OFS_Z: + strcpy(str, "OfsZ"); break; + case MAP_SIZE_X: + strcpy(str, "SizeX"); break; + case MAP_SIZE_Y: + strcpy(str, "SizeY"); break; + case MAP_SIZE_Z: + strcpy(str, "SizeZ"); break; + case MAP_R: + strcpy(str, "texR"); break; + case MAP_G: + strcpy(str, "texG"); break; + case MAP_B: + strcpy(str, "texB"); break; + case MAP_DVAR: + strcpy(str, "DefVar"); break; + case MAP_COLF: + strcpy(str, "Col"); break; + case MAP_NORF: + strcpy(str, "Nor"); break; + case MAP_VARF: + strcpy(str, "Var"); break; + default: + str[0]= 0; + } +} + +void getname_mat_ei(int nr, char *str) +{ + if(nr>=MA_MAP1) getname_tex_ei((nr & (MA_MAP1-1)), str); + else { + switch(nr) { + case MA_COL_R: + strcpy(str, "R"); break; + case MA_COL_G: + strcpy(str, "G"); break; + case MA_COL_B: + strcpy(str, "B"); break; + case MA_SPEC_R: + strcpy(str, "SpecR"); break; + case MA_SPEC_G: + strcpy(str, "SpecG"); break; + case MA_SPEC_B: + strcpy(str, "SpecB"); break; + case MA_MIR_R: + strcpy(str, "MirR"); break; + case MA_MIR_G: + strcpy(str, "MirG"); break; + case MA_MIR_B: + strcpy(str, "MirB"); break; + case MA_REF: + strcpy(str, "Ref"); break; + case MA_ALPHA: + strcpy(str, "Alpha"); break; + case MA_EMIT: + strcpy(str, "Emit"); break; + case MA_AMB: + strcpy(str, "Amb"); break; + case MA_SPEC: + strcpy(str, "Spec"); break; + case MA_HARD: + strcpy(str, "Hard"); break; + case MA_SPTR: + strcpy(str, "SpTra"); break; + case MA_ANG: + strcpy(str, "Ang"); break; + case MA_MODE: + strcpy(str, "Mode"); break; + case MA_HASIZE: + strcpy(str, "HaSize"); break; + default: + str[0]= 0; + } + } +} + +void getname_world_ei(int nr, char *str) +{ + if(nr>=MA_MAP1) getname_tex_ei((nr & (MA_MAP1-1)), str); + else { + switch(nr) { + case WO_HOR_R: + strcpy(str, "HorR"); break; + case WO_HOR_G: + strcpy(str, "HorG"); break; + case WO_HOR_B: + strcpy(str, "HorB"); break; + case WO_ZEN_R: + strcpy(str, "ZenR"); break; + case WO_ZEN_G: + strcpy(str, "ZenG"); break; + case WO_ZEN_B: + strcpy(str, "ZenB"); break; + + case WO_EXPOS: + strcpy(str, "Expos"); break; + + case WO_MISI: + strcpy(str, "Misi"); break; + case WO_MISTDI: + strcpy(str, "MisDi"); break; + case WO_MISTSTA: + strcpy(str, "MisSta"); break; + case WO_MISTHI: + strcpy(str, "MisHi"); break; + + case WO_STAR_R: + strcpy(str, "StarR"); break; + case WO_STAR_G: + strcpy(str, "StarB"); break; + case WO_STAR_B: + strcpy(str, "StarG"); break; + + case WO_STARDIST: + strcpy(str, "StarDi"); break; + case WO_STARSIZE: + strcpy(str, "StarSi"); break; + default: + str[0]= 0; + } + } +} + +void getname_seq_ei(int nr, char *str) +{ + switch(nr) { + case SEQ_FAC1: + strcpy(str, "Fac"); break; + default: + str[0]= 0; + } +} + +void getname_cu_ei(int nr, char *str) +{ + + switch(nr) { + case CU_SPEED: + strcpy(str, "Speed"); break; + default: + str[0]= 0; + } +} + +void getname_key_ei(int nr, char *str) +{ + if(nr==KEY_SPEED) strcpy(str, "Speed"); + else sprintf(str, "Key %d", nr); +} + +void getname_la_ei(int nr, char *str) +{ + if(nr>=MA_MAP1) getname_tex_ei((nr & (MA_MAP1-1)), str); + else { + switch(nr) { + case LA_ENERGY: + strcpy(str, "Energ"); break; + case LA_COL_R: + strcpy(str, "R"); break; + case LA_COL_G: + strcpy(str, "G"); break; + case LA_COL_B: + strcpy(str, "B"); break; + case LA_DIST: + strcpy(str, "Dist"); break; + case LA_SPOTSI: + strcpy(str, "SpoSi"); break; + case LA_SPOTBL: + strcpy(str, "SpoBl"); break; + case LA_QUAD1: + strcpy(str, "Quad1"); break; + case LA_QUAD2: + strcpy(str, "Quad2"); break; + case LA_HALOINT: + strcpy(str, "HaInt"); break; + default: + str[0]= 0; + } + } +} + +void getname_cam_ei(int nr, char *str) +{ + switch(nr) { + case CAM_LENS: + strcpy(str, "Lens"); break; + case CAM_STA: + strcpy(str, "ClSta"); break; + case CAM_END: + strcpy(str, "ClEnd"); break; + default: + str[0]= 0; + } +} + +void getname_snd_ei(int nr, char *str) +{ + switch(nr) { + case SND_VOLUME: + strcpy(str, "Vol"); break; + case SND_PITCH: + strcpy(str, "Pitch"); break; + case SND_PANNING: + strcpy(str, "Pan"); break; + case SND_ATTEN: + strcpy(str, "Atten"); break; + default: + str[0]= 0; + } +} + + +IpoCurve *find_ipocurve(Ipo *ipo, int adrcode) +{ + if(ipo) { + IpoCurve *icu= ipo->curve.first; + while(icu) { + if(icu->adrcode==adrcode) return icu; + icu= icu->next; + } + } + return NULL; +} + +void boundbox_ipocurve(IpoCurve *icu) +{ + BezTriple *bezt; + float vec[3]={0.0,0.0,0.0}; + float min[3], max[3]; + int a; + + if(icu->totvert) { + INIT_MINMAX(min, max); + + if(icu->bezt ) { + a= icu->totvert; + bezt= icu->bezt; + while(a--) { + if(icu->vartype & IPO_BITS) { + vec[0]= bezt->vec[1][0]; + vec[1]= 0.0; + DO_MINMAX(vec, min, max); + + vec[1]= 16.0; + DO_MINMAX(vec, min, max); + } + else { + if(icu->ipo==IPO_BEZ && a!=icu->totvert-1) { + DO_MINMAX(bezt->vec[0], min, max); + } + DO_MINMAX(bezt->vec[1], min, max); + if(icu->ipo==IPO_BEZ && a!=0) { + DO_MINMAX(bezt->vec[2], min, max); + } + } + + bezt++; + } + } + if(min[0]==max[0]) max[0]= (float)(min[0]+1.0); + if(min[1]==max[1]) max[1]= (float)(min[1]+0.1); + + icu->totrct.xmin= min[0]; + icu->totrct.ymin= min[1]; + icu->totrct.xmax= max[0]; + icu->totrct.ymax= max[1]; + } + else { + icu->totrct.xmin= icu->totrct.ymin= 0.0; + icu->totrct.xmax= EFRA; + icu->totrct.ymax= 1.0; + } +} + +void boundbox_ipo(Ipo *ipo, rctf *bb) +{ + IpoCurve *icu; + int first= 1; + + icu= ipo->curve.first; + while(icu) { + + boundbox_ipocurve(icu); + + if(first) { + *bb= icu->totrct; + first= 0; + } + else BLI_union_rctf(bb, &(icu->totrct)); + + icu= icu->next; + } +} + + + +void editipo_changed(SpaceIpo *si, int doredraw) +{ + EditIpo *ei; + View2D *v2d; + Key *key; + KeyBlock *kb; + int a, first=1; + + + ei= si->editipo; + if(ei==0) + return; + + for(a=0; a<si->totipo; a++, ei++) { + + if(ei->icu) { + + /* 2 keer i.v.m. ittereren nieuwe autohandle */ + calchandles_ipocurve(ei->icu); + calchandles_ipocurve(ei->icu); + + if(ei->flag & IPO_VISIBLE) { + + boundbox_ipocurve(ei->icu); + sort_time_ipocurve(ei->icu); + if(first) { + si->v2d.tot= ei->icu->totrct; + first= 0; + } + else BLI_union_rctf(&(si->v2d.tot), &(ei->icu->totrct)); + } + } + } + + v2d= &(si->v2d); +// v2d = &G.v2d; + + /* keylijnen? */ + if(si->blocktype==ID_KE) { + key= (Key *)si->from; + if(key && key->block.first) { + kb= key->block.first; + if(kb->pos < v2d->tot.ymin) v2d->tot.ymin= kb->pos; + kb= key->block.last; + if(kb->pos > v2d->tot.ymax) v2d->tot.ymax= kb->pos; + } + } + + + /* is er geen curve? */ + if(first) { + v2d->tot.xmin= 0.0; + v2d->tot.xmax= EFRA; + v2d->tot.ymin= (float)-0.1; + v2d->tot.ymax= (float)1.1; + + if(si->blocktype==ID_SEQ) { + v2d->tot.xmin= -5.0; + v2d->tot.xmax= 105.0; + v2d->tot.ymin= (float)-0.1; + v2d->tot.ymax= (float)1.1; + } + } + + si->tot= v2d->tot; + + if(doredraw) { + /* als do_ipo altijd wordt aangeroepen: problemen met insertkey, bijvoorbeeld + * als alleen een 'loc' wordt ge-insert wordt de 'ob->rot' veranderd. + */ + + + if(si->blocktype==ID_OB) { + /* clear delta loc,rot,size (bij ipo vrijgeven/deleten) */ + clear_delta_obipo(si->ipo); + + } + + do_ipo(si->ipo); + + allqueue(REDRAWIPO, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWBUTSANIM, 0); + + if(si->blocktype==ID_OB) { + Object *ob= (Object *)si->from; + if(ob && ob->type==OB_IKA) itterate_ika(ob); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWNLA, 0); + } + + else if(si->blocktype==ID_MA) allqueue(REDRAWBUTSMAT, 0); + else if(si->blocktype==ID_WO) allqueue(REDRAWBUTSWORLD, 0); + else if(si->blocktype==ID_LA) allqueue(REDRAWBUTSLAMP, 0); + else if(si->blocktype==ID_SO) allqueue(REDRAWBUTSSOUND, 0); + else if(si->blocktype==ID_CA) { + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); + } + else if(si->blocktype==ID_SEQ) clear_last_seq(); + else if(si->blocktype==ID_AC){ + do_all_actions(); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + else if(si->blocktype==ID_KE) { + do_spec_key((Key *)si->from); + allqueue(REDRAWVIEW3D, 0); + } + else if(si->blocktype==ID_CU) { + calc_curvepath(OBACT); + allqueue(REDRAWVIEW3D, 0); + } + } + + if(si->showkey) make_ipokey(); +} + +void scale_editipo() +{ + /* komt uit buttons, scale met G.sipo->tot rect */ + + EditIpo *ei; + BezTriple *bezt; + float facx, facy; + int a, b; + + facx= (G.sipo->tot.xmax-G.sipo->tot.xmin)/(G.sipo->v2d.tot.xmax-G.sipo->v2d.tot.xmin); + facy= (G.sipo->tot.ymax-G.sipo->tot.ymin)/(G.sipo->v2d.tot.ymax-G.sipo->v2d.tot.ymin); + + ei= G.sipo->editipo; + if(ei==0) return; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + + bezt->vec[0][0]= facx*(bezt->vec[0][0] - G.sipo->v2d.tot.xmin) + G.sipo->tot.xmin; + bezt->vec[1][0]= facx*(bezt->vec[1][0] - G.sipo->v2d.tot.xmin) + G.sipo->tot.xmin; + bezt->vec[2][0]= facx*(bezt->vec[2][0] - G.sipo->v2d.tot.xmin) + G.sipo->tot.xmin; + + bezt->vec[0][1]= facy*(bezt->vec[0][1] - G.sipo->v2d.tot.ymin) + G.sipo->tot.ymin; + bezt->vec[1][1]= facy*(bezt->vec[1][1] - G.sipo->v2d.tot.ymin) + G.sipo->tot.ymin; + bezt->vec[2][1]= facy*(bezt->vec[2][1] - G.sipo->v2d.tot.ymin) + G.sipo->tot.ymin; + + bezt++; + } + } + } + editipo_changed(G.sipo, 1); + allqueue(REDRAWNLA, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); +} + + +Ipo *get_ipo_to_edit(ID **from) +{ + Object *ob= OBACT; + + *from= 0; + + + if (G.sipo->pin) { + *from = G.sipo->from; + return G.sipo->ipo; + } + + if(G.sipo->blocktype==ID_SEQ) { + extern Sequence *last_seq; + + *from= (ID *)last_seq; + if(last_seq) return last_seq->ipo; + } + else if(G.sipo->blocktype==IPO_CO){ + if (ob && ob->activecon){ + *from= (ID*) ob; + return ob->activecon->ipo; + } + } + else if(G.sipo->blocktype==ID_AC) { + bActionChannel *chan; + if (ob && ob->action){ + *from= (ID *) ob->action; + chan= get_hilighted_action_channel(ob->action); + if (chan) + return chan->ipo; + else{ + *from = NULL; + return NULL; + } + } + + } + else if(G.sipo->blocktype==ID_WO) { + World *wo= G.scene->world; + *from= (ID *)wo; + if(wo) return wo->ipo; + } + else if(G.sipo->blocktype==ID_OB) { + if(ob) { + *from= (ID *)ob; + return ob->ipo; + } + } + else if(G.sipo->blocktype==ID_MA) { + if(ob) { + Material *ma= give_current_material(ob, ob->actcol); + *from= (ID *)ma; + if(ma) return ma->ipo; + } + } + else if(G.sipo->blocktype==ID_KE) { + if(ob) { + Key *key= give_current_key(ob); + *from= (ID *)key; + if(key) return key->ipo; + } + } + else if(G.sipo->blocktype==ID_CU) { + if(ob && ob->type==OB_CURVE) { + Curve *cu= ob->data; + *from= (ID *)cu; + return cu->ipo; + } + } + else if(G.sipo->blocktype==ID_LA) { + if(ob && ob->type==OB_LAMP) { + Lamp *la= ob->data; + *from= (ID *)la; + return la->ipo; + } + } + else if(G.sipo->blocktype==ID_CA) { + if(ob && ob->type==OB_CAMERA) { + Camera *ca= ob->data; + *from= (ID *)ca; + if(ca) return ca->ipo; + } + } + else if(G.sipo->blocktype==ID_SO) { + + if (G.buts && G.buts->mainb == BUTS_SOUND) { + + bSound *sound = G.buts->lockpoin; + + *from= (ID *)sound; + + if(sound) return sound->ipo; + + } + } + + return NULL; +} + +unsigned int ipo_rainbow(int cur, int tot) +{ + float dfac, fac, sat; + + dfac= (float)(1.0/( (float)tot+1.0)); + + /* deze berekening zorgt voor twee verschillende cycles regenboogkleuren */ + if(cur< tot/2) fac= (float)(cur*2.0*dfac); + else fac= (float)((cur-tot/2)*2.0*dfac +dfac); + + if(fac>0.5 && fac<0.8) sat= (float)0.4; + else sat= 0.5; + + return hsv_to_cpack(fac, sat, 1.0); +} + +void make_ob_editipo(Object *ob, SpaceIpo *si) +{ + EditIpo *ei; + int a, len, colipo=0; + + if(ob->type==OB_MESH) colipo= 1; + + ei= si->editipo= MEM_callocN(OB_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= OB_TOTIPO; + + for(a=0; a<OB_TOTIPO; a++) { + getname_ob_ei(ob_ar[a], ei->name, colipo); + ei->adrcode= ob_ar[a]; + + if ELEM6(ei->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z, OB_DROT_X, OB_DROT_Y, OB_DROT_Z) ei->disptype= IPO_DISPDEGR; + else if(ei->adrcode==OB_LAY) ei->disptype= IPO_DISPBITS; + else if(ei->adrcode==OB_TIME) ei->disptype= IPO_DISPTIME; + + ei->col= ipo_rainbow(a, OB_TOTIPO); + + if(colipo) { + len= strlen(ei->name); + if(len) { + if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF; + else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50; + else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050; + } + } + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + + +void make_seq_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(SEQ_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= SEQ_TOTIPO; + + + for(a=0; a<SEQ_TOTIPO; a++) { + getname_seq_ei(seq_ar[a], ei->name); + ei->adrcode= seq_ar[a]; + + ei->col= ipo_rainbow(a, SEQ_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + else ei->flag |= IPO_VISIBLE; + + ei++; + } +} + +void make_cu_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(CU_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= CU_TOTIPO; + + + for(a=0; a<CU_TOTIPO; a++) { + getname_cu_ei(cu_ar[a], ei->name); + ei->adrcode= cu_ar[a]; + + ei->col= ipo_rainbow(a, CU_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + else ei->flag |= IPO_VISIBLE; + + ei++; + } +} + +void make_key_editipo(SpaceIpo *si) +{ + Key *key; + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(KEY_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= KEY_TOTIPO; + + for(a=0; a<KEY_TOTIPO; a++) { + getname_key_ei(key_ar[a], ei->name); + ei->adrcode= key_ar[a]; + + ei->col= ipo_rainbow(a, KEY_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + else if(a==0) ei->flag |= IPO_VISIBLE; + + ei++; + } + + ei= si->editipo; + key= (Key *)G.sipo->from; + if(key && key->type==KEY_RELATIVE) { + strcpy(ei->name, "----"); + } + else { + ei->flag |= IPO_VISIBLE; + } +} + +int texchannel_to_adrcode(int channel) +{ + switch(channel) { + case 0: return MA_MAP1; + case 1: return MA_MAP2; + case 2: return MA_MAP3; + case 3: return MA_MAP4; + case 4: return MA_MAP5; + case 5: return MA_MAP6; + case 6: return MA_MAP7; + case 7: return MA_MAP8; + default: return 0; + } +} + +void make_mat_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a, len; + + if(si->from==0) return; + + ei= si->editipo= MEM_callocN(MA_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= MA_TOTIPO; + + for(a=0; a<MA_TOTIPO; a++) { + getname_mat_ei(ma_ar[a], ei->name); + ei->adrcode= ma_ar[a]; + + if(ei->adrcode & MA_MAP1) { + ei->adrcode-= MA_MAP1; + ei->adrcode |= texchannel_to_adrcode(si->channel); + } + else { + /* dit was weggecommentaard. Waarom? */ + if(ei->adrcode==MA_MODE) ei->disptype= IPO_DISPBITS; + } + + ei->col= ipo_rainbow(a, WO_TOTIPO); + + len= strlen(ei->name); + if(len) { + if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF; + else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50; + else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050; + } + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + +void make_world_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a, len; + + if(si->from==0) return; + + ei= si->editipo= MEM_callocN(WO_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= WO_TOTIPO; + + for(a=0; a<WO_TOTIPO; a++) { + getname_world_ei(wo_ar[a], ei->name); + ei->adrcode= wo_ar[a]; + + if(ei->adrcode & MA_MAP1) { + ei->adrcode-= MA_MAP1; + ei->adrcode |= texchannel_to_adrcode(si->channel); + } + else { + if(ei->adrcode==MA_MODE) ei->disptype= IPO_DISPBITS; + } + + ei->col= ipo_rainbow(a, MA_TOTIPO); + + len= strlen(ei->name); + if(len) { + if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF; + else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50; + else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050; + } + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + +void make_lamp_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(LA_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= LA_TOTIPO; + + + for(a=0; a<LA_TOTIPO; a++) { + getname_la_ei(la_ar[a], ei->name); + ei->adrcode= la_ar[a]; + + if(ei->adrcode & MA_MAP1) { + ei->adrcode-= MA_MAP1; + ei->adrcode |= texchannel_to_adrcode(si->channel); + } + + ei->col= ipo_rainbow(a, LA_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + +void make_camera_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(CAM_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= CAM_TOTIPO; + + + for(a=0; a<CAM_TOTIPO; a++) { + getname_cam_ei(cam_ar[a], ei->name); + ei->adrcode= cam_ar[a]; + + ei->col= ipo_rainbow(a, CAM_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + +int make_constraint_editipo(Ipo *ipo, EditIpo **si) +{ + EditIpo *ei; + int a; + + ei= *si= MEM_callocN(CO_TOTIPO*sizeof(EditIpo), "editipo"); + + for(a=0; a<CO_TOTIPO; a++) { + getname_co_ei(co_ar[a], ei->name); + ei->adrcode= co_ar[a]; + + ei->col= ipo_rainbow(a, CO_TOTIPO); + + ei->icu= find_ipocurve(ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } + + return CO_TOTIPO; +} +int make_action_editipo(Ipo *ipo, EditIpo **si) +{ + EditIpo *ei; + int a; + + ei= *si= MEM_callocN(AC_TOTIPO*sizeof(EditIpo), "editipo"); + + for(a=0; a<AC_TOTIPO; a++) { + getname_ac_ei(ac_ar[a], ei->name); + ei->adrcode= ac_ar[a]; + + ei->col= ipo_rainbow(a, AC_TOTIPO); + + ei->icu= find_ipocurve(ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } + + return AC_TOTIPO; +} + +void make_sound_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(SND_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= SND_TOTIPO; + + + for(a=0; a<SND_TOTIPO; a++) { + getname_snd_ei(snd_ar[a], ei->name); + ei->adrcode= snd_ar[a]; + + ei->col= ipo_rainbow(a, SND_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + +void make_editipo() +{ + EditIpo *ei; + Object *ob; + ID *from; + rctf *rf; + int a; + + if(G.sipo->editipo) + MEM_freeN(G.sipo->editipo); + G.sipo->editipo= 0; + G.sipo->totipo= 0; + ob= OBACT; + + G.sipo->ipo= get_ipo_to_edit(&from); + G.sipo->from= from; + + if(G.sipo->ipo) G.sipo->showkey= G.sipo->ipo->showkey; + + if(G.sipo->blocktype==ID_SEQ) { + make_seq_editipo(G.sipo); + } + else if(G.sipo->blocktype==ID_WO) { + make_world_editipo(G.sipo); + } + else if(G.sipo->blocktype==ID_OB) { + if (ob) { + ob->ipowin= ID_OB; + make_ob_editipo(ob, G.sipo); + } + } + else if(G.sipo->blocktype==ID_MA) { + if (ob) { + ob->ipowin= ID_MA; + make_mat_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==ID_CU) { + if (ob) { + ob->ipowin= ID_CU; + make_cu_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==ID_KE) { + if (ob) { + ob->ipowin= ID_KE; + make_key_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==ID_LA) { + if (ob) { + ob->ipowin= ID_LA; + make_lamp_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==ID_CA) { + if (ob) { + ob->ipowin= ID_CA; + make_camera_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==ID_SO) { + if (ob) { + ob->ipowin= ID_SO; + make_sound_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==IPO_CO){ + G.sipo->totipo = make_constraint_editipo(G.sipo->ipo, (EditIpo**)&G.sipo->editipo); + if (ob) { + ob->ipowin= IPO_CO; + } + } + else if(G.sipo->blocktype==ID_AC) { + + G.sipo->totipo = make_action_editipo(G.sipo->ipo, (EditIpo**)&G.sipo->editipo); + if (ob) { + ob->ipowin= ID_AC; + } + } + + if(G.sipo->editipo==0) return; + + /* rowbut voor VISIBLE select */ + G.sipo->rowbut= 0; + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + if(ei->flag & IPO_VISIBLE) G.sipo->rowbut |= (1<<a); + + if(ei->icu) ei->icu->flag= ei->flag; + } + editipo_changed(G.sipo, 0); + + if(G.sipo->ipo) { + + if (G.sipo->pin) + rf= &(G.sipo->v2d.cur); + else + rf= &(G.sipo->ipo->cur); + + if(rf->xmin<rf->xmax && rf->ymin<rf->ymax) G.v2d->cur= *rf; + + } + else { + if(G.sipo->blocktype==ID_OB) { + G.v2d->cur.xmin= 0.0; + G.v2d->cur.xmax= EFRA; + G.v2d->cur.ymin= -5.0; + G.v2d->cur.ymax= +5.0; + } + else if(G.sipo->blocktype==ID_CA) { + G.v2d->cur.xmin= 0.0; + G.v2d->cur.xmax= EFRA; + G.v2d->cur.ymin= 0.0; + G.v2d->cur.ymax= 100.0; + } + else if ELEM5(G.sipo->blocktype, ID_MA, ID_CU, ID_WO, ID_LA, IPO_CO) { + G.v2d->cur.xmin= (float)-0.1; + G.v2d->cur.xmax= EFRA; + G.v2d->cur.ymin= (float)-0.1; + G.v2d->cur.ymax= (float)+1.1; + } + else if(G.sipo->blocktype==ID_SEQ) { + G.v2d->cur.xmin= -5.0; + G.v2d->cur.xmax= 105.0; + G.v2d->cur.ymin= (float)-0.1; + G.v2d->cur.ymax= (float)+1.1; + } + else if(G.sipo->blocktype==ID_KE) { + G.v2d->cur.xmin= (float)-0.1; + G.v2d->cur.xmax= EFRA; + G.v2d->cur.ymin= (float)-0.1; + G.v2d->cur.ymax= (float)+2.1; + } + + } +} + + +void test_editipo() +{ + Ipo *ipo; + ID *from; + + if(G.sipo->editipo==0){ + make_editipo(); + } + else { + ipo= get_ipo_to_edit(&from); + + if(G.sipo->ipo != ipo || G.sipo->from!=from) + make_editipo(); + + } + + if (G.sipo->pin) + return; + + + if(G.sipo->ipo) + G.sipo->ipo->cur = G.v2d->cur; + +} + +/* ****************************************** */ + +int totipo_edit, totipo_sel, totipo_vis, totipo_vert, totipo_vertsel, totipo_key, totipo_keysel; + +void get_status_editipo() +{ + EditIpo *ei; + IpoKey *ik; + BezTriple *bezt; + int a, b; + + totipo_vis= 0; + totipo_sel= 0; + totipo_edit= 0; + totipo_vert= 0; + totipo_vertsel= 0; + totipo_key= 0; + totipo_keysel= 0; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + ei= G.sipo->editipo; + if(ei==0) return; + for(a=0; a<G.sipo->totipo; a++) { + if( ei->flag & IPO_VISIBLE ) { + totipo_vis++; + if(ei->flag & IPO_SELECT) totipo_sel++; + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + + /* als showkey: wel de vertices tellen (voor grab) */ + if(G.sipo->showkey==0) totipo_edit++; + + if(ei->icu) { + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(ei->icu->ipo==IPO_BEZ) { + if(bezt->f1 & 1) totipo_vertsel++; + if(bezt->f3 & 1) totipo_vertsel++; + totipo_vert+= 2; + } + if(bezt->f2 & 1) totipo_vertsel++; + + totipo_vert++; + bezt++; + } + } + } + } + } + ei++; + } + + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + while(ik) { + totipo_key++; + if(ik->flag & 1) totipo_keysel++; + ik= ik->next; + } + } +} + + + +void update_editipo_flags() +{ + EditIpo *ei; + IpoKey *ik; + unsigned int flag; + int a; + + ei= G.sipo->editipo; + if(ei) { + for(a=0; a<G.sipo->totipo; a++, ei++) { + ei->flag &= ~IPO_VISIBLE; + flag= (1<<a); + if( G.sipo->rowbut & flag ) ei->flag |= IPO_VISIBLE; + + if(ei->icu) ei->icu->flag= ei->flag; + + } + } + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + while(ik) { + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + if(ik->flag & 1) { + ik->data[a]->f1 |= 1; + ik->data[a]->f2 |= 1; + ik->data[a]->f3 |= 1; + } + else { + ik->data[a]->f1 &= ~1; + ik->data[a]->f2 &= ~1; + ik->data[a]->f3 &= ~1; + } + } + } + ik= ik->next; + } + } +} + +void set_editflag_editipo() +{ + EditIpo *ei; + int a; /* , tot= 0, ok= 0; */ + + /* van showkey direkt door naar editen geselecteerde punten */ + if(G.sipo->showkey) { + G.sipo->showkey= 0; + if(G.sipo->ipo) G.sipo->ipo->showkey= 0; + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) ei->flag |= IPO_SELECT; + scrarea_queue_headredraw(curarea); + allqueue(REDRAWVIEW3D, 0); + } + + get_status_editipo(); + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if(ei->icu) { + if(ei->flag & IPO_VISIBLE) { + + if(totipo_edit==0 && (ei->flag & IPO_SELECT)) { + ei->flag |= IPO_EDIT; + ei->icu->flag= ei->flag; + } + else if(totipo_edit && (ei->flag & IPO_EDIT)) { + ei->flag -= IPO_EDIT; + ei->icu->flag= ei->flag; + } + else if(totipo_vis==1) { + if(ei->flag & IPO_EDIT) ei->flag -= IPO_EDIT; + else ei->flag |= IPO_EDIT; + ei->icu->flag= ei->flag; + } + } + } + } + + scrarea_queue_winredraw(curarea); +} + +void swap_selectall_editipo() +{ + Object *ob; + EditIpo *ei; + IpoKey *ik; + BezTriple *bezt; + int a, b; /* , sel=0; */ + + + deselectall_key(); + + get_status_editipo(); + + + + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + while(ik) { + if(totipo_vertsel) ik->flag &= ~1; + else ik->flag |= 1; + ik= ik->next; + } + update_editipo_flags(); + + if(G.sipo->showkey && G.sipo->blocktype==ID_OB ) { + ob= OBACT; + if(ob && (ob->ipoflag & OB_DRAWKEY)) draw_object_ext(BASACT); + } + } + else if(totipo_edit==0) { + ei= G.sipo->editipo; + if (ei){ + for(a=0; a<G.sipo->totipo; a++) { + if( ei->flag & IPO_VISIBLE ) { + if(totipo_sel) ei->flag &= ~IPO_SELECT; + else ei->flag |= IPO_SELECT; + } + ei++; + } + update_editipo_flags(); + } + } + else { + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu ) { + bezt= ei->icu->bezt; + if(bezt) { + b= ei->icu->totvert; + while(b--) { + if(totipo_vertsel) { + bezt->f1= bezt->f2= bezt->f3= 0; + } + else { + bezt->f1= bezt->f2= bezt->f3= 1; + } + bezt++; + } + } + } + ei++; + } + + } + + scrarea_queue_winredraw(curarea); + +} + +void swap_visible_editipo() +{ + EditIpo *ei; + Object *ob; + int a; /* , sel=0; */ + + get_status_editipo(); + + G.sipo->rowbut= 0; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if(totipo_vis==0) { + if(ei->icu) { + ei->flag |= IPO_VISIBLE; + G.sipo->rowbut |= (1<<a); + } + } + else ei->flag &= ~IPO_VISIBLE; + ei++; + } + + update_editipo_flags(); + + if(G.sipo->showkey) { + + make_ipokey(); + + ob= OBACT; + if(ob && (ob->ipoflag & OB_DRAWKEY)) allqueue(REDRAWVIEW3D, 0); + } + + scrarea_queue_winredraw(curarea); + +} + +void deselectall_editipo() +{ + EditIpo *ei; + IpoKey *ik; + BezTriple *bezt; + int a, b; /* , sel=0; */ + + deselectall_key(); + + get_status_editipo(); + + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + while(ik) { + ik->flag &= ~1; + ik= ik->next; + } + update_editipo_flags(); + + } + else if(totipo_edit==0) { + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if( ei->flag & IPO_VISIBLE ) { + ei->flag &= ~IPO_SELECT; + } + ei++; + } + update_editipo_flags(); + } + else { + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu ) { + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + bezt->f1= bezt->f2= bezt->f3= 0; + bezt++; + } + } + } + ei++; + } + } + + scrarea_queue_winredraw(curarea); +} + +short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt) +{ + /* selected krijgen een nadeel */ + /* in icu en (bezt of bp) wordt nearest weggeschreven */ + /* return 0 1 2: handlepunt */ + EditIpo *ei; + BezTriple *bezt1; + int a, b; + short dist= 100, temp, mval[2], hpoint=0; + + *icu= 0; + *bezt= 0; + + getmouseco_areawin(mval); + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu) { + + if(ei->icu->bezt) { + bezt1= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + + ipoco_to_areaco_noclip(G.v2d, bezt1->vec[0], bezt1->s[0]); + ipoco_to_areaco_noclip(G.v2d, bezt1->vec[1], bezt1->s[1]); + ipoco_to_areaco_noclip(G.v2d, bezt1->vec[2], bezt1->s[2]); + + if(ei->disptype==IPO_DISPBITS) { + temp= abs(mval[0]- bezt1->s[1][0]); + } + else temp= abs(mval[0]- bezt1->s[1][0])+ abs(mval[1]- bezt1->s[1][1]); + + if( bezt1->f2 & 1) temp+=5; + if(temp<dist) { + hpoint= 1; + *bezt= bezt1; + dist= temp; + *icu= ei->icu; + } + + if(ei->disptype!=IPO_DISPBITS && ei->icu->ipo==IPO_BEZ) { + /* middelste punten een klein voordeel */ + temp= -3+abs(mval[0]- bezt1->s[0][0])+ abs(mval[1]- bezt1->s[0][1]); + if( bezt1->f1 & 1) temp+=5; + if(temp<dist) { + hpoint= 0; + *bezt= bezt1; + dist= temp; + *icu= ei->icu; + } + + temp= abs(mval[0]- bezt1->s[2][0])+ abs(mval[1]- bezt1->s[2][1]); + if( bezt1->f3 & 1) temp+=5; + if(temp<dist) { + hpoint= 2; + *bezt=bezt1; + dist= temp; + *icu= ei->icu; + } + } + bezt1++; + } + } + } + } + + return hpoint; +} + + +void move_to_frame() +{ + EditIpo *ei; + BezTriple *bezt; + ID *id; + float cfra; + int a, b; + + if(G.sipo->editipo==0) return; + + ei= G.sipo->editipo; + + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + + if(ei->icu->bezt) { + + b= ei->icu->totvert; + bezt= ei->icu->bezt; + while(b--) { + if(BEZSELECTED(bezt)) { + + cfra= bezt->vec[1][0]/G.scene->r.framelen; + + id= G.sipo->from; + if(id && GS(id->name)==ID_OB ) { + Object *ob= (Object *)id; + if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) { + cfra+= ob->sf/G.scene->r.framelen; + } + } + CFRA= (short)floor(cfra+0.5); + + if(CFRA < 1) CFRA= 1; + update_for_newframe(); + + break; + } + bezt++; + } + } + } + } + } +} + +/* *********************************** */ + +void do_ipowin_buts(short event) +{ + if((G.qual & LR_SHIFTKEY)==0) { + G.sipo->rowbut= (1<<event); + } + scrarea_queue_winredraw(curarea); + + update_editipo_flags(); + + if(G.sipo->showkey) { + make_ipokey(); + if(G.sipo->blocktype==ID_OB) allqueue(REDRAWVIEW3D, 0); + } + +} + +void do_ipo_selectbuttons() +{ + EditIpo *ei, *ei1; + int a, nr; + short mval[2]; + + if(G.sipo->showkey) return; + + /* geen editipo toestaan: editipo's naar selected omzetten */ + get_status_editipo(); + if(totipo_edit) { + set_editflag_editipo(); + } + + /* welke */ + getmouseco_areawin(mval); + + nr= -(mval[1]-curarea->winy+30-G.sipo->butofs-IPOBUTY)/IPOBUTY; + if(nr>=0 && nr<G.sipo->totipo) { + ei= G.sipo->editipo; + ei+= nr; + + if(ei->icu) { + if((ei->flag & IPO_VISIBLE)==0) { + ei->flag |= IPO_VISIBLE; + G.sipo->rowbut |= (1<<nr); + } + + if((G.qual & LR_SHIFTKEY)==0) { + ei1= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + ei1->flag &= ~IPO_SELECT; + ei1++; + } + } + + if(ei->flag & IPO_SELECT) { + ei->flag &= ~IPO_SELECT; + } + else { + ei->flag |= IPO_SELECT; + } + + update_editipo_flags(); + scrarea_queue_winredraw(curarea); + } + } +} + +/* ******************************************* */ + +EditIpo *get_editipo() +{ + EditIpo *ei; + int a; /* , sel=0; */ + + get_status_editipo(); + + if(totipo_edit>1) { + error("Too many editipo's"); + return 0; + } + if(G.sipo->editipo==0) return 0; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if(ei->flag & IPO_VISIBLE) { + if( ei->flag & IPO_EDIT ) return ei; + else if(totipo_vis==1) return ei; + + if(ei->flag & IPO_SELECT) { + if(totipo_sel==1) return ei; + } + } + ei++; + } + return 0; +} + + +static Ipo *get_ipo(ID *from, short type, int make) +{ + Object *ob; + Material *ma; + Curve *cu; + Sequence *seq; + Key *key; + World *wo; + Lamp *la; + Camera *ca; + Ipo *ipo= 0; + bAction *act; + + if( type==ID_OB) { + ob= (Object *)from; + if(ob->id.lib) return 0; + + ipo= ob->ipo; + if(make && ipo==0) ipo= ob->ipo= add_ipo("ObIpo", ID_OB); + } + else if( type==IPO_CO){ + ob= (Object *)from; + if(ob->id.lib) return 0; + + if (ob->activecon){ + ipo= ob->activecon->ipo; + if(make && ipo==0) ipo= ob->activecon->ipo= add_ipo("CoIpo", IPO_CO); + } + } + else if( type==ID_AC) { + act= (bAction *)from; + if (!act->achan) return 0; + if (act->id.lib) return 0; + ipo= act->achan->ipo; + + /* This should never happen */ + if(make && ipo==0) ipo= act->achan->ipo= add_ipo("AcIpo", ID_AC); + } + else if( type==ID_MA) { + ma= (Material *)from; + if(ma->id.lib) return 0; + ipo= ma->ipo; + + if(make && ipo==0) ipo= ma->ipo= add_ipo("MatIpo", ID_MA); + } + + else if( type==ID_SEQ) { + seq= (Sequence *)from; + + if(seq->type & SEQ_EFFECT) { + ipo= seq->ipo; + if(make && ipo==0) ipo= seq->ipo= add_ipo("SeqIpo", ID_SEQ); + } + else return 0; + } + else if( type==ID_CU) { + cu= (Curve *)from; + if(cu->id.lib) return 0; + ipo= cu->ipo; + + if(make && ipo==0) ipo= cu->ipo= add_ipo("CuIpo", ID_CU); + } + else if( type==ID_KE) { + key= (Key *)from; + if(key->id.lib) return 0; + ipo= key->ipo; + + if(make && ipo==0) ipo= key->ipo= add_ipo("KeyIpo", ID_KE); + } + else if( type==ID_WO) { + wo= (World *)from; + if(wo->id.lib) return 0; + ipo= wo->ipo; + + if(make && ipo==0) ipo= wo->ipo= add_ipo("WoIpo", ID_WO); + } + else if( type==ID_LA) { + la= (Lamp *)from; + if(la->id.lib) return 0; + ipo= la->ipo; + + if(make && ipo==0) ipo= la->ipo= add_ipo("LaIpo", ID_LA); + } + else if( type==ID_CA) { + ca= (Camera *)from; + if(ca->id.lib) return 0; + ipo= ca->ipo; + + if(make && ipo==0) ipo= ca->ipo= add_ipo("CaIpo", ID_CA); + } + else if( type==ID_SO) { + bSound *snd= (bSound *)from; + if(snd->id.lib) return 0; + ipo= snd->ipo; + + if(make && ipo==0) ipo= snd->ipo= add_ipo("SndIpo", ID_SO); + } + else return 0; + + return ipo; +} + + +// this function should not have the G.sipo in it... + +IpoCurve *get_ipocurve(ID *from, short type, int adrcode, Ipo *useipo) +{ + Ipo *ipo= 0; + IpoCurve *icu=0; + + /* return 0 als lib */ + /* ook testen of ipo en ipocurve bestaan */ + + if (useipo==NULL) { + + if (G.sipo==NULL || G.sipo->pin==0){ + ipo= get_ipo(from, type, 1); /* 1= make */ + } + else + ipo = G.sipo->ipo; + + + if(G.sipo) { + if (G.sipo->pin==0) G.sipo->ipo= ipo; + } + } + else + ipo= useipo; + + + if(ipo && ipo->id.lib==0) { + + icu= ipo->curve.first; + while(icu) { + if(icu->adrcode==adrcode) break; + icu= icu->next; + } + if(icu==0) { + icu= MEM_callocN(sizeof(IpoCurve), "ipocurve"); + + icu->flag |= IPO_VISIBLE; + + if (!useipo && G.sipo && G.sipo->pin) + icu->blocktype = G.sipo->blocktype; + else + icu->blocktype= type; + icu->adrcode= adrcode; + + set_icu_vars(icu); + + BLI_addtail( &(ipo->curve), icu); + } + } + return icu; +} + +void insert_vert_ipo(IpoCurve *icu, float x, float y) +{ + BezTriple *bezt, beztr, *newbezt; + int a = 0, h1, h2; + + memset(&beztr, 0, sizeof(BezTriple)); + beztr.vec[1][0]= x; + beztr.vec[1][1]= y; + beztr.hide= IPO_BEZ; + beztr.f1= beztr.f2= beztr.f3= SELECT; + beztr.h1= beztr.h2= HD_AUTO; + + bezt= icu->bezt; + + if(bezt==0) { + icu->bezt= MEM_callocN( sizeof(BezTriple), "beztriple"); + *(icu->bezt)= beztr; + icu->totvert= 1; + } + else { + /* alle vertices deselect */ + for(a=0; a<icu->totvert; a++, bezt++) { + bezt->f1= bezt->f2= bezt->f3= 0; + } + + bezt= icu->bezt; + for(a=0; a<=icu->totvert; a++, bezt++) { + + /* geen dubbele punten */ + if(a<icu->totvert && (bezt->vec[1][0]>x-IPOTHRESH && bezt->vec[1][0]<x+IPOTHRESH)) { + *(bezt)= beztr; + break; + } + if(a==icu->totvert || bezt->vec[1][0] > x) { + newbezt= MEM_callocN( (icu->totvert+1)*sizeof(BezTriple), "beztriple"); + + if(a>0) memcpy(newbezt, icu->bezt, a*sizeof(BezTriple)); + + bezt= newbezt+a; + *(bezt)= beztr; + + if(a<icu->totvert) memcpy(newbezt+a+1, icu->bezt+a, (icu->totvert-a)*sizeof(BezTriple)); + + MEM_freeN(icu->bezt); + icu->bezt= newbezt; + + icu->totvert++; + break; + } + } + } + + + calchandles_ipocurve(icu); + + /* handletype goedzetten */ + if(icu->totvert>2) { + h1= h2= HD_AUTO; + if(a>0) h1= (bezt-1)->h2; + if(a<icu->totvert-1) h2= (bezt+1)->h1; + bezt->h1= h1; + bezt->h2= h2; + + calchandles_ipocurve(icu); + } +} + +void add_vert_ipo() +{ + EditIpo *ei; + float x, y; + int val; + short mval[2]; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + if(G.sipo->showkey) { + G.sipo->showkey= 0; + free_ipokey(&G.sipo->ipokey); + } + + getmouseco_areawin(mval); + + if(mval[0]>G.v2d->mask.xmax) return; + + ei= get_editipo(); + if(ei==0) return; + + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + + if(ei->icu==0) { + if(G.sipo->from) + ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0); + } + if(ei->icu==0) return; + + if(ei->disptype==IPO_DISPBITS) { + ei->icu->vartype= IPO_BITS; + val= (int)floor(y-0.5); + if(val<0) val= 0; + y= (float)(1 << val); + } + + insert_vert_ipo(ei->icu, x, y); + + /* voor zekerheid: als icu 0 was, of maar 1 curve visible */ + ei->flag |= IPO_SELECT; + ei->icu->flag= ei->flag; + + editipo_changed(G.sipo, 1); +} + +void add_duplicate_editipo() +{ + Object *ob; + EditIpo *ei; + IpoCurve *icu; + BezTriple *bezt, *beztn, *newb; + int tot, a, b; + + get_status_editipo(); + if(totipo_vertsel==0) return; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) { + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + icu= ei->icu; + + /* hoeveel punten */ + tot= 0; + b= icu->totvert; + bezt= icu->bezt; + while(b--) { + if(bezt->f2 & 1) tot++; + bezt++; + } + + if(tot) { + icu->totvert+= tot; + newb= beztn= MEM_mallocN(icu->totvert*sizeof(BezTriple), "bezt"); + bezt= icu->bezt; + b= icu->totvert-tot; + while(b--) { + *beztn= *bezt; + if(bezt->f2 & 1) { + beztn->f1= beztn->f2= beztn->f3= 0; + beztn++; + *beztn= *bezt; + } + beztn++; + bezt++; + } + MEM_freeN(icu->bezt); + icu->bezt= newb; + + calchandles_ipocurve(icu); + } + } + } + } + + if(G.sipo->showkey) { + make_ipokey(); + if(G.sipo->blocktype==ID_OB) { + ob= OBACT; + if(ob && (ob->ipoflag & OB_DRAWKEY)) allqueue(REDRAWVIEW3D, 0); + } + } + transform_ipo('g'); +} + +void remove_doubles_ipo() +{ + EditIpo *ei; + IpoKey *ik, *ikn; + BezTriple *bezt, *newb, *new1; + float val; + int mode, a, b; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) { + + /* OF de curve is selected OF in editmode OF in keymode */ + mode= 0; + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) mode= 1; + else if(ei->flag & IPO_SELECT) mode= 2; + + if(mode) { + bezt= ei->icu->bezt; + newb= new1= MEM_mallocN(ei->icu->totvert*sizeof(BezTriple), "newbezt"); + *newb= *bezt; + b= ei->icu->totvert-1; + bezt++; + while(b--) { + + /* mag er verwijderd worden? */ + if(mode==2 || (bezt->f2 & 1)) { + + /* verschillen de punten? */ + if( fabs( bezt->vec[1][0]-newb->vec[1][0] ) > 0.9 ) { + newb++; + *newb= *bezt; + } + else { + /* gemiddelde */ + VecMidf(newb->vec[0], newb->vec[0], bezt->vec[0]); + VecMidf(newb->vec[1], newb->vec[1], bezt->vec[1]); + VecMidf(newb->vec[2], newb->vec[2], bezt->vec[2]); + + newb->h1= newb->h2= HD_FREE; + + ei->icu->totvert--; + } + + } + else { + newb++; + *newb= *bezt; + } + bezt++; + } + + MEM_freeN(ei->icu->bezt); + ei->icu->bezt= new1; + + calchandles_ipocurve(ei->icu); + } + } + } + + editipo_changed(G.sipo, 1); /* maakt ook ipokeys opnieuw! */ + + /* dubbele keys weg */ + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + ikn= ik->next; + + while(ik && ikn) { + if( (ik->flag & 1) && (ikn->flag & 1) ) { + if( fabs(ik->val-ikn->val) < 0.9 ) { + val= (float)((ik->val + ikn->val)/2.0); + + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) ik->data[a]->vec[1][0]= val; + if(ikn->data[a]) ikn->data[a]->vec[1][0]= val; + } + } + } + ik= ikn; + ikn= ikn->next; + + } + + editipo_changed(G.sipo, 1); /* maakt ook ipokeys opnieuw! */ + + } + deselectall_editipo(); +} + +void join_ipo() +{ + EditIpo *ei; + IpoKey *ik; + IpoCurve *icu; + BezTriple *bezt, *beztn, *newb; + float val; + int mode, tot, a, b; + + get_status_editipo(); + + mode= pupmenu("Join %t|All Selected %x1|Selected doubles %x2"); + if( mode==2 ) { + remove_doubles_ipo(); + return; + } + else if(mode!=1) return; + + /* eerst: meerdere geselecteerde verts in 1 curve */ + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) { + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + icu= ei->icu; + + /* hoeveel punten */ + tot= 0; + b= icu->totvert; + bezt= icu->bezt; + while(b--) { + if(bezt->f2 & 1) tot++; + bezt++; + } + + if(tot>1) { + tot--; + icu->totvert-= tot; + + newb= MEM_mallocN(icu->totvert*sizeof(BezTriple), "bezt"); + /* het eerste punt wordt het nieuwe punt */ + beztn= newb+1; + tot= 0; + + bezt= icu->bezt; + b= icu->totvert+tot+1; + while(b--) { + + if(bezt->f2 & 1) { + if(tot==0) *newb= *bezt; + else { + VecAddf(newb->vec[0], newb->vec[0], bezt->vec[0]); + VecAddf(newb->vec[1], newb->vec[1], bezt->vec[1]); + VecAddf(newb->vec[2], newb->vec[2], bezt->vec[2]); + } + tot++; + } + else { + *beztn= *bezt; + beztn++; + } + bezt++; + } + + VecMulf(newb->vec[0], (float)(1.0/((float)tot))); + VecMulf(newb->vec[1], (float)(1.0/((float)tot))); + VecMulf(newb->vec[2], (float)(1.0/((float)tot))); + + MEM_freeN(icu->bezt); + icu->bezt= newb; + + sort_time_ipocurve(icu); + calchandles_ipocurve(icu); + } + } + } + } + + /* dan: in keymode: meerdere geselecteerde keys samenvoegen */ + + editipo_changed(G.sipo, 1); /* maakt ook ipokeys opnieuw! */ + + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + val= 0.0; + tot= 0; + while(ik) { + if(ik->flag & 1) { + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + val+= ik->data[a]->vec[1][0]; + break; + } + } + tot++; + } + ik= ik->next; + } + if(tot>1) { + val/= (float)tot; + + ik= G.sipo->ipokey.first; + while(ik) { + if(ik->flag & 1) { + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + ik->data[a]->vec[1][0]= val; + } + } + } + ik= ik->next; + } + editipo_changed(G.sipo, 0); + } + } + deselectall_editipo(); +} + +void ipo_snapmenu() +{ + EditIpo *ei; + BezTriple *bezt; + float dx = 0.0; + int a, b; + short event, ok, ok2; + + event= pupmenu("Snap %t|Horizontal %x1|To next %x2|To frame %x3|To current frame%x4"); + if(event < 1) return; + + get_status_editipo(); + + ei= G.sipo->editipo; + for(b=0; b<G.sipo->totipo; b++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) { + + ok2= 0; + if(G.sipo->showkey) ok2= 1; + else if(totipo_vert && (ei->flag & IPO_EDIT)) ok2= 2; + else if(totipo_vert==0 && (ei->flag & IPO_SELECT)) ok2= 3; + + if(ok2) { + bezt= ei->icu->bezt; + a= ei->icu->totvert; + while(a--) { + ok= 0; + if(totipo_vert) { + if(bezt->f2 & 1) ok= 1; + } + else ok= 1; + + if(ok) { + if(event==1) { + bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1]; + if(bezt->h1==HD_AUTO || bezt->h1==HD_VECT) bezt->h1= HD_ALIGN; + if(bezt->h2==HD_AUTO || bezt->h2==HD_VECT) bezt->h2= HD_ALIGN; + } + else if(event==2) { + if(a) { + bezt->vec[0][1]= bezt->vec[1][1]= bezt->vec[2][1]= (bezt+1)->vec[1][1]; + if(bezt->h1==HD_AUTO || bezt->h1==HD_VECT) bezt->h1= HD_ALIGN; + if(bezt->h2==HD_AUTO || bezt->h2==HD_VECT) bezt->h2= HD_ALIGN; + } + } + else if(event==3) { + bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]+0.5)); + } + else if(event==4) { /* to current frame */ + + if(ok2==1 || ok2==2) { + + if(G.sipo->blocktype==ID_SEQ) { + Sequence *seq; + + seq= (Sequence *)G.sipo->from; + if(seq) { + dx= (float)(CFRA-seq->startdisp); + dx= (float)(100.0*dx/((float)(seq->enddisp-seq->startdisp))); + + dx-= bezt->vec[1][0]; + } + } + else dx= G.scene->r.framelen*CFRA - bezt->vec[1][0]; + + bezt->vec[0][0]+= dx; + bezt->vec[1][0]+= dx; + bezt->vec[2][0]+= dx; + } + } + } + + bezt++; + } + calchandles_ipocurve(ei->icu); + } + } + } + editipo_changed(G.sipo, 1); +} + + + +void mouse_select_ipo() +{ + Object *ob; + EditIpo *ei, *actei= 0; + IpoCurve *icu; + IpoKey *ik, *actik; + BezTriple *bezt; + Key *key; + KeyBlock *kb, *actkb=0; + float x, y, dist, mindist; + int a, oldflag = 0, hand, ok; + short mval[2], xo, yo; + + if(G.sipo->editipo==0) return; + + get_status_editipo(); + + if(G.sipo->showkey) { + getmouseco_areawin(mval); + + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + actik= 0; + mindist= 1000.0; + ik= G.sipo->ipokey.first; + while(ik) { + dist= (float)(fabs(ik->val-x)); + if(ik->flag & 1) dist+= 1.0; + if(dist < mindist) { + actik= ik; + mindist= dist; + } + ik= ik->next; + } + if(actik) { + oldflag= actik->flag; + + if(G.qual & LR_SHIFTKEY); + else deselectall_editipo(); + + if(G.qual & LR_SHIFTKEY) { + if(oldflag & 1) actik->flag &= ~1; + else actik->flag |= 1; + } + else { + actik->flag |= 1; + } + } + } + else if(totipo_edit) { + + hand= findnearest_ipovert(&icu, &bezt); + + if(G.qual & LR_SHIFTKEY) { + if(bezt) { + if(hand==1) { + if(BEZSELECTED(bezt)) { + bezt->f1= bezt->f2= bezt->f3= 0; + } + else { + bezt->f1= bezt->f2= bezt->f3= 1; + } + } + else if(hand==0) { + if(bezt->f1 & 1) bezt->f1= 0; + else bezt->f1= 1; + } + else { + if(bezt->f3 & 1) bezt->f3= 0; + else bezt->f3= 1; + } + } + } + else { + deselectall_editipo(); + + if(bezt) { + if(hand==1) { + bezt->f1|= 1; bezt->f2|= 1; bezt->f3|= 1; + } + else if(hand==0) bezt->f1|= 1; + else bezt->f3|= 1; + } + } + } + else { + + /* vertex keys ? */ + + if(G.sipo->blocktype==ID_KE && G.sipo->from) { + key= (Key *)G.sipo->from; + + ei= G.sipo->editipo; + if(key->type==KEY_NORMAL || (ei->flag & IPO_VISIBLE)) { + getmouseco_areawin(mval); + + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + /* hoeveel is 20 pixels? */ + mindist= (float)(20.0*(G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)curarea->winy); + + kb= key->block.first; + while(kb) { + dist= (float)(fabs(kb->pos-y)); + if(kb->flag & SELECT) dist+= (float)0.01; + if(dist < mindist) { + actkb= kb; + mindist= dist; + } + kb= kb->next; + } + if(actkb) { + ok= TRUE; + if(G.obedit && (actkb->flag & 1)==0) { + ok= okee("Copy Key after leaving EditMode"); + } + if(ok) { + /* doet ook alle keypos */ + deselectall_editipo(); + + /* oldflag= actkb->flag; */ + + /* if(G.qual & LR_SHIFTKEY); */ + /* else { */ + /* deselectall_key(); */ + /* } */ + + /* if(G.qual & LR_SHIFTKEY) { */ + /* if(oldflag & 1) actkb->flag &= ~1; */ + /* else actkb->flag |= 1; */ + /* } */ + /* else { */ + actkb->flag |= 1; + /* } */ + + /* bereken keypos */ + showkeypos((Key *)G.sipo->from, actkb); + } + } + } + } + + /* select curve */ + if(actkb==0) { + if(totipo_vis==1) { + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if(ei->icu) { + if(ei->flag & IPO_VISIBLE) actei= ei; + } + } + } + else if(totipo_vis>1) { + actei= select_proj_ipo(0, 0); + } + + if(actei) oldflag= actei->flag; + + if(G.qual & LR_SHIFTKEY); + else deselectall_editipo(); + + if(actei) { + if(G.qual & LR_SHIFTKEY) { + if(oldflag & IPO_SELECT) actei->flag &= ~IPO_SELECT; + else actei->flag |= IPO_SELECT; + } + else { + actei->flag |= IPO_SELECT; + } + } + } + } + + update_editipo_flags(); + + force_draw(); + + if(G.sipo->showkey && G.sipo->blocktype==ID_OB) { + ob= OBACT; + if(ob && (ob->ipoflag & OB_DRAWKEY)) draw_object_ext(BASACT); + } + + getmouseco_areawin(mval); + xo= mval[0]; + yo= mval[1]; + + while(get_mbut()&R_MOUSE) { + getmouseco_areawin(mval); + if(abs(mval[0]-xo)+abs(mval[1]-yo) > 4) { + + if(actkb) move_keys(); + else transform_ipo('g'); + + return; + } + BIF_wait_for_statechange(); + } +} + +void sethandles_ipo(int code) +{ + /* code==1: set autohandle */ + /* code==2: set vectorhandle */ + /* als code==3 (HD_ALIGN) toggelt het, vectorhandles worden HD_FREE */ + EditIpo *ei; + BezTriple *bezt; + int a, b, ok=0; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + if(code==1 || code==2) { + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(bezt->f1 || bezt->f3) { + if(bezt->f1) bezt->h1= code; + if(bezt->f3) bezt->h2= code; + + if(bezt->h1!=bezt->h2) { + if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE; + if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE; + } + } + bezt++; + } + calchandles_ipocurve(ei->icu); + } + } + } + else { + /* is er 1 handle NIET vrij: alles vrijmaken, else ALIGNED maken */ + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(bezt->f1 && bezt->h1) ok= 1; + if(bezt->f3 && bezt->h2) ok= 1; + if(ok) break; + bezt++; + } + } + } + if(ok) ok= HD_FREE; + else ok= HD_ALIGN; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(bezt->f1) bezt->h1= ok; + if(bezt->f3 ) bezt->h2= ok; + + bezt++; + } + calchandles_ipocurve(ei->icu); + } + } + } + editipo_changed(G.sipo, 1); +} + +void set_ipotype() +{ + EditIpo *ei; + Key *key; + KeyBlock *kb; + int a; + short event; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + if(G.sipo->showkey) return; + get_status_editipo(); + + if(G.sipo->blocktype==ID_KE && totipo_edit==0 && totipo_sel==0) { + key= (Key *)G.sipo->from; + if(key==0) return; + + event= pupmenu("Key Type %t|Linear %x1|Cardinal %x2|B spline %x3"); + if(event < 1) return; + + kb= key->block.first; + while(kb) { + if(kb->flag & SELECT) { + kb->type= 0; + if(event==1) kb->type= KEY_LINEAR; + if(event==2) kb->type= KEY_CARDINAL; + if(event==3) kb->type= KEY_BSPLINE; + } + kb= kb->next; + } + } + else { + event= pupmenu("Ipo Type %t|Constant %x1|Linear %x2|Bezier %x3"); + if(event < 1) return; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) { + if(event==1) ei->icu->ipo= IPO_CONST; + else if(event==2) ei->icu->ipo= IPO_LIN; + else ei->icu->ipo= IPO_BEZ; + } + } + } + scrarea_queue_winredraw(curarea); +} + +void borderselect_ipo() +{ + EditIpo *ei; + IpoKey *ik; + BezTriple *bezt; + rcti rect; + rctf rectf; + int a, b, val; + short mval[2]; + + get_status_editipo(); + + val= get_border(&rect, 3); + + if(val) { + mval[0]= rect.xmin; + mval[1]= rect.ymin; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + mval[0]= rect.xmax; + mval[1]= rect.ymax; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + while(ik) { + if(rectf.xmin<ik->val && rectf.xmax>ik->val) { + if(val==LEFTMOUSE) ik->flag |= 1; + else ik->flag &= ~1; + } + ik= ik->next; + } + update_editipo_flags(); + } + else if(totipo_edit==0) { + if(rect.xmin<rect.xmax && rect.ymin<rect.ymax) + select_proj_ipo(&rectf, val); + } + else { + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu) { + if(ei->icu->bezt) { + b= ei->icu->totvert; + bezt= ei->icu->bezt; + while(b--) { + int bit= (val==LEFTMOUSE); + + if(BLI_in_rctf(&rectf, bezt->vec[0][0], bezt->vec[0][1])) + bezt->f1 = (bezt->f1&~1) | bit; + if(BLI_in_rctf(&rectf, bezt->vec[1][0], bezt->vec[1][1])) + bezt->f2 = (bezt->f2&~1) | bit; + if(BLI_in_rctf(&rectf, bezt->vec[2][0], bezt->vec[2][1])) + bezt->f3 = (bezt->f3&~1) | bit; + + bezt++; + } + } + } + } + } + scrarea_queue_winredraw(curarea); + } +} + + + + +void del_ipo() +{ + EditIpo *ei; + BezTriple *bezt, *bezt1; + int a, b; + int del, event; + + get_status_editipo(); + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + if(totipo_edit==0 && totipo_sel==0 && totipo_vertsel==0) { + delete_key(); + return; + } + + if( okee("Erase selected")==0 ) return; + + // eerste doorloop, kunnen hele stukken weg? + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + del= 0; + + if(G.sipo->showkey==0 && totipo_edit==0) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) { + del= 1; + } + } + else { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + if(b) { + while(b) { + if( BEZSELECTED(bezt) ); + else break; + b--; + bezt++; + } + if(b==0) del= 1; + } + } + } + } + } + + if(del) { + BLI_remlink( &(G.sipo->ipo->curve), ei->icu); + if(ei->icu->bezt) MEM_freeN(ei->icu->bezt); + MEM_freeN(ei->icu); + ei->flag &= ~IPO_SELECT; + ei->flag &= ~IPO_EDIT; + ei->icu= 0; + } + } + + // tweede doorloop, kleine stukken weg: alleen curves + ei= G.sipo->editipo; + for(b=0; b<G.sipo->totipo; b++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + + event= 0; + if(ei->icu->bezt) { + + bezt= ei->icu->bezt; + for(a=0; a<ei->icu->totvert; a++) { + if( BEZSELECTED(bezt) ) { + memcpy(bezt, bezt+1, (ei->icu->totvert-a-1)*sizeof(BezTriple)); + ei->icu->totvert--; + a--; + event= 1; + } + else bezt++; + } + if(event) { + bezt1 = (BezTriple*) MEM_mallocN(ei->icu->totvert * sizeof(BezTriple), "delNurb"); + memcpy(bezt1, ei->icu->bezt, (ei->icu->totvert)*sizeof(BezTriple) ); + MEM_freeN(ei->icu->bezt); + ei->icu->bezt= bezt1; + } + } + } + } + } + + allqueue(REDRAWNLA, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); +} + +ListBase ipocopybuf={0, 0}; +int totipocopybuf=0; + +void free_ipocopybuf() +{ + IpoCurve *icu; + + while( (icu= ipocopybuf.first) ) { + if(icu->bezt) MEM_freeN(icu->bezt); + BLI_remlink(&ipocopybuf, icu); + MEM_freeN(icu); + } + totipocopybuf= 0; +} + +void copy_editipo() +{ + EditIpo *ei; + IpoCurve *icu; + int a; + + if(G.sipo->showkey) { + error("cannot copy\n"); + return; + } + + free_ipocopybuf(); + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || (ei->flag & IPO_SELECT) ) { + icu= MEM_callocN(sizeof(IpoCurve), "ipocopybuf"); + *icu= *(ei->icu); + BLI_addtail(&ipocopybuf, icu); + if(icu->bezt) { + icu->bezt= MEM_mallocN(icu->totvert*sizeof(BezTriple), "ipocopybuf"); + memcpy(icu->bezt, ei->icu->bezt, icu->totvert*sizeof(BezTriple)); + } + totipocopybuf++; + } + } + } + + if(totipocopybuf==0) error("Copybuf is empty"); +} + +void paste_editipo() +{ + EditIpo *ei; + IpoCurve *icu; + int a, ok; + + if(G.sipo->showkey) return; + + if(totipocopybuf==0) return; + if(G.sipo->ipo==0) return; + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + get_status_editipo(); + + if(totipo_vis==0) { + error("No visible splines"); + } + else if(totipo_vis!=totipocopybuf && totipo_sel!=totipocopybuf) { + error("Incompatible paste"); + } + else { + /* problemen voorkomen: andere splines visible dan select */ + if(totipo_vis==totipo_sel) totipo_vis= 0; + + icu= ipocopybuf.first; + if(icu==0) return; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if(ei->flag & IPO_VISIBLE) { + ok= 0; + if(totipo_vis==totipocopybuf) ok= 1; + if(totipo_sel==totipocopybuf && (ei->flag & IPO_SELECT)) ok= 1; + + if(ok) { + + ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0); + if(ei->icu==0) return; + + if(ei->icu->bezt) MEM_freeN(ei->icu->bezt); + ei->icu->bezt= 0; + + ei->icu->totvert= icu->totvert; + ei->icu->flag= ei->flag= icu->flag; + ei->icu->extrap= icu->extrap; + ei->icu->ipo= icu->ipo; + + if(icu->bezt) { + ei->icu->bezt= MEM_mallocN(icu->totvert*sizeof(BezTriple), "ipocopybuf"); + memcpy(ei->icu->bezt, icu->bezt, icu->totvert*sizeof(BezTriple)); + } + + icu= icu->next; + + } + } + } + editipo_changed(G.sipo, 1); + } +} + +void set_exprap_ipo(int mode) +{ + EditIpo *ei; + int a; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + /* in geval van keys: altijd ok */ + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || (ei->flag & IPO_SELECT) || (G.sipo->showkey) ) { + ei->icu->extrap= mode; + } + } + } + editipo_changed(G.sipo, 1); +} + +int find_other_handles(EditIpo *eicur, float ctime, BezTriple **beztar) +{ + EditIpo *ei; + BezTriple *bezt; + int a, b, c= 1, totvert; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if(ei!=eicur && ei->icu && (ei->flag & IPO_VISIBLE)) { + + bezt= ei->icu->bezt; + totvert= ei->icu->totvert; + + for(b=0; b<totvert; b++, bezt++) { + if( bezt->vec[1][0] < ctime+IPOTHRESH && bezt->vec[1][0] > ctime-IPOTHRESH) { + if(c>2) return 0; + beztar[c]= bezt; + c++; + } + } + } + } + + if(c==3) return 1; + return 0; +} + +void set_speed_editipo(float speed) +{ + EditIpo *ei; + BezTriple *bezt, *beztar[3]; + float vec1[3], vec2[3]; + int a, b, totvert, didit=0; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + /* uitgaande van 1 visible curve, selected punt, bijhorende punten: lencorr! */ + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + bezt= ei->icu->bezt; + totvert= ei->icu->totvert; + + for(b=0; b<totvert; b++, bezt++) { + if(BEZSELECTED(bezt)) { + + beztar[0]= bezt; + + if( find_other_handles(ei, bezt->vec[1][0], beztar) ) { + beztar[0]->h1= beztar[0]->h2= HD_ALIGN; + beztar[1]->h1= beztar[1]->h2= HD_ALIGN; + beztar[2]->h1= beztar[2]->h2= HD_ALIGN; + + vec1[0]= (beztar[0]->vec[1][1] - beztar[0]->vec[0][1]) / (beztar[0]->vec[1][0] - beztar[0]->vec[0][0]) ; + vec2[0]= (beztar[0]->vec[1][1] - beztar[0]->vec[2][1]) / (beztar[0]->vec[2][0] - beztar[0]->vec[1][0]) ; + + vec1[1]= (beztar[1]->vec[1][1] - beztar[1]->vec[0][1]) / (beztar[1]->vec[1][0] - beztar[1]->vec[0][0]) ; + vec2[1]= (beztar[1]->vec[1][1] - beztar[1]->vec[2][1]) / (beztar[1]->vec[2][0] - beztar[1]->vec[1][0]) ; + + vec1[2]= (beztar[2]->vec[1][1] - beztar[2]->vec[0][1]) / (beztar[2]->vec[1][0] - beztar[2]->vec[0][0]) ; + vec2[2]= (beztar[2]->vec[1][1] - beztar[2]->vec[2][1]) / (beztar[2]->vec[2][0] - beztar[2]->vec[1][0]) ; + + Normalise(vec1); + Normalise(vec2); + + VecMulf(vec1, speed); + VecMulf(vec2, speed); + + beztar[0]->vec[0][1]= beztar[0]->vec[1][1] - vec1[0]*(beztar[0]->vec[1][0] - beztar[0]->vec[0][0]) ; + beztar[0]->vec[2][1]= beztar[0]->vec[1][1] - vec2[0]*(beztar[0]->vec[2][0] - beztar[0]->vec[1][0]) ; + + beztar[1]->vec[0][1]= beztar[1]->vec[1][1] - vec1[1]*(beztar[1]->vec[1][0] - beztar[1]->vec[0][0]) ; + beztar[1]->vec[2][1]= beztar[1]->vec[1][1] - vec2[1]*(beztar[1]->vec[2][0] - beztar[1]->vec[1][0]) ; + + beztar[2]->vec[0][1]= beztar[2]->vec[1][1] - vec1[2]*(beztar[2]->vec[1][0] - beztar[2]->vec[0][0]) ; + beztar[2]->vec[2][1]= beztar[2]->vec[1][1] - vec2[2]*(beztar[2]->vec[2][0] - beztar[2]->vec[1][0]) ; + + didit= 1; + } + else { + error("Cannot set speed"); + } + } + } + break; + } + } + + if(didit==0) error("Did not set speed"); + + editipo_changed(G.sipo, 1); + allqueue(REDRAWNLA, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + +} + + +void insertkey(ID *id, int adrcode) +{ + IpoCurve *icu; + Ipo *ipo; + Object *ob; + void *poin; + float curval, cfra; + int type; + + if(id) { + + // this call here, otherwise get_ipo_curve gives it from the pinned ipo + ipo= get_ipo(id, GS(id->name), 1); // 1=make + + icu= get_ipocurve(id, GS(id->name), adrcode, ipo); + + if(icu) { + poin= get_ipo_poin(id, icu, &type); + if(poin) { + curval= read_ipo_poin(poin, type); + + cfra= frame_to_float(CFRA); + + if( GS(id->name)==ID_OB ) { + ob= (Object *)id; + if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) { + /* eigenlijk frametofloat overniew berekenen! daarvoor CFRA als float door kunnen geven */ + cfra-= ob->sf*G.scene->r.framelen; + } + } + + insert_vert_ipo(icu, cfra, curval); + } + } + } +} + +void insertkey_editipo() +{ + EditIpo *ei; + IpoKey *ik; + ID *id; + float *fp, cfra, *insertvals; + int a, nr, ok, tot; + short event; + + if(G.sipo->showkey) + event= pupmenu("Insert KeyVertices %t|Current frame %x1|Selected Keys %x2"); + else + event= pupmenu("Insert KeyVertices %t|Current frame %x1"); + + if(event<1) return; + + ei= G.sipo->editipo; + for(nr=0; nr<G.sipo->totipo; nr++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + + ok= 0; + if(G.sipo->showkey) ok= 1; + else if(ei->flag & IPO_SELECT) ok= 1; + + if(ok) { + /* aantal tellen */ + if(event==1) tot= 1; + else { + ik= G.sipo->ipokey.first; + tot= 0; + while(ik) { + if(ik->flag & 1) tot++; + ik= ik->next; + } + } + if(tot) { + + /* correctie voor ob timeoffs */ + cfra= frame_to_float(CFRA); + id= G.sipo->from; + if(id && GS(id->name)==ID_OB ) { + Object *ob= (Object *)id; + if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) { + cfra-= ob->sf*G.scene->r.framelen; + } + } + else if(id && GS(id->name)==ID_SEQ) { + extern Sequence *last_seq; /* editsequence.c */ + + if(last_seq) { + cfra= (float)(100.0*(cfra-last_seq->startdisp)/((float)(last_seq->enddisp-last_seq->startdisp))); + } + } + + insertvals= MEM_mallocN(sizeof(float)*2*tot, "insertkey_editipo"); + /* zeker zijn dat icu->curval klopt */ + calc_ipo(G.sipo->ipo, cfra); + + if(event==1) { + insertvals[0]= cfra; + + insertvals[1]= ei->icu->curval; + } + else { + fp= insertvals; + ik= G.sipo->ipokey.first; + while(ik) { + if(ik->flag & 1) { + calc_ipo(G.sipo->ipo, ik->val); + + fp[0]= ik->val; + fp[1]= ei->icu->curval; + fp+= 2; + } + ik= ik->next; + } + } + fp= insertvals; + for(a=0; a<tot; a++, fp+=2) { + insert_vert_ipo(ei->icu, fp[0], fp[1]); + } + + MEM_freeN(insertvals); + calc_ipo(G.sipo->ipo, (float)CFRA); + } + } + } + } + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); +} + + +void common_insertkey() +{ + Base *base; + Object *ob; + Material *ma; + ID *id; + IpoCurve *icu; + World *wo; + Lamp *la; + int tlay, map, event; + char menustr[256]; + + if(curarea->spacetype==SPACE_IPO) { + insertkey_editipo(); + } + else if(curarea->spacetype==SPACE_BUTS) { + + if(G.buts->mainb==BUTS_MAT) { + id= G.buts->lockpoin; + ma= G.buts->lockpoin; + if(id) { + event= pupmenu("Insert Key %t|RGB%x0|Alpha%x1|HaSize%x2|Mode %x3|All Color%x10|Ofs%x12|Size%x13|All Mapping%x11"); + if(event== -1) return; + + map= texchannel_to_adrcode(ma->texact); + + if(event==0 || event==10) { + insertkey(id, MA_COL_R); + insertkey(id, MA_COL_G); + insertkey(id, MA_COL_B); + } + if(event==1 || event==10) { + insertkey(id, MA_ALPHA); + } + if(event==2 || event==10) { + insertkey(id, MA_HASIZE); + } + if(event==3 || event==10) { + insertkey(id, MA_MODE); + } + if(event==10) { + insertkey(id, MA_SPEC_R); + insertkey(id, MA_SPEC_G); + insertkey(id, MA_SPEC_B); + insertkey(id, MA_REF); + insertkey(id, MA_EMIT); + insertkey(id, MA_AMB); + insertkey(id, MA_SPEC); + insertkey(id, MA_HARD); + insertkey(id, MA_MODE); + } + if(event==12 || event==11) { + insertkey(id, map+MAP_OFS_X); + insertkey(id, map+MAP_OFS_Y); + insertkey(id, map+MAP_OFS_Z); + } + if(event==13 || event==11) { + insertkey(id, map+MAP_SIZE_X); + insertkey(id, map+MAP_SIZE_Y); + insertkey(id, map+MAP_SIZE_Z); + } + if(event==11) { + insertkey(id, map+MAP_R); + insertkey(id, map+MAP_G); + insertkey(id, map+MAP_B); + insertkey(id, map+MAP_DVAR); + insertkey(id, map+MAP_COLF); + insertkey(id, map+MAP_NORF); + insertkey(id, map+MAP_VARF); + } + } + } + else if(G.buts->mainb==BUTS_WORLD) { + id= G.buts->lockpoin; + wo= G.buts->lockpoin; + if(id) { + event= pupmenu("Insert Key %t|ZenRGB%x0|HorRGB%x1|Mist%x2|stars %x3|Ofs%x12|Size%x13"); + if(event== -1) return; + + map= texchannel_to_adrcode(wo->texact); + + if(event==0) { + insertkey(id, WO_ZEN_R); + insertkey(id, WO_ZEN_G); + insertkey(id, WO_ZEN_B); + } + if(event==1) { + insertkey(id, WO_HOR_R); + insertkey(id, WO_HOR_G); + insertkey(id, WO_HOR_B); + } + if(event==2) { + insertkey(id, WO_MISI); + insertkey(id, WO_MISTDI); + insertkey(id, WO_MISTSTA); + insertkey(id, WO_MISTHI); + } + if(event==3) { + insertkey(id, WO_STAR_R); + insertkey(id, WO_STAR_G); + insertkey(id, WO_STAR_B); + insertkey(id, WO_STARDIST); + insertkey(id, WO_STARSIZE); + } + if(event==12) { + insertkey(id, map+MAP_OFS_X); + insertkey(id, map+MAP_OFS_Y); + insertkey(id, map+MAP_OFS_Z); + } + if(event==13) { + insertkey(id, map+MAP_SIZE_X); + insertkey(id, map+MAP_SIZE_Y); + insertkey(id, map+MAP_SIZE_Z); + } + } + } + else if(G.buts->mainb==BUTS_LAMP) { + id= G.buts->lockpoin; + la= G.buts->lockpoin; + if(id) { + event= pupmenu("Insert Key %t|RGB%x0|Energy%x1|Spotsi%x2|Ofs%x12|Size%x13"); + if(event== -1) return; + + map= texchannel_to_adrcode(la->texact); + + if(event==0) { + insertkey(id, LA_COL_R); + insertkey(id, LA_COL_G); + insertkey(id, LA_COL_B); + } + if(event==1) { + insertkey(id, LA_ENERGY); + } + if(event==2) { + insertkey(id, LA_SPOTSI); + } + if(event==12) { + insertkey(id, map+MAP_OFS_X); + insertkey(id, map+MAP_OFS_Y); + insertkey(id, map+MAP_OFS_Z); + } + if(event==13) { + insertkey(id, map+MAP_SIZE_X); + insertkey(id, map+MAP_SIZE_Y); + insertkey(id, map+MAP_SIZE_Z); + } + + } + } + else if(G.buts->mainb==BUTS_EDIT) { + ob= OBACT; + if(ob && ob->type==OB_CAMERA) { + id= G.buts->lockpoin; + if(id) { + event= pupmenu("Insert Key %t|Lens%x0|Clipping%x1"); + if(event== -1) return; + + if(event==0) { + insertkey(id, CAM_LENS); + } + if(event==1) { + insertkey(id, CAM_STA); + insertkey(id, CAM_END); + } + } + } + } + else if(G.buts->mainb==BUTS_SOUND) { + if(G.ssound) { + id= G.buts->lockpoin; + if(id) { + event= pupmenu("Insert Key %t|Volume%x0|Pitch%x1|Panning%x2|Attennuation%x3"); + if(event== -1) return; + + if(event==0) { + insertkey(id, SND_VOLUME); + } + if(event==1) { + insertkey(id, SND_PITCH); + } + if(event==2) { + insertkey(id, SND_PANNING); + } + if(event==3) { + insertkey(id, SND_ATTEN); + } + } + } + } + + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); + + } + else if(curarea->spacetype==SPACE_VIEW3D) { + + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) break; + base= base->next; + } + if(base==0) return; + + if (G.obpose) + strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Avail%x9"); + else + strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Layer%x5|Avail%x9"); + + + if( (ob = OBACT)) { + if(ob->type==OB_MESH) strcat(menustr, "| %x6|Mesh%x7"); + else if(ob->type==OB_LATTICE) strcat(menustr, "| %x6|Lattice%x7"); + else if(ob->type==OB_CURVE) strcat(menustr, "| %x6|Curve%x7"); + else if(ob->type==OB_SURF) strcat(menustr, "| %x6|Surface%x7"); + else if(ob->type==OB_IKA) strcat(menustr, "| %x6|Effector%x8"); + if(ob->flag & OB_FROMGROUP) strcat(menustr, "| %x6|Entire Group%x10"); + } + + event= pupmenu(menustr); + if(event== -1) return; + + if(event==7) { + if(ob->type==OB_MESH) insert_meshkey(ob->data); + else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(ob->data); + else if(ob->type==OB_LATTICE) insert_lattkey(ob->data); + + allqueue(REDRAWIPO, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWBUTSANIM, 0); + return; + } + + if(event==10) { + Group *group= find_group(ob); + if(group) { + add_group_key(group); + allqueue(REDRAWBUTSANIM, 0); + } + } + + base= FIRSTBASE; + if (G.obpose){ + bAction *act; + bPose *pose; + bPoseChannel *chan; + bActionChannel *achan; + + ob = G.obpose; + + /* Get action & pose from object */ + act=ob->action; + pose=ob->pose; + + collect_pose_garbage(ob); + + if (!act){ + act=G.obpose->action=add_empty_action(); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + if (!pose){ + error ("No pose!"); /* Should never happen */ + } + + if (act->id.lib) + { + error ("Can't key libactions"); + return; + } + filter_pose_keys (); + for (chan=pose->chanbase.first; chan; chan=chan->next) + { + if (chan->flag & POSE_KEY){ + // set_action_key(act, chan); + if(event==0 || event==3 ||event==4) { + set_action_key(act, chan, AC_LOC_X, 1); + set_action_key(act, chan, AC_LOC_Y, 1); + set_action_key(act, chan, AC_LOC_Z, 1); + } + if(event==1 || event==3 ||event==4) { + set_action_key(act, chan, AC_QUAT_X, 1); + set_action_key(act, chan, AC_QUAT_Y, 1); + set_action_key(act, chan, AC_QUAT_Z, 1); + set_action_key(act, chan, AC_QUAT_W, 1); + } + if(event==2 || event==4) { + set_action_key(act, chan, AC_SIZE_X, 1); + set_action_key(act, chan, AC_SIZE_Y, 1); + set_action_key(act, chan, AC_SIZE_Z, 1); + } + if (event==9){ + for (achan = act->chanbase.first; achan; achan=achan->next){ + if (achan->ipo && !strcmp (achan->name, chan->name)){ + for (icu = achan->ipo->curve.first; icu; icu=icu->next){ + set_action_key(act, chan, icu->adrcode, 0); + } + break; + } + } + } + } + + remake_action_ipos(act); + } + allqueue(REDRAWIPO, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + + } + else + { + while(base) { + if TESTBASELIB(base) { + id= (ID *)(base->object); + + /* alle curves in ipo deselect */ + if(base->object->ipo) { + icu= base->object->ipo->curve.first; + while(icu) { + icu->flag &= ~IPO_SELECT; + if(event==9) insertkey(id, icu->adrcode); + icu= icu->next; + } + } + + if(event==0 || event==3 ||event==4) { + insertkey(id, OB_LOC_X); + insertkey(id, OB_LOC_Y); + insertkey(id, OB_LOC_Z); + } + if(event==1 || event==3 ||event==4) { + insertkey(id, OB_ROT_X); + insertkey(id, OB_ROT_Y); + insertkey(id, OB_ROT_Z); + } + if(event==2 || event==4) { + insertkey(id, OB_SIZE_X); + insertkey(id, OB_SIZE_Y); + insertkey(id, OB_SIZE_Z); + } + if(event==5) { + /* localview weghalen */ + tlay= base->object->lay; + base->object->lay &= 0xFFFFFF; + insertkey(id, OB_LAY); + base->object->lay= tlay; + } + if(event==8) { + /* deze patch moet omdat duplicators de positie van effg veranderen */ + Ika *ika= ob->data; + VecMat4MulVecfl(ika->effg, ob->obmat, ika->effn); + + insertkey(id, OB_EFF_X); + insertkey(id, OB_EFF_Y); + insertkey(id, OB_EFF_Z); + } + } + base= base->next; + } + } + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + +} + + +/* **************************************************** */ + +/* IPOKEY: + * + * er zijn drie manieren om hiermee om te gaan: + * 1. hieronder: voor tekenen en editen in Ipo window + * 2. voor tekenen keys in View3D (zie ipo.c en drawobject.c) + * 3. voor editen keys in View3D (hieronder en editobject.c) + * + */ + + +void free_ipokey(ListBase *lb) +{ + IpoKey *ik; + + ik= lb->first; + while(ik) { + if(ik->data) MEM_freeN(ik->data); + ik= ik->next; + } + BLI_freelistN(lb); +} + + +void add_to_ipokey(ListBase *lb, BezTriple *bezt, int nr, int len) +{ + IpoKey *ik, *ikn; + + ik= lb->first; + while(ik) { + + if( ik->val==bezt->vec[1][0] ) { + if(ik->data[nr]==0) { /* dubbele punten! */ + ik->data[nr]= bezt; + if(bezt->f2 & 1) ik->flag= 1; + return; + } + } + else if(ik->val > bezt->vec[1][0]) break; + + ik= ik->next; + } + + ikn= MEM_callocN(sizeof(IpoKey), "add_to_ipokey"); + if(ik) BLI_insertlinkbefore(lb, ik, ikn); + else BLI_addtail(lb, ikn); + + ikn->data= MEM_callocN(sizeof(float *)*len, "add_to_ipokey"); + ikn->data[nr]= bezt; + ikn->val= bezt->vec[1][0]; + + if(bezt->f2 & 1) ikn->flag= 1; +} + +void make_ipokey(void) +{ + EditIpo *ei; + IpoKey *ik; + ListBase *lb; + BezTriple *bezt; + int a, b, sel, desel, totvert; + + lb= &G.sipo->ipokey; + free_ipokey(lb); + + ei= G.sipo->editipo; + if(ei==0) return; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + bezt= ei->icu->bezt; + totvert= ei->icu->totvert; + + for(b=0; b<totvert; b++, bezt++) { + add_to_ipokey(lb, bezt, a, G.sipo->totipo); + } + + ei->flag &= ~IPO_SELECT; + ei->flag &= ~IPO_EDIT; + ei->icu->flag= ei->flag; + } + } + + /* selectflags testen */ + ik= lb->first; + while(ik) { + sel= desel= 0; + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + bezt= ik->data[a]; + if(bezt->f2 & 1) sel++; + else desel++; + } + } + if(sel && desel) sel= 0; + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + bezt= ik->data[a]; + if(sel) { + bezt->f1 |= 1; + bezt->f2 |= 1; + bezt->f3 |= 1; + } + else { + bezt->f1 &= ~1; + bezt->f2 &= ~1; + bezt->f3 &= ~1; + } + } + } + if(sel) ik->flag = 1; + else ik->flag= 0; + + ik= ik->next; + } + get_status_editipo(); +} + +void make_ipokey_transform(Object *ob, ListBase *lb, int sel) +{ + IpoCurve *icu; + BezTriple *bezt; + int a, adrcode = 0, ok, dloc=0, drot=0, dsize=0; + + if(ob->ipo==0) return; + if(ob->ipo->showkey==0) return; + + /* testen: zijn er delta curves? */ + icu= ob->ipo->curve.first; + while(icu) { + if(icu->flag & IPO_VISIBLE) { + switch(icu->adrcode) { + case OB_DLOC_X: + case OB_DLOC_Y: + case OB_DLOC_Z: + dloc= 1; + break; + case OB_DROT_X: + case OB_DROT_Y: + case OB_DROT_Z: + drot= 1; + break; + case OB_DSIZE_X: + case OB_DSIZE_Y: + case OB_DSIZE_Z: + dsize= 1; + break; + } + } + icu= icu->next; + } + + icu= ob->ipo->curve.first; + while(icu) { + if(icu->flag & IPO_VISIBLE) { + ok= 0; + + switch(icu->adrcode) { + case OB_DLOC_X: + case OB_DLOC_Y: + case OB_DLOC_Z: + case OB_DROT_X: + case OB_DROT_Y: + case OB_DROT_Z: + case OB_DSIZE_X: + case OB_DSIZE_Y: + case OB_DSIZE_Z: + ok= 1; + break; + + case OB_LOC_X: + case OB_LOC_Y: + case OB_LOC_Z: + if(dloc==0) ok= 1; + break; + case OB_ROT_X: + case OB_ROT_Y: + case OB_ROT_Z: + if(drot==0) ok= 1; + break; + case OB_SIZE_X: + case OB_SIZE_Y: + case OB_SIZE_Z: + if(dsize==0) ok= 1; + break; + } + if(ok) { + for(a=0; a<OB_TOTIPO; a++) { + if(icu->adrcode==ob_ar[a]) { + adrcode= a; + break; + } + } + + bezt= icu->bezt; + a= icu->totvert; + while(a--) { + if(sel==0 || (bezt->f2 & 1)) { + add_to_ipokey(lb, bezt, adrcode, OB_TOTIPO); + } + bezt++; + } + } + } + icu= icu->next; + } +} + +void update_ipokey_val() /* na verplaatsen vertices */ +{ + IpoKey *ik; + int a; + + ik= G.sipo->ipokey.first; + while(ik) { + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + ik->val= ik->data[a]->vec[1][0]; + break; + } + } + ik= ik->next; + } +} + +void set_tob_old(float *old, float *poin) +{ + old[0]= *(poin); + old[3]= *(poin-3); + old[6]= *(poin+3); +} + +void set_ipo_pointers_transob(IpoKey *ik, TransOb *tob) +{ + BezTriple *bezt; + int a, delta= 0; + + tob->locx= tob->locy= tob->locz= 0; + tob->rotx= tob->roty= tob->rotz= 0; + tob->sizex= tob->sizey= tob->sizez= 0; + + for(a=0; a<OB_TOTIPO; a++) { + if(ik->data[a]) { + bezt= ik->data[a]; + + switch( ob_ar[a] ) { + case OB_LOC_X: + case OB_DLOC_X: + tob->locx= &(bezt->vec[1][1]); break; + case OB_LOC_Y: + case OB_DLOC_Y: + tob->locy= &(bezt->vec[1][1]); break; + case OB_LOC_Z: + case OB_DLOC_Z: + tob->locz= &(bezt->vec[1][1]); break; + + case OB_DROT_X: + delta= 1; + case OB_ROT_X: + tob->rotx= &(bezt->vec[1][1]); break; + case OB_DROT_Y: + delta= 1; + case OB_ROT_Y: + tob->roty= &(bezt->vec[1][1]); break; + case OB_DROT_Z: + delta= 1; + case OB_ROT_Z: + tob->rotz= &(bezt->vec[1][1]); break; + + case OB_SIZE_X: + case OB_DSIZE_X: + tob->sizex= &(bezt->vec[1][1]); break; + case OB_SIZE_Y: + case OB_DSIZE_Y: + tob->sizey= &(bezt->vec[1][1]); break; + case OB_SIZE_Z: + case OB_DSIZE_Z: + tob->sizez= &(bezt->vec[1][1]); break; + } + } + } + + /* oldvals voor o.a. undo */ + if(tob->locx) set_tob_old(tob->oldloc, tob->locx); + if(tob->locy) set_tob_old(tob->oldloc+1, tob->locy); + if(tob->locz) set_tob_old(tob->oldloc+2, tob->locz); + + /* bewaar de eerste oldrot, ivm mapping curves ('1'=10 graden) en correcte berekening */ + if(tob->rotx) set_tob_old(tob->oldrot+3, tob->rotx); + if(tob->roty) set_tob_old(tob->oldrot+4, tob->roty); + if(tob->rotz) set_tob_old(tob->oldrot+5, tob->rotz); + + /* bewaar de eerste oldsize, dit mag niet de dsize zijn! */ + if(tob->sizex) set_tob_old(tob->oldsize+3, tob->sizex); + if(tob->sizey) set_tob_old(tob->oldsize+4, tob->sizey); + if(tob->sizez) set_tob_old(tob->oldsize+5, tob->sizez); + + tob->flag= TOB_IPO; + if(delta) tob->flag |= TOB_IPODROT; +} + + + +void nextkey(ListBase *elems, int dir) +{ + IpoKey *ik, *previk; + int totsel; + + if(dir==1) ik= elems->last; + else ik= elems->first; + previk= 0; + totsel= 0; + + while(ik) { + + if(ik->flag) totsel++; + + if(previk) { + if(G.qual & LR_SHIFTKEY) { + if(ik->flag) previk->flag= 1; + } + else previk->flag= ik->flag; + } + + previk= ik; + if(dir==1) ik= ik->prev; + else ik= ik->next; + + if(G.qual & LR_SHIFTKEY); + else if(ik==0) previk->flag= 0; + } + + /* als geen een key select: */ + if(totsel==0) { + if(dir==1) ik= elems->first; + else ik= elems->last; + + if(ik) ik->flag= 1; + } +} + +static int float_to_frame (float frame) +{ + int to= (int) frame; + + if (frame-to>0.5) to++; + + return to; +} + +void movekey_ipo(int dir) /* alleen extern aanroepen vanuit view3d queue */ +{ + IpoKey *ik; + float toframe = 0.0; + int a; + + if(G.sipo->showkey==0) return; + + ik= G.sipo->ipokey.first; + if (dir==-1) { + while (ik && float_to_frame(ik->val)<CFRA) { + toframe= ik->val; + ik= ik->next; + } + } else { + while (ik && float_to_frame(ik->val)<=CFRA) { + ik= ik->next; + } + if (ik) toframe= ik->val; + } + + a= float_to_frame(toframe); + + if (a!=CFRA && a>0) { + CFRA= a; + + update_for_newframe(); + } + + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); + +} + +void movekey_obipo(int dir) /* alleen extern aanroepen vanuit view3d queue */ +{ + Base *base; + Object *ob; + ListBase elems; + IpoKey *ik; + int a; + float toframe= CFRA; + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + ob= base->object; + if(ob->ipo && ob->ipo->showkey) { + elems.first= elems.last= 0; + make_ipokey_transform(ob, &elems, 0); + + if(elems.first) { + ik= elems.first; + if (dir==-1) { + while (ik && float_to_frame(ik->val)<CFRA) { + toframe= ik->val; + ik= ik->next; + } + } else { + while (ik && float_to_frame(ik->val)<=CFRA) { + ik= ik->next; + } + if (ik) toframe= ik->val; + } + + free_ipokey(&elems); + } + } + } + + base= base->next; + } + + a= float_to_frame(toframe); + + if (a!=CFRA && a>0) { + CFRA= a; + + update_for_newframe(); + } + + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); + +} + +void nextkey_ipo(int dir) /* aanroepen vanuit ipo queue */ +{ + IpoKey *ik; + int a; + + if(G.sipo->showkey==0) return; + + nextkey(&G.sipo->ipokey, dir); + + /* kopieeren naar beziers */ + ik= G.sipo->ipokey.first; + while(ik) { + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) ik->data[a]->f1= ik->data[a]->f2= ik->data[a]->f3= ik->flag; + } + ik= ik->next; + } + + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + if(G.sipo->blocktype == ID_OB) allqueue(REDRAWVIEW3D, 0); +} + +void nextkey_obipo(int dir) /* alleen extern aanroepen vanuit view3d queue */ +{ + Base *base; + Object *ob; + ListBase elems; + IpoKey *ik; + int a; + + /* problem: this doesnt work when you mix dLoc keys with Loc keys */ + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + ob= base->object; + if( (ob->ipoflag & OB_DRAWKEY) && ob->ipo && ob->ipo->showkey) { + elems.first= elems.last= 0; + make_ipokey_transform(ob, &elems, 0); + + if(elems.first) { + + nextkey(&elems, dir); + + /* kopieeren naar beziers */ + ik= elems.first; + while(ik) { + for(a=0; a<OB_TOTIPO; a++) { + if(ik->data[a]) ik->data[a]->f1= ik->data[a]->f2= ik->data[a]->f3= ik->flag; + } + ik= ik->next; + } + + free_ipokey(&elems); + } + } + } + + base= base->next; + } + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWVIEW3D, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); +} + + +/* **************************************************** */ + + +void remake_ipo_transverts(TransVert *transmain, float *dvec, int tot) +{ + EditIpo *ei; + TransVert *tv; + BezTriple *bezt; + int a, b; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + + if(ei->icu->bezt) { + sort_time_ipocurve(ei->icu); + } + } + } + + ei= G.sipo->editipo; + tv= transmain; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(ei->icu->ipo==IPO_BEZ) { + if(bezt->f1 & 1) { + tv->loc= bezt->vec[0]; + tv++; + } + if(bezt->f3 & 1) { + tv->loc= bezt->vec[2]; + tv++; + } + } + if(bezt->f2 & 1) { + tv->loc= bezt->vec[1]; + tv++; + } + + bezt++; + } + testhandles_ipocurve(ei->icu); + } + } + } + } + + if(G.sipo->showkey) make_ipokey(); + + if(dvec==0) return; + + tv= transmain; + for(a=0; a<tot; a++, tv++) { + tv->oldloc[0]= tv->loc[0]-dvec[0]; + tv->oldloc[1]= tv->loc[1]-dvec[1]; + } +} + +void transform_ipo(int mode) +{ + EditIpo *ei; + BezTriple *bezt; + TransVert *transmain = NULL, *tv; + float xref=1.0, yref=1.0, dx, dy, dvec[2], min[3], max[3], vec[2], div, cent[2], size[2], sizefac; + int tot=0, a, b, firsttime=1, afbreek=0, midtog= 0, dosort, proj = 0; + unsigned short event = 0; + short mval[2], val, xo, yo, xn, yn, xc, yc; + char str[32]; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + if(G.sipo->editipo==0) return; + if(mode=='r') return; /* vanuit gesture */ + + INIT_MINMAX(min, max); + + /* welke vertices doen mee */ + get_status_editipo(); + if(totipo_vertsel) { + tot= totipo_vertsel; + tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain"); + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + + + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(ei->icu->ipo==IPO_BEZ) { + if(bezt->f1 & 1) { + tv->loc= bezt->vec[0]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + + /* let op: we nemen middelste vertex */ + DO_MINMAX2(bezt->vec[1], min, max); + + tv++; + } + if(bezt->f3 & 1) { + tv->loc= bezt->vec[2]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + + /* let op: we nemen middelste vertex */ + DO_MINMAX2(bezt->vec[1], min, max); + + tv++; + } + } + if(bezt->f2 & 1) { + tv->loc= bezt->vec[1]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + DO_MINMAX2(bezt->vec[1], min, max); + tv++; + } + bezt++; + } + } + } + } + } + + } + else if(totipo_edit==0 && totipo_sel!=0) { + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) { + if(ei->icu->bezt && ei->icu->ipo==IPO_BEZ) tot+= 3*ei->icu->totvert; + else tot+= ei->icu->totvert; + } + } + if(tot==0) return; + + tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain"); + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) { + if(ei->icu->bezt) { + + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(ei->icu->ipo==IPO_BEZ) { + tv->loc= bezt->vec[0]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + tv++; + + tv->loc= bezt->vec[2]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + tv++; + } + tv->loc= bezt->vec[1]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + + DO_MINMAX2(bezt->vec[1], min, max); + + tv++; + + bezt++; + } + } + } + } + + } + + if(tot==0) { + if(totipo_edit==0) move_keys(); + return; + } + + cent[0]= (float)((min[0]+max[0])/2.0); + cent[1]= (float)((min[1]+max[1])/2.0); + + if(G.sipo->showkey) { + midtog= 1; + proj= 1; + } + + ipoco_to_areaco(G.v2d, cent, mval); + xc= mval[0]; + yc= mval[1]; + + getmouseco_areawin(mval); + xo= xn= mval[0]; + yo= yn= mval[1]; + dvec[0]= dvec[1]= 0.0; + + sizefac= (float)(sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) )); + if(sizefac<2.0) sizefac= 2.0; + + while(afbreek==0) { + getmouseco_areawin(mval); + if(mval[0]!=xo || mval[1]!=yo || firsttime) { + + if(mode=='g') { + + dx= (float)(mval[0]- xo); + dy= (float)(mval[1]- yo); + + div= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin); + dvec[0]+= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div; + + div= (float)(G.v2d->mask.ymax-G.v2d->mask.ymin); + dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div; + + if(midtog) dvec[proj]= 0.0; + + /* vec wordt verderop nog gebruikt: remake_ipo_transverts */ + vec[0]= dvec[0]; + vec[1]= dvec[1]; + + apply_keyb_grid(vec, 0.0, (float)1.0, (float)0.1, U.flag & AUTOGRABGRID); + apply_keyb_grid(vec+1, 0.0, (float)1.0, (float)0.1, 0); + + tv= transmain; + for(a=0; a<tot; a++, tv++) { + tv->loc[0]= tv->oldloc[0]+vec[0]; + + if(tv->flag==0) tv->loc[1]= tv->oldloc[1]+vec[1]; + } + + sprintf(str, "X: %.3f Y: %.3f ", vec[0], vec[1]); + headerprint(str); + } + else if(mode=='s') { + + size[0]=size[1]=(float)( (sqrt( (float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc)) ))/sizefac); + + if(midtog) size[proj]= 1.0; + size[0]*= xref; + size[1]*= yref; + + apply_keyb_grid(size, 0.0, (float)0.2, (float)0.1, U.flag & AUTOSIZEGRID); + apply_keyb_grid(size+1, 0.0, (float)0.2, (float)0.1, U.flag & AUTOSIZEGRID); + + tv= transmain; + + for(a=0; a<tot; a++, tv++) { + tv->loc[0]= size[0]*(tv->oldloc[0]-cent[0])+ cent[0]; + if(tv->flag==0) tv->loc[1]= size[1]*(tv->oldloc[1]-cent[1])+ cent[1]; + } + + sprintf(str, "sizeX: %.3f sizeY: %.3f ", size[0], size[1]); + headerprint(str); + + } + + xo= mval[0]; + yo= mval[1]; + + dosort= 0; + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + + /* let op: als de tijd verkeerd is: niet de handles corrigeren */ + if (test_time_ipocurve(ei->icu) ) dosort++; + else testhandles_ipocurve(ei->icu); + } + } + + if(dosort) { + if(mode=='g') remake_ipo_transverts(transmain, vec, tot); + else remake_ipo_transverts(transmain, 0, tot); + } + if(G.sipo->showkey) update_ipokey_val(); + + calc_ipo(G.sipo->ipo, (float)CFRA); + + /* update realtime */ + if(G.sipo->lock) { + if(G.sipo->blocktype==ID_MA) { + force_draw_plus(SPACE_BUTS); + } + else if(G.sipo->blocktype==ID_KE) { + do_ob_key(OBACT); + makeDispList(OBACT); + force_draw_plus(SPACE_VIEW3D); + } + else if(G.sipo->blocktype==ID_AC) { + do_all_actions(); + force_draw_all(); + } + else if(G.sipo->blocktype==ID_OB) { + Base *base= FIRSTBASE; + + while(base) { + if(base->object->ipo==G.sipo->ipo) do_ob_ipo(base->object); + base= base->next; + } + force_draw_plus(SPACE_VIEW3D); + } + else force_draw(); + } + else { + force_draw(); + } + firsttime= 0; + } + else BIF_wait_for_statechange(); + + while(qtest()) { + event= extern_qread(&val); + if(val) { + switch(event) { + case ESCKEY: + case LEFTMOUSE: + case RIGHTMOUSE: + case SPACEKEY: + case RETKEY: + afbreek= 1; + break; + case MIDDLEMOUSE: + if(G.sipo->showkey==0) { + midtog= ~midtog; + if(midtog) { + if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1; + else proj= 0; + firsttime= 1; + } + } + break; + case XKEY: + case YKEY: + if(event==XKEY) xref= -xref; + else if(G.sipo->showkey==0) yref= -yref; + firsttime= 1; + break; + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + firsttime= 1; + break; + default: + if(mode=='g') { + if(G.qual & LR_CTRLKEY) { + if(event==LEFTARROWKEY) {dvec[0]-= 1.0; firsttime= 1;} + else if(event==RIGHTARROWKEY) {dvec[0]+= 1.0; firsttime= 1;} + else if(event==UPARROWKEY) {dvec[1]+= 1.0; firsttime= 1;} + else if(event==DOWNARROWKEY) {dvec[1]-= 1.0; firsttime= 1;} + } + else arrows_move_cursor(event); + } + else arrows_move_cursor(event); + } + } + if(afbreek) break; + } + } + + if(event==ESCKEY || event==RIGHTMOUSE) { + tv= transmain; + for(a=0; a<tot; a++, tv++) { + tv->loc[0]= tv->oldloc[0]; + tv->loc[1]= tv->oldloc[1]; + } + + dosort= 0; + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + if( test_time_ipocurve(ei->icu)) { + dosort= 1; + break; + } + } + } + } + + if(dosort) remake_ipo_transverts(transmain, 0, tot); + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + testhandles_ipocurve(ei->icu); + } + } + } + calc_ipo(G.sipo->ipo, (float)CFRA); + } + + editipo_changed(G.sipo, 1); + + MEM_freeN(transmain); +} + +void clever_numbuts_ipo() +{ + BezTriple *bezt=0, *bezt1; + Key *key; + KeyBlock *kb; + EditIpo *ei; + float far, delta[3], old[3]; + int a, b, scale10=0, totbut=2; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + if(G.sipo->editipo==0) return; + + /* welke vertices doen mee */ + get_status_editipo(); + + if(G.qual & LR_SHIFTKEY) totbut= 1; + + if(G.vd==0) far= 10000.0; + else far= (float)(MAX2(G.vd->far, 10000.0)); + + if(totipo_vertsel) { + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + + if(ei->icu->bezt) { + bezt1= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(BEZSELECTED(bezt1)) { + bezt= bezt1; + break; + } + bezt1++; + } + + } + } + } + if(bezt) break; + } + + if(bezt==0) return; + + if(bezt->f2 & 1) { + + VECCOPY(old, bezt->vec[1]); + + if(totipo_vis==1 && G.sipo->blocktype==ID_OB) { + if ELEM4(ei->icu->adrcode, OB_TIME, OB_ROT_X, OB_ROT_Y, OB_ROT_Z) scale10= 1; + if ELEM3(ei->icu->adrcode, OB_DROT_X, OB_DROT_Y, OB_DROT_Z) scale10= 1; + } + if(scale10) bezt->vec[1][1]*= 10.0; + + add_numbut(0, NUM|FLO, "LocX:", -1000, 10000, bezt->vec[1], 0); + if(totbut==2) add_numbut(1, NUM|FLO, "LocY:", -far, far, bezt->vec[1]+1, 0); + do_clever_numbuts("Active BezierPoint", totbut, REDRAW); + + if(scale10) bezt->vec[1][1]/= 10.0; + + VecSubf(delta, bezt->vec[1], old); + VECCOPY(bezt->vec[1], old); + + /* apply */ + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(bezt->f2 & 1) { + bezt->vec[0][0]+= delta[0]; + bezt->vec[1][0]+= delta[0]; + bezt->vec[2][0]+= delta[0]; + + bezt->vec[0][1]+= delta[1]; + bezt->vec[1][1]+= delta[1]; + bezt->vec[2][1]+= delta[1]; + } + bezt++; + } + } + } + } + } + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + sort_time_ipocurve(ei->icu); + testhandles_ipocurve(ei->icu); + } + } + + } + else if(bezt->f1 & 1) { + add_numbut(0, NUM|FLO, "LocX:", -1000, 10000, bezt->vec[0], 0); + if(totbut==2) add_numbut(1, NUM|FLO, "LocY:", -far, far, bezt->vec[0]+1, 0); + + do_clever_numbuts("Active HandlePoint", totbut, REDRAW); + } + else if(bezt->f3 & 1) { + add_numbut(0, NUM|FLO, "LocX:", -1000, 10000, bezt->vec[0], 0); + if(totbut==2) add_numbut(1, NUM|FLO, "LocY:", -far, far, bezt->vec[2]+1, 0); + + do_clever_numbuts("Active HandlePoint", totbut, REDRAW); + } + + editipo_changed(G.sipo, 1); + } + else { + + if(G.sipo->blocktype==ID_KE) { + key= (Key *)G.sipo->from; + + if(key==0) return; + + kb= key->block.first; + while(kb) { + if(kb->flag & SELECT) break; + kb= kb->next; + } + if(kb && G.sipo->rowbut&1) { + add_numbut(0, NUM|FLO, "Pos:", -100, 100, &kb->pos, 0); + do_clever_numbuts("Active Key", 1, REDRAW); + sort_keys(key); + } + } + } +} + +void filter_sampledata(float *data, int sfra, int efra) +{ + float *da; + int a; + + da= data+1; + for(a=sfra+1; a<efra; a++, da++) { + da[0]=(float)( 0.25*da[-1] + 0.5*da[0] + 0.25*da[1]); + } + +} + +void sampledata_to_ipocurve(float *data, int sfra, int efra, IpoCurve *icu) +{ + BezTriple *bezt; + float *da; + int a, tot; + + filter_sampledata(data, sfra, efra); + filter_sampledata(data, sfra, efra); + + icu->ipo= IPO_LIN; + + if(icu->bezt) MEM_freeN(icu->bezt); + icu->bezt= 0; + + tot= 1; /* eerste punt */ + da= data+1; + for(a=sfra+1; a<efra; a++, da++) { + if( IS_EQ(da[0], da[1])==0 && IS_EQ(da[1], da[2])==0 ) tot++; + } + + icu->totvert= tot; + bezt= icu->bezt= MEM_callocN(tot*sizeof(BezTriple), "samplebezt"); + bezt->vec[1][0]= (float)sfra; + bezt->vec[1][1]= data[0]; + bezt++; + da= data+1; + for(a=sfra+1; a<efra; a++, da++) { + if( IS_EQ(da[0], da[1])==0 && IS_EQ(da[1], da[2])==0 ) { + bezt->vec[1][0]= (float)a; + bezt->vec[1][1]= da[0]; + bezt++; + } + } +} + +void ipo_record() +{ + /* 1 of 2 aktieve curves + * kopie maken (ESC) + * + * nulpunt is de huidige stand (of 0) + * dx (dy identiek) is de hoogteverhouding + * CTRL start record + */ + extern double tottime; + EditIpo *ei, *ei1=0, *ei2=0; + ScrArea *sa, *oldarea; + Ipo *ipo; + void *poin; + double swaptime; + float or1, or2 = 0.0, fac, *data1, *data2; + int type, a, afbreek=0, firsttime=1, cfrao, cfra, sfra, efra; + unsigned short event = 0; + short anim, val, xn, yn, mvalo[2], mval[2]; + char str[128]; + + if(G.sipo->from==0) return; + if(SFRA>=EFRA) return; + + anim= pupmenu("Record Mouse %t|Still %x1|Play anim %x2"); + if(anim < 1) return; + if(anim!=2) anim= 0; + + ipo= get_ipo(G.sipo->from, G.sipo->blocktype, 1); /* 1= make */ + if(G.sipo) G.sipo->ipo= ipo; + + /* find the curves... */ + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if(ei->flag & IPO_VISIBLE) { + + if(ei1==0) ei1= ei; + else if(ei2==0) ei2= ei; + else { + error("Max 2 visible curves"); + return; + } + } + ei++; + } + + if(ei1==0) { + error("Select 1 or 2 channels"); + return; + } + + /* curves gereedmaken, startwaardes */ + if(ei1->icu==0) ei1->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei1->adrcode, 0); + if(ei1->icu==0) return; + poin= get_ipo_poin(G.sipo->from, ei1->icu, &type); + if(poin) ei1->icu->curval= read_ipo_poin(poin, type); + or1= ei1->icu->curval; + ei1->icu->flag |= IPO_LOCK; + + if(ei2) { + if(ei2->icu==0) ei2->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei2->adrcode, 0); + if(ei2->icu==0) return; + poin= get_ipo_poin(G.sipo->from, ei2->icu, &type); + if(poin) ei2->icu->curval= read_ipo_poin(poin, type); + or2= ei2->icu->curval; + ei2->icu->flag |= IPO_LOCK; + } + + fac= G.v2d->cur.ymax - G.v2d->cur.ymin; + fac/= (float)curarea->winy; + + /* welke area */ + oldarea= curarea; + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->win) { + if(G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_LA) { + if(sa->spacetype==SPACE_BUTS) break; + } + else { + if(sa->spacetype==SPACE_VIEW3D) break; + } + } + sa= sa->next; + } + if(sa) areawinset(sa->win); + + /* kandie? */ + while(get_mbut()&L_MOUSE) BIF_wait_for_statechange(); + data1= MEM_callocN(sizeof(float)*(EFRA-SFRA+1), "data1"); + data2= MEM_callocN(sizeof(float)*(EFRA-SFRA+1), "data2"); + + getmouseco_areawin(mvalo); + xn= mvalo[0]; yn= mvalo[1]; + waitcursor(1); + + tottime= 0.0; + swaptime= speed_to_swaptime(G.animspeed); + cfrao= CFRA; + cfra=efra= SFRA; + sfra= EFRA; + + while(afbreek==0) { + + getmouseco_areawin(mval); + + if(mval[0]!= mvalo[0] || mval[1]!=mvalo[1] || firsttime || (G.qual & LR_CTRLKEY)) { + if(anim) CFRA= cfra; + else firsttime= 0; + + set_timecursor(cfra); + + /* ipo doen: eerst alles daarna de specifieke */ + if(anim==2) { + do_all_ipos(); + do_all_keys(); + } + + ei1->icu->curval= or1 + fac*(mval[0]-xn); + if(ei2) ei2->icu->curval= or2 + fac*(mval[1]-yn); + + do_ipo_nocalc(G.sipo->ipo); + do_all_visible_ikas(); + + if(G.qual & LR_CTRLKEY) { + sprintf(str, "Recording... %d\n", cfra); + data1[ cfra-SFRA ]= ei1->icu->curval; + if(ei2) data2[ cfra-SFRA ]= ei2->icu->curval; + + sfra= MIN2(sfra, cfra); + efra= MAX2(efra, cfra); + } + else sprintf(str, "Mouse Recording. Use CTRL to start. LeftMouse or Space to end"); + + do_ob_key(OBACT); + + headerprint(str); + + if(sa) scrarea_do_windraw(sa); + + /* minimaal swaptime laten voorbijgaan */ + tottime -= swaptime; + while (update_time()) PIL_sleep_ms(1); + + screen_swapbuffers(); + + tottime= 0.0; + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + if(anim || (G.qual & LR_CTRLKEY)) { + cfra++; + if(cfra>EFRA) cfra= SFRA; + } + } + + while(qtest()) { + event= extern_qread(&val); + if(val) { + switch(event) { + case LEFTMOUSE: case ESCKEY: case SPACEKEY: case RETKEY: + afbreek= 1; + break; + } + } + if(afbreek) break; + } + } + + if(event!=ESCKEY) { + sampledata_to_ipocurve(data1+sfra-SFRA, sfra, efra, ei1->icu); + if(ei2) sampledata_to_ipocurve(data2+sfra-SFRA, sfra, efra, ei2->icu); + + /* vervelend als dat aanstaat */ + if(G.sipo->showkey) { + G.sipo->showkey= 0; + free_ipokey(&G.sipo->ipokey); + } + } + else { + /* undo: startwaardes */ + poin= get_ipo_poin(G.sipo->from, ei1->icu, &type); + if(poin) write_ipo_poin(poin, type, or1); + if(ei1->icu->bezt==0) { + BLI_remlink( &(G.sipo->ipo->curve), ei1->icu); + MEM_freeN(ei1->icu); + ei1->icu= 0; + } + if(ei2) { + poin= get_ipo_poin(G.sipo->from, ei2->icu, &type); + if(poin) write_ipo_poin(poin, type, or2); + if(ei2->icu->bezt==0) { + BLI_remlink( &(G.sipo->ipo->curve), ei2->icu); + MEM_freeN(ei2->icu); + ei2->icu= 0; + } + } + } + + if(ei1->icu) ei1->icu->flag &= ~IPO_LOCK; + if(ei2 && ei2->icu) ei2->icu->flag &= ~IPO_LOCK; + + editipo_changed(G.sipo, 0); + do_ipo(G.sipo->ipo); + waitcursor(0); + allqueue(REDRAWVIEW3D, 0); + if(sa) scrarea_queue_headredraw(sa); /* headerprint */ + scrarea_queue_redraw(oldarea); + CFRA= cfrao; + + /* vooropig? */ + update_for_newframe(); + + MEM_freeN(data1); + MEM_freeN(data2); +} + + + +void remake_object_ipos(Object *ob) +{ + IpoCurve *icu; + + if (!ob) + return; + if (!ob->ipo) + return; + + for (icu = ob->ipo->curve.first; icu; icu=icu->next){ + sort_time_ipocurve(icu); + testhandles_ipocurve(icu); + } +} + + +int is_ipo_key_selected(Ipo *ipo) +{ + int i; + IpoCurve *icu; + + if (!ipo) + return 0; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++) + if (BEZSELECTED(&icu->bezt[i])) + return 1; + } + + return 0; +} + + +void set_ipo_key_selection(Ipo *ipo, int sel) +{ + int i; + IpoCurve *icu; + + if (!ipo) + return; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (sel){ + icu->bezt[i].f1|=1; + icu->bezt[i].f2|=1; + icu->bezt[i].f3|=1; + } + else{ + icu->bezt[i].f1&=~1; + icu->bezt[i].f2&=~1; + icu->bezt[i].f3&=~1; + } + } + } +} + +void delete_ipo_keys(Ipo *ipo) +{ + IpoCurve *icu, *next; + int i; + + if (!ipo) + return; + + for (icu=ipo->curve.first; icu; icu=next){ + next = icu->next; + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].f2 & 1){ + // Delete the item + memcpy (&icu->bezt[i], &icu->bezt[i+1], sizeof (BezTriple)*(icu->totvert-i-1)); + icu->totvert--; + i--; + } + } + if (!icu->totvert){ + /* Delete the curve */ + BLI_remlink( &(ipo->curve), icu); + if(icu->bezt) MEM_freeN(icu->bezt); + MEM_freeN(icu); + } + } +} + +int fullselect_ipo_keys(Ipo *ipo) +{ + int i; + IpoCurve *icu; + int tvtot = 0; + + if (!ipo) + return tvtot; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].f2 & 1){ + tvtot+=3; + icu->bezt[i].f1 |= 1; + icu->bezt[i].f3 |= 1; + } + } + } + + return tvtot; +} + +int add_trans_ipo_keys(Ipo *ipo, TransVert *tv, int tvtot) +{ + int i; + IpoCurve *icu; + + if (!ipo) + return tvtot; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].f2 & 1){ + tv[tvtot+0].loc=icu->bezt[i].vec[0]; + tv[tvtot+1].loc=icu->bezt[i].vec[1]; + tv[tvtot+2].loc=icu->bezt[i].vec[2]; + + memcpy (&tv[tvtot+0].oldloc, icu->bezt[i].vec[0], sizeof (float)*3); + memcpy (&tv[tvtot+1].oldloc, icu->bezt[i].vec[1], sizeof (float)*3); + memcpy (&tv[tvtot+2].oldloc, icu->bezt[i].vec[2], sizeof (float)*3); + tvtot+=3; + } + } + } + + return tvtot; +} + +void duplicate_ipo_keys(Ipo *ipo) +{ + IpoCurve *icu; + int i; + BezTriple *newbezt; + + if (!ipo) + return; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + /* If a key is selected */ + if (icu->bezt[i].f2 & 1){ + /* Expand the list */ + newbezt = MEM_callocN(sizeof(BezTriple) * (icu->totvert+1), "beztriple"); + memcpy (newbezt, icu->bezt, sizeof(BezTriple) * (i+1)); + memcpy (newbezt+i+1, icu->bezt+i, sizeof(BezTriple)); + memcpy (newbezt+i+2, icu->bezt+i+1, sizeof (BezTriple) *(icu->totvert-(i+1))); + icu->totvert++; + MEM_freeN (icu->bezt); + icu->bezt=newbezt; + /* Unselect the current key*/ + icu->bezt[i].f1 &= ~ 1; + icu->bezt[i].f2 &= ~ 1; + icu->bezt[i].f3 &= ~ 1; + i++; + /* Select the copied key */ + icu->bezt[i].f1 |= 1; + icu->bezt[i].f2 |= 1; + icu->bezt[i].f3 |= 1; + + } + } + } +} + +void borderselect_ipo_key(Ipo *ipo, float xmin, float xmax, int val) +{ + int i; + IpoCurve *icu; + + if (!ipo) + return; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].vec[1][0] > xmin && icu->bezt[i].vec[1][0] < xmax ){ + if (val==1){ + icu->bezt[i].f1 |= 1; + icu->bezt[i].f2 |= 1; + icu->bezt[i].f3 |= 1; + } + else{ + icu->bezt[i].f1 &= ~1; + icu->bezt[i].f2 &= ~1; + icu->bezt[i].f3 &= ~1; + } + } + } + } +} + +void select_ipo_key(Ipo *ipo, float selx, int sel) +{ + int i; + IpoCurve *icu; + + if (!ipo) + return; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].vec[1][0]==selx){ + if (sel) { + icu->bezt[i].f1 &= ~1; + icu->bezt[i].f2 &= ~1; + icu->bezt[i].f3 &= ~1; + } + else { + icu->bezt[i].f1 |= 1; + icu->bezt[i].f2 |= 1; + icu->bezt[i].f3 |= 1; + } + } + } + } +}
\ No newline at end of file diff --git a/source/blender/src/editkey.c b/source/blender/src/editkey.c new file mode 100644 index 00000000000..9ef514102f4 --- /dev/null +++ b/source/blender/src/editkey.c @@ -0,0 +1,654 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_curve_types.h" +#include "DNA_ipo_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view2d_types.h" +#include "DNA_lattice_types.h" +#include "DNA_scene_types.h" + +#include "BKE_utildefines.h" +#include "BKE_anim.h" +#include "BKE_curve.h" +#include "BKE_global.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_object.h" + +#include "BIF_editkey.h" +#include "BIF_editview.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_toolbox.h" + +#include "BSE_editipo.h" +#include "BSE_trans_types.h" + +#include "BDR_editobject.h" + +#include "blendef.h" +#include "mydevice.h" +#include "ipo.h" + +extern ListBase editNurb; /* in editcurve.c */ + +static void default_key_ipo(Key *key) +{ + IpoCurve *icu; + BezTriple *bezt; + + key->ipo= add_ipo("KeyIpo", ID_KE); + + icu= MEM_callocN(sizeof(IpoCurve), "ipocurve"); + + icu->blocktype= ID_KE; + icu->adrcode= KEY_SPEED; + icu->flag= IPO_VISIBLE+IPO_SELECT; + set_icu_vars(icu); + + BLI_addtail( &(key->ipo->curve), icu); + + icu->bezt= bezt= MEM_callocN(2*sizeof(BezTriple), "defaultipo"); + icu->totvert= 2; + + bezt->hide= IPO_BEZ; + bezt->f1=bezt->f2= bezt->f3= SELECT; + bezt->h1= bezt->h2= HD_AUTO; + bezt++; + bezt->vec[1][0]= 100.0; + bezt->vec[1][1]= 1.0; + bezt->hide= IPO_BEZ; + bezt->f1=bezt->f2= bezt->f3= SELECT; + bezt->h1= bezt->h2= HD_AUTO; + + calchandles_ipocurve(icu); +} + + + +/* **************************************** */ + +void mesh_to_key(Mesh *me, KeyBlock *kb) +{ + MVert *mvert; + float *fp; + int a; + + if(me->totvert==0) return; + + if(kb->data) MEM_freeN(kb->data); + + kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data"); + kb->totelem= me->totvert; + + mvert= me->mvert; + fp= kb->data; + for(a=0; a<kb->totelem; a++, fp+=3, mvert++) { + VECCOPY(fp, mvert->co); + + } +} + +void key_to_mesh(KeyBlock *kb, Mesh *me) +{ + MVert *mvert; + float *fp; + int a, tot; + + mvert= me->mvert; + fp= kb->data; + + tot= MIN2(kb->totelem, me->totvert); + + for(a=0; a<tot; a++, fp+=3, mvert++) { + VECCOPY(mvert->co, fp); + } +} + + + +void insert_meshkey(Mesh *me) +{ + Key *key; + KeyBlock *kb, *kkb; + float curpos; + + if(me->key==0) { + me->key= add_key( (ID *)me); + default_key_ipo(me->key); + } + key= me->key; + + kb= MEM_callocN(sizeof(KeyBlock), "Keyblock"); + BLI_addtail(&key->block, kb); + kb->type= KEY_CARDINAL; + + curpos= bsystem_time(0, 0, (float)CFRA, 0.0); + if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &curpos)==0) { + curpos /= 100.0; + } + kb->pos= curpos; + + key->totkey++; + if(key->totkey==1) key->refkey= kb; + + mesh_to_key(me, kb); + + sort_keys(me->key); + + /* curent actief: */ + kkb= key->block.first; + while(kkb) { + kkb->flag &= ~SELECT; + if(kkb==kb) kkb->flag |= SELECT; + + kkb= kkb->next; + } +} + +/* ******************** */ + +void latt_to_key(Lattice *lt, KeyBlock *kb) +{ + BPoint *bp; + float *fp; + int a, tot; + + tot= lt->pntsu*lt->pntsv*lt->pntsw; + if(tot==0) return; + + if(kb->data) MEM_freeN(kb->data); + + kb->data= MEM_callocN(lt->key->elemsize*tot, "kb->data"); + kb->totelem= tot; + + bp= lt->def; + fp= kb->data; + for(a=0; a<kb->totelem; a++, fp+=3, bp++) { + VECCOPY(fp, bp->vec); + } +} + +void key_to_latt(KeyBlock *kb, Lattice *lt) +{ + BPoint *bp; + float *fp; + int a, tot; + + bp= lt->def; + fp= kb->data; + + tot= lt->pntsu*lt->pntsv*lt->pntsw; + tot= MIN2(kb->totelem, tot); + + for(a=0; a<tot; a++, fp+=3, bp++) { + VECCOPY(bp->vec, fp); + } + +} + +void insert_lattkey(Lattice *lt) +{ + Key *key; + KeyBlock *kb, *kkb; + float curpos; + + if(lt->key==0) { + lt->key= add_key( (ID *)lt); + default_key_ipo(lt->key); + } + key= lt->key; + + kb= MEM_callocN(sizeof(KeyBlock), "Keyblock"); + BLI_addtail(&key->block, kb); + kb->type= KEY_CARDINAL; + + curpos= bsystem_time(0, 0, (float)CFRA, 0.0); + if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &curpos)==0) { + curpos /= 100.0; + } + kb->pos= curpos; + + key->totkey++; + if(key->totkey==1) key->refkey= kb; + + latt_to_key(lt, kb); + + sort_keys(lt->key); + + /* curent actief: */ + kkb= key->block.first; + while(kkb) { + kkb->flag &= ~SELECT; + if(kkb==kb) kkb->flag |= SELECT; + + kkb= kkb->next; + } +} + +/* ******************************** */ + +void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb) +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + float *fp; + int a, tot; + + /* tellen */ + tot= count_curveverts(nurb); + if(tot==0) return; + + if(kb->data) MEM_freeN(kb->data); + + kb->data= MEM_callocN(cu->key->elemsize*tot, "kb->data"); + kb->totelem= tot; + + nu= nurb->first; + fp= kb->data; + while(nu) { + + if(nu->bezt) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + VECCOPY(fp, bezt->vec[0]); + fp+= 3; + VECCOPY(fp, bezt->vec[1]); + fp+= 3; + VECCOPY(fp, bezt->vec[2]); + fp+= 3; + fp+= 3; /* alfa's */ + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + VECCOPY(fp, bp->vec); + fp[3]= bp->alfa; + + fp+= 4; + bp++; + } + } + nu= nu->next; + } +} + +void key_to_curve(KeyBlock *kb, Curve *cu, ListBase *nurb) +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + float *fp; + int a, tot; + + nu= nurb->first; + fp= kb->data; + + tot= count_curveverts(nurb); + + tot= MIN2(kb->totelem, tot); + + while(nu && tot>0) { + + if(nu->bezt) { + bezt= nu->bezt; + a= nu->pntsu; + while(a-- && tot>0) { + VECCOPY(bezt->vec[0], fp); + fp+= 3; + VECCOPY(bezt->vec[1], fp); + fp+= 3; + VECCOPY(bezt->vec[2], fp); + fp+= 3; + fp+= 3; /* alfa's */ + + tot-= 3; + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a-- && tot>0) { + VECCOPY(bp->vec, fp); + bp->alfa= fp[3]; + + fp+= 4; + tot--; + bp++; + } + } + nu= nu->next; + } +} + + + +void insert_curvekey(Curve *cu) +{ + Key *key; + KeyBlock *kb, *kkb; + float curpos; + + if(cu->key==0) { + cu->key= add_key( (ID *)cu); + default_key_ipo(cu->key); + } + key= cu->key; + + kb= MEM_callocN(sizeof(KeyBlock), "Keyblock"); + BLI_addtail(&key->block, kb); + kb->type= KEY_CARDINAL; + + curpos= bsystem_time(0, 0, (float)CFRA, 0.0); + if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &curpos)==0) { + curpos /= 100.0; + } + kb->pos= curpos; + + key->totkey++; + if(key->totkey==1) key->refkey= kb; + + if(editNurb.first) curve_to_key(cu, kb, &editNurb); + else curve_to_key(cu, kb, &cu->nurb); + + sort_keys(cu->key); + + /* curent actief: */ + kkb= key->block.first; + while(kkb) { + kkb->flag &= ~SELECT; + if(kkb==kb) kkb->flag |= SELECT; + + kkb= kkb->next; + } +} + + +/* ******************** */ + +Key *give_current_key(Object *ob) +{ + Mesh *me; + Curve *cu; + Lattice *lt; + + if(ob->type==OB_MESH) { + me= ob->data; + return me->key; + } + else if ELEM(ob->type, OB_CURVE, OB_SURF) { + cu= ob->data; + return cu->key; + } + else if(ob->type==OB_LATTICE) { + lt= ob->data; + return lt->key; + } + return 0; +} + +void showkeypos(Key *key, KeyBlock *kb) +{ + Object *ob; + Mesh *me; + Lattice *lt; + Curve *cu; + int tot; + + /* vanuit ipo */ + ob= OBACT; + if(ob==0) return; + + if(key == give_current_key(ob)) { + + if(ob->type==OB_MESH) { + me= ob->data; + + cp_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, kb, 0); + + make_displists_by_obdata(me); + } + else if(ob->type==OB_LATTICE) { + lt= ob->data; + tot= lt->pntsu*lt->pntsv*lt->pntsw; + + cp_key(0, tot, tot, (char *)lt->def->vec, lt->key, kb, 0); + + make_displists_by_parent(ob); + } + else if ELEM(ob->type, OB_CURVE, OB_SURF) { + cu= ob->data; + tot= count_curveverts(&cu->nurb); + cp_cu_key(cu, kb, 0, tot); + +/* make_displists_by_obdata(me); */ + make_displists_by_obdata(cu); + } + + allqueue(REDRAWVIEW3D, 0); + } +} + +void deselectall_key(void) +{ + KeyBlock *kb; + Key *key; + + if(G.sipo->blocktype!=ID_KE) return; + key= (Key *)G.sipo->from; + if(key==0) return; + + kb= key->block.first; + while(kb) { + kb->flag &= ~SELECT; + kb= kb->next; + } +} + + +void delete_key(void) +{ + KeyBlock *kb, *kbn; + Key *key; + + if(G.sipo->blocktype!=ID_KE) return; + + if(okee("Erase selected keys")==0) return; + + key= (Key *)G.sipo->from; + if(key==0) return; + + kb= key->block.first; + while(kb) { + kbn= kb->next; + if(kb->flag & SELECT) { + BLI_remlink(&key->block, kb); + key->totkey--; + if(key->refkey== kb) key->refkey= key->block.first; + + if(kb->data) MEM_freeN(kb->data); + MEM_freeN(kb); + + } + kb= kbn; + } + + if(key->totkey==0) { + if(GS(key->from->name)==ID_ME) ((Mesh *)key->from)->key= 0; + else if(GS(key->from->name)==ID_CU) ((Curve *)key->from)->key= 0; + else if(GS(key->from->name)==ID_LT) ((Lattice *)key->from)->key= 0; + + free_libblock_us(&(G.main->key), key); + scrarea_queue_headredraw(curarea); /* ipo ook weg */ + } + else do_spec_key(key); + + allqueue(REDRAWVIEW3D, 0); + scrarea_queue_winredraw(curarea); +} + +void move_keys(void) +{ + Key *key; + KeyBlock *kb; + TransVert *transmain, *tv; + float div, dy, vec[3], dvec[3]; + int a, tot=0, afbreek=0, firsttime= 1; + unsigned short event = 0; + short mval[2], val, xo, yo; + char str[32]; + + if(G.sipo->blocktype!=ID_KE) return; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + if(G.sipo->editipo==0) return; + + key= (Key *)G.sipo->from; + if(key==0) return; + + /* welke keys doen mee */ + kb= key->block.first; + while(kb) { + if(kb->flag & SELECT) tot++; + kb= kb->next; + } + + if(tot==0) return; + + tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain"); + kb= key->block.first; + while(kb) { + if(kb->flag & SELECT) { + tv->loc= &kb->pos; + tv->oldloc[0]= kb->pos; + tv++; + } + kb= kb->next; + } + + getmouseco_areawin(mval); + xo= mval[0]; + yo= mval[1]; + dvec[0]=dvec[1]=dvec[2]= 0.0; + + + while(afbreek==0) { + getmouseco_areawin(mval); + if(mval[0]!=xo || mval[1]!=yo || firsttime) { + firsttime= 0; + + dy= (float)(mval[1]- yo); + + div= (float)(G.v2d->mask.ymax-G.v2d->mask.ymin); + dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div; + + VECCOPY(vec, dvec); + + apply_keyb_grid(vec, 0.0, 1.0, 0.1, U.flag & AUTOGRABGRID); + apply_keyb_grid(vec+1, 0.0, 1.0, 0.1, U.flag & AUTOGRABGRID); + + tv= transmain; + for(a=0; a<tot; a++, tv++) { + tv->loc[0]= tv->oldloc[0]+vec[1]; + } + + sprintf(str, "Y: %.3f ", vec[1]); + headerprint(str); + + xo= mval[0]; + yo= mval[1]; + + force_draw(); + } + else BIF_wait_for_statechange(); + + while(qtest()) { + event= extern_qread(&val); + if(val) { + switch(event) { + case ESCKEY: + case LEFTMOUSE: + case SPACEKEY: + afbreek= 1; + break; + default: + arrows_move_cursor(event); + } + } + } + } + + if(event==ESCKEY) { + tv= transmain; + for(a=0; a<tot; a++, tv++) { + tv->loc[0]= tv->oldloc[0]; + } + } + + sort_keys(key); + do_spec_key(key); + + /* voor boundbox */ + editipo_changed(G.sipo, 0); + + MEM_freeN(transmain); + allqueue(REDRAWVIEW3D, 0); + scrarea_queue_redraw(curarea); +} diff --git a/source/blender/src/editlattice.c b/source/blender/src/editlattice.c new file mode 100644 index 00000000000..68c16ea2d44 --- /dev/null +++ b/source/blender/src/editlattice.c @@ -0,0 +1,318 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * i.t.t. wat de naam doet vermoeden: ook algemene lattice (calc) functies + */ + +#include <stdlib.h> +#include <math.h> +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_lattice_types.h" +#include "DNA_curve_types.h" +#include "DNA_key_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_key.h" +#include "BKE_displist.h" +#include "BKE_lattice.h" +#include "BKE_global.h" + +#include "BIF_toolbox.h" +#include "BIF_space.h" +#include "BIF_screen.h" +#include "BIF_editlattice.h" +#include "BIF_editkey.h" + +#include "BSE_edit.h" + +#include "BDR_editobject.h" +#include "BDR_drawobject.h" + +#include "blendef.h" +#include "mydevice.h" + +#include "render.h" + +#include "BKE_armature.h" + +void apply_lattice(void) +{ + Base *base; + Object *par; + + if(okee("Apply Lattice Deform")==0) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if( (par= base->object->parent) ) { + if(par->type==OB_LATTICE) { + + lt_applyflag= 1; + object_deform(base->object); + lt_applyflag= 0; + + base->object->parent= 0; + } + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); +} + +/* ***************************** */ + + + + +void free_editLatt(void) +{ + if(editLatt) { + if(editLatt->def) MEM_freeN(editLatt->def); + MEM_freeN(editLatt); + editLatt= 0; + } +} + + +static void setflagsLatt(int flag) +{ + BPoint *bp; + int a; + + bp= editLatt->def; + + a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + + while(a--) { + if(bp->hide==0) { + bp->f1= flag; + } + bp++; + } +} + + + +void make_editLatt(void) +{ + Lattice *lt; + KeyBlock *actkey=0; + + free_editLatt(); + + lt= G.obedit->data; + + /* keys? */ + if(lt->key) { + actkey= lt->key->block.first; + while(actkey) { + if(actkey->flag & SELECT) break; + actkey= actkey->next; + } + } + + if(actkey) { + key_to_latt(actkey, lt); + } + + editLatt= MEM_dupallocN(lt); + + editLatt->def= MEM_dupallocN(lt->def); + + setflagsLatt(0); +} + + +void load_editLatt(void) +{ + Lattice *lt; + KeyBlock *actkey=0; + BPoint *bp; + float *fp; + int tot; + + lt= G.obedit->data; + + /* zijn er keys? */ + if(lt->key) { + actkey= lt->key->block.first; + while(actkey) { + if(actkey->flag & SELECT) break; + actkey= actkey->next; + } + } + + if(actkey) { + /* aktieve key: vertices */ + tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + + if(actkey->data) MEM_freeN(actkey->data); + + fp=actkey->data= MEM_callocN(lt->key->elemsize*tot, "actkey->data"); + actkey->totelem= tot; + + bp= editLatt->def; + while(tot--) { + VECCOPY(fp, bp->vec); + fp+= 3; + bp++; + } + + if(actkey) do_spec_key(lt->key); + } + else { + + MEM_freeN(lt->def); + + lt->def= MEM_dupallocN(editLatt->def); + + lt->flag= editLatt->flag; + + lt->pntsu= editLatt->pntsu; + lt->pntsv= editLatt->pntsv; + lt->pntsw= editLatt->pntsw; + + lt->typeu= editLatt->typeu; + lt->typev= editLatt->typev; + lt->typew= editLatt->typew; + } +} + +void remake_editLatt(void) +{ + if(okee("Reload Original data")==0) return; + + make_editLatt(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); +} + + +void deselectall_Latt(void) +{ + BPoint *bp; + int a; + + bp= editLatt->def; + + a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + + allqueue(REDRAWVIEW3D, 0); + + while(a--) { + if(bp->hide==0) { + if(bp->f1) { + setflagsLatt(0); + return; + } + } + bp++; + } + setflagsLatt(1); +} + + +static BPoint *findnearestLattvert(int sel) +{ + /* sel==1: selected krijgen een nadeel */ + /* in bp wordt nearest weggeschreven */ + BPoint *bp1, *bp; + short dist= 100, temp, mval[2], a; + + bp= 0; + + /* projektie doen */ + calc_lattverts_ext(); /* drawobject.c */ + + getmouseco_areawin(mval); + + + bp1= editLatt->def; + + a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + + while(a--) { + if(bp1->hide==0) { + temp= abs(mval[0]- bp1->s[0])+ abs(mval[1]- bp1->s[1]); + if( (bp1->f1 & 1)==sel) temp+=5; + if(temp<dist) { + bp= bp1; + dist= temp; + } + } + bp1++; + } + + return bp; +} + + +void mouse_lattice(void) +{ + BPoint *bp=0; + + bp= findnearestLattvert(1); + + if(bp) { + if((G.qual & LR_SHIFTKEY)==0) { + + setflagsLatt(0); + bp->f1 |= 1; + + allqueue(REDRAWVIEW3D, 0); + } + else { + + if(bp->f1 & 1) bp->f1 &= ~1; + else bp->f1 |= 1; + + allqueue(REDRAWVIEW3D, 0); + + } + + countall(); + } + + rightmouse_transform(); + +} diff --git a/source/blender/src/editmball.c b/source/blender/src/editmball.c new file mode 100644 index 00000000000..329157fcda0 --- /dev/null +++ b/source/blender/src/editmball.c @@ -0,0 +1,301 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_screen_types.h" +#include "DNA_meta_types.h" +#include "DNA_object_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_object.h" + +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_screen.h" +#include "BIF_toolbox.h" +#include "BIF_space.h" + +#include "BDR_editobject.h" +#include "BDR_editmball.h" + +#include "BSE_edit.h" +#include "BSE_view.h" + +#include "render.h" +#include "blendef.h" +#include "mydevice.h" + +extern short editbutflag; + +ListBase editelems= {0, 0}; +MetaElem *lastelem; + +void make_editMball() +{ + MetaBall *mb; + MetaElem *ml, *newmb; + + BLI_freelistN(&editelems); + lastelem= 0; + + mb= G.obedit->data; + ml= mb->elems.first; + + while(ml) { + newmb= MEM_dupallocN(ml); + BLI_addtail(&editelems, newmb); + if(ml->flag & SELECT) lastelem= newmb; + + ml= ml->next; + } + + allqueue(REDRAWBUTSEDIT, 0); + + countall(); +} + +void load_editMball() +{ + /* load mball in object */ + MetaBall *mb; + MetaElem *ml, *newml; + + if(G.obedit==0) return; + + mb= G.obedit->data; + BLI_freelistN(&(mb->elems)); + + + ml= editelems.first; + while(ml) { + newml= MEM_dupallocN(ml); + BLI_addtail(&(mb->elems), newml); + + ml= ml->next; + } +} + +void add_primitiveMball(int dummy_argument) +{ + MetaElem *ml; + float *curs, mat[3][3], cent[3], imat[3][3], cmat[3][3]; + + if(G.scene->id.lib) return; + + /* this function also comes from an info window */ + if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return; + + check_editmode(OB_MBALL); + + /* als geen obedit: nieuw object en in editmode gaan */ + if(G.obedit==0) { + add_object(OB_MBALL); + base_init_from_view3d(BASACT, G.vd); + G.obedit= BASACT->object; + + where_is_object(G.obedit); + + make_editMball(); + setcursor_space(SPACE_VIEW3D, CURSOR_EDIT); + } + + /* deselecteren */ + ml= editelems.first; + while(ml) { + ml->flag &= ~SELECT; + ml= ml->next; + } + + /* imat en centrum en afmeting */ + Mat3CpyMat4(mat, G.obedit->obmat); + + curs= give_cursor(); + VECCOPY(cent, curs); + cent[0]-= G.obedit->obmat[3][0]; + cent[1]-= G.obedit->obmat[3][1]; + cent[2]-= G.obedit->obmat[3][2]; + + Mat3CpyMat4(imat, G.vd->viewmat); + Mat3MulVecfl(imat, cent); + Mat3MulMat3(cmat, imat, mat); + Mat3Inv(imat,cmat); + + Mat3MulVecfl(imat, cent); + + ml= MEM_callocN(sizeof(MetaElem), "metaelem"); + BLI_addtail(&editelems, ml); + + ml->x= cent[0]; + ml->y= cent[1]; + ml->z= cent[2]; + ml->rad= 1.0; + ml->lay= 1; + ml->s= 2.0; + ml->len= 1.0; + ml->expx= ml->expy= ml->expz= 2.0; + ml->flag= SELECT; + + lastelem= ml; + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSALL, 0); + makeDispList(G.obedit); +} + +void deselectall_mball() +{ + MetaElem *ml; + int sel= 0; + + ml= editelems.first; + while(ml) { + if(ml->flag & SELECT) break; + ml= ml->next; + } + + if(ml) sel= 1; + + ml= editelems.first; + while(ml) { + if(sel) ml->flag &= ~SELECT; + else ml->flag |= SELECT; + ml= ml->next; + } + allqueue(REDRAWVIEW3D, 0); +} + +void mouse_mball() +{ + static MetaElem *startelem=0; + MetaElem *ml, *act=0; + int a, hits; + /* was IGLuint ... but is stupid */ + GLuint buffer[MAXPICKBUF]; + + hits= selectprojektie(buffer, 0, 0, 0, 0); + + /* bestaat startelem? */ + ml= editelems.first; + while(ml) { + if(ml==startelem) break; + ml= ml->next; + } + if(ml==0) startelem= editelems.first; + + if(hits>0) { + ml= startelem; + while(ml) { + /* if(base->lay & G.vd->lay) { */ + + for(a=0; a<hits; a++) { + /* index converted for gl stuff */ + if(ml->selcol==buffer[ 4 * a + 3 ]) act= ml; + } + /* } */ + + if(act) break; + + ml= ml->next; + if(ml==0) ml= editelems.first; + if(ml==startelem) break; + } + if(act) { + if((G.qual & LR_SHIFTKEY)==0) { + deselectall_mball(); + if(act->flag & SELECT) deselectall_mball(); + act->flag |= SELECT; + } + else { + if(act->flag & SELECT) { + act->flag &= ~SELECT; + } + else act->flag |= SELECT; + } + lastelem= act; + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + } + } + rightmouse_transform(); +} + +void adduplicate_mball() +{ + MetaElem *ml, *newml; + + ml= editelems.last; + while(ml) { + if(ml->flag & SELECT) { + newml= MEM_dupallocN(ml); + BLI_addtail(&editelems, newml); + lastelem= newml; + ml->flag &= ~SELECT; + } + ml= ml->prev; + } + + transform('g'); + allqueue(REDRAWBUTSEDIT, 0); +} + +void delete_mball() +{ + MetaElem *ml, *next; + + if(okee("Erase selected")==0) return; + + ml= editelems.first; + while(ml) { + next= ml->next; + if(ml->flag & SELECT) { + if(lastelem==ml) lastelem= 0; + BLI_remlink(&editelems, ml); + MEM_freeN(ml); + } + ml= next; + } + + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); +} diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c new file mode 100644 index 00000000000..7597e0b8cd3 --- /dev/null +++ b/source/blender/src/editmesh.c @@ -0,0 +1,6387 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_rand.h" + +#include "MTC_matrixops.h" + +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_key_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" +#include "DNA_material_types.h" +#include "DNA_texture_types.h" + +#include "BKE_utildefines.h" +#include "BKE_key.h" +#include "BKE_object.h" +#include "BKE_texture.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_mesh.h" + +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_editkey.h" +#include "BIF_space.h" +#include "BIF_toolbox.h" +#include "BIF_screen.h" +#include "BIF_interface.h" +#include "BIF_editmesh.h" +#include "BIF_mywindow.h" + +#include "BSE_view.h" +#include "BSE_edit.h" +#include "BSE_trans_types.h" + +#include "BDR_drawobject.h" +#include "BDR_editobject.h" +#include "BDR_editface.h" +#include "BDR_vpaint.h" + +#include "mydevice.h" +#include "blendef.h" +#include "interface.h" /* MAART: for NUM and FLO types */ +#include "nla.h" /* For __NLA : Important - Do not remove! */ +#include "render.h" + +/****/ + +static void free_editverts(ListBase *edve); +static float convex(float *v1, float *v2, float *v3, float *v4); + +/****/ + + +/* extern ListBase fillvertbase, filledgebase; */ /* scanfill.c, in + the lib... already in BLI_blenlib.h */ + +/* voor debug: +#define free(a) freeN(a) +#define malloc(a) mallocN(a, "malloc") +#define calloc(a, b) callocN((a)*(b), "calloc") +#define freelist(a) freelistN(a) +*/ + +extern short editbutflag; + +static float icovert[12][3] = { + {0,0,-200}, + {144.72, -105.144,-89.443}, + {-55.277, -170.128,-89.443}, + {-178.885,0,-89.443}, + {-55.277,170.128,-89.443}, + {144.72,105.144,-89.443}, + {55.277,-170.128,89.443}, + {-144.72,-105.144,89.443}, + {-144.72,105.144,89.443}, + {55.277,170.128,89.443}, + {178.885,0,89.443}, + {0,0,200} +}; +static short icovlak[20][3] = { + {1,0,2}, + {1,0,5}, + {2,0,3}, + {3,0,4}, + {4,0,5}, + {1,5,10}, + {2,1,6}, + {3,2,7}, + {4,3,8}, + {5,4,9}, + {10,1,6}, + {6,2,7}, + {7,3,8}, + {8,4,9}, + {9,5,10}, + {6,10,11}, + {7,6,11}, + {8,7,11}, + {9,8,11}, + {10,9,11} +}; + +/* DEFINES */ +#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float)); + +#define TEST_EDITMESH if(G.obedit==0) return; \ + if( (G.vd->lay & G.obedit->lay)==0 ) return; + +#define FACE_MARKCLEAR(f) (f->f1 = 1) + +/* ***************** HASH ********************* */ + +/* HASH struct voor snel opzoeken edges */ +struct HashEdge { + struct EditEdge *eed; + struct HashEdge *next; +}; + +struct HashEdge *hashedgetab=0; + +/********* qsort routines *********/ + + +struct xvertsort { + float x; + EditVert *v1; +}; + +/* Functions */ +static int vergxco(const void *v1, const void *v2) +{ + const struct xvertsort *x1=v1, *x2=v2; + + if( x1->x > x2->x ) return 1; + else if( x1->x < x2->x) return -1; + return 0; +} + +struct vlaksort { + long x; + struct EditVlak *evl; +}; + + +static int vergvlak(const void *v1, const void *v2) +{ + const struct vlaksort *x1=v1, *x2=v2; + + if( x1->x > x2->x ) return 1; + else if( x1->x < x2->x) return -1; + return 0; +} + + +/* ************ ADD / REMOVE / FIND ****************** */ + +#define EDHASH(a, b) ( (a)*256 + (b) ) +#define EDHASHSIZE 65536 + +#if 0 +static void check_hashedge(void) +{ + int i, i2, doubedge=0; + struct HashEdge *he, *he2; + + for (i=0; i<64; i++) { + he= hashedgetab+i; + + while (he && he->eed) { + for (i2=i+1; i2<64; i2++) { + he2= hashedgetab+i2; + + while (he2) { + if (he->eed == he2->eed) doubedge++; + + he2= he2->next; + } + } + + he= he->next; + } + } + + if (doubedge) printf("%d double edges!\n", doubedge); +} +#endif + +EditVert *addvertlist(float *vec) +{ + EditVert *eve; + static unsigned char hashnr= 0; + + eve= calloc(sizeof(EditVert),1); + BLI_addtail(&G.edve, eve); + + if(vec) VECCOPY(eve->co, vec); + + eve->hash= hashnr++; + + return eve; +} + +EditEdge *findedgelist(EditVert *v1, EditVert *v2) +{ + EditVert *v3; + struct HashEdge *he; + + if(hashedgetab==0) { + hashedgetab= MEM_callocN(EDHASHSIZE*sizeof(struct HashEdge), "hashedgetab"); + } + + /* swap ? */ + if( (long)v1 > (long)v2) { + v3= v2; + v2= v1; + v1= v3; + } + + /* eerst even op de flip-plek kijken */ + +/* he= hashedgetab + EDHASH(v2->hash, v1->hash); */ +/* if(he->eed && he->eed->v1==v1 && he->eed->v2==v2) return he->eed; */ + + + he= hashedgetab + EDHASH(v1->hash, v2->hash); + + while(he) { + + if(he->eed && he->eed->v1==v1 && he->eed->v2==v2) return he->eed; + + he= he->next; + } + return 0; +} + +static void insert_hashedge(EditEdge *eed) +{ + /* er van uitgaande dat eed nog niet in lijst zit, en eerst een find is gedaan */ + + struct HashEdge *first, *he; + + /* eerst even op de flip-plek kijken */ +/* he= hashedgetab + EDHASH(eed->v2->hash, eed->v1->hash); */ + +/* if(he->eed==0) { */ +/* he->eed= eed; */ +/* return; */ +/* } */ + + first= hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash); + + if( first->eed==0 ) { + first->eed= eed; + } + else { + he= (struct HashEdge *)malloc(sizeof(struct HashEdge)); + he->eed= eed; + he->next= first->next; + first->next= he; + } +} + +static void remove_hashedge(EditEdge *eed) +{ + /* er van uitgaande dat eed in lijst zit */ + + struct HashEdge *first, *he, *prev=NULL; + + + /* eerst even op de flip-plek kijken */ +/* first= hashedgetab + EDHASH(eed->v2->hash, eed->v1->hash); */ + +/* if(first->eed==eed) { */ + /* uit lijst verwijderen */ + +/* if(first->next) { */ +/* he= first->next; */ +/* first->eed= he->eed; */ +/* first->next= he->next; */ +/* free(he); */ +/* } */ +/* else first->eed= 0; */ + +/* return; */ +/* } */ + + + he=first= hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash); + + while(he) { + if(he->eed == eed) { + /* uit lijst verwijderen */ + if(he==first) { + if(first->next) { + he= first->next; + first->eed= he->eed; + first->next= he->next; + free(he); + } + else he->eed= 0; + } + else { + prev->next= he->next; + free(he); + } + return; + } + prev= he; + he= he->next; + } +} + +void free_hashedgetab(void) +{ + struct HashEdge *he, *first, *hen; + int a; +/* int test[30], nr, toted=0; */ + + /* for(a=0; a<30; a++) test[a]=0; */ + + if(hashedgetab) { + + first= hashedgetab; + for(a=0; a<EDHASHSIZE; a++, first++) { + he= first->next; + /* nr= 0; */ + /* if(first->eed) toted++; */ + /* if(first->eed) nr++; */ + while(he) { + hen= he->next; + free(he); + he= hen; + /* nr++; */ + } + /* if(nr>29) nr= 29; */ + /* test[nr]++; */ + } + MEM_freeN(hashedgetab); + hashedgetab= 0; + + /* printf("toted %d\n", toted); */ + /* toted= 0; */ + /* for(a=0; a<30; a++) { */ + /* printf("tab %d %d\n", a, test[a]); */ + /* } */ + } +} + +EditEdge *addedgelist(EditVert *v1, EditVert *v2) +{ + EditVert *v3; + EditEdge *eed; + int swap= 0; + + /* swap ? */ + if(v1>v2) { + v3= v2; + v2= v1; + v1= v3; + swap= 1; + } + + if(v1==v2) return 0; + if(v1==0 || v2==0) return 0; + + /* opzoeken in hashlijst */ + eed= findedgelist(v1, v2); + + if(eed==0) { + + eed= (EditEdge *)calloc(sizeof(EditEdge), 1); + eed->v1= v1; + eed->v2= v2; + BLI_addtail(&G.eded, eed); + eed->dir= swap; + insert_hashedge(eed); + } + return eed; +} + + +void remedge(EditEdge *eed) +{ + + BLI_remlink(&G.eded, eed); + + remove_hashedge(eed); +} + +static void freevlak(EditVlak *evl) +{ + free(evl); +} + +static void freevlaklist(ListBase *lb) +{ + EditVlak *evl, *next; + + evl= lb->first; + while(evl) { + next= evl->next; + freevlak(evl); + evl= next; + } + lb->first= lb->last= 0; +} + +EditVlak *addvlaklist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, EditVlak *example) +{ + EditVlak *evl; + EditEdge *e1, *e2=0, *e3=0, *e4=0; + + + /* voeg vlak toe aan lijst en doe meteen de edges */ + e1= addedgelist(v1, v2); + if(v3) e2= addedgelist(v2, v3); + if(v4) e3= addedgelist(v3, v4); else e3= addedgelist(v3, v1); + if(v4) e4= addedgelist(v4, v1); + + if(v1==v2 || v2==v3 || v1==v3) return 0; + if(e2==0) return 0; + + evl= (EditVlak *)calloc(sizeof(EditVlak), 1); + evl->v1= v1; + evl->v2= v2; + evl->v3= v3; + evl->v4= v4; + + evl->e1= e1; + evl->e2= e2; + evl->e3= e3; + evl->e4= e4; + + if(example) { + evl->mat_nr= example->mat_nr; + evl->tface= example->tface; + evl->flag= example->flag; + memcpy(evl->col, example->col, sizeof(example->col)); + memcpy(evl->uv, example->uv, sizeof(example->uv)); + } + else { + if (G.obedit && G.obedit->actcol) + evl->mat_nr= G.obedit->actcol-1; + default_uv(evl->uv, 1.0); + + /* Initialize colors */ + evl->col[0]= evl->col[1]= evl->col[2]= evl->col[3]= vpaint_get_current_col(); + } + + BLI_addtail(&G.edvl, evl); + + if(evl->v4) CalcNormFloat4(v1->co, v2->co, v3->co, v4->co, evl->n); + else CalcNormFloat(v1->co, v2->co, v3->co, evl->n); + + return evl; +} + +static int comparevlak(EditVlak *vl1, EditVlak *vl2) +{ + EditVert *v1, *v2, *v3, *v4; + + if(vl1->v4 && vl2->v4) { + v1= vl2->v1; + v2= vl2->v2; + v3= vl2->v3; + v4= vl2->v4; + + if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1 || vl1->v4==v1) { + if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2 || vl1->v4==v2) { + if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3 || vl1->v4==v3) { + if(vl1->v1==v4 || vl1->v2==v4 || vl1->v3==v4 || vl1->v4==v4) { + return 1; + } + } + } + } + } + else if(vl1->v4==0 && vl2->v4==0) { + v1= vl2->v1; + v2= vl2->v2; + v3= vl2->v3; + + if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1) { + if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2) { + if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3) { + return 1; + } + } + } + } + + return 0; +} + + +#if 0 +static int dubbelvlak(EditVlak *evltest) +{ + + EditVlak *evl; + + evl= G.edvl.first; + while(evl) { + if(evl!=evltest) { + if(comparevlak(evltest, evl)) return 1; + } + evl= evl->next; + } + return 0; +} +#endif + +static int exist_vlak(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4) +{ + EditVlak *evl, evltest; + + evltest.v1= v1; + evltest.v2= v2; + evltest.v3= v3; + evltest.v4= v4; + + evl= G.edvl.first; + while(evl) { + if(comparevlak(&evltest, evl)) return 1; + evl= evl->next; + } + return 0; +} + + +static int vlakselectedOR(EditVlak *evl, int flag) +{ + + if(evl->v1->f & flag) return 1; + if(evl->v2->f & flag) return 1; + if(evl->v3->f & flag) return 1; + if(evl->v4 && (evl->v4->f & 1)) return 1; + return 0; +} + +int vlakselectedAND(EditVlak *evl, int flag) +{ + if(evl->v1->f & flag) { + if(evl->v2->f & flag) { + if(evl->v3->f & flag) { + if(evl->v4) { + if(evl->v4->f & flag) return 1; + } + else return 1; + } + } + } + return 0; +} + +void recalc_editnormals(void) +{ + EditVlak *evl; + + evl= G.edvl.first; + while(evl) { + if(evl->v4) CalcNormFloat4(evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co, evl->n); + else CalcNormFloat(evl->v1->co, evl->v2->co, evl->v3->co, evl->n); + evl= evl->next; + } +} + +static void flipvlak(EditVlak *evl) +{ + if(evl->v4) { + SWAP(EditVert *, evl->v2, evl->v4); + SWAP(EditEdge *, evl->e1, evl->e4); + SWAP(EditEdge *, evl->e2, evl->e3); + SWAP(unsigned int, evl->col[1], evl->col[3]); + if(evl->tface) { + SWAP(float, evl->uv[1][0], evl->uv[3][0]); + SWAP(float, evl->uv[1][1], evl->uv[3][1]); + } + } + else { + SWAP(EditVert *, evl->v2, evl->v3); + SWAP(EditEdge *, evl->e1, evl->e3); + SWAP(unsigned int, evl->col[1], evl->col[2]); + evl->e2->dir= 1-evl->e2->dir; + if(evl->tface) { + SWAP(float, evl->uv[1][0], evl->uv[2][0]); + SWAP(float, evl->uv[1][1], evl->uv[2][1]); + } + } + if(evl->v4) CalcNormFloat4(evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co, evl->n); + else CalcNormFloat(evl->v1->co, evl->v2->co, evl->v3->co, evl->n); +} + + +void flip_editnormals(void) +{ + EditVlak *evl; + + evl= G.edvl.first; + while(evl) { + if( vlakselectedAND(evl, 1) ) { + flipvlak(evl); + } + evl= evl->next; + } +} + +/* ************************ IN & OUT ***************************** */ + +static void edge_normal_compare(EditEdge *eed, EditVlak *evl1) +{ + EditVlak *evl2; + float cent1[3], cent2[3]; + float inp; + + evl2= (EditVlak *)eed->vn; + if(evl1==evl2) return; + + inp= evl1->n[0]*evl2->n[0] + evl1->n[1]*evl2->n[1] + evl1->n[2]*evl2->n[2]; + if(inp<0.999 && inp >-0.999) eed->f= 1; + + if(evl1->v4) CalcCent4f(cent1, evl1->v1->co, evl1->v2->co, evl1->v3->co, evl1->v4->co); + else CalcCent3f(cent1, evl1->v1->co, evl1->v2->co, evl1->v3->co); + if(evl2->v4) CalcCent4f(cent2, evl2->v1->co, evl2->v2->co, evl2->v3->co, evl2->v4->co); + else CalcCent3f(cent2, evl2->v1->co, evl2->v2->co, evl2->v3->co); + + VecSubf(cent1, cent2, cent1); + Normalise(cent1); + inp= cent1[0]*evl1->n[0] + cent1[1]*evl1->n[1] + cent1[2]*evl1->n[2]; + + if(inp < -0.001 ) eed->f1= 1; +} + +static void edge_drawflags(void) +{ + EditVert *eve; + EditEdge *eed, *e1, *e2, *e3, *e4; + EditVlak *evl; + + /* - tel aantal keren in vlakken gebruikt: 0 en 1 is tekenen + * - edges meer dan 1 keer: in *vn zit pointer naar (eerste) vlak + * - loop alle vlakken af, is normaal te afwijkend: tekenen (flag wordt 1) + */ + + recalc_editnormals(); + + /* init */ + eve= G.edve.first; + while(eve) { + eve->f1= 1; /* wordt bij test op nul gezet */ + eve= eve->next; + } + eed= G.eded.first; + while(eed) { + eed->f= eed->f1= 0; + eed->vn= 0; + eed= eed->next; + } + + evl= G.edvl.first; + while(evl) { + e1= evl->e1; + e2= evl->e2; + e3= evl->e3; + e4= evl->e4; + if(e1->f<3) e1->f+= 1; + if(e2->f<3) e2->f+= 1; + if(e3->f<3) e3->f+= 1; + if(e4 && e4->f<3) e4->f+= 1; + + if(e1->vn==0) e1->vn= (EditVert *)evl; + if(e2->vn==0) e2->vn= (EditVert *)evl; + if(e3->vn==0) e3->vn= (EditVert *)evl; + if(e4 && e4->vn==0) e4->vn= (EditVert *)evl; + + evl= evl->next; + } + + if(G.f & G_ALLEDGES) { + evl= G.edvl.first; + while(evl) { + if(evl->e1->f>=2) evl->e1->f= 1; + if(evl->e2->f>=2) evl->e2->f= 1; + if(evl->e3->f>=2) evl->e3->f= 1; + if(evl->e4 && evl->e4->f>=2) evl->e4->f= 1; + + evl= evl->next; + } + } + else { + + /* single-edges afvangen voor cylinder flag */ + + eed= G.eded.first; + while(eed) { + if(eed->f==1) eed->f1= 1; + eed= eed->next; + } + + /* alle vlakken, alle edges met flag==2: vergelijk normaal */ + evl= G.edvl.first; + while(evl) { + if(evl->e1->f==2) edge_normal_compare(evl->e1, evl); + if(evl->e2->f==2) edge_normal_compare(evl->e2, evl); + if(evl->e3->f==2) edge_normal_compare(evl->e3, evl); + if(evl->e4 && evl->e4->f==2) edge_normal_compare(evl->e4, evl); + + evl= evl->next; + } + + /* sphere collision flag */ + + eed= G.eded.first; + while(eed) { + if(eed->f1!=1) { + eed->v1->f1= eed->v2->f1= 0; + } + eed= eed->next; + } + + } +} + +static int contrpuntnorm(float *n, float *puno) +{ + float inp; + + inp= n[0]*puno[0]+n[1]*puno[1]+n[2]*puno[2]; + + /* angles 90 degrees: dont flip */ + if(inp> -0.000001) return 0; + + return 1; +} + +void vertexnormals(int testflip) +{ + Mesh *me; + EditVert *eve; + EditVlak *evl; + float n1[3], n2[3], n3[3], n4[3], co[4], fac1, fac2, fac3, fac4, *temp; + float *f1, *f2, *f3, *f4, xn, yn, zn; + float opp, len; + + if(G.obedit && G.obedit->type==OB_MESH) { + me= G.obedit->data; + if((me->flag & ME_TWOSIDED)==0) testflip= 0; + } + + if(G.totvert==0) return; + + if(G.totface==0) { + /* namaak puno's voor halopuno! */ + eve= G.edve.first; + while(eve) { + VECCOPY(eve->no, eve->co); + Normalise( (float *)eve->no); + eve= eve->next; + } + return; + } + + /* clear normals */ + eve= G.edve.first; + while(eve) { + eve->no[0]= eve->no[1]= eve->no[2]= 0.0; + eve= eve->next; + } + + /* berekenen cos hoeken en oppervlakte en optellen bij puno */ + evl= G.edvl.first; + while(evl) { + VecSubf(n1, evl->v2->co, evl->v1->co); + VecSubf(n2, evl->v3->co, evl->v2->co); + Normalise(n1); + Normalise(n2); + + if(evl->v4==0) { + VecSubf(n3, evl->v1->co, evl->v3->co); + Normalise(n3); + + /* opp= AreaT3Dfl(evl->v1->co, evl->v2->co, evl->v3->co); */ + /* if(opp!=0.0) opp=1.0/opp; */ + /* opp= sqrt(opp); */ + /* for smooth subdivide...*/ + opp= 1.0; + co[0]= opp*saacos(-n3[0]*n1[0]-n3[1]*n1[1]-n3[2]*n1[2]); + co[1]= opp*saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]); + co[2]= opp*saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]); + + } + else { + VecSubf(n3, evl->v4->co, evl->v3->co); + VecSubf(n4, evl->v1->co, evl->v4->co); + Normalise(n3); + Normalise(n4); + + /* opp= AreaQ3Dfl(evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co); */ + /* if(opp!=0.0) opp=1.0/opp; */ + /* opp= sqrt(opp); */ + /* for smooth subdivide...*/ + opp= 1.0; + co[0]= opp*saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]); + co[1]= opp*saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]); + co[2]= opp*saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]); + co[3]= opp*saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]); + } + + temp= evl->v1->no; + if(testflip && contrpuntnorm(evl->n, temp) ) co[0]= -co[0]; + temp[0]+= co[0]*evl->n[0]; + temp[1]+= co[0]*evl->n[1]; + temp[2]+= co[0]*evl->n[2]; + + temp= evl->v2->no; + if(testflip && contrpuntnorm(evl->n, temp) ) co[1]= -co[1]; + temp[0]+= co[1]*evl->n[0]; + temp[1]+= co[1]*evl->n[1]; + temp[2]+= co[1]*evl->n[2]; + + temp= evl->v3->no; + if(testflip && contrpuntnorm(evl->n, temp) ) co[2]= -co[2]; + temp[0]+= co[2]*evl->n[0]; + temp[1]+= co[2]*evl->n[1]; + temp[2]+= co[2]*evl->n[2]; + + if(evl->v4) { + temp= evl->v4->no; + if(testflip && contrpuntnorm(evl->n, temp) ) co[3]= -co[3]; + temp[0]+= co[3]*evl->n[0]; + temp[1]+= co[3]*evl->n[1]; + temp[2]+= co[3]*evl->n[2]; + } + + evl= evl->next; + } + + /* normaliseren puntnormalen */ + eve= G.edve.first; + while(eve) { + len= Normalise(eve->no); + if(len==0.0) { + VECCOPY(eve->no, eve->co); + Normalise( eve->no); + } + eve= eve->next; + } + + /* puntnormaal omklap-vlaggen voor bij shade */ + evl= G.edvl.first; + while(evl) { + evl->f=0; + + if(testflip) { + f1= evl->v1->no; + f2= evl->v2->no; + f3= evl->v3->no; + + fac1= evl->n[0]*f1[0] + evl->n[1]*f1[1] + evl->n[2]*f1[2]; + if(fac1<0.0) { + evl->f = ME_FLIPV1; + } + fac2= evl->n[0]*f2[0] + evl->n[1]*f2[1] + evl->n[2]*f2[2]; + if(fac2<0.0) { + evl->f += ME_FLIPV2; + } + fac3= evl->n[0]*f3[0] + evl->n[1]*f3[1] + evl->n[2]*f3[2]; + if(fac3<0.0) { + evl->f += ME_FLIPV3; + } + if(evl->v4) { + f4= evl->v4->no; + fac4= evl->n[0]*f4[0] + evl->n[1]*f4[1] + evl->n[2]*f4[2]; + if(fac4<0.0) { + evl->f += ME_FLIPV4; + } + } + } + /* proj voor cubemap! */ + xn= fabs(evl->n[0]); + yn= fabs(evl->n[1]); + zn= fabs(evl->n[2]); + + if(zn>xn && zn>yn) evl->f += ME_PROJXY; + else if(yn>xn && yn>zn) evl->f += ME_PROJXZ; + else evl->f += ME_PROJYZ; + + evl= evl->next; + } +} + +void free_editMesh(void) +{ + +// if(G.edve.first) BLI_freelist(&G.edve); + if(G.edve.first) free_editverts(&G.edve); + if(G.eded.first) BLI_freelist(&G.eded); + if(G.edvl.first) freevlaklist(&G.edvl); + free_hashedgetab(); + G.totvert= G.totface= 0; +} + +static void free_editverts(ListBase *edve) { +#ifdef __NLA + EditVert *eve; +#endif + + if (!edve) + return; + + if (!edve->first) + return; + +#ifdef __NLA + for (eve= edve->first; eve; eve=eve->next){ + if (eve->dw) + MEM_freeN (eve->dw); + } +#endif + + BLI_freelist (edve); + +} + +static void free_editvert (EditVert *eve) +{ +#ifdef __NLA + if (eve->dw) + MEM_freeN (eve->dw); +#endif + free (eve); +} + +void make_editMesh(void) +{ + Mesh *me; + MFace *mface; + TFace *tface; + MVert *mvert; + KeyBlock *actkey=0; + EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4; + EditVlak *evl; + int tot, a; + + if(G.obedit==0) return; + + /* ivm reload */ + free_editMesh(); + + me= get_mesh(G.obedit); + G.totvert= tot= me->totvert; + + if(tot==0) { + countall(); + return; + } + + waitcursor(1); + + /* keys? */ + if(me->key) { + actkey= me->key->block.first; + while(actkey) { + if(actkey->flag & SELECT) break; + actkey= actkey->next; + } + } + + if(actkey) { + key_to_mesh(actkey, me); + tot= actkey->totelem; + } + + /* editverts aanmaken */ + mvert= me->mvert; + + evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist"); + for(a=0; a<tot; a++, mvert++) { + eve= addvertlist(mvert->co); + evlist[a]= eve; + eve->no[0]= mvert->no[0]/32767.0; + eve->no[1]= mvert->no[1]/32767.0; + eve->no[2]= mvert->no[2]/32767.0; +#ifdef __NLA + + /* OLD VERSION */ + /* + eve->totweight = mvert->totweight; + if (mvert->dw){ + eve->dw = BLI_callocN (sizeof(MDeformWeight) * mvert->totweight, "deformWeight"); + memcpy (eve->dw, mvert->dw, sizeof(MDeformWeight) * mvert->totweight); + } + */ + + /* NEW VERSION */ + if (me->dvert){ + eve->totweight = me->dvert[a].totweight; + if (me->dvert[a].dw){ + eve->dw = MEM_callocN (sizeof(MDeformWeight) * me->dvert[a].totweight, "deformWeight"); + memcpy (eve->dw, me->dvert[a].dw, sizeof(MDeformWeight) * me->dvert[a].totweight); + } + } + +#endif + } + + if(actkey && actkey->totelem!=me->totvert); + else { + unsigned int *mcol; + + /* edges en vlakken maken */ + mface= me->mface; + tface= me->tface; + mcol= (unsigned int *)me->mcol; + + for(a=0; a<me->totface; a++, mface++) { + eve1= evlist[mface->v1]; + eve2= evlist[mface->v2]; + if(mface->v3) eve3= evlist[mface->v3]; else eve3= 0; + if(mface->v4) eve4= evlist[mface->v4]; else eve4= 0; + + evl= addvlaklist(eve1, eve2, eve3, eve4, NULL); + + if(evl) { + if(mcol) memcpy(evl->col, mcol, 4*sizeof(int)); + + if(me->tface) { + memcpy(evl->col, tface->col, sizeof(tface->col)); + memcpy(evl->uv, tface->uv, sizeof(tface->uv)); + + if( tface->flag & TF_SELECT) { + if(G.f & G_FACESELECT) { + eve1->f |= 1; + eve2->f |= 1; + if(eve3) eve3->f |= 1; + if(eve4) eve4->f |= 1; + } + } + } + + evl->mat_nr= mface->mat_nr; + evl->flag= mface->flag; + evl->tface= tface; + } + + if(me->tface) tface++; + if(mcol) mcol+=4; + } + } + MEM_freeN(evlist); + + countall(); + + if (mesh_uses_displist(me)) + makeDispList(G.obedit); + + waitcursor(0); +} + +/** Rotates MFace and UVFace vertices in case the last + * vertex index is = 0. + * This function is a hack and may only be called in the + * conversion from EditMesh to Mesh data. + * This function is similar to test_index_mface in + * blenkernel/intern/mesh.c. + * To not clutter the blenkernel code with more bad level + * calls/structures, this function resides here. + */ + + +static void fix_faceindices(MFace *mface, EditVlak *evl, int nr) +{ + int a; + float tmpuv[2]; + unsigned int tmpcol; + +/* +mface = ((MFace *) me->mface) + index; + tface = ((TFace *) me->tface) + index; + +*/ + + /* first test if the face is legal */ + + if(mface->v3 && mface->v3==mface->v4) { + mface->v4= 0; + nr--; + } + if(mface->v2 && mface->v2==mface->v3) { + mface->v3= mface->v4; + mface->v4= 0; + nr--; + } + if(mface->v1==mface->v2) { + mface->v2= mface->v3; + mface->v3= mface->v4; + mface->v4= 0; + nr--; + } + + /* voorkom dat een nul op de verkeerde plek staat */ + if(nr==2) { + if(mface->v2==0) SWAP(int, mface->v1, mface->v2); + } + else if(nr==3) { + if(mface->v3==0) { + SWAP(int, mface->v1, mface->v2); + SWAP(int, mface->v2, mface->v3); + /* rotate face UV coordinates, too */ + UVCOPY(tmpuv, evl->uv[0]); + UVCOPY(evl->uv[0], evl->uv[1]); + UVCOPY(evl->uv[1], evl->uv[2]); + UVCOPY(evl->uv[2], tmpuv); + /* same with vertex colours */ + tmpcol = evl->col[0]; + evl->col[0] = evl->col[1]; + evl->col[1] = evl->col[2]; + evl->col[2] = tmpcol; + + + a= mface->edcode; + mface->edcode= 0; + if(a & ME_V1V2) mface->edcode |= ME_V3V1; + if(a & ME_V2V3) mface->edcode |= ME_V1V2; + if(a & ME_V3V1) mface->edcode |= ME_V2V3; + + a= mface->puno; + mface->puno &= ~15; + if(a & ME_FLIPV1) mface->puno |= ME_FLIPV2; + if(a & ME_FLIPV2) mface->puno |= ME_FLIPV3; + if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1; + } + } + else if(nr==4) { + if(mface->v3==0 || mface->v4==0) { + SWAP(int, mface->v1, mface->v3); + SWAP(int, mface->v2, mface->v4); + /* swap UV coordinates */ + UVCOPY(tmpuv, evl->uv[0]); + UVCOPY(evl->uv[0], evl->uv[2]); + UVCOPY(evl->uv[2], tmpuv); + UVCOPY(tmpuv, evl->uv[1]); + UVCOPY(evl->uv[1], evl->uv[3]); + UVCOPY(evl->uv[3], tmpuv); + /* swap vertex colours */ + tmpcol = evl->col[0]; + evl->col[0] = evl->col[2]; + evl->col[2] = tmpcol; + tmpcol = evl->col[1]; + evl->col[1] = evl->col[3]; + evl->col[3] = tmpcol; + + a= mface->edcode; + mface->edcode= 0; + if(a & ME_V1V2) mface->edcode |= ME_V3V4; + if(a & ME_V2V3) mface->edcode |= ME_V2V3; + if(a & ME_V3V4) mface->edcode |= ME_V1V2; + if(a & ME_V4V1) mface->edcode |= ME_V4V1; + + a= mface->puno; + mface->puno &= ~15; + if(a & ME_FLIPV1) mface->puno |= ME_FLIPV3; + if(a & ME_FLIPV2) mface->puno |= ME_FLIPV4; + if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1; + if(a & ME_FLIPV4) mface->puno |= ME_FLIPV2; + } + } + +} + + + +/* load from EditMode to Mesh */ + +void load_editMesh(void) +{ + Mesh *me; + MFace *mface; + MVert *mvert; + MSticky *ms; + KeyBlock *actkey=0; + EditVert *eve; + EditVlak *evl; + EditEdge *eed; + float *fp, nor[3]; + int i, a, ototvert; +#ifdef __NLA + MDeformVert *dvert; + int usedDvert = 0; +#endif + + waitcursor(1); + countall(); + + me= get_mesh(G.obedit); + + ototvert= me->totvert; + + /* zijn er keys? */ + if(me->key) { + actkey= me->key->block.first; + while(actkey) { + if(actkey->flag & SELECT) break; + actkey= actkey->next; + } + } + + + if(actkey && me->key->refkey!=actkey) { + /* aktieve key && niet de refkey: alleen vertices */ + + if(G.totvert) { + if(actkey->data) MEM_freeN(actkey->data); + + fp=actkey->data= MEM_callocN(me->key->elemsize*G.totvert, "actkey->data"); + actkey->totelem= G.totvert; + + eve= G.edve.first; + while(eve) { + VECCOPY(fp, eve->co); + fp+= 3; + eve= eve->next; + } + } + } + else if(me->key && actkey==0) { + /* er zijn keys, alleen veranderingen in mverts schrijven */ + /* als aantal vertices verschillen, beetje onvoorspelbaar */ + + eve= G.edve.first; + mvert= me->mvert; + for(a=0; a<me->totvert; a++, mvert++) { + VECCOPY(mvert->co, eve->co); + eve= eve->next; + if(eve==0) break; + } + } + else { + /* als er keys zijn: de refkey, anders gewoon de me */ + + /* deze telt ook of edges niet in vlakken zitten: */ + /* eed->f==0 niet in vlak, f==1 is tekenen */ + /* eed->f1 : flag voor dynaface (cylindertest) */ + /* eve->f1 : flag voor dynaface (sphere test) */ + edge_drawflags(); + + /* LET OP: op evl->f de punoflag */ + vertexnormals( (me->flag & ME_NOPUNOFLIP)==0 ); + + eed= G.eded.first; + while(eed) { + if(eed->f==0) G.totface++; + eed= eed->next; + } + + /* nieuw Face blok */ + if(G.totface==0) mface= 0; + else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh1"); + /* nieuw Vertex blok */ + if(G.totvert==0) mvert= 0; + else mvert= MEM_callocN(G.totvert*sizeof(MVert), "loadeditMesh2"); + +#ifdef __NLA + if (G.totvert==0) dvert=0; + else dvert = MEM_callocN(G.totvert*sizeof(MDeformVert), "loadeditMesh3"); + + if (me->dvert) free_dverts(me->dvert, me->totvert); + me->dvert=dvert; +#endif + if(me->mvert) MEM_freeN(me->mvert); + me->mvert= mvert; + + if(me->mface) MEM_freeN(me->mface); + me->mface= mface; + me->totvert= G.totvert; + me->totface= G.totface; + + /* de vertices, gebruik ->vn als teller */ + eve= G.edve.first; + a=0; + + + + while(eve) { + VECCOPY(mvert->co, eve->co); + mvert->mat_nr= 255; /* waarvoor ook al weer, haloos? */ + + /* puno */ + VECCOPY(nor, eve->no); + VecMulf(nor, 32767.0); + VECCOPY(mvert->no, nor); +#ifdef __NLA +/* OLD VERSION */ +/* mvert->totweight = eve->totweight; + if (eve->dw){ + int cv; + mvert->dw = BLI_callocN (sizeof(MDeformWeight)*eve->totweight, "deformWeight"); + memcpy (mvert->dw, eve->dw, sizeof(MDeformWeight)*eve->totweight); + } +*/ + /* NEW VERSION */ + if (dvert){ + dvert->totweight=eve->totweight; + if (eve->dw){ + dvert->dw = MEM_callocN (sizeof(MDeformWeight)*eve->totweight, "deformWeight"); + memcpy (dvert->dw, eve->dw, sizeof(MDeformWeight)*eve->totweight); + usedDvert++; + } + } +#endif + + eve->vn= (EditVert *)(long)(a++); /* teller */ + + mvert->flag= 0; + if(eve->f1==1) mvert->flag |= ME_SPHERETEST; + + eve= eve->next; + mvert++; +#ifdef __NLA + dvert++; +#endif + } + +#ifdef __NLA + /* If we didn't actually need the dverts, get rid of them */ + if (!usedDvert){ + free_dverts(me->dvert, G.totvert); + me->dvert=NULL; + } +#endif + + /* de vlakken */ + evl= G.edvl.first; + i = 0; + while(evl) { + mface= &((MFace *) me->mface)[i]; + + mface->v1= (unsigned int) evl->v1->vn; + mface->v2= (unsigned int) evl->v2->vn; + mface->v3= (unsigned int) evl->v3->vn; + if(evl->v4) mface->v4= (unsigned int) evl->v4->vn; + + mface->mat_nr= evl->mat_nr; + mface->puno= evl->f; + mface->flag= evl->flag; + + /* mat_nr in vertex */ + if(me->totcol>1) { + mvert= me->mvert+mface->v1; + if(mvert->mat_nr == 255) mvert->mat_nr= mface->mat_nr; + mvert= me->mvert+mface->v2; + if(mvert->mat_nr == 255) mvert->mat_nr= mface->mat_nr; + mvert= me->mvert+mface->v3; + if(mvert->mat_nr == 255) mvert->mat_nr= mface->mat_nr; + if(mface->v4) { + mvert= me->mvert+mface->v4; + if(mvert->mat_nr == 255) mvert->mat_nr= mface->mat_nr; + } + } + + /* dyna cilinder flag minder kritisch testen: 'dubbel' in vlakken laten zitten. + * gaat anders fout bij scherpe hoeken (inpspeed voor een wel, ander niet!) + * Mogelijk oplossen door volgorde aan te passen: sphere-cyl-face. Kost te veel? + */ + + /* letop: evl->e1->f==0 is losse edge */ + + if(evl->e1->f==1) { + mface->edcode |= ME_V1V2; + evl->e1->f= 2; + } + if(evl->e2->f==1) { + mface->edcode |= ME_V2V3; + evl->e2->f= 2; + } + if(evl->e3->f==1) { + if(evl->v4) { + mface->edcode |= ME_V3V4; + } + else { + mface->edcode |= ME_V3V1; + } + evl->e3->f= 2; + } + if(evl->e4 && evl->e4->f==1) { + mface->edcode |= ME_V4V1; + evl->e4->f= 2; + } + + /* geen index '0' op plek 3 of 4 */ + if(evl->v4) fix_faceindices(mface, evl, 4); + else fix_faceindices(mface, evl, 3); + + i++; + evl= evl->next; + } + + /* losse edges als vlak toevoegen */ + eed= G.eded.first; + while(eed) { + if( eed->f==0 ) { + mface= &((MFace *) me->mface)[i]; + mface->v1= (unsigned int) eed->v1->vn; + mface->v2= (unsigned int) eed->v2->vn; + test_index_mface(mface, 2); + mface->edcode= ME_V1V2; + i++; + } + eed= eed->next; + } + + tex_space_mesh(me); + if(actkey) mesh_to_key(me, actkey); + + /* texmesh: ahv ->tface alles opnieuw maken */ + if(me->tface && me->totface) { + TFace *tfn, *tf; + + tf=tfn= MEM_callocN(sizeof(TFace)*me->totface, "tface"); + evl= G.edvl.first; + while(evl) { + + if(evl->tface) *tf= *(evl->tface); + else default_tface(tf); + + memcpy(tf->col, evl->col, sizeof(tf->col)); + memcpy(tf->uv, evl->uv, sizeof(tf->uv)); + + if(G.f & G_FACESELECT) { + if( vlakselectedAND(evl, 1) ) tf->flag |= TF_SELECT; + else tf->flag &= ~TF_SELECT; + } + + /* sometimes editmode doesn't free (before render) */ + evl->tface= tf; + + tf++; + evl= evl->next; + } + + MEM_freeN(me->tface); + me->tface= tfn; + } + else if(me->tface) { + /* freeN(me->tface); */ + /* me->tface= 0; */ + } + + /* mcol: ahv indexnrs opnieuw maken */ + if(me->mcol && me->totface) { + unsigned int *mcn, *mc; + + mc=mcn= MEM_mallocN(4*sizeof(int)*me->totface, "mcol"); + evl= G.edvl.first; + while(evl) { + + memcpy(mc, evl->col, 4*sizeof(int)); + + mc+=4; + evl= evl->next; + } + + MEM_freeN(me->mcol); + me->mcol= (MCol *)mcn; + } + else if(me->mcol) { + MEM_freeN(me->mcol); + me->mcol= 0; + } + } + + if(actkey) do_spec_key(me->key); + + /* voor zekerheid: ->vn pointers wissen */ + eve= G.edve.first; + while(eve) { + eve->vn= 0; + eve= eve->next; + } + + /* displisten van alle users, ook deze */ + freedisplist(&me->disp); + freedisplist(&G.obedit->disp); + + /* sticky */ + if(me->msticky) { + if (ototvert<me->totvert) { + ms= MEM_callocN(me->totvert*sizeof(MSticky), "msticky"); + memcpy(ms, me->msticky, ototvert*sizeof(MSticky)); + MEM_freeN(me->msticky); + me->msticky= ms; + error("Sticky was too small"); + } + } + waitcursor(0); +} + + +void remake_editMesh(void) +{ + + if(okee("Reload Original data")==0) return; + + make_editMesh(); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +/* ********************* TOOLS ********************* */ + + + +void make_sticky(void) +{ + Object *ob; + Base *base; + MVert *mvert; + Mesh *me; + MSticky *ms; + float ho[4], mat[4][4]; + int a; + + if(G.scene->camera==0) return; + + if(G.obedit) { + error("Unable to perform function in EditMode"); + return; + } + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base->object->type==OB_MESH) { + ob= base->object; + + me= ob->data; + mvert= me->mvert; + if(me->msticky) MEM_freeN(me->msticky); + me->msticky= MEM_mallocN(me->totvert*sizeof(MSticky), "sticky"); + + /* stukje roteerscene */ + R.r= G.scene->r; + R.r.xsch= (R.r.size*R.r.xsch)/100; + R.r.ysch= (R.r.size*R.r.ysch)/100; + + R.afmx= R.r.xsch/2; + R.afmy= R.r.ysch/2; + + R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp); + + R.rectx= R.r.xsch; + R.recty= R.r.ysch; + R.xstart= -R.afmx; + R.ystart= -R.afmy; + R.xend= R.xstart+R.rectx-1; + R.yend= R.ystart+R.recty-1; + + where_is_object(G.scene->camera); + Mat4CpyMat4(R.viewinv, G.scene->camera->obmat); + Mat4Ortho(R.viewinv); + Mat4Invert(R.viewmat, R.viewinv); + + RE_setwindowclip(1, -1); + + where_is_object(ob); + Mat4MulMat4(mat, ob->obmat, R.viewmat); + + ms= me->msticky; + for(a=0; a<me->totvert; a++, ms++, mvert++) { + VECCOPY(ho, mvert->co); + Mat4MulVecfl(mat, ho); + RE_projectverto(ho, ho); + ms->co[0]= ho[0]/ho[3]; + ms->co[1]= ho[1]/ho[3]; + } + } + } + base= base->next; + } + allqueue(REDRAWBUTSEDIT, 0); +} + +void fasterdraw(void) +{ + Base *base; + Mesh *me; + MFace *mface; + int toggle, a; + + if(G.obedit) return; + + /* vlaggen resetten */ + me= G.main->mesh.first; + while(me) { + me->flag &= ~ME_ISDONE; + me= me->id.next; + } + + base= FIRSTBASE; + while(base) { + if( TESTBASELIB(base) && (base->object->type==OB_MESH)) { + me= base->object->data; + if(me->id.lib==0 && (me->flag & ME_ISDONE)==0) { + me->flag |= ME_ISDONE; + mface= me->mface; + toggle= 0; + for(a=0; a<me->totface; a++) { + if( (mface->edcode & ME_V1V2) && ( (toggle++) & 1) ) { + mface->edcode-= ME_V1V2; + } + if( (mface->edcode & ME_V2V3) && ( (toggle++) & 1)) { + mface->edcode-= ME_V2V3; + } + if( (mface->edcode & ME_V3V1) && ( (toggle++) & 1)) { + mface->edcode-= ME_V3V1; + } + if( (mface->edcode & ME_V4V1) && ( (toggle++) & 1)) { + mface->edcode-= ME_V4V1; + } + if( (mface->edcode & ME_V3V4) && ( (toggle++) & 1)) { + mface->edcode-= ME_V3V4; + } + mface++; + } + } + } + base= base->next; + } + + /* belangrijk?: vlaggen weer resetten */ + me= G.main->mesh.first; + while(me) { + me->flag &= ~ME_ISDONE; + me= me->id.next; + } + + allqueue(REDRAWVIEW3D, 0); +} + +void slowerdraw(void) /* reset fasterdraw */ +{ + Base *base; + Mesh *me; + MFace *mface; + int a; + + if(G.obedit) return; + + base= FIRSTBASE; + while(base) { + if( TESTBASELIB(base) && (base->object->type==OB_MESH)) { + me= base->object->data; + if(me->id.lib==0) { + + mface= me->mface; + + for(a=0; a<me->totface; a++) { + + mface->edcode |= ME_V1V2|ME_V2V3; + mface++; + } + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); +} + + +void convert_to_triface(int all) +{ + EditVlak *evl, *evln, *next; + + evl= G.edvl.first; + while(evl) { + next= evl->next; + if(evl->v4) { + if(all || vlakselectedAND(evl, 1) ) { + + evln= addvlaklist(evl->v1, evl->v2, evl->v3, 0, evl); + evln= addvlaklist(evl->v1, evl->v3, evl->v4, 0, evl); + + if(evl->tface) { + evln->uv[1][0]= evln->uv[2][0]; + evln->uv[1][1]= evln->uv[2][1]; + evln->uv[2][0]= evln->uv[3][0]; + evln->uv[2][1]= evln->uv[3][1]; + } + + evln->col[1]= evln->col[2]; + evln->col[2]= evln->col[3]; + + BLI_remlink(&G.edvl, evl); + freevlak(evl); + } + } + evl= next; + } + +} + + +void deselectall_mesh(void) /* toggle */ +{ + EditVert *eve; + int a; + + if(G.obedit->lay & G.vd->lay) { + a= 0; + eve= G.edve.first; + while(eve) { + if(eve->f & 1) { + a= 1; + break; + } + eve= eve->next; + } + eve= G.edve.first; + while(eve) { + if(eve->h==0) { + if(a) eve->f&= -2; + else eve->f|= 1; + } + eve= eve->next; + } + tekenvertices_ext(a==0); + } + countall(); +} + + +void righthandfaces(int select) /* maakt vlakken rechtsdraaiend */ +{ + EditEdge *eed, *ed1, *ed2, *ed3, *ed4; + EditVlak *evl, *startvl; + float maxx, nor[3], cent[3]; + int totsel, found, foundone, direct, turn; + + /* op basis selectconnected om losse objecten te onderscheiden */ + + /* tel per edge hoeveel vlakken het heeft */ + + /* vind het meest linkse, voorste, bovenste vlak */ + + /* zet normaal naar buiten en de eerste richtings vlaggen in de edges */ + + /* loop object af en zet richtingen / richtingsvlaggen: alleen bij edges van 1 of 2 vlakken */ + /* dit is in feit de select connected */ + + /* indien nog (selected) vlakken niet gedaan: opnieuw vind de meest linkse ... */ + + waitcursor(1); + + eed= G.eded.first; + while(eed) { + eed->f= 0; + eed->f1= 0; + eed= eed->next; + } + + /* vlakken en edges tellen */ + totsel= 0; + evl= G.edvl.first; + while(evl) { + if(select==0 || vlakselectedAND(evl, 1) ) { + evl->f= 1; + totsel++; + evl->e1->f1++; + evl->e2->f1++; + evl->e3->f1++; + if(evl->v4) evl->e4->f1++; + } + else evl->f= 0; + + evl= evl->next; + } + + while(totsel>0) { + /* van buiten naar binnen */ + + evl= G.edvl.first; + startvl= 0; + maxx= -1.0e10; + + while(evl) { + if(evl->f) { + CalcCent3f(cent, evl->v1->co, evl->v2->co, evl->v3->co); + cent[0]= fabs(cent[0])+fabs(cent[1])+fabs(cent[2]); + + if(cent[0]>maxx) { + maxx= cent[0]; + startvl= evl; + } + } + evl= evl->next; + } + + /* eerste vlak goedzetten: normaal berekenen */ + CalcNormFloat(startvl->v1->co, startvl->v2->co, startvl->v3->co, nor); + CalcCent3f(cent, startvl->v1->co, startvl->v2->co, startvl->v3->co); + + /* eerste normaal staat zus of zo */ + if(select) { + if(select==2) { + if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] > 0.0) flipvlak(startvl); + } + else { + if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipvlak(startvl); + } + } + else if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipvlak(startvl); + + + eed= startvl->e1; + if(eed->v1==startvl->v1) eed->f= 1; + else eed->f= 2; + + eed= startvl->e2; + if(eed->v1==startvl->v2) eed->f= 1; + else eed->f= 2; + + eed= startvl->e3; + if(eed->v1==startvl->v3) eed->f= 1; + else eed->f= 2; + + eed= startvl->e4; + if(eed) { + if(eed->v1==startvl->v4) eed->f= 1; + else eed->f= 2; + } + + startvl->f= 0; + totsel--; + + /* de normalen testen */ + found= 1; + direct= 1; + while(found) { + found= 0; + if(direct) evl= G.edvl.first; + else evl= G.edvl.last; + while(evl) { + if(evl->f) { + turn= 0; + foundone= 0; + + ed1= evl->e1; + ed2= evl->e2; + ed3= evl->e3; + ed4= evl->e4; + + if(ed1->f) { + if(ed1->v1==evl->v1 && ed1->f==1) turn= 1; + if(ed1->v2==evl->v1 && ed1->f==2) turn= 1; + foundone= 1; + } + else if(ed2->f) { + if(ed2->v1==evl->v2 && ed2->f==1) turn= 1; + if(ed2->v2==evl->v2 && ed2->f==2) turn= 1; + foundone= 1; + } + else if(ed3->f) { + if(ed3->v1==evl->v3 && ed3->f==1) turn= 1; + if(ed3->v2==evl->v3 && ed3->f==2) turn= 1; + foundone= 1; + } + else if(ed4 && ed4->f) { + if(ed4->v1==evl->v4 && ed4->f==1) turn= 1; + if(ed4->v2==evl->v4 && ed4->f==2) turn= 1; + foundone= 1; + } + + if(foundone) { + found= 1; + totsel--; + evl->f= 0; + + if(turn) { + if(ed1->v1==evl->v1) ed1->f= 2; + else ed1->f= 1; + if(ed2->v1==evl->v2) ed2->f= 2; + else ed2->f= 1; + if(ed3->v1==evl->v3) ed3->f= 2; + else ed3->f= 1; + if(ed4) { + if(ed4->v1==evl->v4) ed4->f= 2; + else ed4->f= 1; + } + + flipvlak(evl); + + } + else { + if(ed1->v1== evl->v1) ed1->f= 1; + else ed1->f= 2; + if(ed2->v1==evl->v2) ed2->f= 1; + else ed2->f= 2; + if(ed3->v1==evl->v3) ed3->f= 1; + else ed3->f= 2; + if(ed4) { + if(ed4->v1==evl->v4) ed4->f= 1; + else ed4->f= 2; + } + } + } + } + if(direct) evl= evl->next; + else evl= evl->prev; + } + direct= 1-direct; + } + } + + recalc_editnormals(); + + makeDispList(G.obedit); + + waitcursor(0); +} + +static EditVert *findnearestvert(short sel) +{ + /* als sel==1 krijgen vertices met flag==1 een nadeel */ + EditVert *eve,*act=0; + static EditVert *acto=0; + short dist=100,temp,mval[2]; + + if(G.edve.first==0) return 0; + + /* projektie doen */ + calc_meshverts_ext(); /* drawobject.c */ + + /* er wordt geteld van acto->next tot last en van first tot acto */ + /* bestaat acto ? */ + eve= G.edve.first; + while(eve) { + if(eve==acto) break; + eve= eve->next; + } + if(eve==0) acto= G.edve.first; + + if(acto==0) return 0; + + /* is er een aangegeven vertex? deel 1 */ + getmouseco_areawin(mval); + eve= acto->next; + while(eve) { + if(eve->h==0) { + temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys); + if( (eve->f & 1)==sel ) temp+=5; + if(temp<dist) { + act= eve; + dist= temp; + if(dist<4) break; + } + } + eve= eve->next; + } + /* is er een aangegeven vertex? deel 2 */ + if(dist>3) { + eve= G.edve.first; + while(eve) { + if(eve->h==0) { + temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys); + if( (eve->f & 1)==sel ) temp+=5; + if(temp<dist) { + act= eve; + if(temp<4) break; + dist= temp; + } + if(eve== acto) break; + } + eve= eve->next; + } + } + + acto= act; + return act; +} + +static void tekenvertices_special(int mode, EditVert *act) +{ + /* voor speciale gevallen: + * mode 0: deselect geselecteerde, teken ze, behalve act + * mode 1: teken alleen act + */ + ScrArea *tempsa, *sa; + View3D *vd; + EditVert *eve; + float mat[4][4]; + int doit=0; + + /* eerst testen of er wel special vertices zijn */ + + eve= (EditVert *)G.edve.first; + while(eve) { + eve->f1= 0; + if(eve->h==0) { + if(mode==0) { + if(eve!=act && eve->f & 1) { + doit= 1; + eve->f1= 1; + eve->f -= 1; + } + } + else if(mode==1) { + if(eve==act) eve->f1= 1; + doit= 1; + } + } + eve= eve->next; + } + if(doit==0) return; + + if(G.f & (G_FACESELECT+G_DRAWFACES)) { + scrarea_queue_winredraw(curarea); + return; + } + + if(G.zbuf) glDisable(GL_DEPTH_TEST); + + glDrawBuffer(GL_FRONT); + + /* alle views aflopen */ + tempsa= curarea; + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==SPACE_VIEW3D) { + vd= sa->spacedata.first; + if(G.obedit->lay & vd->lay) { + areawinset(sa->win); + mymultmatrix(G.obedit->obmat); + + MTC_Mat4SwapMat4(G.vd->persmat, mat); + mygetsingmatrix(G.vd->persmat); + + tekenvertices(0); + tekenvertices(1); + + MTC_Mat4SwapMat4(G.vd->persmat, mat); + + sa->win_swap= WIN_FRONT_OK; + + myloadmatrix(G.vd->viewmat); + } + } + sa= sa->next; + } + if(curarea!=tempsa) areawinset(tempsa->win); + + glDrawBuffer(GL_BACK); + if(G.zbuf) glEnable(GL_DEPTH_TEST); +} + +void mouse_mesh(void) +{ + EditVert *act=0; + + act= findnearestvert(1); + if(act) { + + if((G.qual & LR_SHIFTKEY)==0) { + tekenvertices_special(0, act); + } + if( (act->f & 1)==0) act->f+= 1; + else if(G.qual & LR_SHIFTKEY) act->f-= 1; + + tekenvertices_special(1, act); + countall(); + } + + rightmouse_transform(); +} + +static void selectconnectedAll(void) +{ + EditVert *v1,*v2; + EditEdge *eed; + short flag=1,toggle=0; + + if(G.eded.first==0) return; + + while(flag==1) { + flag= 0; + toggle++; + if(toggle & 1) eed= G.eded.first; + else eed= G.eded.last; + while(eed) { + v1= eed->v1; + v2= eed->v2; + if(eed->h==0) { + if(v1->f & 1) { + if( (v2->f & 1)==0 ) { + v2->f |= 1; + flag= 1; + } + } + else if(v2->f & 1) { + if( (v1->f & 1)==0 ) { + v1->f |= 1; + flag= 1; + } + } + } + if(toggle & 1) eed= eed->next; + else eed= eed->prev; + } + } + countall(); + + tekenvertices_ext(1); + +} + + +void selectconnected_mesh(void) +{ + EditVert *eve,*v1,*v2,*act= 0; + EditEdge *eed; + short flag=1,sel,toggle=0; + + if(G.eded.first==0) return; + + if(G.qual & LR_CTRLKEY) { + selectconnectedAll(); + return; + } + + sel= 3; + if(G.qual & LR_SHIFTKEY) sel=2; + + act= findnearestvert(sel-2); + if(act==0) { + error(" Nothing indicated "); + return; + } + + /* testflaggen wissen */ + eve= G.edve.first; + while(eve) { + eve->f&= ~2; + eve= eve->next; + } + act->f= (act->f & ~3) | sel; + + while(flag==1) { + flag= 0; + toggle++; + if(toggle & 1) eed= G.eded.first; + else eed= G.eded.last; + while(eed) { + v1= eed->v1; + v2= eed->v2; + if(eed->h==0) { + if(v1->f & 2) { + if( (v2->f & 2)==0 ) { + v2->f= (v2->f & ~3) | sel; + flag= 1; + } + } + else if(v2->f & 2) { + if( (v1->f & 2)==0 ) { + v1->f= (v1->f & ~3) | sel; + flag= 1; + } + } + } + if(toggle & 1) eed= eed->next; + else eed= eed->prev; + } + } + countall(); + + tekenvertices_ext( sel==3 ); +} + + +short extrudeflag(short flag,short type) +{ + /* als type=1 worden oude extrudevlakken verwijderd (ivm spin etc) */ + /* alle verts met (flag & 'flag') extrude */ + /* van oude wordt flag 'flag' gewist, van nieuwe gezet */ + + EditVert *eve, *v1, *v2, *v3, *v4, *nextve; + EditEdge *eed, *e1, *e2, *e3, *e4, *nexted; + EditVlak *evl, *nextvl; + short sel=0, deloud= 0; + + if(G.obedit==0 || get_mesh(G.obedit)==0) return 0; + + /* de vert flag f1 wissen, hiermee test op losse geselecteerde vert */ + eve= G.edve.first; + while(eve) { + if(eve->f & flag) eve->f1= 1; + else eve->f1= 0; + eve= eve->next; + } + /* de edges tellerflag wissen, als selected op 1 zetten */ + eed= G.eded.first; + while(eed) { + if( (eed->v1->f & flag) && (eed->v2->f & flag) ) { + eed->f= 1; + eed->v1->f1= 0; + eed->v2->f1= 0; + } + else eed->f= 0; + + eed->f1= 1; /* aangeven is 'oude' edge (er worden in deze routine nieuwe gemaakt */ + + eed= eed->next; + } + + + /* in alle vlak sel een dupl.flag zetten en bijhorende edgeflags ophogen */ + + evl= G.edvl.first; + while(evl) { + evl->f= 0; + + if(vlakselectedAND(evl, flag)) { + e1= evl->e1; + e2= evl->e2; + e3= evl->e3; + e4= evl->e4; + + if(e1->f < 3) e1->f++; + if(e2->f < 3) e2->f++; + if(e3->f < 3) e3->f++; + if(e4 && e4->f < 3) e4->f++; + evl->f= 1; + } + else if(vlakselectedOR(evl, flag)) { + e1= evl->e1; + e2= evl->e2; + e3= evl->e3; + e4= evl->e4; + + if( (e1->v1->f & flag) && (e1->v2->f & flag) ) e1->f1= 2; + if( (e2->v1->f & flag) && (e2->v2->f & flag) ) e2->f1= 2; + if( (e3->v1->f & flag) && (e3->v2->f & flag) ) e3->f1= 2; + if( e4 && (e4->v1->f & flag) && (e4->v2->f & flag) ) e4->f1= 2; + } + + evl= evl->next; + } + + /* set direction of edges */ + evl= G.edvl.first; + while(evl) { + if(evl->f== 0) { + if(evl->e1->f==2) { + if(evl->e1->v1 == evl->v1) evl->e1->dir= 0; + else evl->e1->dir= 1; + } + if(evl->e2->f==2) { + if(evl->e2->v1 == evl->v2) evl->e2->dir= 0; + else evl->e2->dir= 1; + } + if(evl->e3->f==2) { + if(evl->e3->v1 == evl->v3) evl->e3->dir= 0; + else evl->e3->dir= 1; + } + if(evl->e4 && evl->e4->f==2) { + if(evl->e4->v1 == evl->v4) evl->e4->dir= 0; + else evl->e4->dir= 1; + } + } + evl= evl->next; + } + + + /* de stand van zaken nu: + eve->f1==1: losse selected vertex + + eed->f==0 : edge niet selected, geen extrude + eed->f==1 : edge selected, komt niet in vlak voor, extrude + eed->f==2 : edge selected, komt 1 keer in vlak voor, extrude + eed->f==3 : edge selected, komt in meer vlakken voor, geen extrude + + eed->f1==0: nieuwe edge + eed->f1==1: edge selected, komt in selected vlak voor, als f==3: remove + eed->f1==2: edge selected, komt in NIET selected vlak voor + + + evl->f==1 : vlak dupliceren + */ + + /* alle geselecteerde vertices kopieeren, */ + /* de pointer naar nieuwe vert in oude struct schrijven op eve->vn */ + eve= G.edve.last; + while(eve) { + eve->f&= ~128; /* wissen voor test later op losse verts */ + if(eve->f & flag) { + sel= 1; + v1= addvertlist(0); + + VECCOPY(v1->co, eve->co); + v1->f= eve->f; + eve->f-= flag; + eve->vn= v1; + } + else eve->vn= 0; + eve= eve->prev; + } + + if(sel==0) return 0; + + /* alle edges met eed->f==1 of eed->f==2 worden vlakken */ + /* als deloud==1 worden edges eed->f>2 verwijderd */ + eed= G.eded.last; + while(eed) { + nexted= eed->prev; + if( eed->f<3) { + eed->v1->f|=128; /* =geen losse vert! */ + eed->v2->f|=128; + } + if( (eed->f==1 || eed->f==2) ) { + if(eed->f1==2) deloud=1; + + /* that dir thing does work somewhat... */ + + if(eed->dir==1) addvlaklist(eed->v1, eed->v2, eed->v2->vn, eed->v1->vn, NULL); + else addvlaklist(eed->v2, eed->v1, eed->v1->vn, eed->v2->vn, NULL); + } + + eed= nexted; + } + if(deloud) { + eed= G.eded.first; + while(eed) { + nexted= eed->next; + if(eed->f==3 && eed->f1==1) { + remedge(eed); + free(eed); + } + eed= nexted; + } + } + /* de vlakken dupliceren, eventueel oude verwijderen */ + evl= G.edvl.first; + while(evl) { + nextvl= evl->next; + if(evl->f & 1) { + + v1= evl->v1->vn; + v2= evl->v2->vn; + v3= evl->v3->vn; + if(evl->v4) v4= evl->v4->vn; else v4= 0; + + addvlaklist(v1, v2, v3, v4, evl); + + if(deloud) { + BLI_remlink(&G.edvl, evl); + freevlak(evl); + } + + } + evl= nextvl; + } + /* alle verts met eve->vn!=0 + als eve->f1==1: edge maken + als flag!=128 :als deloud==1: verwijderen + */ + eve= G.edve.last; + while(eve) { + nextve= eve->prev; + if(eve->vn) { + if(eve->f1==1) addedgelist(eve,eve->vn); + else if( (eve->f & 128)==0) { + if(deloud) { + BLI_remlink(&G.edve,eve); +// free(eve); + free_editvert(eve); + eve= NULL; + } + } + } + if(eve) eve->f&= ~128; + + eve= nextve; + } + + /* debug temp: testen op consistente: + evl= G.edvl.first; + while(evl) { + e1= findedgelist(evl->v1, evl->v2); + e2= findedgelist(evl->v2, evl->v3); + e3= findedgelist(evl->v3, evl->v1); + if(e1==0 || e2==0 || e3==0) { + error("edge not in edgelist"); + break; + } + evl= evl->next; + } + */ + + return 1; +} + +void rotateflag(short flag, float *cent, float rotmat[][3]) +{ + /* alle verts met (flag & 'flag') rotate */ + + EditVert *eve; + + eve= G.edve.first; + while(eve) { + if(eve->f & flag) { + eve->co[0]-=cent[0]; + eve->co[1]-=cent[1]; + eve->co[2]-=cent[2]; + Mat3MulVecfl(rotmat,eve->co); + eve->co[0]+=cent[0]; + eve->co[1]+=cent[1]; + eve->co[2]+=cent[2]; + } + eve= eve->next; + } +} + +void translateflag(short flag, float *vec) +{ + /* alle verts met (flag & 'flag') translate */ + + EditVert *eve; + + eve= G.edve.first; + while(eve) { + if(eve->f & flag) { + eve->co[0]+=vec[0]; + eve->co[1]+=vec[1]; + eve->co[2]+=vec[2]; + } + eve= eve->next; + } +} + +short removedoublesflag(short flag, float limit) /* return aantal */ +{ + /* alle verts met (flag & 'flag') worden getest */ + EditVert *eve, *v1, *nextve; + EditEdge *eed, *e1, *nexted; + EditVlak *evl, *nextvl; + struct xvertsort *sortblock, *sb, *sb1; + struct vlaksort *vlsortblock, *vsb, *vsb1; + float dist; + int a, b, test, aantal; + + /* flag 128 wordt gewist, aantal tellen */ + eve= G.edve.first; + aantal= 0; + while(eve) { + eve->f&= ~128; + if(eve->f & flag) aantal++; + eve= eve->next; + } + if(aantal==0) return 0; + + /* geheugen reserveren en qsorten */ + sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*aantal,"sortremovedoub"); + eve= G.edve.first; + while(eve) { + if(eve->f & flag) { + sb->x= eve->co[0]+eve->co[1]+eve->co[2]; + sb->v1= eve; + sb++; + } + eve= eve->next; + } + qsort(sortblock, aantal, sizeof(struct xvertsort), vergxco); + + /* testen op doubles */ + sb= sortblock; + for(a=0; a<aantal; a++) { + eve= sb->v1; + if( (eve->f & 128)==0 ) { + sb1= sb+1; + for(b=a+1; b<aantal; b++) { + /* eerste test: simpel dist */ + dist= sb1->x - sb->x; + if(dist > limit) break; + + /* tweede test: is vertex toegestaan */ + v1= sb1->v1; + if( (v1->f & 128)==0 ) { + + dist= fabs(v1->co[0]-eve->co[0]); + if(dist<=limit) { + dist= fabs(v1->co[1]-eve->co[1]); + if(dist<=limit) { + dist= fabs(v1->co[2]-eve->co[2]); + if(dist<=limit) { + v1->f|= 128; + v1->vn= eve; + } + } + } + } + sb1++; + } + } + sb++; + } + MEM_freeN(sortblock); + + /* edges testen en opnieuw invoegen */ + eed= G.eded.first; + while(eed) { + eed->f= 0; + eed= eed->next; + } + eed= G.eded.last; + while(eed) { + nexted= eed->prev; + + if(eed->f==0) { + if( (eed->v1->f & 128) || (eed->v2->f & 128) ) { + remedge(eed); + + if(eed->v1->f & 128) eed->v1= eed->v1->vn; + if(eed->v2->f & 128) eed->v2= eed->v2->vn; + + e1= addedgelist(eed->v1,eed->v2); + + if(e1) e1->f= 1; + if(e1!=eed) free(eed); + } + } + eed= nexted; + } + + /* eerst aantal testvlakken tellen */ + evl= (struct EditVlak *)G.edvl.first; + aantal= 0; + while(evl) { + evl->f= 0; + if(evl->v1->f & 128) evl->f= 1; + else if(evl->v2->f & 128) evl->f= 1; + else if(evl->v3->f & 128) evl->f= 1; + else if(evl->v4 && (evl->v4->f & 128)) evl->f= 1; + + if(evl->f==1) aantal++; + evl= evl->next; + } + + /* vlakken testen op dubbele punten en eventueel verwijderen */ + evl= (struct EditVlak *)G.edvl.first; + while(evl) { + nextvl= evl->next; + if(evl->f==1) { + + if(evl->v1->f & 128) evl->v1= evl->v1->vn; + if(evl->v2->f & 128) evl->v2= evl->v2->vn; + if(evl->v3->f & 128) evl->v3= evl->v3->vn; + if(evl->v4 && (evl->v4->f & 128)) evl->v4= evl->v4->vn; + + test= 0; + if(evl->v1==evl->v2) test+=1; + if(evl->v2==evl->v3) test+=2; + if(evl->v3==evl->v1) test+=4; + if(evl->v4==evl->v1) test+=8; + if(evl->v3==evl->v4) test+=16; + if(evl->v2==evl->v4) test+=32; + + if(test) { + if(evl->v4) { + if(test==1 || test==2) { + evl->v2= evl->v3; + evl->v3= evl->v4; + evl->v4= 0; + test= 0; + } + else if(test==8 || test==16) { + evl->v4= 0; + test= 0; + } + else { + BLI_remlink(&G.edvl, evl); + freevlak(evl); + aantal--; + } + } + else { + BLI_remlink(&G.edvl, evl); + freevlak(evl); + aantal--; + } + } + + if(test==0) { + /* edgepointers goedzetten */ + evl->e1= findedgelist(evl->v1, evl->v2); + evl->e2= findedgelist(evl->v2, evl->v3); + if(evl->v4==0) { + evl->e3= findedgelist(evl->v3, evl->v1); + evl->e4= 0; + } + else { + evl->e3= findedgelist(evl->v3, evl->v4); + evl->e4= findedgelist(evl->v4, evl->v1); + } + } + } + evl= nextvl; + } + + /* dubbele vlakken: sortblock */ + /* opnieuw tellen, nu alle selected vlakken */ + aantal= 0; + evl= G.edvl.first; + while(evl) { + evl->f= 0; + if(vlakselectedAND(evl, 1)) { + evl->f= 1; + aantal++; + } + evl= evl->next; + } + + if(aantal) { + /* dubbele vlakken: sortblock */ + vsb= vlsortblock= MEM_mallocN(sizeof(struct vlaksort)*aantal, "sortremovedoub"); + evl= G.edvl.first; + while(evl) { + if(evl->f & 1) { + if(evl->v4) vsb->x= (long) MIN4( (long)evl->v1, (long)evl->v2, (long)evl->v3, (long)evl->v4); + else vsb->x= (long) MIN3( (long)evl->v1, (long)evl->v2, (long)evl->v3); + + vsb->evl= evl; + vsb++; + } + evl= evl->next; + } + + qsort(vlsortblock, aantal, sizeof(struct vlaksort), vergvlak); + + vsb= vlsortblock; + for(a=0; a<aantal; a++) { + evl= vsb->evl; + if( (evl->f & 128)==0 ) { + vsb1= vsb+1; + + for(b=a+1; b<aantal; b++) { + + /* eerste test: zelfde poin? */ + if(vsb->x != vsb1->x) break; + + /* tweede test: is test toegestaan */ + evl= vsb1->evl; + if( (evl->f & 128)==0 ) { + if( comparevlak(evl, vsb->evl)) evl->f |= 128; + + } + vsb1++; + } + } + vsb++; + } + + MEM_freeN(vlsortblock); + + /* dubbele vlakken eruit */ + evl= (struct EditVlak *)G.edvl.first; + while(evl) { + nextvl= evl->next; + if(evl->f & 128) { + BLI_remlink(&G.edvl, evl); + freevlak(evl); + } + evl= nextvl; + } + } + + /* dubbele vertices eruit */ + a= 0; + eve= (struct EditVert *)G.edve.first; + while(eve) { + nextve= eve->next; + if(eve->f & flag) { + if(eve->f & 128) { + a++; + BLI_remlink(&G.edve, eve); + +// free(eve); + free_editvert(eve); + } + } + eve= nextve; + } + return a; /* aantal */ +} + +void xsortvert_flag(int flag) +//short flag; +{ + /* alle verts met (flag & 'flag') worden gesorteerd */ + EditVert *eve; + struct xvertsort *sortblock, *sb; + ListBase tbase; + int aantal; + + /* aantal tellen */ + eve= G.edve.first; + aantal= 0; + while(eve) { + if(eve->f & flag) aantal++; + eve= eve->next; + } + if(aantal==0) return; + + /* geheugen reserveren en qsorten */ + sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*aantal,"sortremovedoub"); + eve= G.edve.first; + while(eve) { + if(eve->f & flag) { + sb->x= eve->xs; + sb->v1= eve; + sb++; + } + eve= eve->next; + } + qsort(sortblock, aantal, sizeof(struct xvertsort), vergxco); + + /* tijdelijke listbase maken */ + tbase.first= tbase.last= 0; + sb= sortblock; + while(aantal--) { + eve= sb->v1; + BLI_remlink(&G.edve, eve); + BLI_addtail(&tbase, eve); + sb++; + } + + addlisttolist(&G.edve, &tbase); + + MEM_freeN(sortblock); +} + + +void hashvert_flag(int flag) +{ + EditVert *eve; + struct xvertsort *sortblock, *sb, onth, *newsort; + ListBase tbase; + int aantal, a, b; + + /* aantal tellen */ + eve= G.edve.first; + aantal= 0; + while(eve) { + if(eve->f & flag) aantal++; + eve= eve->next; + } + if(aantal==0) return; + + /* geheugen reserveren */ + sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*aantal,"sortremovedoub"); + eve= G.edve.first; + while(eve) { + if(eve->f & flag) { + sb->v1= eve; + sb++; + } + eve= eve->next; + } + + BLI_srand(1); + + sb= sortblock; + for(a=0; a<aantal; a++, sb++) { + b= aantal*BLI_drand(); + if(b>=0 && b<aantal) { + newsort= sortblock+b; + onth= *sb; + *sb= *newsort; + *newsort= onth; + } + } + + /* tijdelijke listbase maken */ + tbase.first= tbase.last= 0; + sb= sortblock; + while(aantal--) { + eve= sb->v1; + BLI_remlink(&G.edve, eve); + BLI_addtail(&tbase, eve); + sb++; + } + + addlisttolist(&G.edve, &tbase); + + MEM_freeN(sortblock); +} + +static unsigned int cpack_half(unsigned int col1, unsigned int col2) +{ + char *cp1, *cp2, *cp; + unsigned int col=0; + + cp1= (char *)&col1; + cp2= (char *)&col2; + cp= (char *)&col; + + cp[0]= (cp1[0]+cp2[0])>>1; + cp[1]= (cp1[1]+cp2[1])>>1; + cp[2]= (cp1[2]+cp2[2])>>1; + cp[3]= (cp1[3]+cp2[3])>>1; + + return col; +} + + +static void uv_half(float *uv, float *uv1, float *uv2) +{ + uv[0]= (uv1[0]+uv2[0])/2.0; + uv[1]= (uv1[1]+uv2[1])/2.0; + +} + +static void uv_quart(float *uv, float *uv1) +{ + uv[0]= (uv1[0]+uv1[2]+uv1[4]+uv1[6])/4.0; + uv[1]= (uv1[1]+uv1[3]+uv1[5]+uv1[7])/4.0; +} + +static void set_wuv(int tot, EditVlak *evl, int v1, int v2, int v3, int v4) +{ + /* deze vreemde fie alleen bij de subdiv te gebruiken, de 'w' in de naam slaat nergens op! */ + float *uv, uvo[4][2]; + unsigned int *col, colo[4], col1, col2; + int a, v; + + memcpy(uvo, evl->uv, sizeof(uvo)); + uv= evl->uv[0]; + + memcpy(colo, evl->col, sizeof(colo)); + col= evl->col; + + if(tot==4) { + for(a=0; a<4; a++, uv+=2, col++) { + if(a==0) v= v1; + else if(a==1) v= v2; + else if(a==2) v= v3; + else v= v4; + + if(a==3 && v4==0) break; + + if(v<=4) { + uv[0]= uvo[v-1][0]; + uv[1]= uvo[v-1][1]; + *col= colo[v-1]; + } + else if(v==8) { + uv_half(uv, uvo[3], uvo[0]); + *col= cpack_half(colo[3], colo[0]); + } + else if(v==9) { + uv_quart(uv, uvo[0]); + col1= cpack_half(colo[1], colo[0]); + col2= cpack_half(colo[2], colo[3]); + *col= cpack_half(col1, col2); + } + else { + uv_half(uv, uvo[v-5], uvo[v-4]); + *col= cpack_half(colo[v-5], colo[v-4]); + } + } + } + else { + for(a=0; a<3; a++, uv+=2, col++) { + if(a==0) v= v1; + else if(a==1) v= v2; + else v= v3; + + if(v<=4) { + uv[0]= uvo[v-1][0]; + uv[1]= uvo[v-1][1]; + *col= colo[v-1]; + } + else if(v==7) { + uv_half(uv, uvo[2], uvo[0]); + *col= cpack_half(colo[2], colo[0]); + } + else { + uv_half(uv, uvo[v-5], uvo[v-4]); + *col= cpack_half(colo[v-5], colo[v-4]); + } + } + } +} + +static EditVert *vert_from_number(EditVlak *evl, int nr) +{ + switch(nr) { + case 0: + return 0; + case 1: + return evl->v1; + case 2: + return evl->v2; + case 3: + return evl->v3; + case 4: + return evl->v4; + case 5: + return evl->e1->vn; + case 6: + return evl->e2->vn; + case 7: + return evl->e3->vn; + case 8: + return evl->e4->vn; + } + + return NULL; +} + +static void addvlak_subdiv(EditVlak *evl, int val1, int val2, int val3, int val4, EditVert *eve) +{ + EditVlak *w; + EditVert *v1, *v2, *v3, *v4; + + if(val1==9) v1= eve; + else v1= vert_from_number(evl, val1); + + if(val2==9) v2= eve; + else v2= vert_from_number(evl, val2); + + if(val3==9) v3= eve; + else v3= vert_from_number(evl, val3); + + if(val4==9) v4= eve; + else v4= vert_from_number(evl, val4); + + w= addvlaklist(v1, v2, v3, v4, evl); + + if(w) { + if(evl->v4) set_wuv(4, w, val1, val2, val3, val4); + else set_wuv(3, w, val1, val2, val3, val4); + } +} + +static float smoothperc= 0.0; + +static void smooth_subdiv_vec(float *v1, float *v2, float *n1, float *n2, float *vec) +{ + float len, fac, nor[3], nor1[3], nor2[3]; + + VecSubf(nor, v1, v2); + len= 0.5*Normalise(nor); + + VECCOPY(nor1, n1); + VECCOPY(nor2, n2); + + /* cosine angle */ + fac= nor[0]*nor1[0] + nor[1]*nor1[1] + nor[2]*nor1[2] ; + + vec[0]= fac*nor1[0]; + vec[1]= fac*nor1[1]; + vec[2]= fac*nor1[2]; + + /* cosine angle */ + fac= -nor[0]*nor2[0] - nor[1]*nor2[1] - nor[2]*nor2[2] ; + + vec[0]+= fac*nor2[0]; + vec[1]+= fac*nor2[1]; + vec[2]+= fac*nor2[2]; + + vec[0]*= smoothperc*len; + vec[1]*= smoothperc*len; + vec[2]*= smoothperc*len; +} + +static void smooth_subdiv_quad(EditVlak *evl, float *vec) +{ + + float nor1[3], nor2[3]; + float vec1[3], vec2[3]; + float cent[3]; + + /* vlr->e1->vn is new vertex inbetween v1 / v2 */ + + VecMidf(nor1, evl->v1->no, evl->v2->no); + Normalise(nor1); + VecMidf(nor2, evl->v3->no, evl->v4->no); + Normalise(nor2); + + smooth_subdiv_vec( evl->e1->vn->co, evl->e3->vn->co, nor1, nor2, vec1); + + VecMidf(nor1, evl->v2->no, evl->v3->no); + Normalise(nor1); + VecMidf(nor2, evl->v4->no, evl->v1->no); + Normalise(nor2); + + smooth_subdiv_vec( evl->e2->vn->co, evl->e4->vn->co, nor1, nor2, vec2); + + VecAddf(vec1, vec1, vec2); + + CalcCent4f(cent, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co); + VecAddf(vec, cent, vec1); +} + +void subdivideflag(int flag, float rad, int beauty) +{ + /* divide alle vlakken met (vertflag & flag) */ + /* als rad>0.0 zet dan nieuw vert op afstand rad van 0,0,0 */ + extern float doublimit; + EditVert *eve; + EditEdge *eed, *e1, *e2, *e3, *e4, *nexted; + EditVlak *evl; + float fac, vec[3], vec1[3], len1, len2, len3; + short test; + + if(beauty & B_SMOOTH) { + short perc= 100; + + if(button(&perc, 10, 500, "Percentage:")==0) return; + + smoothperc= 0.292*perc/100.0; + } + + /* edgeflags */ + eed= G.eded.first; + while(eed) { + + if( (eed->v1->f & flag) && (eed->v2->f & flag) ) eed->f= flag; + else eed->f= 0; + + eed= eed->next; + } + + /* als beauty: opp testen en edgeflags wissen van 'lelijke' edges */ + if(beauty & B_BEAUTY) { + evl= G.edvl.first; + while(evl) { + if( vlakselectedAND(evl, flag) ) { + if(evl->v4) { + + /* opp */ + len1= AreaQ3Dfl(evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co); + if(len1 <= doublimit) { + evl->e1->f = 0; + evl->e2->f = 0; + evl->e3->f = 0; + evl->e4->f = 0; + } + else { + len1= VecLenf(evl->v1->co, evl->v2->co) + VecLenf(evl->v3->co, evl->v4->co); + len2= VecLenf(evl->v2->co, evl->v3->co) + VecLenf(evl->v1->co, evl->v4->co); + + if(len1 < len2) { + evl->e1->f = 0; + evl->e3->f = 0; + } + else if(len1 > len2) { + evl->e2->f = 0; + evl->e4->f = 0; + } + } + } + else { + + /* opp */ + len1= AreaT3Dfl(evl->v1->co, evl->v2->co, evl->v3->co); + if(len1 <= doublimit) { + evl->e1->f = 0; + evl->e2->f = 0; + evl->e3->f = 0; + } + else { + + len1= VecLenf(evl->v1->co, evl->v2->co) ; + len2= VecLenf(evl->v2->co, evl->v3->co) ; + len3= VecLenf(evl->v3->co, evl->v1->co) ; + + if(len1<len2 && len1<len3) { + evl->e1->f = 0; + } + else if(len2<len3 && len2<len1) { + evl->e2->f = 0; + } + else if(len3<len2 && len3<len1) { + evl->e3->f = 0; + } + } + } + } + evl= evl->next; + } + } + + if(beauty & B_SMOOTH) { + + vertexnormals(0); /* no1*/ + + } + + /* nieuw punt maken en in edge wegschrijven, flag wissen! is voor vlakkenmaak stuk nodig */ + eed= G.eded.first; + while(eed) { + if(eed->f & flag) { + + vec[0]= (eed->v1->co[0]+eed->v2->co[0])/2.0; + vec[1]= (eed->v1->co[1]+eed->v2->co[1])/2.0; + vec[2]= (eed->v1->co[2]+eed->v2->co[2])/2.0; + + if(rad > 0.0) { /* perf sph */ + Normalise(vec); + vec[0]*= rad; + vec[1]*= rad; + vec[2]*= rad; + } + else if(rad< 0.0) { /* fract */ + fac= rad* VecLenf(eed->v1->co, eed->v2->co); + vec1[0]= fac*BLI_drand(); + vec1[1]= fac*BLI_drand(); + vec1[2]= fac*BLI_drand(); + VecAddf(vec, vec, vec1); + } + + if(beauty & B_SMOOTH) { + smooth_subdiv_vec(eed->v1->co, eed->v2->co, eed->v1->no, eed->v2->no, vec1); + VecAddf(vec, vec, vec1); + } + + eed->vn= addvertlist(vec); + eed->vn->f= eed->v1->f; + + } + else eed->vn= 0; + + eed->f= 0; /* moet! */ + + eed= eed->next; + } + + /* alle vlakken testen op subdiv edges, 8 of 16 gevallen! */ + + evl= G.edvl.last; + while(evl) { + if( vlakselectedOR(evl, flag) ) { + e1= evl->e1; + e2= evl->e2; + e3= evl->e3; + e4= evl->e4; + + test= 0; + if(e1 && e1->vn) { + test+= 1; + e1->f= 1; + } + if(e2 && e2->vn) { + test+= 2; + e2->f= 1; + } + if(e3 && e3->vn) { + test+= 4; + e3->f= 1; + } + if(e4 && e4->vn) { + test+= 8; + e4->f= 1; + } + + if(test) { + if(evl->v4==0) { + if((test & 3)==3) addvlak_subdiv(evl, 2, 2+4, 1+4, 0, 0); + if((test & 6)==6) addvlak_subdiv(evl, 3, 3+4, 2+4, 0, 0); + if((test & 5)==5) addvlak_subdiv(evl, 1, 1+4, 3+4, 0, 0); + + if(test==7) { /* vier nieuwe vlakken, oude vernieuwt */ + evl->v1= e1->vn; + evl->v2= e2->vn; + evl->v3= e3->vn; + set_wuv(3, evl, 1+4, 2+4, 3+4, 0); + } + else if(test==3) { + addvlak_subdiv(evl, 1+4, 2+4, 3, 0, 0); + evl->v2= e1->vn; + set_wuv(3, evl, 1, 1+4, 3, 0); + } + else if(test==6) { + addvlak_subdiv(evl, 2+4, 3+4, 1, 0, 0); + evl->v3= e2->vn; + set_wuv(3, evl, 1, 2, 2+4, 0); + } + else if(test==5) { + addvlak_subdiv(evl, 3+4, 1+4, 2, 0, 0); + evl->v1= e3->vn; + set_wuv(3, evl, 3+4, 2, 3, 0); + } + else if(test==1) { + addvlak_subdiv(evl, 1+4, 2, 3, 0, 0); + evl->v2= e1->vn; + set_wuv(3, evl, 1, 1+4, 3, 0); + } + else if(test==2) { + addvlak_subdiv(evl, 2+4, 3, 1, 0, 0); + evl->v3= e2->vn; + set_wuv(3, evl, 1, 2, 2+4, 0); + } + else if(test==4) { + addvlak_subdiv(evl, 3+4, 1, 2, 0, 0); + evl->v1= e3->vn; + set_wuv(3, evl, 3+4, 2, 3, 0); + } + evl->e1= addedgelist(evl->v1, evl->v2); + evl->e2= addedgelist(evl->v2, evl->v3); + evl->e3= addedgelist(evl->v3, evl->v1); + + } + else { + if(test==15) { + /* nog een nieuw punt toevoegen */ + CalcCent4f(vec, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co); + + if(beauty & B_SMOOTH) { + smooth_subdiv_quad(evl, vec); /* adds */ + } + eve= addvertlist(vec); + + eve->f |= flag; + + addvlak_subdiv(evl, 2, 2+4, 9, 1+4, eve); + addvlak_subdiv(evl, 3, 3+4, 9, 2+4, eve); + addvlak_subdiv(evl, 4, 4+4, 9, 3+4, eve); + + evl->v2= e1->vn; + evl->v3= eve; + evl->v4= e4->vn; + set_wuv(4, evl, 1, 1+4, 9, 4+4); + } + else { + /* kleine hoekpunten */ + if((test & 3)==3) addvlak_subdiv(evl, 1+4, 2, 2+4, 0, 0); + if((test & 6)==6) addvlak_subdiv(evl, 2+4, 3, 3+4, 0, 0); + if((test & 12)==12) addvlak_subdiv(evl, 3+4, 4, 4+4, 0, 0); + if((test & 9)==9) addvlak_subdiv(evl, 4+4, 1, 1+4, 0, 0); + + if(test==1) { + addvlak_subdiv(evl, 1+4, 2, 3, 0, 0); + addvlak_subdiv(evl, 1+4, 3, 4, 0, 0); + evl->v2= e1->vn; + evl->v3= evl->v4; + evl->v4= 0; + set_wuv(4, evl, 1, 1+4, 4, 0); + } + else if(test==2) { + addvlak_subdiv(evl, 2+4, 3, 4, 0, 0); + addvlak_subdiv(evl, 2+4, 4, 1, 0, 0); + evl->v3= e2->vn; + evl->v4= 0; + set_wuv(4, evl, 1, 2, 2+4, 0); + } + else if(test==4) { + addvlak_subdiv(evl, 3+4, 4, 1, 0, 0); + addvlak_subdiv(evl, 3+4, 1, 2, 0, 0); + evl->v1= evl->v2; + evl->v2= evl->v3; + evl->v3= e3->vn; + evl->v4= 0; + set_wuv(4, evl, 2, 3, 3+4, 0); + } + else if(test==8) { + addvlak_subdiv(evl, 4+4, 1, 2, 0, 0); + addvlak_subdiv(evl, 4+4, 2, 3, 0, 0); + evl->v1= evl->v3; + evl->v2= evl->v4; + evl->v3= e4->vn; + evl->v4= 0; + set_wuv(4, evl, 3, 4, 4+4, 0); + } + else if(test==3) { + addvlak_subdiv(evl, 1+4, 2+4, 4, 0, 0); + addvlak_subdiv(evl, 2+4, 3, 4, 0, 0); + evl->v2= e1->vn; + evl->v3= evl->v4; + evl->v4= 0; + set_wuv(4, evl, 1, 1+4, 4, 0); + } + else if(test==6) { + addvlak_subdiv(evl, 2+4, 3+4, 1, 0, 0); + addvlak_subdiv(evl, 3+4, 4, 1, 0, 0); + evl->v3= e2->vn; + evl->v4= 0; + set_wuv(4, evl, 1, 2, 2+4, 0); + } + else if(test==12) { + addvlak_subdiv(evl, 3+4, 4+4, 2, 0, 0); + addvlak_subdiv(evl, 4+4, 1, 2, 0, 0); + evl->v1= evl->v2; + evl->v2= evl->v3; + evl->v3= e3->vn; + evl->v4= 0; + set_wuv(4, evl, 2, 3, 3+4, 0); + } + else if(test==9) { + addvlak_subdiv(evl, 4+4, 1+4, 3, 0, 0); + addvlak_subdiv(evl, 1+4, 2, 3, 0, 0); + evl->v1= evl->v3; + evl->v2= evl->v4; + evl->v3= e4->vn; + evl->v4= 0; + set_wuv(4, evl, 3, 4, 4+4, 0); + } + else if(test==5) { + addvlak_subdiv(evl, 1+4, 2, 3, 3+4, 0); + evl->v2= e1->vn; + evl->v3= e3->vn; + set_wuv(4, evl, 1, 1+4, 3+4, 4); + } + else if(test==10) { + addvlak_subdiv(evl, 2+4, 3, 4, 4+4, 0); + evl->v3= e2->vn; + evl->v4= e4->vn; + set_wuv(4, evl, 1, 2, 2+4, 4+4); + } + + else if(test==7) { + addvlak_subdiv(evl, 1+4, 2+4, 3+4, 0, 0); + evl->v2= e1->vn; + evl->v3= e3->vn; + set_wuv(4, evl, 1, 1+4, 3+4, 4); + } + else if(test==14) { + addvlak_subdiv(evl, 2+4, 3+4, 4+4, 0, 0); + evl->v3= e2->vn; + evl->v4= e4->vn; + set_wuv(4, evl, 1, 2, 2+4, 4+4); + } + else if(test==13) { + addvlak_subdiv(evl, 3+4, 4+4, 1+4, 0, 0); + evl->v4= e3->vn; + evl->v1= e1->vn; + set_wuv(4, evl, 1+4, 3, 3, 3+4); + } + else if(test==11) { + addvlak_subdiv(evl, 4+4, 1+4, 2+4, 0, 0); + evl->v1= e4->vn; + evl->v2= e2->vn; + set_wuv(4, evl, 4+4, 2+4, 3, 4); + } + } + evl->e1= addedgelist(evl->v1, evl->v2); + evl->e2= addedgelist(evl->v2, evl->v3); + if(evl->v4) evl->e3= addedgelist(evl->v3, evl->v4); + else evl->e3= addedgelist(evl->v3, evl->v1); + if(evl->v4) evl->e4= addedgelist(evl->v4, evl->v1); + else evl->e4= 0; + } + } + } + evl= evl->prev; + } + + /* alle oude edges verwijderen, eventueel nog nieuwe maken */ + eed= G.eded.first; + while(eed) { + nexted= eed->next; + if( eed->vn ) { + if(eed->f==0) { /* niet gebruikt in vlak */ + addedgelist(eed->v1,eed->vn); + addedgelist(eed->vn,eed->v2); + } + remedge(eed); + free(eed); + } + eed= nexted; + } + countall(); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +void adduplicateflag(int flag) +{ + /* oude verts hebben flag 128 gezet en flag 'flag' gewist + nieuwe verts hebben flag 'flag' gezet */ + EditVert *eve, *v1, *v2, *v3, *v4; + EditEdge *eed; + EditVlak *evl; + + /* eerst vertices */ + eve= G.edve.last; + while(eve) { + eve->f&= ~128; + if(eve->f & flag) { + v1= addvertlist(eve->co); + v1->f= eve->f; + eve->f-= flag; + eve->f|= 128; + eve->vn= v1; +#ifdef __NLA + /* >>>>> FIXME: Copy deformation weight ? */ + v1->totweight = eve->totweight; + if (eve->totweight){ + v1->dw = MEM_mallocN (eve->totweight * sizeof(MDeformWeight), "deformWeight"); + memcpy (v1->dw, eve->dw, eve->totweight * sizeof(MDeformWeight)); + } + else + v1->dw=NULL; +#endif + } + eve= eve->prev; + } + eed= G.eded.first; + while(eed) { + if( (eed->v1->f & 128) && (eed->v2->f & 128) ) { + v1= eed->v1->vn; + v2= eed->v2->vn; + addedgelist(v1,v2); + } + eed= eed->next; + } + + /* tenslotte de vlakken dupliceren */ + evl= G.edvl.first; + while(evl) { + if( (evl->v1->f & 128) && (evl->v2->f & 128) && (evl->v3->f & 128) ) { + if(evl->v4) { + if(evl->v4->f & 128) { + v1= evl->v1->vn; + v2= evl->v2->vn; + v3= evl->v3->vn; + v4= evl->v4->vn; + addvlaklist(v1, v2, v3, v4, evl); + } + } + else { + v1= evl->v1->vn; + v2= evl->v2->vn; + v3= evl->v3->vn; + addvlaklist(v1, v2, v3, 0, evl); + } + } + evl= evl->next; + } +} + +static void delvlakflag(int flag) +{ + /* alle vlak 3/4 verts flag + edges + losse vertices deleten */ + /* van alle verts wordt 'flag' gewist */ + EditVert *eve,*nextve; + EditEdge *eed, *nexted; + EditVlak *evl,*nextvl; + + eed= G.eded.first; + while(eed) { + eed->f= 0; + eed= eed->next; + } + + evl= G.edvl.first; + while(evl) { + nextvl= evl->next; + if(vlakselectedAND(evl, flag)) { + + evl->e1->f= 1; + evl->e2->f= 1; + evl->e3->f= 1; + if(evl->e4) { + evl->e4->f= 1; + } + + BLI_remlink(&G.edvl, evl); + freevlak(evl); + } + evl= nextvl; + } + /* alle vlakken 1, 2 (3) verts select edges behouden */ + evl= G.edvl.first; + while(evl) { + evl->e1->f= 0; + evl->e2->f= 0; + evl->e3->f= 0; + if(evl->e4) { + evl->e4->f= 0; + } + + evl= evl->next; + } + + /* alle edges testen op vertices met flag en wissen */ + eed= G.eded.first; + while(eed) { + nexted= eed->next; + if(eed->f==1) { + remedge(eed); + free(eed); + } + else if( (eed->v1->f & flag) || (eed->v2->f & flag) ) { + eed->v1->f&= ~flag; + eed->v2->f&= ~flag; + } + eed= nexted; + } + /* vertices met flag nog gezet zijn losse en worden verwijderd */ + eve= G.edve.first; + while(eve) { + nextve= eve->next; + if(eve->f & flag) { + BLI_remlink(&G.edve, eve); +// free(eve); + free_editvert(eve); + } + eve= nextve; + } + +} + +void extrude_mesh(void) +{ + short a; + + TEST_EDITMESH + + if(okee("Extrude")==0) return; + + waitcursor(1); + + a= extrudeflag(1,1); + waitcursor(0); + if(a==0) { + error("Can't extrude"); + } + else { + countall(); /* voor G.totvert in calc_meshverts() */ + calc_meshverts(); + transform('d'); + } + +} + +void adduplicate_mesh(void) +{ + + TEST_EDITMESH + + waitcursor(1); + adduplicateflag(1); + waitcursor(0); + + countall(); /* voor G.totvert in calc_meshverts() */ + transform('d'); +} + +void split_mesh(void) +{ + + TEST_EDITMESH + + if(okee(" Split ")==0) return; + + waitcursor(1); + + /* eerst duplicate maken */ + adduplicateflag(1); + /* oude vlakken hebben 3x flag 128 gezet, deze deleten */ + delvlakflag(128); + + waitcursor(0); + + countall(); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +void separate_mesh(void) +{ + EditVert *eve, *v1; + EditEdge *eed, *e1; + EditVlak *evl, *vl1; + Object *oldob; + Mesh *me, *men; + Base *base, *oldbase; + ListBase edve, eded, edvl; + float trans[9]; + int ok, flag; + + TEST_EDITMESH + + if(okee("Separate")==0) return; + + waitcursor(1); + + me= get_mesh(G.obedit); + if(me->key) { + error("Can't separate with vertex keys"); + return; + } + + /* we gaan de zaak als volgt neppen: + * 1. duplicate object: dit wordt de nieuwe, oude pointer onthouden + * 2: split doen als modig. + * 3. alle NIET geselecteerde verts, edges, vlakken apart zetten + * 4. loadobeditdata(): dit is de nieuwe ob + * 5. freelist en oude verts, eds, vlakken weer terughalen + */ + + /* alleen obedit geselecteerd */ + base= FIRSTBASE; + while(base) { + if(base->lay & G.vd->lay) { + if(base->object==G.obedit) base->flag |= SELECT; + else base->flag &= ~SELECT; + } + base= base->next; + } + + /* testen of split */ + ok= 0; + eed= G.eded.first; + while(eed) { + flag= (eed->v1->f & 1)+(eed->v2->f & 1); + if(flag==1) { + ok= 1; + break; + } + eed= eed->next; + } + if(ok) { + /* SPLIT: eerst duplicate maken */ + adduplicateflag(1); + /* SPLIT: oude vlakken hebben 3x flag 128 gezet, deze deleten */ + delvlakflag(128); + } + + /* apart zetten: alles wat maar enigszins NIET select is */ + edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0; + eve= G.edve.first; + while(eve) { + v1= eve->next; + if((eve->f & 1)==0) { + BLI_remlink(&G.edve, eve); + BLI_addtail(&edve, eve); + } + eve= v1; + } + eed= G.eded.first; + while(eed) { + e1= eed->next; + if( (eed->v1->f & 1)==0 || (eed->v2->f & 1)==0 ) { + BLI_remlink(&G.eded, eed); + BLI_addtail(&eded, eed); + } + eed= e1; + } + evl= G.edvl.first; + while(evl) { + vl1= evl->next; + if( (evl->v1->f & 1)==0 || (evl->v2->f & 1)==0 || (evl->v3->f & 1)==0 ) { + BLI_remlink(&G.edvl, evl); + BLI_addtail(&edvl, evl); + } + evl= vl1; + } + + oldob= G.obedit; + oldbase= BASACT; + + trans[0]=trans[1]=trans[2]=trans[3]=trans[4]=trans[5]= 0.0; + trans[6]=trans[7]=trans[8]= 1.0; + G.qual |= LR_ALTKEY; /* patch om zeker te zijn van gelinkte dupli */ + adduplicate(trans); + G.qual &= ~LR_ALTKEY; + + G.obedit= BASACT->object; /* basact wordt in adduplicate() gezet */ + + men= copy_mesh(me); + set_mesh(G.obedit, men); + /* omdat nieuwe mesh een kopie is: aantal users verlagen */ + men->id.us--; + + load_editMesh(); + + BASACT->flag &= ~SELECT; + + makeDispList(G.obedit); + free_editMesh(); + + G.edve= edve; + G.eded= eded; + G.edvl= edvl; + + /* hashedges are freed now, make new! */ + eed= G.eded.first; + while(eed) { + if( findedgelist(eed->v1, eed->v2)==NULL ) + insert_hashedge(eed); + eed= eed->next; + } + + G.obedit= oldob; + BASACT= oldbase; + BASACT->flag |= SELECT; + + waitcursor(0); + + countall(); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); + +} + +void extrude_repeat_mesh(int steps, float offs) +{ + float dvec[3], tmat[3][3], bmat[3][3]; +/* float phi; */ + short a,ok; + + TEST_EDITMESH + waitcursor(1); + + /* dvec */ + dvec[0]= G.vd->persinv[2][0]; + dvec[1]= G.vd->persinv[2][1]; + dvec[2]= G.vd->persinv[2][2]; + Normalise(dvec); + dvec[0]*= offs; + dvec[1]*= offs; + dvec[2]*= offs; + + /* base correctie */ + Mat3CpyMat4(bmat, G.obedit->obmat); + /* phi= ((struct ObData *)G.obedit->d)->vv->ws; */ + /* Mat3MulFloat(bmat, phi); */ + Mat3Inv(tmat, bmat); + Mat3MulVecfl(tmat, dvec); + + for(a=0;a<steps;a++) { + ok= extrudeflag(1,1); + if(ok==0) { + error("Can't extrude"); + break; + } + translateflag(1, dvec); + } + + countall(); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); + waitcursor(0); +} + +void spin_mesh(int steps,int degr,float *dvec, int mode) +{ + EditVert *eve,*nextve; + float *curs, si,n[3],q[4],cmat[3][3],imat[3][3], tmat[3][3]; + float cent[3],bmat[3][3]; + float phi; + short a,ok; + + TEST_EDITMESH + + waitcursor(1); + + /* imat en centrum en afmeting */ + Mat3CpyMat4(bmat, G.obedit->obmat); + Mat3Inv(imat,bmat); + + curs= give_cursor(); + VECCOPY(cent, curs); + cent[0]-= G.obedit->obmat[3][0]; + cent[1]-= G.obedit->obmat[3][1]; + cent[2]-= G.obedit->obmat[3][2]; + Mat3MulVecfl(imat, cent); + + phi= degr*M_PI/360.0; + phi/= steps; + if(editbutflag & B_CLOCKWISE) phi= -phi; + + if(dvec) { + n[0]=n[1]= 0.0; + n[2]= 1.0; + } else { + n[0]= G.vd->viewinv[2][0]; + n[1]= G.vd->viewinv[2][1]; + n[2]= G.vd->viewinv[2][2]; + Normalise(n); + } + + q[0]= cos(phi); + si= sin(phi); + q[1]= n[0]*si; + q[2]= n[1]*si; + q[3]= n[2]*si; + QuatToMat3(q, cmat); + + Mat3MulMat3(tmat,cmat,bmat); + Mat3MulMat3(bmat,imat,tmat); + + if(mode==0) if(editbutflag & B_KEEPORIG) adduplicateflag(1); + ok= 1; + + for(a=0;a<steps;a++) { + if(mode==0) ok= extrudeflag(1,1); + else adduplicateflag(1); + if(ok==0) { + error("Can't spin"); + break; + } + rotateflag(1, cent, bmat); + if(dvec) { + Mat3MulVecfl(bmat,dvec); + translateflag(1,dvec); + } + } + + waitcursor(0); + if(ok==0) { + /* geen of alleen losse verts select, dups verwijderen */ + eve= G.edve.first; + while(eve) { + nextve= eve->next; + if(eve->f & 1) { + BLI_remlink(&G.edve,eve); +// free(eve); + free_editvert(eve); + } + eve= nextve; + } + } + countall(); + recalc_editnormals(); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +void screw_mesh(int steps,int turns) +{ + EditVert *eve,*v1=0,*v2=0; + EditEdge *eed; + float dvec[3], nor[3]; + + TEST_EDITMESH + + /* eerste voorwaarde: frontview! */ + if(G.vd->view!=1) { + error("Only in frontview!"); + return; + } + + /* flags wissen */ + eve= G.edve.first; + while(eve) { + eve->f1= 0; + eve= eve->next; + } + /* edges zetten flags in verts */ + eed= G.eded.first; + while(eed) { + if(eed->v1->f & 1) { + if(eed->v2->f & 1) { + /* oppassen f1 is een byte */ + if(eed->v1->f1<2) eed->v1->f1++; + if(eed->v2->f1<2) eed->v2->f1++; + } + } + eed= eed->next; + } + /* vind twee vertices met eve->f1==1, meer of minder is fout */ + eve= G.edve.first; + while(eve) { + if(eve->f1==1) { + if(v1==0) v1= eve; + else if(v2==0) v2= eve; + else { + v1=0; + break; + } + } + eve= eve->next; + } + if(v1==0 || v2==0) { + error("No curve selected"); + return; + } + + /* bereken dvec */ + dvec[0]= ( (v1->co[0]- v2->co[0]) )/(steps); + dvec[1]= ( (v1->co[1]- v2->co[1]) )/(steps); + dvec[2]= ( (v1->co[2]- v2->co[2]) )/(steps); + + VECCOPY(nor, G.obedit->obmat[2]); + + if(nor[0]*dvec[0]+nor[1]*dvec[1]+nor[2]*dvec[2]>0.000) { + dvec[0]= -dvec[0]; + dvec[1]= -dvec[1]; + dvec[2]= -dvec[2]; + } + + spin_mesh(turns*steps, turns*360, dvec, 0); + +} + +void selectswap_mesh(void) +{ + EditVert *eve; + + eve= G.edve.first; + while(eve) { + if(eve->h==0) { + if(eve->f & 1) eve->f&= ~1; + else eve->f|= 1; + } + eve= eve->next; + } + countall(); + allqueue(REDRAWVIEW3D, 0); + +} + +/* ******************************* ADD ********************* */ + +void addvert_mesh(void) +{ + EditVert *eve,*v1=0; + float *curs, mat[3][3],imat[3][3]; + + TEST_EDITMESH + + Mat3CpyMat4(mat, G.obedit->obmat); + Mat3Inv(imat, mat); + + v1= G.edve.first; + while(v1) { + if(v1->f & 1) break; + v1= v1->next; + } + eve= v1; /* voorkomen dat er nog meer select zijn */ + while(eve) { + eve->f&= ~1; + eve= eve->next; + } + + eve= addvertlist(0); + + curs= give_cursor(); + VECCOPY(eve->co, curs); + eve->xs= G.vd->mx; + eve->ys= G.vd->my; + VecSubf(eve->co, eve->co, G.obedit->obmat[3]); + + Mat3MulVecfl(imat, eve->co); + eve->f= 1; + + if(v1) { + addedgelist(v1, eve); + v1->f= 0; + } + countall(); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); + + while(get_mbut()&R_MOUSE); + +} + +void addedgevlak_mesh(void) +{ + EditVert *eve, *neweve[4]; + EditVlak *evl; + float con1, con2, con3; + short aantal=0; + + if( (G.vd->lay & G.obedit->lay)==0 ) return; + + /* hoeveel geselecteerd ? */ + eve= G.edve.first; + while(eve) { + if(eve->f & 1) { + aantal++; + if(aantal>4) break; + neweve[aantal-1]= eve; + } + eve= eve->next; + } + if(aantal==2) { + addedgelist(neweve[0], neweve[1]); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); + return; + } + if(aantal<2 || aantal>4) { + error("Can't make edge/face"); + return; + } + + evl= NULL; // check later + + if(aantal==3) { + if(exist_vlak(neweve[0], neweve[1], neweve[2], 0)==0) { + + evl= addvlaklist(neweve[0], neweve[1], neweve[2], 0, NULL); + + } + else error("Already a face"); + } + else if(aantal==4) { + if(exist_vlak(neweve[0], neweve[1], neweve[2], neweve[3])==0) { + + con1= convex(neweve[0]->co, neweve[1]->co, neweve[2]->co, neweve[3]->co); + con2= convex(neweve[0]->co, neweve[2]->co, neweve[3]->co, neweve[1]->co); + con3= convex(neweve[0]->co, neweve[3]->co, neweve[1]->co, neweve[2]->co); + + if(con1>=con2 && con1>=con3) + evl= addvlaklist(neweve[0], neweve[1], neweve[2], neweve[3], NULL); + else if(con2>=con1 && con2>=con3) + evl= addvlaklist(neweve[0], neweve[2], neweve[3], neweve[1], NULL); + else + evl= addvlaklist(neweve[0], neweve[2], neweve[1], neweve[3], NULL); + + } + else error("Already a face"); + } + + if(evl) { // now we're calculating direction of normal + float inp; + /* dot product view mat with normal, should give info! */ + + CalcNormFloat(evl->v1->co, evl->v2->co, evl->v3->co, evl->n); + + inp= evl->n[0]*G.vd->viewmat[0][2] + evl->n[1]*G.vd->viewmat[1][2] + evl->n[2]*G.vd->viewmat[2][2]; + + if(inp < 0.0) flipvlak(evl); + } + + countall(); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +static void erase_edges(ListBase *l) +{ + EditEdge *ed, *nexted; + + ed = (EditEdge *) l->first; + while(ed) { + nexted= ed->next; + if( (ed->v1->f & 1) || (ed->v2->f & 1) ) { + remedge(ed); + free(ed); + } + ed= nexted; + } +} + +static void erase_faces(ListBase *l) +{ + EditVlak *f, *nextf; + + f = (EditVlak *) l->first; + + while(f) { + nextf= f->next; + if( vlakselectedOR(f, 1) ) { + BLI_remlink(l, f); + freevlak(f); + } + f = nextf; + } +} + +static void erase_vertices(ListBase *l) +{ + EditVert *v, *nextv; + + v = (EditVert *) l->first; + while(v) { + nextv= v->next; + if(v->f & 1) { + BLI_remlink(l, v); + free_editvert(v); + } + v = nextv; + } +} + +void delete_mesh(void) +{ + EditVlak *evl, *nextvl; + EditVert *eve,*nextve; + EditEdge *eed,*nexted; + short event; + int count; + + TEST_EDITMESH + + event= pupmenu("ERASE %t|Vertices%x10|Edges%x1|Faces%x2|All%x3|Edges & Faces%x4|Only Faces%x5"); + if(event<1) return; + + if(event==10 ) { + erase_edges(&G.eded); + erase_faces(&G.edvl); + erase_vertices(&G.edve); + } + else if(event==4) { + evl= G.edvl.first; + while(evl) { + nextvl= evl->next; + /* delete only faces with 2 or more vertices selected */ + count= 0; + if(evl->v1->f & 1) count++; + if(evl->v2->f & 1) count++; + if(evl->v3->f & 1) count++; + if(evl->v4 && (evl->v4->f & 1)) count++; + if(count>1) { + BLI_remlink(&G.edvl, evl); + freevlak(evl); + } + evl= nextvl; + } + eed= G.eded.first; + while(eed) { + nexted= eed->next; + if( (eed->v1->f & 1) && (eed->v2->f & 1) ) { + remedge(eed); + free(eed); + } + eed= nexted; + } + evl= G.edvl.first; + while(evl) { + nextvl= evl->next; + event=0; + if( evl->v1->f & 1) event++; + if( evl->v2->f & 1) event++; + if( evl->v3->f & 1) event++; + if(evl->v4 && (evl->v4->f & 1)) event++; + + if(event>1) { + BLI_remlink(&G.edvl, evl); + freevlak(evl); + } + evl= nextvl; + } + } + else if(event==1) { + eed= G.eded.first; + while(eed) { + nexted= eed->next; + if( (eed->v1->f & 1) && (eed->v2->f & 1) ) { + remedge(eed); + free(eed); + } + eed= nexted; + } + evl= G.edvl.first; + while(evl) { + nextvl= evl->next; + event=0; + if( evl->v1->f & 1) event++; + if( evl->v2->f & 1) event++; + if( evl->v3->f & 1) event++; + if(evl->v4 && (evl->v4->f & 1)) event++; + + if(event>1) { + BLI_remlink(&G.edvl, evl); + freevlak(evl); + } + evl= nextvl; + } + /* om losse vertices te wissen: */ + eed= G.eded.first; + while(eed) { + if( eed->v1->f & 1) eed->v1->f-=1; + if( eed->v2->f & 1) eed->v2->f-=1; + eed= eed->next; + } + eve= G.edve.first; + while(eve) { + nextve= eve->next; + if(eve->f & 1) { + BLI_remlink(&G.edve,eve); +// free(eve); + free_editvert(eve); + } + eve= nextve; + } + + } + else if(event==2) delvlakflag(1); + else if(event==3) { +// if(G.edve.first) BLI_freelist(&G.edve); + if(G.edve.first) free_editverts(&G.edve); + if(G.eded.first) BLI_freelist(&G.eded); + if(G.edvl.first) freevlaklist(&G.edvl); + } + else if(event==5) { + evl= G.edvl.first; + while(evl) { + nextvl= evl->next; + if(vlakselectedAND(evl, 1)) { + BLI_remlink(&G.edvl, evl); + freevlak(evl); + } + evl= nextvl; + } + } + + countall(); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + + + +void add_primitiveMesh(int type) +{ + Mesh *me; + EditVert *eve, *v1=NULL, *v2, *v3, *v4=NULL, *vtop, *vdown; + float *curs, d, dia, phi, phid, cent[3], vec[3], imat[3][3], mat[3][3]; + float q[4], cmat[3][3]; + static short tot=32, seg=32, subdiv=2; + short a, b, ext=0, fill=0, totoud, newob=0; + + if(G.scene->id.lib) return; + + /* this function also comes from an info window */ + if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return; + if(G.vd==0) return; + + check_editmode(OB_MESH); + + G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT); + setcursor_space(SPACE_VIEW3D, CURSOR_STD); + + /* als geen obedit: nieuw object en in editmode gaan */ + if(G.obedit==0) { + /* add_object actually returns an object ! :-) + But it also stores the added object struct in + G.scene->basact->object (BASACT->object) */ + + add_object(OB_MESH); + base_init_from_view3d(BASACT, G.vd); + G.obedit= BASACT->object; + + where_is_object(G.obedit); + + make_editMesh(); + setcursor_space(SPACE_VIEW3D, CURSOR_EDIT); + newob= 1; + } + me= G.obedit->data; + + /* deselectall */ + eve= G.edve.first; + while(eve) { + if(eve->f & 1) eve->f&= ~1; + eve= eve->next; + } + + totoud= tot; /* onthouden en terugzetten als cube/plane */ + + /* imat en centrum en afmeting */ + Mat3CpyMat4(mat, G.obedit->obmat); + + curs= give_cursor(); + VECCOPY(cent, curs); + cent[0]-= G.obedit->obmat[3][0]; + cent[1]-= G.obedit->obmat[3][1]; + cent[2]-= G.obedit->obmat[3][2]; + + if(type!= 11) { + Mat3CpyMat4(imat, G.vd->viewmat); + Mat3MulVecfl(imat, cent); + Mat3MulMat3(cmat, imat, mat); + Mat3Inv(imat,cmat); + } else { + Mat3Inv(imat, mat); + } + + /* ext==extrudeflag, tot==aantal verts in basis */ + + switch(type) { + case 0: /* plane */ + tot= 4; + ext= 0; + fill= 1; + if(newob) rename_id((ID *)G.obedit, "Plane"); + if(newob) rename_id((ID *)me, "Plane"); + break; + case 1: /* cube */ + tot= 4; + ext= 1; + fill= 1; + if(newob) rename_id((ID *)G.obedit, "Cube"); + if(newob) rename_id((ID *)me, "Cube"); + break; + case 4: /* circle */ + if(button(&tot,3,100,"Vertices:")==0) return; + ext= 0; + fill= 0; + if(newob) rename_id((ID *)G.obedit, "Circle"); + if(newob) rename_id((ID *)me, "Circle"); + break; + case 5: /* cylinder */ + if(button(&tot,3,100,"Vertices:")==0) return; + ext= 1; + fill= 1; + if(newob) rename_id((ID *)G.obedit, "Cylinder"); + if(newob) rename_id((ID *)me, "Cylinder"); + break; + case 6: /* tube */ + if(button(&tot,3,100,"Vertices:")==0) return; + ext= 1; + fill= 0; + if(newob) rename_id((ID *)G.obedit, "Tube"); + if(newob) rename_id((ID *)me, "Tube"); + break; + case 7: /* cone */ + if(button(&tot,3,100,"Vertices:")==0) return; + ext= 0; + fill= 1; + if(newob) rename_id((ID *)G.obedit, "Cone"); + if(newob) rename_id((ID *)me, "Cone"); + break; + case 10: /* grid */ + if(button(&tot,2,100,"X res:")==0) return; + if(button(&seg,2,100,"Y res:")==0) return; + if(newob) rename_id((ID *)G.obedit, "Grid"); + if(newob) rename_id((ID *)me, "Grid"); + break; + case 11: /* UVsphere */ + if(button(&seg,3,100,"Segments:")==0) return; + if(button(&tot,3,100,"Rings:")==0) return; + if(newob) rename_id((ID *)G.obedit, "Sphere"); + if(newob) rename_id((ID *)me, "Sphere"); + break; + case 12: /* Icosphere */ + if(button(&subdiv,1,5,"Subdivision:")==0) return; + if(newob) rename_id((ID *)G.obedit, "Sphere"); + if(newob) rename_id((ID *)me, "Sphere"); + break; + case 13: /* Monkey */ + if(newob) rename_id((ID *)G.obedit, "Suzanne"); + if(newob) rename_id((ID *)me, "Suzanne"); + break; + } + + dia= sqrt(2.0)*G.vd->grid; + d= -G.vd->grid; + phid= 2*M_PI/tot; + phi= .25*M_PI; + + + if(type<10) { /* alles behalve grid of sphere */ + if(ext==0 && type!=7) d= 0; + + /* de vertices */ + vtop= vdown= v1= v2= 0; + for(b=0; b<=ext; b++) { + for(a=0; a<tot; a++) { + + vec[0]= cent[0]+dia*sin(phi); + vec[1]= cent[1]+dia*cos(phi); + vec[2]= cent[2]+d; + + Mat3MulVecfl(imat, vec); + eve= addvertlist(vec); + eve->f= 1; + if(a==0) { + if(b==0) v1= eve; + else v2= eve; + } + phi+=phid; + } + d= -d; + } + /* centrum vertices */ + if(fill && type>1) { + VECCOPY(vec,cent); + vec[2]-= -d; + Mat3MulVecfl(imat,vec); + vdown= addvertlist(vec); + if(ext || type==7) { + VECCOPY(vec,cent); + vec[2]-= d; + Mat3MulVecfl(imat,vec); + vtop= addvertlist(vec); + } + } else { + vdown= v1; + vtop= v2; + } + if(vtop) vtop->f= 1; + if(vdown) vdown->f= 1; + + /* boven en ondervlak */ + if(fill) { + if(tot==4 && (type==0 || type==1)) { + v3= v1->next->next; + if(ext) v4= v2->next->next; + + addvlaklist(v3, v1->next, v1, v3->next, NULL); + if(ext) addvlaklist(v2, v2->next, v4, v4->next, NULL); + + } + else { + v3= v1; + v4= v2; + for(a=1; a<tot; a++) { + addvlaklist(vdown, v3, v3->next, 0, NULL); + v3= v3->next; + if(ext) { + addvlaklist(vtop, v4, v4->next, 0, NULL); + v4= v4->next; + } + } + if(type>1) { + addvlaklist(vdown, v3, v1, 0, NULL); + if(ext) addvlaklist(vtop, v4, v2, 0, NULL); + } + } + } + else if(type==4) { /* wel edges bij circle */ + v3= v1; + for(a=1;a<tot;a++) { + addedgelist(v3,v3->next); + v3= v3->next; + } + addedgelist(v3,v1); + } + /* zijvlakken */ + if(ext) { + v3= v1; + v4= v2; + for(a=1; a<tot; a++) { + addvlaklist(v3, v3->next, v4->next, v4, NULL); + v3= v3->next; + v4= v4->next; + } + addvlaklist(v3, v1, v2, v4, NULL); + } + else if(type==7) { /* cone */ + v3= v1; + for(a=1; a<tot; a++) { + addvlaklist(vtop, v3->next, v3, 0, NULL); + v3= v3->next; + } + addvlaklist(vtop, v1, v3, 0, NULL); + } + + if(type<2) tot= totoud; + + } + else if(type==10) { /* grid */ + /* alle flags wissen */ + eve= G.edve.first; + while(eve) { + eve->f= 0; + eve= eve->next; + } + dia= G.vd->grid; + /* eerst een segment: de X as */ + phi= -1.0; + phid= 2.0/((float)tot-1); + for(a=0;a<tot;a++) { + vec[0]= cent[0]+dia*phi; + vec[1]= cent[1]- dia; + vec[2]= cent[2]; + Mat3MulVecfl(imat,vec); + eve= addvertlist(vec); + eve->f= 1+2+4; + if (a) addedgelist(eve->prev,eve); + phi+=phid; + } + /* extruden en transleren */ + vec[0]= vec[2]= 0.0; + vec[1]= dia*phid; + Mat3MulVecfl(imat, vec); + for(a=0;a<seg-1;a++) { + extrudeflag(2,0); + translateflag(2, vec); + } + } + else if(type==11) { /* UVsphere */ + float tmat[3][3]; + + /* alle flags wissen */ + eve= G.edve.first; + while(eve) { + eve->f= 0; + eve= eve->next; + } + + /* eerst een segment */ + phi= 0; + phid/=2; + for(a=0; a<=tot; a++) { + vec[0]= cent[0]+dia*sin(phi); + vec[1]= cent[1]; + vec[2]= cent[2]+dia*cos(phi); + Mat3MulVecfl(imat,vec); + eve= addvertlist(vec); + eve->f= 1+2+4; + if(a==0) v1= eve; + else addedgelist(eve->prev, eve); + phi+= phid; + } + + /* extruden en roteren */ + phi= M_PI/seg; + q[0]= cos(phi); + q[3]= sin(phi); + q[1]=q[2]= 0; + QuatToMat3(q, cmat); + Mat3MulMat3(tmat, cmat, mat); + Mat3MulMat3(cmat, imat, tmat); + + for(a=0; a<seg; a++) { + extrudeflag(2, 0); + rotateflag(2, v1->co, cmat); + } + removedoublesflag(4, 0.01); + } + else if(type==12) { /* Icosphere */ + EditVert *eva[12]; + + /* alle flags wissen */ + eve= G.edve.first; + while(eve) { + eve->f= 0; + eve= eve->next; + } + dia/=200; + for(a=0;a<12;a++) { + vec[0]= dia*icovert[a][0]; + vec[1]= dia*icovert[a][1]; + vec[2]= dia*icovert[a][2]; + eva[a]= addvertlist(vec); + eva[a]->f= 1+2; + } + for(a=0;a<20;a++) { + v1= eva[ icovlak[a][0] ]; + v2= eva[ icovlak[a][1] ]; + v3= eva[ icovlak[a][2] ]; + addvlaklist(v1, v2, v3, 0, NULL); + } + + dia*=200; + for(a=1; a<subdiv; a++) subdivideflag(2, dia, 0); + /* nu pas met imat */ + eve= G.edve.first; + while(eve) { + if(eve->f & 2) { + VecAddf(eve->co,eve->co,cent); + Mat3MulVecfl(imat,eve->co); + } + eve= eve->next; + } + } else if (type==13) { /* Monkey */ + extern int monkeyo, monkeynv, monkeynf; + extern signed char monkeyf[][4]; + extern signed char monkeyv[][3]; + EditVert **tv= MEM_mallocN(sizeof(*tv)*monkeynv*2, "tv"); + int i; + + for (i=0; i<monkeynv; i++) { + float v[3]; + v[0]= (monkeyv[i][0]+127)/128.0, v[1]= monkeyv[i][1]/128.0, v[2]= monkeyv[i][2]/128.0; + tv[i]= addvertlist(v); + tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(v); + } + for (i=0; i<monkeynf; i++) { + addvlaklist(tv[monkeyf[i][0]+i-monkeyo], tv[monkeyf[i][1]+i-monkeyo], tv[monkeyf[i][2]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeyf[i][3]+i-monkeyo]:NULL, NULL); + addvlaklist(tv[monkeynv+monkeyf[i][2]+i-monkeyo], tv[monkeynv+monkeyf[i][1]+i-monkeyo], tv[monkeynv+monkeyf[i][0]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeynv+monkeyf[i][3]+i-monkeyo]:NULL, NULL); + } + + MEM_freeN(tv); + } + + if(type!=0 && type!=10) righthandfaces(1); + countall(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWHEADERS, 0); + allqueue(REDRAWINFO, 1); /* 1, want header->win==0! */ + allqueue(REDRAWBUTSEDIT, 0); + makeDispList(G.obedit); + + if (type==13) notice("Oooh Oooh Oooh"); +} + +void vertexsmooth(void) +{ + struct EditVert *eve; + struct EditEdge *eed; + float *adror, *adr, fac; + float fvec[3]; + int teller=0; + + if(G.obedit==0) return; + + /* aantal tellen */ + eve= G.edve.first; + while(eve) { + if(eve->f & 1) teller++; + eve= eve->next; + } + if(teller==0) return; + + adr=adror= (float *)MEM_callocN(3*sizeof(float *)*teller, "vertsmooth"); + eve= G.edve.first; + while(eve) { + if(eve->f & 1) { + eve->vn= (EditVert *)adr; + eve->f1= 0; + adr+= 3; + } + eve= eve->next; + } + + eed= G.eded.first; + while(eed) { + if( (eed->v1->f & 1) || (eed->v2->f & 1) ) { + fvec[0]= (eed->v1->co[0]+eed->v2->co[0])/2.0; + fvec[1]= (eed->v1->co[1]+eed->v2->co[1])/2.0; + fvec[2]= (eed->v1->co[2]+eed->v2->co[2])/2.0; + + if((eed->v1->f & 1) && eed->v1->f1<255) { + eed->v1->f1++; + VecAddf((float *)eed->v1->vn, (float *)eed->v1->vn, fvec); + } + if((eed->v2->f & 1) && eed->v2->f1<255) { + eed->v2->f1++; + VecAddf((float *)eed->v2->vn, (float *)eed->v2->vn, fvec); + } + } + eed= eed->next; + } + + eve= G.edve.first; + while(eve) { + if(eve->f & 1) { + if(eve->f1) { + adr= (float *)eve->vn; + fac= 0.5/(float)eve->f1; + + eve->co[0]= 0.5*eve->co[0]+fac*adr[0]; + eve->co[1]= 0.5*eve->co[1]+fac*adr[1]; + eve->co[2]= 0.5*eve->co[2]+fac*adr[2]; + } + eve->vn= 0; + } + eve= eve->next; + } + MEM_freeN(adror); + + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + + +void vertexnoise(void) +{ + extern float Tin; + Material *ma; + Tex *tex; + EditVert *eve; + float b2, ofs, vec[3]; + + if(G.obedit==0) return; + + ma= give_current_material(G.obedit, G.obedit->actcol); + if(ma==0 || ma->mtex[0]==0 || ma->mtex[0]->tex==0) { + return; + } + tex= ma->mtex[0]->tex; + + ofs= tex->turbul/200.0; + + eve= (struct EditVert *)G.edve.first; + while(eve) { + if(eve->f & 1) { + + if(tex->type==TEX_STUCCI) { + + b2= BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2]); + if(tex->stype) ofs*=(b2*b2); + vec[0]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0]+ofs, eve->co[1], eve->co[2])); + vec[1]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1]+ofs, eve->co[2])); + vec[2]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2]+ofs)); + + VecAddf(eve->co, eve->co, vec); + } + else { + + externtex(ma->mtex[0], eve->co); + + eve->co[2]+= 0.05*Tin; + } + } + eve= eve->next; + } + + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +void hide_mesh(int swap) +{ + struct EditVert *eve; + struct EditEdge *eed; + + if(G.obedit==0) return; + + if(swap) { + eve= G.edve.first; + while(eve) { + if((eve->f & 1)==0) { + eve->xs= 3200; + eve->h= 1; + } + eve= eve->next; + } + } + else { + eve= G.edve.first; + while(eve) { + if(eve->f & 1) { + eve->f-=1; + eve->xs= 3200; + eve->h= 1; + } + eve= eve->next; + } + } + eed= G.eded.first; + while(eed) { + if(eed->v1->h || eed->v2->h) eed->h= 1; + else eed->h= 0; + eed= eed->next; + } + + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + + +void reveal_mesh(void) +{ + struct EditVert *eve; + struct EditEdge *eed; + + if(G.obedit==0) return; + + eve= G.edve.first; + while(eve) { + if(eve->h) { + eve->h= 0; + eve->f|=1; + } + eve= eve->next; + } + + eed= G.eded.first; + while(eed) { + eed->h= 0; + eed= eed->next; + } + + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +static float convex(float *v1, float *v2, float *v3, float *v4) +{ + float cross[3], test[3]; + float inpr; + + CalcNormFloat(v1, v2, v3, cross); + CalcNormFloat(v1, v3, v4, test); + + inpr= cross[0]*test[0]+cross[1]*test[1]+cross[2]*test[2]; + + return inpr; +} + +/* returns vertices of two adjacent triangles forming a quad + - can be righthand or lefthand + + 4-----3 + |\ | + | \ 2 | <- evl1 + | \ | + evl-> | 1 \ | + | \| + 1-----2 + +*/ +#define VTEST(face, num, other) \ + (face->v##num != other->v1 && face->v##num != other->v2 && face->v##num != other->v3) + +static void givequadverts(EditVlak *evl, EditVlak *evl1, EditVert **v1, EditVert **v2, EditVert **v3, EditVert **v4, float **uv, unsigned int *col) +{ + if VTEST(evl, 1, evl1) { + //if(evl->v1!=evl1->v1 && evl->v1!=evl1->v2 && evl->v1!=evl1->v3) { + *v1= evl->v1; + *v2= evl->v2; + uv[0] = evl->uv[0]; + uv[1] = evl->uv[1]; + col[0] = evl->col[0]; + col[1] = evl->col[1]; + } + else if VTEST(evl, 2, evl1) { + //else if(evl->v2!=evl1->v1 && evl->v2!=evl1->v2 && evl->v2!=evl1->v3) { + *v1= evl->v2; + *v2= evl->v3; + uv[0] = evl->uv[1]; + uv[1] = evl->uv[2]; + col[0] = evl->col[1]; + col[1] = evl->col[2]; + } + else if VTEST(evl, 3, evl1) { + // else if(evl->v3!=evl1->v1 && evl->v3!=evl1->v2 && evl->v3!=evl1->v3) { + *v1= evl->v3; + *v2= evl->v1; + uv[0] = evl->uv[2]; + uv[1] = evl->uv[0]; + col[0] = evl->col[2]; + col[1] = evl->col[0]; + } + + if VTEST(evl1, 1, evl) { + // if(evl1->v1!=evl->v1 && evl1->v1!=evl->v2 && evl1->v1!=evl->v3) { + *v3= evl1->v1; + uv[2] = evl1->uv[0]; + col[2] = evl1->col[0]; + + *v4= evl1->v2; + uv[3] = evl1->uv[1]; + col[3] = evl1->col[1]; +/* +if(evl1->v2== *v2) { + *v4= evl1->v3; + uv[3] = evl1->uv[2]; + } else { + *v4= evl1->v2; + uv[3] = evl1->uv[1]; + } + */ + } + else if VTEST(evl1, 2, evl) { + // else if(evl1->v2!=evl->v1 && evl1->v2!=evl->v2 && evl1->v2!=evl->v3) { + *v3= evl1->v2; + uv[2] = evl1->uv[1]; + col[2] = evl1->col[1]; + + *v4= evl1->v3; + uv[3] = evl1->uv[2]; + col[3] = evl1->col[2]; +/* +if(evl1->v3== *v2) { + *v4= evl1->v1; + uv[3] = evl1->uv[0]; + } else { + *v4= evl1->v3; + uv[3] = evl1->uv[2]; + } + */ + } + else if VTEST(evl1, 3, evl) { + // else if(evl1->v3!=evl->v1 && evl1->v3!=evl->v2 && evl1->v3!=evl->v3) { + *v3= evl1->v3; + uv[2] = evl1->uv[2]; + col[2] = evl1->col[2]; + + *v4= evl1->v1; + uv[3] = evl1->uv[0]; + col[3] = evl1->col[0]; +/* +if(evl1->v1== *v2) { + *v4= evl1->v2; + uv[3] = evl1->uv[3]; + } else { + *v4= evl1->v1; + uv[3] = evl1->uv[0]; + } + */ + } + else { + pupmenu("Wanna crash?%t|Yes Please!%x1"); + return; + } + +} + + +/* ook weer twee zeer vreemde 'patch' functies om de uv van tfaces te bewaren */ +/* +static float *set_correct_uv(EditVert *eve, EditVlak **evla) +{ + + if(eve== evla[1]->v3) return evla[1]->uv[2]; + if(eve== evla[0]->v3) return evla[0]->uv[2]; + if(eve== evla[1]->v2) return evla[1]->uv[1]; + if(eve== evla[0]->v2) return evla[0]->uv[1]; + if(eve== evla[1]->v1) return evla[1]->uv[0]; + if(eve== evla[0]->v1) return evla[0]->uv[0]; + return 0; +} + +crazy code commented out.. +static void restore_wuv(EditVlak *evl, void **evla) +{ + int *lp; + + lp= (int *)set_correct_uv(evl->v1, (EditVlak **)evla); + ((int *)(evl->uv[0]))[0]= lp[0]; + ((int *)(evl->uv[0]))[4]= lp[4]; + + lp= (int *)set_correct_uv(evl->v2, (EditVlak **)evla); + ((int *)(evl->uv[1]))[0]= lp[0]; + ((int *)(evl->uv[1]))[4]= lp[4]; + + lp= (int *)set_correct_uv(evl->v3, (EditVlak **)evla); + ((int *)(evl->uv[2]))[0]= lp[0]; + ((int *)(evl->uv[2]))[4]= lp[4]; + +} +*/ + + +/* Helper functions for edge/quad edit features*/ +/* + +*/ + +static void untag_edges(EditVlak *f) +{ + f->e1->f = 0; + f->e2->f = 0; + if (f->e3) f->e3->f = 0; + if (f->e4) f->e4->f = 0; +} + +#if 0 +static void mark_clear_edges(EditVlak *f) +{ + f->e1->f1 = 1; + f->e2->f1 = 1; + if (f->e3) f->e3->f1 = 1; + if (f->e4) f->e4->f1 = 1; +} +#endif + +static int count_edges(EditEdge *ed) +{ + int totedge = 0; + while(ed) { + ed->vn= 0; + if( (ed->v1->f & 1) && (ed->v2->f & 1) ) totedge++; + ed= ed->next; + } + return totedge; +} + +/** remove and free list of tagged edges */ +static void free_tagged_edgelist(EditEdge *eed) +{ + EditEdge *nexted; + + while(eed) { + nexted= eed->next; + if(eed->f1) { + remedge(eed); + free(eed); + } + eed= nexted; + } +} +/** remove and free list of tagged faces */ + +static void free_tagged_facelist(EditVlak *evl) +{ + EditVlak *nextvl; + + while(evl) { + nextvl= evl->next; + if(evl->f1) { + BLI_remlink(&G.edvl, evl); + freevlak(evl); + } + evl= nextvl; + } +} + +typedef EditVlak *EVPtr; +typedef EVPtr EVPTuple[2]; + +/** builds EVPTuple array evla of face tuples (in fact pointers to EditVlaks) + sharing one edge. + arguments: selected edge list, face list. + Edges will also be tagged accordingly (see eed->f) */ + +static int collect_quadedges(EVPTuple *evla, EditEdge *eed, EditVlak *evl) +{ + int i = 0; + EditEdge *e1, *e2, *e3; + EVPtr *evp; + + /* run through edges, if selected, set pointer edge-> facearray */ + while(eed) { + eed->f= 0; + eed->f1= 0; + if( (eed->v1->f & 1) && (eed->v2->f & 1) ) { + eed->vn= (EditVert *) (&evla[i]); + i++; + } + eed= eed->next; + } + + + /* find edges pointing to 2 faces by procedure: + + - run through faces and their edges, increase + face counter e->f for each face + */ + + while(evl) { + evl->f1= 0; + if(evl->v4==0) { /* if triangle */ + if(vlakselectedAND(evl, 1)) { + + e1= evl->e1; + e2= evl->e2; + e3= evl->e3; + if(e1->f<3) { + if(e1->f<2) { + evp= (EVPtr *) e1->vn; + evp[(int)e1->f]= evl; + } + e1->f+= 1; + } + if(e2->f<3) { + if(e2->f<2) { + evp= (EVPtr *) e2->vn; + evp[(int)e2->f]= evl; + } + e2->f+= 1; + } + if(e3->f<3) { + if(e3->f<2) { + evp= (EVPtr *) e3->vn; + evp[(int)e3->f]= evl; + } + e3->f+= 1; + } + } + } + evl= evl->next; + } + return i; +} + + +void join_triangles(void) +{ + EditVert *v1, *v2, *v3, *v4; + EditVlak *evl, *w; + EVPTuple *evlar; + EVPtr *evla; + EditEdge *eed, *nexted; + int totedge, ok; + float *uv[4]; + unsigned int col[4]; + + + totedge = count_edges(G.eded.first); + if(totedge==0) return; + + evlar= (EVPTuple *) MEM_callocN(totedge * sizeof(EVPTuple), "jointris"); + + ok = collect_quadedges(evlar, G.eded.first, G.edvl.first); + if (G.f & G_DEBUG) { + printf("edges selected: %d\n", ok); + } + + eed= G.eded.first; + while(eed) { + nexted= eed->next; + + if(eed->f==2) { /* points to 2 faces */ + + evla= (EVPtr *) eed->vn; + + /* don't do it if flagged */ + + ok= 1; + evl= evla[0]; + if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0; + evl= evla[1]; + if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0; + + if(ok) { + /* test convex */ + givequadverts(evla[0], evla[1], &v1, &v2, &v3, &v4, uv, col); + +/* + 4-----3 4-----3 + |\ | | | + | \ 1 | | | + | \ | -> | | + | 0 \ | | | + | \| | | + 1-----2 1-----2 +*/ + /* make new faces */ + if( convex(v1->co, v2->co, v3->co, v4->co) > 0.01) { + if(exist_vlak(v1, v2, v3, v4)==0) { + w = addvlaklist(v1, v2, v3, v4, evla[0]); + untag_edges(w); + if (w->tface) { + UVCOPY(w->uv[0], uv[0]); + UVCOPY(w->uv[1], uv[1]); + UVCOPY(w->uv[2], uv[2]); + UVCOPY(w->uv[3], uv[3]); + } + memcpy(w->col, col, sizeof(w->col)); + } + /* tag as to-be-removed */ + FACE_MARKCLEAR(evla[0]); + FACE_MARKCLEAR(evla[1]); + eed->f1 = 1; + } /* endif test convex */ + } + } + eed= nexted; + } + free_tagged_edgelist(G.eded.first); + free_tagged_facelist(G.edvl.first); + + MEM_freeN(evlar); + + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); + +} + +/* quick hack, basically a copy of beauty_fill */ +void edge_flip(void) +{ + EditVert *v1, *v2, *v3, *v4; + EditEdge *eed, *nexted; + EditVlak *evl, *w; + //void **evlar, **evla; + EVPTuple *evlar; + EVPtr *evla; + + float *uv[4]; + unsigned int col[4]; + + int totedge, ok; + + /* - alle geselecteerde edges met 2 vlakken + * - vind die vlakken: opslaan in edges (extra datablok) + * - per edge: - test convex + * - test edge: flip? + - zoja: remedge, addedge, alle randedges nieuwe vlakpointers + */ + + totedge = count_edges(G.eded.first); + if(totedge==0) return; + + /* temporary array for : edge -> face[1], face[2] */ + evlar= (EVPTuple *) MEM_callocN(totedge * sizeof(EVPTuple), "edgeflip"); + + ok = collect_quadedges(evlar, G.eded.first, G.edvl.first); + + eed= G.eded.first; + while(eed) { + nexted= eed->next; + + if(eed->f==2) { /* points to 2 faces */ + + evla= (EVPtr *) eed->vn; + + /* don't do it if flagged */ + + ok= 1; + evl= evla[0]; + if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0; + evl= evla[1]; + if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0; + + if(ok) { + /* test convex */ + givequadverts(evla[0], evla[1], &v1, &v2, &v3, &v4, uv, col); + +/* + 4-----3 4-----3 + |\ | | /| + | \ 1 | | 1 / | + | \ | -> | / | + | 0 \ | | / 0 | + | \| |/ | + 1-----2 1-----2 +*/ + /* make new faces */ + if (v1 && v2 && v3){ + if( convex(v1->co, v2->co, v3->co, v4->co) > 0.01) { + if(exist_vlak(v1, v2, v3, v4)==0) { + w = addvlaklist(v1, v2, v3, 0, evla[1]); + + untag_edges(w); + if (w->tface) { + UVCOPY(w->uv[0], uv[0]); + UVCOPY(w->uv[1], uv[1]); + UVCOPY(w->uv[2], uv[2]); + } + w->col[0] = col[0]; w->col[1] = col[1]; w->col[2] = col[2]; + + w = addvlaklist(v1, v3, v4, 0, evla[1]); + untag_edges(w); + if (w->tface) { + UVCOPY(w->uv[0], uv[0]); + UVCOPY(w->uv[1], uv[2]); + UVCOPY(w->uv[2], uv[3]); + } + w->col[0] = col[0]; w->col[1] = col[2]; w->col[2] = col[3]; + + /* erase old faces and edge */ + } + /* tag as to-be-removed */ + FACE_MARKCLEAR(evla[1]); + FACE_MARKCLEAR(evla[0]); + eed->f1 = 1; + + } /* endif test convex */ + } + } + } + eed= nexted; + } + + /* clear tagged edges and faces: */ + free_tagged_edgelist(G.eded.first); + free_tagged_facelist(G.edvl.first); + + MEM_freeN(evlar); + + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +void beauty_fill(void) +{ + EditVert *v1, *v2, *v3, *v4; + EditEdge *eed, *nexted; + EditEdge dia1, dia2; + EditVlak *evl, *w; + // void **evlar, **evla; + EVPTuple *evlar; + EVPtr *evla; + float *uv[4]; + unsigned int col[4]; + float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2; + int totedge, ok, notbeauty=8, onedone; + + /* - alle geselecteerde edges met 2 vlakken + * - vind die vlakken: opslaan in edges (extra datablok) + * - per edge: - test convex + * - test edge: flip? + - zoja: remedge, addedge, alle randedges nieuwe vlakpointers + */ + + totedge = count_edges(G.eded.first); + if(totedge==0) return; + + if(okee("Beauty Fill")==0) return; + + /* tempblok met vlakpointers */ + evlar= (EVPTuple *) MEM_callocN(totedge * sizeof(EVPTuple), "beautyfill"); + + while (notbeauty) { + notbeauty--; + + ok = collect_quadedges(evlar, G.eded.first, G.edvl.first); + + /* gaatie */ + onedone= 0; + + eed= G.eded.first; + while(eed) { + nexted= eed->next; + + if(eed->f==2) { + + evla = (EVPtr *) eed->vn; + + /* geen van de vlakken mag al gedaan zijn */ + ok= 1; + evl= evla[0]; + if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0; + evl= evla[1]; + if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0; + + if(ok) { + /* test convex */ + givequadverts(evla[0], evla[1], &v1, &v2, &v3, &v4, uv, col); + if( convex(v1->co, v2->co, v3->co, v4->co) > -0.5) { + + /* test edges */ + if( ((long)v1) > ((long)v3) ) { + dia1.v1= v3; + dia1.v2= v1; + } + else { + dia1.v1= v1; + dia1.v2= v3; + } + + if( ((long)v2) > ((long)v4) ) { + dia2.v1= v4; + dia2.v2= v2; + } + else { + dia2.v1= v2; + dia2.v2= v4; + } + + /* testregel: + * de oppervlakte gedeeld door de totale edgelengte + * + */ + + len1= VecLenf(v1->co, v2->co); + len2= VecLenf(v2->co, v3->co); + len3= VecLenf(v3->co, v4->co); + len4= VecLenf(v4->co, v1->co); + len5= VecLenf(v1->co, v3->co); + len6= VecLenf(v2->co, v4->co); + + opp1= AreaT3Dfl(v1->co, v2->co, v3->co); + opp2= AreaT3Dfl(v1->co, v3->co, v4->co); + + fac1= opp1/(len1+len2+len5) + opp2/(len3+len4+len5); + + opp1= AreaT3Dfl(v2->co, v3->co, v4->co); + opp2= AreaT3Dfl(v2->co, v4->co, v1->co); + + fac2= opp1/(len2+len3+len6) + opp2/(len4+len1+len6); + + ok= 0; + if(fac1 > fac2) { + if(dia2.v1==eed->v1 && dia2.v2==eed->v2) { + eed->f1= 1; + evl= evla[0]; + evl->f1= 1; + evl= evla[1]; + evl->f1= 1; + + w= addvlaklist(v1, v2, v3, 0, evl); + if (w->tface) { + UVCOPY(w->uv[0], uv[0]); + UVCOPY(w->uv[1], uv[1]); + UVCOPY(w->uv[2], uv[2]); + } + w->col[0] = col[0]; w->col[1] = col[1]; w->col[2] = col[2]; + w= addvlaklist(v1, v3, v4, 0, evl); + if (w->tface) { + UVCOPY(w->uv[0], uv[0]); + UVCOPY(w->uv[1], uv[2]); + UVCOPY(w->uv[2], uv[3]); + } + w->col[0] = col[0]; w->col[1] = col[2]; w->col[2] = col[3]; + + onedone= 1; + } + } + else if(fac1 < fac2) { + if(dia1.v1==eed->v1 && dia1.v2==eed->v2) { + eed->f1= 1; + evl= evla[0]; + evl->f1= 1; + evl= evla[1]; + evl->f1= 1; + + w= addvlaklist(v2, v3, v4, 0, evl); + if (w->tface) { + UVCOPY(w->uv[0], uv[1]); + UVCOPY(w->uv[1], uv[3]); + UVCOPY(w->uv[2], uv[4]); + } + + w= addvlaklist(v1, v2, v4, 0, evl); + if (w->tface) { + UVCOPY(w->uv[0], uv[0]); + UVCOPY(w->uv[1], uv[1]); + UVCOPY(w->uv[2], uv[3]); + } + onedone= 1; + } + } + } + } + + } + eed= nexted; + } + + free_tagged_edgelist(G.eded.first); + free_tagged_facelist(G.edvl.first); + + if(onedone==0) break; + } + + MEM_freeN(evlar); + + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +/** tests whether selected mesh objects have tfaces */ +static int testSelected_TfaceMesh(void) +{ + Base *base; + Mesh *me; + + base = FIRSTBASE; + while (base) { + if TESTBASE(base) { + if(base->object->type==OB_MESH) { + me= base->object->data; + if (me->tface) + return 1; + } + } + base= base->next; + } + return 0; +} + +void join_mesh(void) +{ + Base *base, *nextb; + Object *ob; + Material **matar, *ma; + Mesh *me; + MVert *mvert, *mvertmain; + MFace *mface = NULL, *mfacemain; + TFace *tface = NULL, *tfacemain; + unsigned int *mcol=NULL, *mcolmain; + float imat[4][4], cmat[4][4]; + int a, b, totcol, totvert=0, totface=0, ok=0, vertofs, map[MAXMAT]; +#ifdef __NLA + int i, j, index; + bDeformGroup *dg, *odg; + MDeformVert *dvert, *dvertmain; +#endif + + if(G.obedit) return; + + ob= OBACT; + if(!ob || ob->type!=OB_MESH) return; + + /* tellen */ + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + if(base->object->type==OB_MESH) { + me= base->object->data; + totvert+= me->totvert; + totface+= me->totface; + + if(base->object == ob) ok= 1; + } + } + base= base->next; + } + + /* zodoende is het aktieve object altijd select */ + if(ok==0) return; + + if(totvert==0 || totvert>65000) return; + + if(okee("Join selected Meshes")==0) return; + + /* nieuwe materiaal indexen en hoofdarray */ + matar= MEM_callocN(sizeof(void *)*MAXMAT, "join_mesh"); + totcol= ob->totcol; + + /* obact materials in nieuw hoofdarray, is mooiere start! */ + for(a=1; a<=ob->totcol; a++) { + matar[a-1]= give_current_material(ob, a); + id_us_plus((ID *)matar[a-1]); + /* id->us ophogen: wordt ook verlaagd */ + } + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + if(ob!=base->object && base->object->type==OB_MESH) { + me= base->object->data; +#ifdef __NLA + // Join this object's vertex groups to the base one's + for (dg=base->object->defbase.first; dg; dg=dg->next){ + /* See if this group exists in the object */ + for (odg=ob->defbase.first; odg; odg=odg->next){ + if (!strcmp(odg->name, dg->name)){ + break; + } + } + if (!odg){ + odg = MEM_callocN (sizeof(bDeformGroup), "deformGroup"); + memcpy (odg, dg, sizeof(bDeformGroup)); + BLI_addtail(&ob->defbase, odg); + } + + } + if (ob->defbase.first && ob->actdef==0) + ob->actdef=1; +#endif + if(me->totvert) { + for(a=1; a<=base->object->totcol; a++) { + ma= give_current_material(base->object, a); + if(ma) { + for(b=0; b<totcol; b++) { + if(ma == matar[b]) break; + } + if(b==totcol) { + matar[b]= ma; + ma->id.us++; + totcol++; + } + if(totcol>=MAXMAT-1) break; + } + } + } + } + if(totcol>=MAXMAT-1) break; + } + base= base->next; + } + + me= ob->data; + mvert= mvertmain= MEM_mallocN(totvert*sizeof(MVert), "joinmesh1"); + + if (totface) mface= mfacemain= MEM_mallocN(totface*sizeof(MFace), "joinmesh2"); + else mfacemain= 0; + + if(me->mcol) mcol= mcolmain= MEM_callocN(totface*4*sizeof(int), "joinmesh3"); + else mcolmain= 0; + + /* if active object doesn't have Tfaces, but one in the selection does, + make TFaces for active, so we don't lose texture information in the + join process */ + if(me->tface || testSelected_TfaceMesh()) tface= tfacemain= MEM_callocN(totface*4*sizeof(TFace), "joinmesh4"); + else + tfacemain= 0; + +#ifdef __NLA + if(me->dvert) + dvert= dvertmain= MEM_callocN(totvert*sizeof(MDeformVert), "joinmesh5"); + else dvert=dvertmain= NULL; +#endif + + vertofs= 0; + + /* alle geselecteerde meshes invers transformen in obact */ + Mat4Invert(imat, ob->obmat); + + base= FIRSTBASE; + while(base) { + nextb= base->next; + if TESTBASE(base) { + if(base->object->type==OB_MESH) { + + me= base->object->data; + + if(me->totvert) { + + memcpy(mvert, me->mvert, me->totvert*sizeof(MVert)); + +#ifdef __NLA + copy_dverts(dvert, me->dvert, me->totvert); + + /* >>>>> FIXME: Ensure that deformation groups are updated correctly */ + /* OLD VERSION */ + /* + for (i=0; i<me->totvert; i++){ + for (j=0; j<mvert[i].totweight; j++){ + // Find the old vertex group + odg = BLI_findlink (&base->object->defbase, mvert[i].dw[j].def_nr); + + // Search for a match in the new object + for (dg=ob->defbase.first, index=0; dg; dg=dg->next, index++){ + if (!strcmp(dg->name, odg->name)){ + mvert[i].dw[j].def_nr = index; + break; + } + } + } + } + */ + /* NEW VERSION */ + if (dvertmain){ + for (i=0; i<me->totvert; i++){ + for (j=0; j<dvert[i].totweight; j++){ + // Find the old vertex group + odg = BLI_findlink (&base->object->defbase, dvert[i].dw[j].def_nr); + + // Search for a match in the new object + for (dg=ob->defbase.first, index=0; dg; dg=dg->next, index++){ + if (!strcmp(dg->name, odg->name)){ + dvert[i].dw[j].def_nr = index; + break; + } + } + } + } + dvert+=me->totvert; + } + +#endif + if(base->object != ob) { + /* let op: matmul omkeren is ECHT fout */ + Mat4MulMat4(cmat, base->object->obmat, imat); + + a= me->totvert; + while(a--) { + Mat4MulVecfl(cmat, mvert->co); + mvert++; + } + } + else mvert+= me->totvert; + + if(mcolmain) { + if(me->mcol) memcpy(mcol, me->mcol, me->totface*4*4); + mcol+= 4*me->totface; + } + } + if(me->totface) { + + /* mapping maken voor materialen */ + memset(map, 0, 4*MAXMAT); + for(a=1; a<=base->object->totcol; a++) { + ma= give_current_material(base->object, a); + if(ma) { + for(b=0; b<totcol; b++) { + if(ma == matar[b]) { + map[a-1]= b; + break; + } + } + } + } + + memcpy(mface, me->mface, me->totface*sizeof(MFace)); + + a= me->totface; + while(a--) { + mface->v1+= vertofs; + mface->v2+= vertofs; + if(mface->v3) mface->v3+= vertofs; + if(mface->v4) mface->v4+= vertofs; + + mface->mat_nr= map[(int)mface->mat_nr]; + + mface++; + } + + if(tfacemain) { + if(me->tface) memcpy(tface, me->tface, me->totface*sizeof(TFace)); + tface+= me->totface; + } + + } + vertofs+= me->totvert; + + if(base->object!=ob) { + free_and_unlink_base(base); + } + } + } + base= nextb; + } + + me= ob->data; + + if(me->mface) MEM_freeN(me->mface); + me->mface= mfacemain; + if(me->mvert) MEM_freeN(me->mvert); +#ifdef __NLA + if(me->dvert) free_dverts(me->dvert, me->totvert); + me->dvert = dvertmain; +#endif + me->mvert= mvertmain; + if(me->mcol) MEM_freeN(me->mcol); + me->mcol= (MCol *)mcolmain; + if(me->tface) MEM_freeN(me->tface); + me->tface= tfacemain; + me->totvert= totvert; + me->totface= totface; + + /* oude material array */ + for(a=1; a<=ob->totcol; a++) { + ma= ob->mat[a-1]; + if(ma) ma->id.us--; + } + for(a=1; a<=me->totcol; a++) { + ma= me->mat[a-1]; + if(ma) ma->id.us--; + } + if(ob->mat) MEM_freeN(ob->mat); + if(me->mat) MEM_freeN(me->mat); + ob->mat= me->mat= 0; + + if(totcol) { + me->mat= matar; + ob->mat= MEM_callocN(sizeof(void *)*totcol, "join obmatar"); + } + else MEM_freeN(matar); + + ob->totcol= me->totcol= totcol; + ob->colbits= 0; + + /* andere mesh gebruikers */ + test_object_materials((ID *)me); + + enter_editmode(); + exit_editmode(1); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSMAT, 0); + makeDispList(G.obedit); + +} + +void clever_numbuts_mesh(void) +{ + EditVert *eve; + + eve= G.edve.first; + while(eve) { + if(eve->f & 1) break; + eve= eve->next; + } + if(eve==0) return; + + add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, eve->co, 0); + add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, eve->co+1, 0); + add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, eve->co+2, 0); + + do_clever_numbuts("Active Vertex", 3, REDRAW); +} + +/* never used, see CVS */ +/* static void insert_radiogour(char *str) */ + +static void permutate(void *list, int num, int size, int *index) +{ + void *buf; + int len; + int i; + + len = num * size; + + buf = malloc(len); + memcpy(buf, list, len); + + for (i = 0; i < num; i++) { + memcpy((char *)list + (i * size), (char *)buf + (index[i] * size), size); + } + free(buf); +} + +static MVert *mvertbase; +static MFace *mfacebase; + +static int verg_mface(const void *v1, const void *v2) +{ + MFace *x1, *x2; + + MVert *ve1, *ve2; + int i1, i2; + + i1 = ((int *) v1)[0]; + i2 = ((int *) v2)[0]; + + x1 = mfacebase + i1; + x2 = mfacebase + i2; + + ve1= mvertbase+x1->v1; + ve2= mvertbase+x2->v1; + + if( ve1->co[2] > ve2->co[2] ) return 1; + else if( ve1->co[2] < ve2->co[2]) return -1; + return 0; +} + + +void sort_faces(void) +{ + Object *ob= OBACT; + Mesh *me; + + int i, *index; + + if(ob==0) return; + if(G.obedit) return; + if(ob->type!=OB_MESH) return; + + if(okee("Sort Faces in Z")==0) return; + me= ob->data; + if(me->totface==0) return; + +/* create index list */ + index = (int *) malloc(sizeof(int) * me->totface); + for (i = 0; i < me->totface; i++) { + index[i] = i; + } + mvertbase= me->mvert; + mfacebase = me->mface; + +/* sort index list instead of faces itself + and apply this permutation to the face list plus + to the texture faces */ + qsort(index, me->totface, sizeof(int), verg_mface); + + permutate(mfacebase, me->totface, sizeof(MFace), index); + if (me->tface) + permutate(me->tface, me->totface, sizeof(TFace), index); + + free(index); + + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +void vertices_to_sphere(void) +{ + EditVert *eve; + Object *ob= OBACT; + float *curs, len, vec[3], cent[3], fac, facm, imat[3][3], bmat[3][3]; + int tot; + short perc=100; + + if(ob==0) return; + TEST_EDITMESH + + if(button(&perc, 1, 100, "Percentage:")==0) return; + fac= perc/100.0; + facm= 1.0-fac; + + Mat3CpyMat4(bmat, ob->obmat); + Mat3Inv(imat, bmat); + + /* centrum */ + curs= give_cursor(); + cent[0]= curs[0]-ob->obmat[3][0]; + cent[1]= curs[1]-ob->obmat[3][1]; + cent[2]= curs[2]-ob->obmat[3][2]; + Mat3MulVecfl(imat, cent); + + len= 0.0; + tot= 0; + eve= G.edve.first; + while(eve) { + if(eve->f & 1) { + tot++; + len+= VecLenf(cent, eve->co); + } + eve= eve->next; + } + len/=tot; + + if(len==0.0) len= 10.0; + + eve= G.edve.first; + while(eve) { + if(eve->f & 1) { + vec[0]= eve->co[0]-cent[0]; + vec[1]= eve->co[1]-cent[1]; + vec[2]= eve->co[2]-cent[2]; + + Normalise(vec); + + eve->co[0]= fac*(cent[0]+vec[0]*len) + facm*eve->co[0]; + eve->co[1]= fac*(cent[1]+vec[1]*len) + facm*eve->co[1]; + eve->co[2]= fac*(cent[2]+vec[2]*len) + facm*eve->co[2]; + + } + eve= eve->next; + } + + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +/* Got this from scanfill.c. You will need to juggle around the + * callbacks for the scanfill.c code a bit for this to work. */ +void fill_mesh(void) +{ + EditVert *eve,*v1; + EditEdge *eed,*e1,*nexted; + EditVlak *evl,*nextvl; + short ok; + + if(G.obedit==0 || (G.obedit->type!=OB_MESH)) return; + + waitcursor(1); + + /* alle selected vertices kopieeren */ + eve= G.edve.first; + while(eve) { + if(eve->f & 1) { + v1= BLI_addfillvert(eve->co); + eve->vn= v1; + v1->vn= eve; + v1->h= 0; + } + eve= eve->next; + } + /* alle selected edges kopieeren */ + eed= G.eded.first; + while(eed) { + if( (eed->v1->f & 1) && (eed->v2->f & 1) ) { + e1= BLI_addfilledge(eed->v1->vn, eed->v2->vn); + e1->v1->h++; + e1->v2->h++; + } + eed= eed->next; + } + /* van alle selected vlakken vertices en edges verwijderen om dubbels te voorkomen */ + /* alle edges tellen punten op, vlakken trekken af, + edges met vertices ->h<2 verwijderen */ + evl= G.edvl.first; + ok= 0; + while(evl) { + nextvl= evl->next; + if( vlakselectedAND(evl, 1) ) { + evl->v1->vn->h--; + evl->v2->vn->h--; + evl->v3->vn->h--; + if(evl->v4) evl->v4->vn->h--; + ok= 1; + + } + evl= nextvl; + } + if(ok) { /* er zijn vlakken geselecteerd */ + eed= filledgebase.first; + while(eed) { + nexted= eed->next; + if(eed->v1->h<2 || eed->v2->h<2) { + BLI_remlink(&filledgebase,eed); + } + eed= nexted; + } + } + + /* tijd=clock(); */ + + /* to make edgefill work */ + BLI_setScanFillObjectRef(G.obedit); + BLI_setScanFillColourRef(&G.obedit->actcol); + + ok= BLI_edgefill(0); + + /* printf("time: %d\n",(clock()-tijd)/1000); */ + + if(ok) { + evl= fillvlakbase.first; + while(evl) { + addvlaklist(evl->v1->vn, evl->v2->vn, evl->v3->vn, 0, evl); + evl= evl->next; + } + } + /* else printf("fill error\n"); */ + + BLI_end_edgefill(); + + waitcursor(0); + + countall(); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + +/* ***************** */ + +/* this one for NOT in editmode + +(only used by external modules, that is, until now by the +python NMesh module) + +TODO: Probably it's better to convert the mesh into a EditMesh, call +vertexnormals() and convert it back to a Mesh again. + +*/ + +void vertexnormals_mesh(Mesh *me, float *extverts) +{ + MVert *mvert; + MFace *mface; + float n1[3], n2[3], n3[3], n4[3], co[4], fac1, fac2, fac3, fac4, *temp; + float *f1, *f2, *f3, *f4, xn, yn, zn, *normals; + float *v1, *v2, *v3, *v4, len, vnor[3]; + int a, testflip; + + if(me->totvert==0) return; + + testflip= (me->flag & ME_NOPUNOFLIP)==0; + if((me->flag & ME_TWOSIDED)==0) testflip= 0; /* grote hoeken */ + + if(me->totface==0) { + /* namaak puno's voor halopuno! */ + mvert= me->mvert; + for(a=0; a<me->totvert; a++, mvert++) { + VECCOPY(n1, mvert->co); + Normalise(n1); + mvert->no[0]= 32767.0*n1[0]; + mvert->no[1]= 32767.0*n1[1]; + mvert->no[2]= 32767.0*n1[2]; + } + return; + } + + normals= MEM_callocN(me->totvert*3*sizeof(float), "normals"); + + /* berekenen cos hoeken en oppervlakte en optellen bij puno */ + mface= me->mface; + mvert= me->mvert; + for(a=0; a<me->totface; a++, mface++) { + + if(mface->v3==0) continue; + + if(extverts) { + v1= extverts+3*mface->v1; + v2= extverts+3*mface->v2; + v3= extverts+3*mface->v3; + v4= extverts+3*mface->v4; + } + else { + v1= (mvert+mface->v1)->co; + v2= (mvert+mface->v2)->co; + v3= (mvert+mface->v3)->co; + v4= (mvert+mface->v4)->co; + } + + VecSubf(n1, v2, v1); + VecSubf(n2, v3, v2); + Normalise(n1); + Normalise(n2); + + if(mface->v4==0) { + VecSubf(n3, v1, v3); + Normalise(n3); + + co[0]= saacos(-n3[0]*n1[0]-n3[1]*n1[1]-n3[2]*n1[2]); + co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]); + co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]); + + } + else { + VecSubf(n3, v4, v3); + VecSubf(n4, v1, v4); + Normalise(n3); + Normalise(n4); + + co[0]= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]); + co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]); + co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]); + co[3]= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]); + } + + CalcNormFloat(v1, v2, v3, vnor); + + temp= normals+3*mface->v1; + if(testflip && contrpuntnorm(vnor, temp) ) co[0]= -co[0]; + temp[0]+= co[0]*vnor[0]; + temp[1]+= co[0]*vnor[1]; + temp[2]+= co[0]*vnor[2]; + + temp= normals+3*mface->v2; + if(testflip && contrpuntnorm(vnor, temp) ) co[1]= -co[1]; + temp[0]+= co[1]*vnor[0]; + temp[1]+= co[1]*vnor[1]; + temp[2]+= co[1]*vnor[2]; + + temp= normals+3*mface->v3; + if(testflip && contrpuntnorm(vnor, temp) ) co[2]= -co[2]; + temp[0]+= co[2]*vnor[0]; + temp[1]+= co[2]*vnor[1]; + temp[2]+= co[2]*vnor[2]; + + if(mface->v4) { + temp= normals+3*mface->v4; + if(testflip && contrpuntnorm(vnor, temp) ) co[3]= -co[3]; + temp[0]+= co[3]*vnor[0]; + temp[1]+= co[3]*vnor[1]; + temp[2]+= co[3]*vnor[2]; + } + } + + /* normaliseren puntnormalen */ + mvert= me->mvert; + for(a=0; a<me->totvert; a++, mvert++) { + len= Normalise(normals+3*a); + if(len!=0.0) { + VECCOPY(n1, normals+3*a); + Normalise(n1); + + mvert->no[0]= 32767.0*n1[0]; + mvert->no[1]= 32767.0*n1[1]; + mvert->no[2]= 32767.0*n1[2]; + } + } + + /* puntnormaal omklap-vlaggen voor bij shade */ + mface= me->mface; + mvert= me->mvert; + for(a=0; a<me->totface; a++, mface++) { + mface->puno=0; + + if(mface->v3==0) continue; + + if(extverts) { + v1= extverts+3*mface->v1; + v2= extverts+3*mface->v2; + v3= extverts+3*mface->v3; + } + else { + v1= (mvert+mface->v1)->co; + v2= (mvert+mface->v2)->co; + v3= (mvert+mface->v3)->co; + } + + CalcNormFloat(v1, v2, v3, vnor); + + if(testflip) { + f1= normals + 3*mface->v1; + f2= normals + 3*mface->v2; + f3= normals + 3*mface->v3; + + fac1= vnor[0]*f1[0] + vnor[1]*f1[1] + vnor[2]*f1[2]; + if(fac1<0.0) { + mface->puno = ME_FLIPV1; + } + fac2= vnor[0]*f2[0] + vnor[1]*f2[1] + vnor[2]*f2[2]; + if(fac2<0.0) { + mface->puno += ME_FLIPV2; + } + fac3= vnor[0]*f3[0] + vnor[1]*f3[1] + vnor[2]*f3[2]; + if(fac3<0.0) { + mface->puno += ME_FLIPV3; + } + if(mface->v4) { + f4= normals + 3*mface->v4; + fac4= vnor[0]*f4[0] + vnor[1]*f4[1] + vnor[2]*f4[2]; + if(fac4<0.0) { + mface->puno += ME_FLIPV4; + } + } + } + /* proj voor cubemap! */ + xn= fabs(vnor[0]); + yn= fabs(vnor[1]); + zn= fabs(vnor[2]); + + if(zn>xn && zn>yn) mface->puno += ME_PROJXY; + else if(yn>xn && yn>zn) mface->puno += ME_PROJXZ; + else mface->puno += ME_PROJYZ; + + } + + MEM_freeN(normals); +} + +/***/ + +static int editmesh_nfaces_selected(void) +{ + EditVlak *evl; + int count= 0; + + for (evl= G.edvl.first; evl; evl= evl->next) + if (vlakselectedAND(evl, SELECT)) + count++; + + return count; +} + +static int editmesh_nvertices_selected(void) +{ + EditVert *eve; + int count= 0; + + for (eve= G.edve.first; eve; eve= eve->next) + if (eve->f & SELECT) + count++; + + return count; +} + +static void editmesh_calc_selvert_center(float cent_r[3]) +{ + EditVert *eve; + int nsel= 0; + + cent_r[0]= cent_r[1]= cent_r[0]= 0.0; + + for (eve= G.edve.first; eve; eve= eve->next) { + if (eve->f & SELECT) { + cent_r[0]+= eve->co[0]; + cent_r[1]+= eve->co[1]; + cent_r[2]+= eve->co[2]; + nsel++; + } + } + + if (nsel) { + cent_r[0]/= nsel; + cent_r[1]/= nsel; + cent_r[2]/= nsel; + } +} + +static int tface_is_selected(TFace *tf) +{ + return (!(tf->flag & TF_HIDE) && (tf->flag & TF_SELECT)); +} + +static int faceselect_nfaces_selected(Mesh *me) +{ + int i, count= 0; + + for (i=0; i<me->totface; i++) { + MFace *mf= ((MFace*) me->mface) + i; + TFace *tf= ((TFace*) me->tface) + i; + + if (mf->v3 && tface_is_selected(tf)) + count++; + } + + return count; +} + + /* XXX, code for both these functions should be abstract, + * then unified, then written for other things (like objects, + * which would use same as vertices method), then added + * to interface! Hoera! - zr + */ +void faceselect_align_view_to_selected(View3D *v3d, Mesh *me, int axis) +{ + if (!faceselect_nfaces_selected(me)) { + error("No faces selected."); + } else { + float norm[3]; + int i; + + norm[0]= norm[1]= norm[2]= 0.0; + for (i=0; i<me->totface; i++) { + MFace *mf= ((MFace*) me->mface) + i; + TFace *tf= ((TFace*) me->tface) + i; + + if (mf->v3 && tface_is_selected(tf)) { + float *v1, *v2, *v3, fno[3]; + + v1= me->mvert[mf->v1].co; + v2= me->mvert[mf->v2].co; + v3= me->mvert[mf->v3].co; + if (mf->v4) { + float *v4= me->mvert[mf->v4].co; + CalcNormFloat4(v1, v2, v3, v4, fno); + } else { + CalcNormFloat(v1, v2, v3, fno); + } + + norm[0]+= fno[0]; + norm[1]+= fno[1]; + norm[2]+= fno[2]; + } + } + + view3d_align_axis_to_vector(v3d, axis, norm); + } +} + +void editmesh_align_view_to_selected(View3D *v3d, int axis) +{ + int nselverts= editmesh_nvertices_selected(); + + if (nselverts<3) { + if (nselverts==0) { + error("No faces or vertices selected."); + } else { + error("At least one face or three vertices must be selected."); + } + } else if (editmesh_nfaces_selected()) { + float norm[3]; + EditVlak *evl; + + norm[0]= norm[1]= norm[2]= 0.0; + for (evl= G.edvl.first; evl; evl= evl->next) { + if (vlakselectedAND(evl, SELECT)) { + float fno[3]; + if (evl->v4) CalcNormFloat4(evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co, fno); + else CalcNormFloat(evl->v1->co, evl->v2->co, evl->v3->co, fno); + /* XXX, fixme, should be flipped intp a + * consistent direction. -zr + */ + norm[0]+= fno[0]; + norm[1]+= fno[1]; + norm[2]+= fno[2]; + } + } + + view3d_align_axis_to_vector(v3d, axis, norm); + } else { + float cent[3], norm[3]; + EditVert *eve, *leve= NULL; + + norm[0]= norm[1]= norm[2]= 0.0; + editmesh_calc_selvert_center(cent); + for (eve= G.edve.first; eve; eve= eve->next) { + if (eve->f & SELECT) { + if (leve) { + float tno[3]; + CalcNormFloat(cent, leve->co, eve->co, tno); + + /* XXX, fixme, should be flipped intp a + * consistent direction. -zr + */ + norm[0]+= tno[0]; + norm[1]+= tno[1]; + norm[2]+= tno[2]; + } + leve= eve; + } + } + + view3d_align_axis_to_vector(v3d, axis, norm); + } +}
\ No newline at end of file diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c new file mode 100644 index 00000000000..54ee4682c0e --- /dev/null +++ b/source/blender/src/editnla.c @@ -0,0 +1,1738 @@ +/** +* $Id$ +* + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** +* This file is a horrible mess: An attmept to cram some +* final functionality into blender before it is too late. +* +* Hopefully it can be tidied up at a later date... +*/ + +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "PIL_time.h" + +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_library.h" +#include "BKE_nla.h" +#include "BKE_action.h" + +#include "BIF_screen.h" +#include "BIF_interface.h" +#include "BIF_buttons.h" +#include "BIF_space.h" +#include "BIF_mywindow.h" +#include "BIF_editview.h" +#include "BIF_toolbox.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" + +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_ipo_types.h" +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_userdef_types.h" +#include "DNA_action_types.h" +#include "DNA_nla_types.h" +#include "DNA_constraint_types.h" + +#include "BSE_editipo.h" +#include "BSE_editnla_types.h" +#include "BSE_headerbuttons.h" +#include "BSE_drawipo.h" +#include "BSE_trans_types.h" +#include "BSE_edit.h" +#include "BDR_editobject.h" + +#include "interface.h" +#include "blendef.h" +#include "mydevice.h" +#include "blendertimer.h" +#include "license_key.h" +#include "keyed_functions.h" + +/* Note: A lot of these pretty much duplicate the behaviour of the +action windows. The functions should be shared, not copy-pasted */ +typedef struct NlaParam{ + SpaceNla *snla; + unsigned short event; + short val; +}NlaParam; + +static void deselect_nlachannel_keys (int test); +static void deselect_nlachannels(int test); +static void transform_nlachannel_keys(char mode); +static void delete_nlachannel_keys(void); +static void delete_nlachannels(void); +static void duplicate_nlachannel_keys(void); +static void borderselect_nla(void); +static void mouse_nla(void); +static Base *get_nearest_nlachannel_ob_key (float *index, short *sel); +static bAction *get_nearest_nlachannel_ac_key (float *index, short *sel); +static Base *get_nearest_nlastrip (bActionStrip **rstrip, short *sel); + +static void mouse_nlachannels(short mval[2]); +static void add_nlablock(short mval[2]); +static bActionStrip *get_active_nlastrip(void); +static void convert_nla(short mval[2]); + +extern int count_nla_levels(void); /* From drawnla.c */ +extern int nla_filter (Base* base, int flags); /* From drawnla.c */ + +/* ******************** SPACE: NLA ********************** */ + +/* Protected creator function */ +int calc_memleak (void* ptr){ + int doredraw= 0; + short mval[2]; + float dx,dy; + int cfra; + SpaceNla *snla; + NlaParam *params=(NlaParam*) ptr; + unsigned short event; + short val ; + + if (!ptr) + return -1; + + snla= params->snla; + event = params->event; + val = params->val; + + if (LICENSE_KEY_VALID){ + if(curarea->win==0) return 0; + + if (!snla) + return 0; + + if(val) { + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + getmouseco_areawin(mval); + + switch(event) { + case UI_BUT_EVENT: + do_blenderbuttons(val); + break; + case HOMEKEY: + do_nla_buttons(B_NLAHOME); + break; + case DKEY: + if (G.qual & LR_SHIFTKEY && mval[0]>=NLAWIDTH){ + duplicate_nlachannel_keys(); + update_for_newframe(); + } + break; + case DELKEY: + case XKEY: + if (mval[0]>=NLAWIDTH) + delete_nlachannel_keys (); + else + delete_nlachannels(); + update_for_newframe(); + break; + case GKEY: + if (mval[0]>=NLAWIDTH) + transform_nlachannel_keys ('g'); + update_for_newframe(); + break; + case SKEY: + if (mval[0]>=NLAWIDTH) + transform_nlachannel_keys ('s'); + update_for_newframe(); + break; + case BKEY: + borderselect_nla(); + break; + case CKEY: + convert_nla(mval); + break; + + case AKEY: + if (G.qual & LR_SHIFTKEY){ + add_nlablock(mval); + allqueue (REDRAWNLA, 0); + allqueue (REDRAWVIEW3D, 0); + } + else{ + if (mval[0]>=NLAWIDTH) + deselect_nlachannel_keys(1); + else{ + deselect_nlachannels(1); + allqueue (REDRAWVIEW3D, 0); + } + allqueue (REDRAWNLA, 0); + allqueue (REDRAWIPO, 0); + } + break; + case RIGHTMOUSE: + if (mval[0]>=NLAWIDTH) + mouse_nla(); + else + mouse_nlachannels(mval); + break; + case LEFTMOUSE: + if (mval[0]>NLAWIDTH){ + do { + getmouseco_areawin(mval); + + areamouseco_to_ipoco(G.v2d, mval, &dx, &dy); + + cfra= (int)dx; + if(cfra< 1) cfra= 1; + + if( cfra!=CFRA ) { + CFRA= cfra; + update_for_newframe(); + force_draw_plus(SPACE_VIEW3D); + force_draw_plus(SPACE_IPO); + } + + } while(get_mbut()&L_MOUSE); + } + + break; + case MIDDLEMOUSE: + view2dmove(); /* in drawipo.c */ + break; + } + } + + if(doredraw) scrarea_queue_winredraw(curarea); + } + return 0; +} + +void winqreadnlaspace(unsigned short event, short val, char ascii) +{ + NlaParam param; + Base *base; + bActionStrip *strip, *next; + short mval[2]; + float dx, dy; + int cfra; + + param.event = event; + param.val = val; + param.snla = curarea->spacedata.first; + + + /* Call the protected (&obfuscated) eventloop function */ + if (KEY_NLA_EVENT){ + KEY_NLA_EVENT(¶m); + } + else{ + getmouseco_areawin(mval); + switch(event) { + case GKEY: + case SKEY: + case AKEY: + case CKEY: + case NKEY: + case RIGHTMOUSE: + notice ("NLA window editing only available in Blender Publisher"); + break; + case LEFTMOUSE: + if (mval[0]>NLAWIDTH){ + do { + getmouseco_areawin(mval); + + areamouseco_to_ipoco(G.v2d, mval, &dx, &dy); + + cfra= (int)dx; + if(cfra< 1) cfra= 1; + + if( cfra!=CFRA ) { + CFRA= cfra; + update_for_newframe(); + force_draw_plus(SPACE_VIEW3D); + force_draw_plus(SPACE_IPO); + } + + } while(get_mbut()&L_MOUSE); + } + + break; + case MIDDLEMOUSE: + view2dmove(); /* in drawipo.c */ + break; + case DELKEY: + case XKEY: + if (okee ("This will remove all NLA information from all objects!")){ + for (base = G.scene->base.first; base; base=base->next){ + for (strip=base->object->nlastrips.first; strip; strip=next){ + next=strip->next; + free_actionstrip(strip); + BLI_freelinkN(&base->object->nlastrips, strip); + } + } + update_for_newframe(); + } + break; + + default: + break; + } + } +} + +static void convert_nla(short mval[2]) +{ + short event; + float ymax, ymin; + Base *base; + float x,y; + int sel=0; + bActionStrip *strip, *nstrip; + if (LICENSE_KEY_VALID){ + /* Find out what strip we're over */ + ymax = count_nla_levels() * (NLACHANNELSKIP+NLACHANNELHEIGHT); + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + + for (base=G.scene->base.first; base; base=base->next){ + if (nla_filter(base, 0)){ + /* Check object ipo */ + ymin=ymax-(NLACHANNELSKIP+NLACHANNELHEIGHT); + if (y>=ymin && y<=ymax) + break; + ymax=ymin; + + if (base->object->type==OB_ARMATURE){ + /* Check action ipo */ + ymin=ymax-(NLACHANNELSKIP+NLACHANNELHEIGHT); + if (y>=ymin && y<=ymax) + break; + ymax=ymin; + + /* Check nlastrips */ + for (strip=base->object->nlastrips.first; strip; strip=strip->next){ + ymin=ymax-(NLACHANNELSKIP+NLACHANNELHEIGHT); + if (y>=ymin && y<=ymax){ + sel = 1; + break; + } + ymax=ymin; + } + if (sel) + break; + } + } + } + + if (!base) + return; + + if (base->object->type==OB_ARMATURE){ + event = pupmenu("Convert%t|Action to NLAstrip%x1"); + switch (event){ + case 1: + if (base->object->action){ + /* Make new actionstrip */ + nstrip = MEM_callocN(sizeof(bActionStrip), "bActionStrip"); + + deselect_nlachannel_keys(0); + + /* Link the action to the nstrip */ + nstrip->act = base->object->action; + nstrip->actstart = calc_action_start(base->object->action); /* MAKE THIS THE FIRST FRAME OF THE ACTION */ + nstrip->actend = calc_action_end(base->object->action); + nstrip->start = nstrip->actstart; + nstrip->end = nstrip->actend; + nstrip->flag = ACTSTRIP_SELECT; + nstrip->repeat = 1.0; + + BLI_addtail(&base->object->nlastrips, nstrip); + + /* Unlink action */ + base->object->action = NULL; + + allqueue (REDRAWNLA, 0); + } + + + break; + default: + break; + } + } + } +} + +static void add_nlablock(short mval[2]) +{ + /* Make sure we are over an armature */ + Base *base; + bAction *act=NULL; + bActionStrip *strip; + int foundsel=0; + float ymin, ymax; + float x, y; + rctf rectf; + short event; + char *str; + short nr; + int cur; + + if (LICENSE_KEY_VALID){ + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + + mval[0]-=7; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + + mval[0]+=14; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + ymax = count_nla_levels(); + ymax*=(NLACHANNELHEIGHT + NLACHANNELSKIP); + + for (base=G.scene->base.first; base; base=base->next){ + /* Handle object ipo selection */ + if (nla_filter(base, 0)){ + + /* STUPID STUPID STUPID */ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); + + /* Handle object ipos */ + if (base->object->type==OB_ARMATURE){ + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) + break; + } + + ymax=ymin; + + /* Handle action ipos & Action strips */ + if (base->object->type==OB_ARMATURE){ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP)*(BLI_countlist(&base->object->nlastrips) + 1); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) + break; + ymax=ymin; + + + } + } + } + + /* Make sure we have an armature */ + if (!base){ + error ("Not an armature!"); + return; + } + + /* Popup action menu */ + IDnames_to_pupstring(&str, "Add action", NULL, &G.main->action, (ID *)G.scene, &nr); + + event = pupmenu(str); + + if (event!=-1){ + for (cur = 1, act=G.main->action.first; act; act=act->id.next, cur++){ + if (cur==event){ + break; + } + } + } + + MEM_freeN(str); + + /* Bail out if no action was chosen */ + if (!act){ + return; + } + + /* Initialize the new action block */ + strip = MEM_callocN(sizeof(bActionStrip), "bActionStrip"); + + deselect_nlachannel_keys(0); + + /* Link the action to the strip */ + strip->act = act; + strip->actstart = 1.0; + strip->actend = calc_action_end(act); + strip->start = G.scene->r.cfra; /* Should be mval[0] */ + strip->end = strip->start + (strip->actend-strip->actstart); + strip->flag = ACTSTRIP_SELECT; + strip->repeat = 1.0; + + act->id.us++; + + BLI_addtail(&base->object->nlastrips, strip); + } +} + +static void mouse_nlachannels(short mval[2]) +{ + /* Find which strip has been clicked */ +// bActionChannel *chan; + bConstraintChannel *conchan=NULL; + bActionStrip *strip; + float click; + int wsize; + int sel; + Base *base; + + wsize = (count_nla_levels ()*(NLACHANNELHEIGHT+NLACHANNELSKIP)); + + + click = (wsize-(mval[1]+G.v2d->cur.ymin)); + click += NLACHANNELHEIGHT/2; + click /= (NLACHANNELHEIGHT+NLACHANNELSKIP); + + if (click<0) + return; + + for (base = G.scene->base.first; base; base=base->next){ + if (nla_filter(base, 0)){ + /* See if this is a base selected */ + if ((int)click==0) + break; + + click--; + + /* Check for click in a constraint */ + for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next){ + if ((int)click==0){ + base=G.scene->base.last; + break; + } + click--; + } + + /* See if this is an action */ + if (base->object->type==OB_ARMATURE && base->object->action){ + if ((int)click==0){ + break; + } + click--; + } + + /* See if this is an nla strip */ + for (strip = base->object->nlastrips.first; strip; strip=strip->next){ + if ((int)click==0){ + base=G.scene->base.last; + break; + } + click--; + } + } + } + + if (!base && !conchan) + return; + + /* Handle constraint strip selection */ + if (conchan){ + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT) + sel = 0; + else + sel =1; + + /* Channel names clicking */ + if (G.qual & LR_SHIFTKEY){ + // select_poseelement_by_name(chan->name, !(chan->flag & ACHAN_SELECTED)); + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT){ + conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT; + // hilight_channel(act, chan, 0); + } + else{ + conchan->flag |= CONSTRAINT_CHANNEL_SELECT; + // hilight_channel(act, chan, 1); + } + } + else{ + deselect_nlachannels (0); // Auto clear + conchan->flag |= CONSTRAINT_CHANNEL_SELECT; + // hilight_channel(act, chan, 1); + // act->achan = chan; + // select_poseelement_by_name(chan->name, 1); + } + + } + + /* Handle object strip selection */ + else if (base) + { + /* Choose the mode */ + if (base->flag & SELECT) + sel = 0; + else + sel =1; + + /* Channel names clicking */ + if (G.qual & LR_SHIFTKEY){ + // select_poseelement_by_name(chan->name, !(chan->flag & ACHAN_SELECTED)); + if (base->flag & SELECT){ + base->flag &= ~SELECT; + // hilight_channel(act, chan, 0); + } + else{ + base->flag |= SELECT; + // hilight_channel(act, chan, 1); + } + } + else{ + deselect_nlachannels (0); // Auto clear + base->flag |= SELECT; + // hilight_channel(act, chan, 1); + // act->achan = chan; + // select_poseelement_by_name(chan->name, 1); + } + + } + allqueue (REDRAWIPO, 0); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + +} + +void init_nlaspace(ScrArea *sa) +{ + SpaceNla *snla; + + snla= MEM_callocN(sizeof(SpaceNla), "initnlaspace"); + BLI_addhead(&sa->spacedata, snla); + + snla->spacetype= SPACE_NLA; + + snla->v2d.tot.xmin= 1.0; + snla->v2d.tot.ymin= 0.0; + snla->v2d.tot.xmax= 1000.0; + snla->v2d.tot.ymax= 1000.0; + + snla->v2d.cur.xmin= -5.0; + snla->v2d.cur.ymin= 0.0; + snla->v2d.cur.xmax= 65.0; + snla->v2d.cur.ymax= 1000.0; + + snla->v2d.min[0]= 0.0; + snla->v2d.min[1]= 0.0; + + snla->v2d.max[0]= 1000.0; + snla->v2d.max[1]= 1000.0; + + snla->v2d.minzoom= 0.1F; + snla->v2d.maxzoom= 10; + + snla->v2d.scroll= R_SCROLL+B_SCROLL; + snla->v2d.keepaspect= 0; + snla->v2d.keepzoom= V2D_LOCKZOOM_Y; + snla->v2d.keeptot= 0; + + snla->lock = 0; +}; + +static void deselect_nlachannel_keys (int test) +{ + Base *base; + int sel=1; + bActionChannel *chan; + bActionStrip *strip; + bConstraintChannel *conchan; + + /* Determine if this is selection or deselection */ + if (LICENSE_KEY_VALID){ + if (test){ + for (base=G.scene->base.first; base && sel; base=base->next){ + + /* Test object ipos */ + if (is_ipo_key_selected(base->object->ipo)){ + sel = 0; + break; + } + + /* Test object constraint ipos */ + if (sel){ + for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next){ + if (is_ipo_key_selected(conchan->ipo)){ + sel=0; + break; + } + } + } + + /* Test action ipos */ + if (sel){ + if (base->object->type==OB_ARMATURE && base->object->action){ + for (chan=base->object->action->chanbase.first; chan; chan=chan->next){ + if (is_ipo_key_selected(chan->ipo)){ + sel=0; + break; + } + + /* Test action constraints */ + if (sel){ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + if (is_ipo_key_selected(conchan->ipo)){ + sel=0; + break; + } + } + } + } + } + } + + /* Test NLA strips */ + if (sel){ + if (base->object->type==OB_ARMATURE){ + for (strip=base->object->nlastrips.first; strip; strip=strip->next){ + if (strip->flag & ACTSTRIP_SELECT){ + sel = 0; + break; + } + } + } + } + } + } + else + sel=0; + + + /* Set the flags */ + for (base=G.scene->base.first; base; base=base->next){ + /* Set the object ipos */ + set_ipo_key_selection(base->object->ipo, sel); + + + /* Set the object constraint ipos */ + for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next){ + set_ipo_key_selection(conchan->ipo, sel); + } + + /* Set the action ipos */ + if (base->object->type==OB_ARMATURE && base->object->action){ + for (chan=base->object->action->chanbase.first; chan; chan=chan->next){ + set_ipo_key_selection(chan->ipo, sel); + /* Set the action constraint ipos */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + set_ipo_key_selection(conchan->ipo, sel); + } + } + + /* Set the nlastrips */ + if (base->object->type==OB_ARMATURE){ + for (strip=base->object->nlastrips.first; strip; strip=strip->next){ + if (sel) + strip->flag |= ACTSTRIP_SELECT; + else + strip->flag &= ~ACTSTRIP_SELECT; + } + } + } + } +} + + +static void transform_nlachannel_keys(char mode) +{ + Base *base; + TransVert *tv; + int /*sel=0,*/ i; + short mvals[2], mvalc[2]; + // short cent[2]; + float sval[2], cval[2], lastcval[2]; + short cancel=0; + float fac=0.0F; + int loop=1; + int tvtot=0; + float deltax, startx; + // float cenf[2]; + int invert=0, firsttime=1; + char str[256]; + bActionChannel *chan; + bActionStrip *strip; + bConstraintChannel *conchan; + + if (LICENSE_KEY_VALID){ + /* Ensure that partial selections result in beztriple selections */ + for (base=G.scene->base.first; base; base=base->next){ + + /* Check object ipos */ + tvtot+=fullselect_ipo_keys(base->object->ipo); + + /* Check object constraint ipos */ + for(conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next) + tvtot+=fullselect_ipo_keys(conchan->ipo); + + /* Check action ipos */ + if (base->object->type == OB_ARMATURE && base->object->action){ + for (chan=base->object->action->chanbase.first; chan; chan=chan->next){ + tvtot+=fullselect_ipo_keys(chan->ipo); + + /* Check action constraint ipos */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + tvtot+=fullselect_ipo_keys(conchan->ipo); + } + + } + + /* Check nlastrips */ + if (base->object->type==OB_ARMATURE){ + for (strip=base->object->nlastrips.first; strip; strip=strip->next){ + if (strip->flag & ACTSTRIP_SELECT) + tvtot+=2; + } + } + } + + /* If nothing is selected, bail out */ + if (!tvtot) + return; + + + /* Build the transvert structure */ + tv = MEM_callocN (sizeof(TransVert) * tvtot, "transVert"); + tvtot=0; + for (base=G.scene->base.first; base; base=base->next){ + /* Manipulate object ipos */ + tvtot=add_trans_ipo_keys(base->object->ipo, tv, tvtot); + + /* Manipulate object constraint ipos */ + for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next) + tvtot=add_trans_ipo_keys(conchan->ipo, tv, tvtot); + + /* Manipulate action ipos */ + if (base->object->type==OB_ARMATURE && base->object->action){ + for (chan=base->object->action->chanbase.first; chan; chan=chan->next){ + tvtot=add_trans_ipo_keys(chan->ipo, tv, tvtot); + + /* Manipulate action constraint ipos */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + tvtot=add_trans_ipo_keys(conchan->ipo, tv, tvtot); + } + } + + /* Manipulate nlastrips */ + for (strip=base->object->nlastrips.first; strip; strip=strip->next){ + if (strip->flag & ACTSTRIP_SELECT){ + tv[tvtot+0].val=&strip->start; + tv[tvtot+1].val=&strip->end; + + tv[tvtot+0].oldval = strip->start; + tv[tvtot+1].oldval = strip->end; + + tvtot+=2; + } + } + } + + /* Do the event loop */ + // cent[0] = curarea->winx + (G.snla->v2d.hor.xmax)/2; + // cent[1] = curarea->winy + (G.snla->v2d.hor.ymax)/2; + + // areamouseco_to_ipoco(cent, &cenf[0], &cenf[1]); + + getmouseco_areawin (mvals); + areamouseco_to_ipoco(G.v2d, mvals, &sval[0], &sval[1]); + + startx=sval[0]; + while (loop) { + /* Get the input */ + /* If we're cancelling, reset transformations */ + /* Else calc new transformation */ + /* Perform the transformations */ + while (qtest()) { + short val; + unsigned short event= extern_qread(&val); + + if (val) { + switch (event) { + case LEFTMOUSE: + case SPACEKEY: + case RETKEY: + loop=0; + break; + case XKEY: + break; + case ESCKEY: + case RIGHTMOUSE: + cancel=1; + loop=0; + break; + default: + arrows_move_cursor(event); + break; + }; + } + } + + if (cancel) { + for (i=0; i<tvtot; i++) { + if (tv[i].loc){ + tv[i].loc[0]=tv[i].oldloc[0]; + tv[i].loc[1]=tv[i].oldloc[1]; + } + if (tv[i].val) + tv[i].val[0]=tv[i].oldval; + } + } + else { + getmouseco_areawin (mvalc); + areamouseco_to_ipoco(G.v2d, mvalc, &cval[0], &cval[1]); + + if (!firsttime && lastcval[0]==cval[0] && lastcval[1]==cval[1]) { + PIL_sleep_ms(1); + } + else { + for (i=0; i<tvtot; i++){ + if (tv[i].loc) + tv[i].loc[0]=tv[i].oldloc[0]; + if (tv[i].val) + tv[i].val[0]=tv[i].oldval; + + switch (mode){ + case 'g': + deltax = cval[0]-sval[0]; + fac= deltax; + + apply_keyb_grid(&fac, 0.0F, 1.0F, 0.1F, U.flag & AUTOGRABGRID); + + if (tv[i].loc) + tv[i].loc[0]+=fac; + if (tv[i].val) + tv[i].val[0]+=fac; + break; + case 's': + startx=mvals[0]-(NLAWIDTH/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2); + deltax=mvalc[0]-(NLAWIDTH/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2); + fac= (float)fabs(deltax/startx); + + apply_keyb_grid(&fac, 0.0F, 0.2F, 0.1F, U.flag & AUTOSIZEGRID); + + if (invert){ + if (i % 03 == 0){ + memcpy (tv[i].loc, tv[i].oldloc, sizeof(tv[i+2].oldloc)); + } + if (i % 03 == 2){ + memcpy (tv[i].loc, tv[i].oldloc, sizeof(tv[i-2].oldloc)); + } + + fac*=-1; + } + startx= (G.scene->r.cfra); + + if (tv[i].loc){ + tv[i].loc[0]-= startx; + tv[i].loc[0]*=fac; + tv[i].loc[0]+= startx; + } + if (tv[i].val){ + tv[i].val[0]-= startx; + tv[i].val[0]*=fac; + tv[i].val[0]+= startx; + } + + break; + } + } + } + + if (mode=='s'){ + sprintf(str, "sizeX: %.3f", fac); + headerprint(str); + } + else if (mode=='g'){ + sprintf(str, "deltaX: %.3f", fac); + headerprint(str); + } + + if (G.snla->lock){ + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWNLA, 0); + allqueue (REDRAWIPO, 0); + force_draw_all(); + } + else { + addqueue (curarea->win, REDRAWALL, 0); + force_draw (); + } + } + + lastcval[0]= cval[0]; + lastcval[1]= cval[1]; + firsttime= 0; + } + + allspace(REMAKEALLIPO, 0); + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWNLA, 0); + allqueue (REDRAWIPO, 0); + MEM_freeN (tv); + } +} + +static void delete_nlachannel_keys(void) +{ + Base *base; + bActionChannel *chan; + bConstraintChannel *conchan; + bActionStrip *strip, *nextstrip; + + if (LICENSE_KEY_VALID){ + if (!okee("Erase selected keys")) + return; + + for (base = G.scene->base.first; base; base=base->next){ + + /* Delete object ipos */ + delete_ipo_keys(base->object->ipo); + + /* Delete object constraint keys */ + for(conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next) + delete_ipo_keys(conchan->ipo); + + /* Delete NLA strips */ + if (base->object->type==OB_ARMATURE){ + for (strip = base->object->nlastrips.first; strip; strip=nextstrip){ + nextstrip=strip->next; + if (strip->flag & ACTSTRIP_SELECT){ + free_actionstrip(strip); + BLI_remlink(&base->object->nlastrips, strip); + MEM_freeN(strip); + } + } + } + + /* Delete action ipos */ + if (base->object->type==OB_ARMATURE && base->object->action){ + for (chan=base->object->action->chanbase.first; chan; chan=chan->next){ + delete_ipo_keys(chan->ipo); + /* Delete action constraint keys */ + for(conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + delete_ipo_keys(conchan->ipo); + } + } + } + + allspace(REMAKEALLIPO, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWIPO, 0); + } +} + +static void duplicate_nlachannel_keys(void) +{ + Base *base; + bActionChannel *chan; + bConstraintChannel *conchan; + bActionStrip *strip, *laststrip; + if (LICENSE_KEY_VALID){ + + /* Find selected items */ + for (base = G.scene->base.first; base; base=base->next){ + /* Duplicate object keys */ + duplicate_ipo_keys(base->object->ipo); + + /* Duplicate object constraint keys */ + for(conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next) + duplicate_ipo_keys(conchan->ipo); + + /* Duplicate nla strips */ + if (base->object->type == OB_ARMATURE){ + laststrip = base->object->nlastrips.last; + for (strip=base->object->nlastrips.first; strip; strip=strip->next){ + if (strip->flag & ACTSTRIP_SELECT){ + bActionStrip *newstrip; + + copy_actionstrip(&newstrip, &strip); + + BLI_addtail(&base->object->nlastrips, newstrip); + + strip->flag &= ~ACTSTRIP_SELECT; + newstrip->flag |= ACTSTRIP_SELECT; + + } + if (strip==laststrip) + break; + } + } + + /* Duplicate actionchannel keys */ + if (base->object->type == OB_ARMATURE && base->object->action){ + for (chan=base->object->action->chanbase.first; chan; chan=chan->next){ + duplicate_ipo_keys(chan->ipo); + /* Duplicate action constraint keys */ + for(conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + duplicate_ipo_keys(conchan->ipo); + } + } + } + + transform_nlachannel_keys ('g'); + } +} + +static void borderselect_nla(void) +{ + Base *base; + rcti rect; + rctf rectf; + int val; + short mval[2]; + float ymin, ymax; + bActionStrip *strip; + bConstraintChannel *conchan; + + if (LICENSE_KEY_VALID){ + val= get_border (&rect, 3); + + if (val){ + mval[0]= rect.xmin; + mval[1]= rect.ymin+2; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + mval[0]= rect.xmax; + mval[1]= rect.ymax-2; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + ymax = count_nla_levels(); + ymax*= (NLACHANNELHEIGHT+NLACHANNELSKIP); + + for (base=G.scene->base.first; base; base=base->next){ + /* Check object ipos */ + if (nla_filter(base, 0)){ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); + if (base->object->ipo){ + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) + borderselect_ipo_key(base->object->ipo, rectf.xmin, rectf.xmax, val); + } + ymax=ymin; + + /* Check object constraint ipos */ + for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next){ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) + borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, val); + ymax=ymin; + } + + /* Check action ipos */ + if (ACTIVE_ARMATURE(base)){ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); + if (base->object->action){ + bActionChannel *chan; + + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){ + for (chan=base->object->action->chanbase.first; chan; chan=chan->next){ + borderselect_ipo_key(chan->ipo, rectf.xmin, rectf.xmax, val); + /* Check action constraint ipos */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, val); + } + } + } + ymax=ymin; + } /* End of if armature */ + + /* Skip nlastrips */ + if (base->object->type==OB_ARMATURE){ + for (strip=base->object->nlastrips.first; strip; strip=strip->next){ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); + // + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){ + if (!((rectf.xmax<strip->start) || (rectf.xmin>strip->end))){ + if (val==1) + strip->flag |= ACTSTRIP_SELECT; + else + strip->flag &= ~ACTSTRIP_SELECT; + } + } + + ymax=ymin; + } + } + + } /* End of object filter */ + } + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + } + } +} + +static void mouse_nla(void) +{ + short sel; + float selx; + short mval[2]; + Base *base; + bAction *act; + bActionChannel *chan; + bActionStrip *rstrip; + bConstraintChannel *conchan; + + if (LICENSE_KEY_VALID){ + getmouseco_areawin (mval); + + /* Try object ipo selection */ + base=get_nearest_nlachannel_ob_key(&selx, &sel); + if (base){ + if (!(G.qual & LR_SHIFTKEY)){ + deselect_nlachannel_keys(0); + sel = 0; + } + + select_ipo_key(base->object->ipo, selx, sel); + + /* Try object constraint selection */ + for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next) + select_ipo_key(conchan->ipo, selx, sel); + + + allqueue(REDRAWIPO, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWNLA, 0); + return; + } + + /* Try action ipo selection */ + act=get_nearest_nlachannel_ac_key(&selx, &sel); + if (act){ + if (!(G.qual & LR_SHIFTKEY)){ + deselect_nlachannel_keys(0); + sel = 0; + } + + for (chan=act->chanbase.first; chan; chan=chan->next){ + select_ipo_key(chan->ipo, selx, sel); + /* Try action constraint selection */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + select_ipo_key(conchan->ipo, selx, sel); + } + + allqueue(REDRAWIPO, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWNLA, 0); + return; + } + + /* Try nla strip selection */ + base=get_nearest_nlastrip(&rstrip, &sel); + if (base){ + if (!(G.qual & LR_SHIFTKEY)){ + deselect_nlachannel_keys(0); + sel = 0; + } + + if (sel) + rstrip->flag &= ~ACTSTRIP_SELECT; + else + rstrip->flag |= ACTSTRIP_SELECT; + + allqueue(REDRAWIPO, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWNLA, 0); + return; + + } + + } + +} + +static Base *get_nearest_nlastrip (bActionStrip **rstrip, short *sel) +/* This function is currently more complicated than it seems like it should be. +* However, this will be needed once the nla strip timeline is more complex */ +{ + Base *base, *firstbase=NULL; + short mval[2]; + short foundsel = 0; + rctf rectf; + float ymin, ymax; + bActionStrip *strip, *firststrip, *foundstrip; + + if (LICENSE_KEY_VALID){ + getmouseco_areawin (mval); + + mval[0]-=7; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + + mval[0]+=14; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + ymax = count_nla_levels(); + ymax*=(NLACHANNELHEIGHT + NLACHANNELSKIP); + + for (base = G.scene->base.first; base; base=base->next){ + if (nla_filter(base, 0)){ + /* Skip object ipos */ + // if (base->object->ipo) + ymax-=(NLACHANNELHEIGHT+NLACHANNELSKIP); + + if (base->object->type==OB_ARMATURE){ + /* Skip action ipos */ + if (base->object->action) + ymax-=(NLACHANNELHEIGHT+NLACHANNELSKIP); + + for (strip=base->object->nlastrips.first; strip; strip=strip->next){ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); + /* Do Ytest */ + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){ + /* Do XTest */ + if (!((rectf.xmax<strip->start) || (rectf.xmin>strip->end))){ + if (!firstbase){ + firstbase=base; + firststrip=strip; + *sel = strip->flag & ACTSTRIP_SELECT; + } + + if (strip->flag & ACTSTRIP_SELECT){ + if (!foundsel){ + foundsel=1; + foundstrip = strip; + } + } + else if (foundsel && strip != foundstrip){ + *rstrip=strip; + *sel = 0; + return base; + } + } + } + ymax=ymin; + } + } + } + } + *rstrip=firststrip; + return firstbase; + } + else + return NULL; +} + +static Base *get_nearest_nlachannel_ob_key (float *index, short *sel) +{ + Base *base; + IpoCurve *icu; + Base *firstbase=NULL; + bConstraintChannel *conchan; + int foundsel=0; + float firstvert=-1, foundx=-1; + int i; + short mval[2]; + float ymin, ymax; + rctf rectf; + + if (LICENSE_KEY_VALID){ + *index=0; + + getmouseco_areawin (mval); + + mval[0]-=7; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + + mval[0]+=14; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + ymax = count_nla_levels(); + + ymax*=(NLACHANNELHEIGHT + NLACHANNELSKIP); + + *sel=0; + + for (base=G.scene->base.first; base; base=base->next){ + /* Handle object ipo selection */ + if (nla_filter(base, 0)){ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); + if (base->object->ipo){ + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){ + for (icu=base->object->ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].vec[1][0] > rectf.xmin && icu->bezt[i].vec[1][0] <= rectf.xmax ){ + if (!firstbase){ + firstbase=base; + firstvert=icu->bezt[i].vec[1][0]; + *sel = icu->bezt[i].f2 & 1; + } + + if (icu->bezt[i].f2 & 1){ + if (!foundsel){ + foundsel=1; + foundx = icu->bezt[i].vec[1][0]; + } + } + else if (foundsel && icu->bezt[i].vec[1][0] != foundx){ + *index=icu->bezt[i].vec[1][0]; + *sel = 0; + return base; + } + } + } + } + } + } + + ymax=ymin; + + /* Handle object constraint ipos */ + for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next){ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){ + for (icu=conchan->ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].vec[1][0] > rectf.xmin && icu->bezt[i].vec[1][0] <= rectf.xmax ){ + if (!firstbase){ + firstbase=base; + firstvert=icu->bezt[i].vec[1][0]; + *sel = icu->bezt[i].f2 & 1; + } + + if (icu->bezt[i].f2 & 1){ + if (!foundsel){ + foundsel=1; + foundx = icu->bezt[i].vec[1][0]; + } + } + else if (foundsel && icu->bezt[i].vec[1][0] != foundx){ + *index=icu->bezt[i].vec[1][0]; + *sel = 0; + return base; + } + } + } + } + } + ymax=ymin; + } + + /* Skip action ipos */ + if (ACTIVE_ARMATURE(base)){ + ymax-=(NLACHANNELHEIGHT+NLACHANNELSKIP); + } + /* Skip nlastrips */ + if (base->object->type==OB_ARMATURE){ + ymax-=(NLACHANNELHEIGHT+NLACHANNELSKIP)*BLI_countlist(&base->object->nlastrips); + } + } + } + + *index=firstvert; + return firstbase; + } + else + return NULL; +} + +static bAction *get_nearest_nlachannel_ac_key (float *index, short *sel) +{ + Base *base; + IpoCurve *icu; + bAction *firstact=NULL; + int foundsel=0; + float firstvert=-1, foundx=-1; + int i; + short mval[2]; + float ymin, ymax; + rctf rectf; + bActionChannel *chan; + bConstraintChannel *conchan; + + if (LICENSE_KEY_VALID){ + *index=0; + + getmouseco_areawin (mval); + + mval[0]-=7; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + + mval[0]+=14; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + ymax = count_nla_levels(); + + ymax*=(NLACHANNELHEIGHT + NLACHANNELSKIP); + + *sel=0; + + for (base=G.scene->base.first; base; base=base->next){ + /* Handle object ipo selection */ + if (nla_filter(base, 0)){ + /* Skip object ipo */ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); + ymax=ymin; + + /* Handle action ipos */ + if (ACTIVE_ARMATURE(base)){ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){ + for (chan=base->object->action->chanbase.first; chan; chan=chan->next){ + for (icu=chan->ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].vec[1][0] > rectf.xmin && icu->bezt[i].vec[1][0] <= rectf.xmax ){ + if (!firstact){ + firstact=base->object->action; + firstvert=icu->bezt[i].vec[1][0]; + *sel = icu->bezt[i].f2 & 1; + } + + if (icu->bezt[i].f2 & 1){ + if (!foundsel){ + foundsel=1; + foundx = icu->bezt[i].vec[1][0]; + } + } + else if (foundsel && icu->bezt[i].vec[1][0] != foundx){ + *index=icu->bezt[i].vec[1][0]; + *sel = 0; + return base->object->action; + } + } + } + } + + + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){ + for (icu=conchan->ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].vec[1][0] > rectf.xmin && icu->bezt[i].vec[1][0] <= rectf.xmax ){ + if (!firstact){ + firstact=base->object->action; + firstvert=icu->bezt[i].vec[1][0]; + *sel = icu->bezt[i].f2 & 1; + } + + if (icu->bezt[i].f2 & 1){ + if (!foundsel){ + foundsel=1; + foundx = icu->bezt[i].vec[1][0]; + } + } + else if (foundsel && icu->bezt[i].vec[1][0] != foundx){ + *index=icu->bezt[i].vec[1][0]; + *sel = 0; + return base->object->action; + } + } + } + } + } + ymax=ymin; + } + + + } + } + ymax=ymin; + } + + /* Skip nlastrips */ + if (base->object->type==OB_ARMATURE){ + ymax-=(NLACHANNELHEIGHT+NLACHANNELSKIP)*BLI_countlist(&base->object->nlastrips); + } + } + } + + *index=firstvert; + return firstact; + } + else + return NULL; +} + +static bActionStrip *get_active_nlastrip(void) +/* For now just returns the first selected strip */ +{ + Base *base; + bActionStrip *strip; + + if (LICENSE_KEY_VALID){ + for (base=G.scene->base.first; base; base=base->next){ + if (nla_filter(base, 0) && base->object->type==OB_ARMATURE){ + for (strip=base->object->nlastrips.first; strip; strip=strip->next){ + if (strip->flag & ACTSTRIP_SELECT) + return strip; + } + } + } + + return NULL; + } + else + return NULL; +} + +void clever_numbuts_nla(void){ + bActionStrip *strip; + int but=0; + if (LICENSE_KEY_VALID){ + + /* Determine if an nla strip has been selected */ + strip = get_active_nlastrip(); + if (!strip) + return; + + add_numbut(but++, LABEL, "Timeline Range:", 1.0, 18000.0, 0, 0); + add_numbut(but++, NUM|FLO, "Strip Start:", 1.0, 18000.0, &strip->start, "First frame in the timeline"); + add_numbut(but++, NUM|FLO, "Strip End:", 1.0, 18000.0, &strip->end, "Last frame in the timeline"); + add_numbut(but++, LABEL, "Action Range:", 1.0, 18000.0, 0, 0); + add_numbut(but++, NUM|FLO, "Action Start:", 1.0, 18000.0, &strip->actstart, "First frame of the action to map to the playrange"); + add_numbut(but++, NUM|FLO, "Action End:", 1.0, 18000.0, &strip->actend, "Last frame of the action to map to the playrange"); + add_numbut(but++, LABEL, "Blending:", 1.0, 18000.0, 0, 0); + add_numbut(but++, NUM|FLO, "Blendin:", 0.0, 18000.0, &strip->blendin, "Number of frames of ease-in"); + add_numbut(but++, NUM|FLO, "Blendout:", 0.0, 18000.0, &strip->blendout, "Number of frames of ease-out"); + add_numbut(but++, LABEL, "Options:", 1.0, 18000.0, 0, 0); + add_numbut(but++, NUM|FLO, "Repeat:", 0.0001, 18000.0, &strip->repeat, "Number of times the action should repeat"); + add_numbut(but++, NUM|FLO, "Stride:", 0.0001, 1000.0, &strip->stridelen, "Distance covered by one complete cycle of the action specified in the Action Range"); + { + /* STUPID HACK BECAUSE NUMBUTS ARE BROKEN WITH MULTIPLE TOGGLES */ + short hold= (strip->flag & ACTSTRIP_HOLDLASTFRAME) ? 1 : 0; + short frompath=(strip->flag & ACTSTRIP_USESTRIDE) ? 1 : 0; + + add_numbut(but++, TOG|SHO, "Use Path", 0, 0, &frompath, "Plays action based on position on path & stride length. Only valid for armatures that are parented to a path"); + add_numbut(but++, TOG|SHO, "Hold", 0, 0, &hold, "Toggles whether or not to continue displaying the last frame past the end of the strip"); + add_numbut(but++, TOG|SHO, "Add", 0, 0, &strip->mode, "Toggles additive blending mode"); + + do_clever_numbuts("Action", but, REDRAW); + + /* STUPID HACK BECAUSE NUMBUTS ARE BROKEN WITH MULTIPLE TOGGLES */ + if (hold) strip->flag |= ACTSTRIP_HOLDLASTFRAME; + else strip->flag &= ~ACTSTRIP_HOLDLASTFRAME; + + if (frompath) strip->flag |= ACTSTRIP_USESTRIDE; + else strip->flag &= ~ACTSTRIP_USESTRIDE; + + } + + if (strip->end<strip->start) + strip->end=strip->start; + + + if (strip->blendin>(strip->end-strip->start)) + strip->blendin = strip->end-strip->start; + + if (strip->blendout>(strip->end-strip->start)) + strip->blendout = strip->end-strip->start; + + if (strip->blendin > (strip->end-strip->start-strip->blendout)) + strip->blendin = (strip->end-strip->start-strip->blendout); + + if (strip->blendout > (strip->end-strip->start-strip->blendin)) + strip->blendout = (strip->end-strip->start-strip->blendin); + + + update_for_newframe(); + allqueue (REDRAWNLA, 0); + allqueue (REDRAWVIEW3D, 0); + } +} + +static void deselect_nlachannels(int test){ + int sel = 1; + Base *base; + bConstraintChannel *conchan; + + if (test){ + for (base=G.scene->base.first; base; base=base->next){ + /* Check base flags for previous selection */ + if (base->flag & SELECT){ + sel=0; + break; + } + + /* Check constraint flags for previous selection */ + for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next){ + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT){ + sel=0; + base = G.scene->base.last; + break; + } + } + } + } + else + sel = 0; + + /* Select objects */ + for (base=G.scene->base.first; base; base=base->next){ + if (sel){ + if (nla_filter(base, 0)) + base->flag |= SELECT; + } + else + base->flag &= ~SELECT; + + /* Select constraint channels */ + for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next){ + if (sel){ + if (nla_filter(base, 0)) + conchan->flag |= CONSTRAINT_CHANNEL_SELECT; + } + else + conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT; + } + } +} + +static void delete_nlachannels(void){ + Base *base; + bConstraintChannel *conchan, *nextchan; + int sel=0; + + /* See if there is anything selected */ + for (base = G.scene->base.first; base && (!sel); base=base->next){ + /* Check constraints */ + for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next){ + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT){ + sel = 1; + break; + } + } + } + + if (!sel) + return; + + if (okee ("Delete selected channels")){ + for (base=G.scene->base.first; base; base=base->next){ + for (conchan=base->object->constraintChannels.first; conchan; conchan=nextchan){ + nextchan = conchan->next; + + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT){ + /* If we're the active constraint, unlink us */ + if (conchan==base->object->activecon) + base->object->activecon = NULL; + + if (conchan->ipo) + conchan->ipo->id.us--; + BLI_freelinkN(&base->object->constraintChannels, conchan); + } + } + } + } +}
\ No newline at end of file diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c new file mode 100644 index 00000000000..31f542a2b1b --- /dev/null +++ b/source/blender/src/editobject.c @@ -0,0 +1,5944 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/** + * Theorie: (matrices) A x B x C == A x ( B x C x Binv) x B + * ofwel: OB x PAR x EDIT = OB x (PAR x EDIT x PARinv) x PAR + */ + +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" +#include "PIL_time.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_ghash.h" + +#include "IMB_imbuf_types.h" + +#include "DNA_camera_types.h" +#include "DNA_curve_types.h" +#include "DNA_effect_types.h" +#include "DNA_ika_types.h" +#include "DNA_image_types.h" +#include "DNA_ipo_types.h" +#include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_lattice_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_texture_types.h" +#include "DNA_view3d_types.h" +#include "DNA_world_types.h" +#include "DNA_userdef_types.h" +#include "DNA_property_types.h" +#include "DNA_vfont_types.h" +#include "DNA_constraint_types.h" + +#include "BKE_nla.h" +#include "BKE_utildefines.h" +#include "BKE_anim.h" +#include "BKE_blender.h" +#include "BKE_curve.h" +#include "BKE_displist.h" +#include "BKE_effect.h" +#include "BKE_font.h" +#include "BKE_global.h" +#include "BKE_ika.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_lattice.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_mball.h" +#include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_property.h" +#include "BKE_sca.h" +#include "BKE_scene.h" +#include "BKE_subsurf.h" +#include "BKE_texture.h" +#include "BKE_booleanops.h" + +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_interface.h" +#include "BIF_mywindow.h" +#include "BIF_toolbox.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_buttons.h" +#include "BIF_editdeform.h" +#include "BIF_editfont.h" +#include "BIF_editika.h" +#include "BIF_editlattice.h" +#include "BIF_editmesh.h" +#include "BIF_editoops.h" +#include "BIF_editview.h" +#include "BIF_editarmature.h" + +#include "BSE_edit.h" +#include "BSE_editaction.h" +#include "BSE_editipo.h" +#include "BSE_filesel.h" /* For activate_databrowse() */ +#include "BSE_view.h" +#include "BSE_trans_types.h" +#include "BSE_editipo_types.h" + +#include "BDR_vpaint.h" +#include "BDR_editmball.h" +#include "BDR_editobject.h" +#include "BDR_drawobject.h" +#include "BDR_editcurve.h" + +#include "render.h" +#include <time.h> +#include "mydevice.h" +#include "nla.h" + +#include "blendef.h" +/* #include "graphics.h" */ +#include "interface.h" + +#include "BKE_constraint.h" +#include "BIF_editconstraint.h" + +#include "BKE_action.h" +#include "DNA_action_types.h" +#include "BKE_armature.h" +#include "DNA_armature_types.h" +#include "BIF_poseobject.h" + + +#include "license_key.h" // For functions behind the key + +/* extern Lattice *copy_lattice(Lattice *lt); */ +extern ListBase editNurb; +extern ListBase editelems; + +TransOb *transmain= 0; +TransVert *transvmain= 0; +int tottrans=0, transmode=0; /* 1: texspace */ + +float prop_size= 1.0; +int prop_mode= 0; +float prop_cent[3]; + +/* used in editipo, editcurve and here */ +#define BEZSELECTED(bezt) (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1)) + +#define TRANS_TEX 1 + +#define KEYFLAG_ROT 0x00000001 +#define KEYFLAG_LOC 0x00000002 +#define KEYFLAG_SIZE 0x00000004 + +float centre[3], centroid[3]; + +void add_object_draw(int type) /* voor toolbox */ +{ + Object *ob; + + G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT); + setcursor_space(SPACE_VIEW3D, CURSOR_STD); + + if ELEM3(curarea->spacetype, SPACE_VIEW3D, SPACE_BUTS, SPACE_INFO) { + if (G.obedit) exit_editmode(1); + ob= add_object(type); + base_init_from_view3d(BASACT, G.vd); + + if(type==OB_IKA) { + where_is_object(ob); + while(TRUE) { + if( extrude_ika(ob, 1) ) break; + } + + calc_ika(ob->data, 0); + init_defstate_ika(ob); + } + + allqueue(REDRAWVIEW3D, 0); + } + + redraw_test_buttons(BASACT); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION,0); + allqueue(REDRAWHEADERS, 0); + allqueue(REDRAWNLA, 0); + deselect_all_area_oops(); + set_select_flag_oops(); + allqueue(REDRAWINFO, 1); /* 1, want header->win==0! */ + +} + +void free_and_unlink_base(Base *base) +{ + if (base==BASACT) + BASACT= NULL; + + BLI_remlink(&G.scene->base, base); + free_libblock_us(&G.main->object, base->object); + MEM_freeN(base); +} + +void delete_obj(int ok) +{ + Base *base; + + if(G.obpose) return; + if(G.obedit) return; + if(G.scene->id.lib) return; + + base= FIRSTBASE; + while(base) { + Base *nbase= base->next; + + if TESTBASE(base) { + if(ok==0 && (ok=okee("ERASE SELECTED"))==0) return; + + free_and_unlink_base(base); + } + + base= nbase; + } + countall(); + + G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT); + setcursor_space(SPACE_VIEW3D, CURSOR_STD); + + test_scene_constraints(); + allqueue(REDRAWVIEW3D, 0); + redraw_test_buttons(BASACT); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWDATASELECT, 0); + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); +} + + +void make_track(void) +{ + Base *base; + + if(G.scene->id.lib) return; + if(G.obedit) { + return; + } + if(BASACT==0) return; + +#if 0 + /* Not yet */ + notice ("Make Track no longer supported. Use constraints instead."); + return; +#endif + + if(okee("Make Track")==0) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base!=BASACT) { + + base->object->track= BASACT->object; + } + } + base= base->next; + } + + test_scene_constraints(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); + sort_baselist(G.scene); +} + +void apply_obmat(Object *ob) +{ + float mat[3][3], imat[3][3], tmat[3][3]; + + /* from obmat to loc rot size */ + + if(ob==0) return; + Mat3CpyMat4(mat, ob->obmat); + + VECCOPY(ob->loc, ob->obmat[3]); + + if(ob->transflag & OB_QUAT) { + Mat3ToQuat(mat, ob->quat); + QuatToMat3(ob->quat, tmat); + } + else { + Mat3ToEul(mat, ob->rot); + EulToMat3(ob->rot, tmat); + } + Mat3Inv(imat, tmat); + + Mat3MulMat3(tmat, imat, mat); + + ob->size[0]= tmat[0][0]; + ob->size[1]= tmat[1][1]; + ob->size[2]= tmat[2][2]; + +} + +void clear_parent(void) +{ + Object *par; + Base *base; + int mode; + + if(G.obedit) return; + if(G.scene->id.lib) return; + + mode= pupmenu("OK? %t|Clear Parent %x1| ... and keep transform (clr track) %x2|Clear parent inverse %x3"); + + if(mode<1) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + par= 0; + if(mode==1 || mode==2) { + if(base->object->type==OB_IKA) { + Ika *ika= base->object->data; + ika->parent= 0; + } + par= base->object->parent; + base->object->parent= 0; + + if(mode==2) { + base->object->track= 0; + apply_obmat(base->object); + } + } + else if(mode==3) { + Mat4One(base->object->parentinv); + } + + if(par) { + if(par->type==OB_LATTICE) makeDispList(base->object); + if(par->type==OB_IKA) makeDispList(base->object); + if(par->type==OB_ARMATURE) makeDispList(base->object); + } + } + base= base->next; + } + + test_scene_constraints(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); +} + +void clear_track(void) +{ + Base *base; + int mode; + + if(G.obedit) return; + if(G.scene->id.lib) return; + + mode= pupmenu("OK? %t|Clear Track %x1| ... and keep transform %x2"); + + if(mode<1) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + base->object->track= 0; + + if(mode==2) { + apply_obmat(base->object); + } + } + base= base->next; + } + test_scene_constraints(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); +} + +void clear_object(char mode) +{ + Base *base; + float *v1, *v3, mat[3][3]; + + if(G.obedit) return; + if(G.scene->id.lib) return; + + if(mode=='r' && okee("Clear rotation")==0) return; + else if(mode=='g' && okee("Clear location")==0) return; + else if(mode=='s' && okee("Clear size")==0) return; + else if(mode=='o' && okee("Clear origin")==0) return; + + if (G.obpose){ + + switch (G.obpose->type){ + case OB_ARMATURE: + clear_armature (G.obpose, mode); +#if 1 + make_displists_by_armature (G.obpose); +#endif + break; + } + + allqueue(REDRAWVIEW3D, 0); + return; + } + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(mode=='r') { + memset(base->object->rot, 0, 3*sizeof(float)); + memset(base->object->drot, 0, 3*sizeof(float)); + QuatOne(base->object->quat); + QuatOne(base->object->dquat); + } + else if(mode=='g') { + memset(base->object->loc, 0, 3*sizeof(float)); + memset(base->object->dloc, 0, 3*sizeof(float)); + } + else if(mode=='s') { + memset(base->object->dsize, 0, 3*sizeof(float)); + base->object->size[0]= 1.0; + base->object->size[1]= 1.0; + base->object->size[2]= 1.0; + } + else if(mode=='o') { + if(base->object->parent) { + v1= base->object->loc; + v3= base->object->parentinv[3]; + + Mat3CpyMat4(mat, base->object->parentinv); + VECCOPY(v3, v1); + v3[0]= -v3[0]; + v3[1]= -v3[1]; + v3[2]= -v3[2]; + Mat3MulVecfl(mat, v3); + } + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); +} + +void reset_slowparents(void) +{ + /* terug op correcte plek */ + Base *base; + + base= FIRSTBASE; + while(base) { + if(base->object->parent) { + if(base->object->partype & PARSLOW) { + base->object->partype -= PARSLOW; + where_is_object(base->object); + base->object->partype |= PARSLOW; + } + } + base= base->next; + } +} + +void set_slowparent(void) +{ + Base *base; + + if( okee("Set Slow parent")==0 ) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base->object->parent) base->object->partype |= PARSLOW; + } + base= base->next; + } + +} + +void make_vertex_parent(void) +{ + EditVert *eve; + Base *base; + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + Object *par, *ob; + int a, v1=0, v2=0, v3=0, nr=1; + + /* er moet 1 of 3 vertices select zijn */ + + if(G.obedit->type==OB_MESH) { + eve= G.edve.first; + while(eve) { + if(eve->f & 1) { + if(v1==0) v1= nr; + else if(v2==0) v2= nr; + else if(v3==0) v3= nr; + else break; + } + nr++; + eve= eve->next; + } + } + else if ELEM(G.obedit->type, OB_SURF, OB_CURVE) { + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(BEZSELECTED(bezt)) { + if(v1==0) v1= nr; + else if(v2==0) v2= nr; + else if(v3==0) v3= nr; + else break; + } + nr++; + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->f1 & SELECT) { + if(v1==0) v1= nr; + else if(v2==0) v2= nr; + else if(v3==0) v3= nr; + else break; + } + nr++; + bp++; + } + } + nu= nu->next; + } + + } + + if( !(v1 && v2==0 && v3==0) && !(v1 && v2 && v3) ) { + error("select 1 or 3 vertices"); + return; + } + + if(okee("Make vertex-parent")==0) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base!=BASACT) { + ob= base->object; + par= BASACT->object->parent; + + while(par) { + if(par==ob) break; + par= par->parent; + } + if(par) { + error("Loop in parents"); + } + else { + ob->parent= BASACT->object; + if(v3) { + ob->partype= PARVERT3; + ob->par1= v1-1; + ob->par2= v2-1; + ob->par3= v3-1; + + /* inverse parent matrix berekenen */ + what_does_parent(ob); + Mat4Invert(ob->parentinv, workob.obmat); + clear_workob(); + } + else { + ob->partype= PARVERT1; + ob->par1= v1-1; + + /* inverse parent matrix berekenen */ + what_does_parent(ob); + Mat4Invert(ob->parentinv, workob.obmat); + clear_workob(); + } + } + } + } + base= base->next; + } + allqueue(REDRAWVIEW3D, 0); + +} + +int test_parent_loop(Object *par, Object *ob) +{ + /* test if 'ob' is a parent somewhere in par's parents */ + + if(par==0) return 0; + if(ob == par) return 1; + + if(par->type==OB_IKA) { + Ika *ika= par->data; + + if( ob == ika->parent ) return 1; + if( test_parent_loop(ika->parent, ob) ) return 1; + } + + return test_parent_loop(par->parent, ob); + +} + +void make_parent(void) +{ + Base *base; + Object *par; + Ika *ika; + short qual, ok, mode=0, limbnr=0, effchild=0; + char *bonestr=NULL; + Bone *bone=NULL; + int bonenr; + + if(G.scene->id.lib) return; + if(G.obedit) { + if ELEM3(G.obedit->type, OB_MESH, OB_CURVE, OB_SURF) make_vertex_parent(); + else if (G.obedit->type==OB_ARMATURE) make_bone_parent(); + return; + } + if(BASACT==0) return; + + qual= G.qual; + par= BASACT->object; + + if(par->type==OB_IKA) { + + if(qual & LR_SHIFTKEY) + mode= pupmenu("Make Parent without inverse%t|Use Vertex %x1|Use Limb %x2|Use Skeleton %x3"); + else + mode= pupmenu("Make Parent %t|Use Vertex %x1|Use Limb %x2|Use Skeleton %x3"); + + if(mode==1) { + draw_ika_nrs(par, 0); + if(button(&limbnr, 0, 99, "Vertex: ")==0) { + allqueue(REDRAWVIEW3D, 0); + return; + } + } + else if(mode==2) { + draw_ika_nrs(par, 1); + if(button(&limbnr, 0, 99, "Limb: ")==0) { + allqueue(REDRAWVIEW3D, 0); + return; + } + } + else if(mode==3) { + ika= par->data; + if(ika->def==0) { + error("No skeleton available: use CTRL K"); + return; + } + } + else return; + + if(mode==1) mode= PARVERT1; + else if(mode==2) mode= PARLIMB; + else if(mode==3) mode= PARSKEL; + + /* test effchild */ + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base->object->type==OB_IKA && base->object!=par && mode==PARVERT1 ) { + if(effchild==0) { + if(okee("Effector as Child")) effchild= 1; + else effchild= 2; + } + } + } + if(effchild) break; + base= base->next; + } + } + else if(par->type == OB_ARMATURE){ + mode= pupmenu("Make Parent %t|Use Bone %x1|Use Armature %x2|Use Object %x3"); + switch (mode){ + case 1: + mode=PARBONE; + /* Make bone popup menu */ + + bonestr = make_bone_menu(get_armature(par)); + // if(mbutton(&bone, bonestr, 1, 24, "Bone: ")==0) { + + bonenr= pupmenu_col(bonestr, 20); + if (bonestr) + MEM_freeN (bonestr); + + if (bonenr==-1){ + allqueue(REDRAWVIEW3D, 0); + return; + } + + apply_pose_armature(get_armature(par), par->pose, 0); + bone=get_indexed_bone(get_armature(par), bonenr); + if (!bone){ + // error ("Invalid bone! Warn reevan@blender.nl"); + allqueue(REDRAWVIEW3D, 0); + return; + } + + break; + case 2: + mode=PARSKEL; + break; + case 3: + mode=PAROBJECT; + break; + default: + return; + } + } + else { + if(qual & LR_SHIFTKEY) { + if(okee("Make Parent without inverse")==0) return; + } + else { + if(qual & LR_ALTKEY) { + if(okee("Make VertexParent")==0) return; + } + else if(okee("Make Parent")==0) return; + + /* test effchild */ + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base->object->type==OB_IKA && base->object != par) { + if(effchild==0) { + if(okee("Effector as Child")) effchild= 1; + else effchild= 2; + } + } + } + if(effchild) break; + base= base->next; + } + + /* nu gaan we alle objecten clearparentandkeeptransformen */ + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base!=BASACT && base->object->parent) { + if(base->object->type==OB_IKA && effchild==1); + else { + base->object->parent= 0; + apply_obmat(base->object); + } + } + } + base= base->next; + } + } + } + + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base!=BASACT) { + + ok= 1; + if(base->object->type==OB_IKA) { + + if(effchild==1) { + + if( test_parent_loop(par, base->object)==0 ) { + + Ika *ika= base->object->data; + + ika->parent= par; + ika->par1= limbnr; + ika->partype= mode; + itterate_ika(base->object); + ok= 0; + } + else { + ok= 0; + error("Loop in parents"); + } + } + } + + if(ok) { + if( test_parent_loop(par, base->object) ) { + error("Loop in parents"); + } + else { + + if(par->type==OB_IKA){ + base->object->partype= mode; + base->object->par1= limbnr; + } + else if (par->type==OB_ARMATURE){ + base->object->partype= mode; + if (bone) + strcpy (base->object->parsubstr, bone->name); + else + base->object->parsubstr[0]=0; + } + + else if(qual & LR_ALTKEY) { + base->object->partype= PARVERT1; + } + else { + base->object->partype= PAROBJECT; + } + + base->object->parent= par; + + /* inverse parent matrix berekenen? */ + if( (qual & LR_SHIFTKEY) ) { + /* niet dus... */ + Mat4One(base->object->parentinv); + memset(base->object->loc, 0, 3*sizeof(float)); + } + else { + if(mode==PARSKEL && par->type == OB_ARMATURE) { + base->object->partype= PAROBJECT; + what_does_parent(base->object); + Mat4One (base->object->parentinv); + base->object->partype= mode; + } + else + what_does_parent(base->object); + Mat4Invert(base->object->parentinv, workob.obmat); + } + + if(par->type==OB_LATTICE) makeDispList(base->object); + if(par->type==OB_IKA && mode==PARSKEL) makeDispList(base->object); + if(par->type==OB_ARMATURE && mode == PARSKEL){ + verify_defgroups(base->object); + makeDispList(base->object); + } + } + } + } + } + base= base->next; + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); + + test_scene_constraints(); + sort_baselist(G.scene); +} + + +void enter_editmode(void) +{ + Base *base; + Object *ob; + Ika *ika; + ID *id; + Mesh *me; + int ok= 0; + bArmature *arm; + + if(G.scene->id.lib) return; + base= BASACT; + if(base==0) return; + if((base->lay & G.vd->lay)==0) return; + + ob= base->object; + if(ob->data==0) return; + + id= ob->data; + if(id->lib) { + error("Can't edit libdata"); + return; + } + + if(ob->type==OB_MESH) { + me= get_mesh(ob); + if( me==0 ) return; + if(me->id.lib) { + error("Can't edit libdata"); + return; + } + ok= 1; + G.obedit= ob; + make_editMesh(); + allqueue(REDRAWBUTSGAME, 0); + } + if (ob->type==OB_ARMATURE){ + arm=base->object->data; + if (!arm) return; + if (arm->id.lib){ + error("Can't edit libdata"); + return; + } + ok=1; + G.obedit=ob; + make_editArmature(); + allqueue (REDRAWVIEW3D,0); + } + else if(ob->type==OB_IKA) { /* grabtype */ + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + if(base->object->type==OB_IKA) { + ika= base->object->data; + if(ika->flag & IK_GRABEFF) ika->flag &= ~IK_GRABEFF; + else ika->flag |= IK_GRABEFF; + } + } + base= base->next; + } + allqueue(REDRAWVIEW3D, 0); + } + else if(ob->type==OB_FONT) { + G.obedit= ob; + ok= 1; + make_editText(); + } + else if(ob->type==OB_MBALL) { + G.obedit= ob; + ok= 1; + make_editMball(); + } + else if(ob->type==OB_LATTICE) { + G.obedit= ob; + ok= 1; + make_editLatt(); + } + else if(ob->type==OB_SURF || ob->type==OB_CURVE) { + ok= 1; + G.obedit= ob; + make_editNurb(); + } + allqueue(REDRAWBUTSEDIT, 0); + countall(); + + if(ok) { + setcursor_space(SPACE_VIEW3D, CURSOR_EDIT); + + allqueue(REDRAWVIEW3D, 0); + } + else G.obedit= 0; + + if (G.obpose) + exit_posemode (1); + scrarea_queue_headredraw(curarea); +} + +void make_displists_by_parent(Object *ob) { + Base *base; + + for (base= FIRSTBASE; base; base= base->next) + if (ob==base->object->parent) + makeDispList(base->object); +} + +void exit_editmode(int freedata) /* freedata==0 bij render */ +{ + Base *base; + Object *ob; + Curve *cu; + + if(G.obedit==0) return; + + if(G.obedit->type==OB_MESH) { + + /* tijdelijk */ + countall(); + if(G.totvert>65000) { + error("too many vertices"); + return; + } + load_editMesh(); + + if(freedata) free_editMesh(); + if(G.f & G_FACESELECT) allqueue(REDRAWIMAGE, 0); + + build_particle_system(G.obedit); + } + else if (G.obedit->type==OB_ARMATURE){ + load_editArmature(); + if (freedata) free_editArmature(); + } + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + load_editNurb(); + if(freedata) freeNurblist(&editNurb); + } + else if(G.obedit->type==OB_FONT && freedata==1) { + load_editText(); + } + else if(G.obedit->type==OB_LATTICE) { + load_editLatt(); + if(freedata) free_editLatt(); + } + else if(G.obedit->type==OB_MBALL) { + load_editMball(); + if(freedata) BLI_freelistN(&editelems); + } + + ob= G.obedit; + + /* obedit moet 0 zijn voor curve-extrude, niet voor smeshes */ + if(ob->type==OB_CURVE) G.obedit= 0; + G.obedit= 0; + makeDispList(ob); + + + + /* heeft dit nog invloed op andere bases? */ + if(ob->type==OB_CURVE) { + + /* test of ob als bevelcurve of textoncurve wordt gebruikt */ + base= FIRSTBASE; + while(base) { + if ELEM(base->object->type, OB_CURVE, OB_FONT) { + cu= base->object->data; + + if(cu->textoncurve==ob) { + text_to_curve(base->object, 0); + makeDispList(base->object); + } + if(cu->bevobj== ob) { + makeDispList(base->object); + } + } + base= base->next; + } + + } + else if(ob->type==OB_LATTICE) { + make_displists_by_parent(ob); + } + + if(freedata) { + setcursor_space(SPACE_VIEW3D, CURSOR_STD); + + countall(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSGAME, 0); + } + else { + G.obedit= ob; + } + scrarea_queue_headredraw(curarea); + +} + +void check_editmode(int type) +{ + + if (G.obedit==0 || G.obedit->type==type) return; + + exit_editmode(1); +} + +static int centremode= 0; /* 0 == do centre, 1 == centre new, 2 == centre cursor */ + +void docentre(void) +{ + Base *base; + Object *ob; + Mesh *me, *tme; + Curve *cu; + MVert *mvert; +// BezTriple *bezt; +// BPoint *bp; + Nurb *nu, *nu1; + EditVert *eve; + float cent[3], centn[3], min[3], max[3], omat[3][3]; + int a; + + if(G.scene->id.lib) return; + + if(G.obedit) { + + INIT_MINMAX(min, max); + + if(G.obedit->type==OB_MESH) { + eve= G.edve.first; + while(eve) { + DO_MINMAX(eve->co, min, max); + eve= eve->next; + } + cent[0]= (min[0]+max[0])/2.0; + cent[1]= (min[1]+max[1])/2.0; + cent[2]= (min[2]+max[2])/2.0; + + eve= G.edve.first; + while(eve) { + VecSubf(eve->co, eve->co, cent); + eve= eve->next; + } + } + } + + /* vlaggen resetten */ + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + base->object->flag &= ~OB_DONE; + } + base= base->next; + } + me= G.main->mesh.first; + while(me) { + me->flag &= ~ME_ISDONE; + me= me->id.next; + } + + base= FIRSTBASE; + while(base) { + + if TESTBASELIB(base) { + if((base->object->flag & OB_DONE)==0) { + + base->object->flag |= OB_DONE; + + if(G.obedit==0 && (me=get_mesh(base->object)) ) { + + if(me->key) { + error("Mesh with vertexkey!"); + return; + } + + if(centremode==2) { + VECCOPY(cent, give_cursor()); + Mat4Invert(base->object->imat, base->object->obmat); + Mat4MulVecfl(base->object->imat, cent); + } else { + INIT_MINMAX(min, max); + + mvert= me->mvert; + for(a=0; a<me->totvert; a++, mvert++) { + DO_MINMAX(mvert->co, min, max); + } + + cent[0]= (min[0]+max[0])/2.0; + cent[1]= (min[1]+max[1])/2.0; + cent[2]= (min[2]+max[2])/2.0; + } + + mvert= me->mvert; + for(a=0; a<me->totvert; a++, mvert++) { + VecSubf(mvert->co, mvert->co, cent); + } + me->flag |= ME_ISDONE; + + if(centremode) { + Mat3CpyMat4(omat, base->object->obmat); + + VECCOPY(centn, cent); + Mat3MulVecfl(omat, centn); + base->object->loc[0]+= centn[0]; + base->object->loc[1]+= centn[1]; + base->object->loc[2]+= centn[2]; + + /* andere users? */ + ob= G.main->object.first; + while(ob) { + if((ob->flag & OB_DONE)==0) { + tme= get_mesh(ob); + + if(tme==me) { + + ob->flag |= OB_DONE; + + Mat3CpyMat4(omat, ob->obmat); + VECCOPY(centn, cent); + Mat3MulVecfl(omat, centn); + ob->loc[0]+= centn[0]; + ob->loc[1]+= centn[1]; + ob->loc[2]+= centn[2]; + + if(tme && (tme->flag & ME_ISDONE)==0) { + mvert= tme->mvert; + for(a=0; a<tme->totvert; a++, mvert++) { + VecSubf(mvert->co, mvert->co, cent); + } + tme->flag |= ME_ISDONE; + } + } + } + + ob= ob->id.next; + } + } + + /* displisten van alle users, ook deze base */ + makeDispList(base->object); + + /* DOEN: alle users aflopen... */ + tex_space_mesh(me); + + } + else if ELEM(base->object->type, OB_CURVE, OB_SURF) { + + if(G.obedit) { + nu1= editNurb.first; + } + else { + cu= base->object->data; + nu1= cu->nurb.first; + } + + if(centremode==2) { + VECCOPY(cent, give_cursor()); + Mat4Invert(base->object->imat, base->object->obmat); + Mat4MulVecfl(base->object->imat, cent); + + /* Curves need to be 2d, never offset in + * Z. Is a somewhat arbitrary restriction, + * would probably be nice to remove. + */ + cent[2]= 0.0; + } else { + INIT_MINMAX(min, max); + + nu= nu1; + while(nu) { + minmaxNurb(nu, min, max); + nu= nu->next; + } + + cent[0]= (min[0]+max[0])/2.0; + cent[1]= (min[1]+max[1])/2.0; + cent[2]= (min[2]+max[2])/2.0; + } + + nu= nu1; + while(nu) { + if( (nu->type & 7)==1) { + a= nu->pntsu; + while (a--) { + VecSubf(nu->bezt[a].vec[0], nu->bezt[a].vec[0], cent); + VecSubf(nu->bezt[a].vec[1], nu->bezt[a].vec[1], cent); + VecSubf(nu->bezt[a].vec[2], nu->bezt[a].vec[2], cent); + } + } + else { + a= nu->pntsu*nu->pntsv; + while (a--) + VecSubf(nu->bp[a].vec, nu->bp[a].vec, cent); + } + nu= nu->next; + } + + if(centremode && G.obedit==0) { + Mat3CpyMat4(omat, base->object->obmat); + + Mat3MulVecfl(omat, cent); + base->object->loc[0]+= cent[0]; + base->object->loc[1]+= cent[1]; + base->object->loc[2]+= cent[2]; + } + + if(G.obedit) { + makeDispList(G.obedit); + break; + } + else makeDispList(base->object); + + } + else if(base->object->type==OB_FONT) { + /* uit de bb halen */ + + cu= base->object->data; + if(cu->bb==0) return; + + cu->xof= -0.5*( cu->bb->vec[4][0] - cu->bb->vec[0][0]); + cu->yof= -0.5 -0.5*( cu->bb->vec[0][1] - cu->bb->vec[2][1]); /* extra 0.5 is de hoogte van de bovenste regel */ + + /* klopt niet helemaal, een keer goed doen! */ + cu->xof /= cu->fsize; + cu->yof /= cu->fsize; + + text_to_curve(base->object, 0); + makeDispList(base->object); + + allqueue(REDRAWBUTSEDIT, 0); + } + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); +} + +void docentre_new(void) +{ + if(G.scene->id.lib) return; + + if(G.obedit) { + error("Unable to perform function in EditMode"); + } + else { + centremode= 1; + docentre(); + centremode= 0; + } +} + +void docentre_cursor(void) +{ + if(G.scene->id.lib) return; + + if(G.obedit) { + error("Unable to perform function in EditMode"); + } + else { + centremode= 2; + docentre(); + centremode= 0; + } +} + +void movetolayer(void) +{ + Base *base; + unsigned int lay= 0, local; + + if(G.scene->id.lib) return; + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) lay |= base->lay; + base= base->next; + } + if(lay==0) return; + lay &= 0xFFFFFF; + + if( movetolayer_buts(&lay)==0 ) return; + if(lay==0) return; + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + local= base->lay & 0xFF000000; + base->lay= lay + local; + + base->object->lay= lay; + } + base= base->next; + } + countall(); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWINFO, 0); +} + + +void special_editmenu(void) +{ + extern short editbutflag; + extern float doublimit; + float fac; + int nr; + short randfac; + + if(G.obedit==0) { + if(G.f & G_FACESELECT) { + Mesh *me= get_mesh(OBACT); + TFace *tface; + int a; + + if(me==0 || me->tface==0) return; + + nr= pupmenu("Specials%t|Set Tex%x1| Shared%x2| Light%x3| Invisible%x4| Collision%x5|Clr Tex%x6| Shared%x7| Light%x8| Invisible%x9| Collision%x10"); + + for(a=me->totface, tface= me->tface; a>0; a--, tface++) { + if(tface->flag & SELECT) { + switch(nr) { + case 1: + tface->mode |= TF_TEX; break; + case 2: + tface->mode |= TF_SHAREDCOL; break; + case 3: + tface->mode |= TF_LIGHT; break; + case 4: + tface->mode |= TF_INVISIBLE; break; + case 5: + tface->mode |= TF_DYNAMIC; break; + case 6: + tface->mode &= ~TF_TEX; + tface->tpage= 0; + break; + case 7: + tface->mode &= ~TF_SHAREDCOL; break; + case 8: + tface->mode &= ~TF_LIGHT; break; + case 9: + tface->mode &= ~TF_INVISIBLE; break; + case 10: + tface->mode &= ~TF_DYNAMIC; break; + } + } + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSGAME, 0); + } + else if(G.f & G_VERTEXPAINT) { + Mesh *me= get_mesh(OBACT); + + if(me==0 || (me->mcol==NULL && me->tface==NULL) ) return; + + nr= pupmenu("Specials%t|Shared VertexCol%x1"); + if(nr==1) { + + if(me->tface) tface_to_mcol(me); + + copy_vpaint_undo( (unsigned int *)me->mcol, me->totface); + do_shared_vertexcol(me); + + if(me->tface) mcol_to_tface(me, 1); + } + } + else { + Base *base, *base_select= NULL; + + // Get the active object mesh. + Mesh *me= get_mesh(OBACT); + + // If the active object is a mesh and license key valid.. + if(me && LICENSE_KEY_VALID) { + // Bring up a little menu with the boolean operation choices on. + nr= pupmenu("Boolean %t|Intersect%x1|Union%x2|Difference%x3"); + + if (nr > 0) { + // user has made a choice of a menu element. + // All of the boolean functions require 2 mesh objects + // we search through the object list to find the other + // selected item and make sure it is distinct and a mesh. + + base= FIRSTBASE; + while(base) { + if(base->flag & SELECT) { + if(base->object != OBACT) base_select= base; + } + + base= base->next; + } + + if (base_select) { + if (get_mesh(base_select->object)) { + waitcursor(1); + + if (!NewBooleanMesh(BASACT,base_select,nr)) { + error("An internal error occurred -- sorry!"); + } + + waitcursor(0); + } else { + error("Please select 2 meshes"); + } + } else { + error("Please select 2 meshes"); + } + } + + allqueue(REDRAWVIEW3D, 0); + } + } + } + else if(G.obedit->type==OB_MESH) { + + nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Fractal%x2|Subdivide Smooth%x3|Remove Doubles%x4|Hide%x5|Reveal%x6|Select swap%x7|Flip Normals %x8|Smooth %x9"); + if(nr>0) waitcursor(1); + + switch(nr) { + case 1: + subdivideflag(1, 0.0, editbutflag); + break; + case 2: + randfac= 10; + if(button(&randfac, 1, 100, "Rand fac:")==0) return; + fac= -( (float)randfac )/100; + subdivideflag(1, fac, editbutflag); + break; + case 3: + subdivideflag(1, 0.0, editbutflag | B_SMOOTH); + break; + case 4: + notice("Removed: %d\n", removedoublesflag(1, doublimit)); + break; + case 5: + hide_mesh(0); + break; + case 6: + reveal_mesh(); + break; + case 7: + selectswap_mesh(); + break; + case 8: + flip_editnormals(); + break; + case 9: + vertexsmooth(); + break; + } + + makeDispList(G.obedit); + + if(nr>0) waitcursor(0); + + } +/* else if (G.obedit->type==OB_ARMATURE){ + nr= pupmenu("Specials%t|"); + if (nr>0) waitcursor (1); + switch (nr){ + case 1: + } + if (nr>0) waitcursor (0); + } +*/ + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + + /* nr= pupmenu("Specials%t|Subdivide%x1|Hide%x5|Reveal%x6|Select swap%x7"); */ + nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2"); + + switch(nr) { + case 1: + subdivideNurb(); + break; + case 2: + switchdirectionNurb2(); + break; + } + } + + + + + countall(); + allqueue(REDRAWVIEW3D, 0); + +} + +void convertmenu(void) +{ + Base *base, *basen, *basact; + Object *ob, *ob1; + Curve *cu; + MetaBall *mb; + Mesh *me; + DispList *dl; + int ok=0, nr = 0, a; + + if(G.scene->id.lib) return; + + ob= OBACT; + if(ob==0) return; + if(G.obedit) return; + + basact= BASACT; /* will be restored */ + + if(ob->type==OB_FONT) { + nr= pupmenu("Convert Font to%t|Curve"); + if(nr>0) ok= 1; + } + else if(ob->type==OB_MBALL) { + nr= pupmenu("Convert MetaBall to%t|Mesh (keep original)"); + if(nr>0) ok= 1; + } + else if(ob->type==OB_CURVE) { + nr= pupmenu("Convert Curve to%t|Mesh"); + if(nr>0) ok= 1; + } + else if(ob->type==OB_SURF) { + nr= pupmenu("Convert Nurbs Surf to%t|Mesh"); + if(nr>0) ok= 1; + } + else if(ob->type==OB_MESH && ((Mesh*) ob->data)->flag&ME_SUBSURF) { + nr= pupmenu("Convert SubSurf to%t|Mesh (keep original)"); + if(nr>0) ok= 1; + } + if(ok==0) return; + + /* denk aan meerdere users! */ + + /* vlaggen resetten */ + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + base->object->flag &= ~OB_DONE; + } + base= base->next; + } + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + + ob= base->object; + + if(ob->flag & OB_DONE); + else if(ob->type==OB_MESH) { + Mesh *oldme= ob->data; + + if (oldme->flag&ME_SUBSURF) { + ob->flag |= OB_DONE; + + ob1= copy_object(ob); + + basen= MEM_mallocN(sizeof(Base), "duplibase"); + *basen= *base; + BLI_addhead(&G.scene->base, basen); /* addhead: anders oneindige lus */ + basen->object= ob1; + basen->flag &= ~SELECT; + + me= ob1->data; + me->id.us--; + + ob1->data= add_mesh(); + G.totmesh++; + ob1->type= OB_MESH; + + me= ob1->data; + me->totcol= oldme->totcol; + if(ob1->totcol) { + me->mat= MEM_dupallocN(oldme->mat); + for(a=0; a<ob1->totcol; a++) id_us_plus((ID *)me->mat[a]); + } + + subsurf_to_mesh(ob, ob1->data); + + tex_space_mesh(me); + } + } + else if(ob->type==OB_FONT) { + if(nr==1) { + + ob->flag |= OB_DONE; + + ob->type= OB_CURVE; + cu= ob->data; + + if(cu->vfont) { + cu->vfont->id.us--; + cu->vfont= 0; + } + /* andere users */ + if(cu->id.us>1) { + ob1= G.main->object.first; + while(ob1) { + if(ob1->data==cu) ob1->type= OB_CURVE; + ob1= ob1->id.next; + } + } + } + } + else if ELEM(ob->type, OB_CURVE, OB_SURF) { + if(nr==1) { + + ob->flag |= OB_DONE; + cu= ob->data; + + dl= cu->disp.first; + if(dl==0) makeDispList(ob); + + nurbs_to_mesh(ob); /* doet ook users */ + + /* texspace en normalen */ + BASACT= base; + enter_editmode(); + exit_editmode(1); + BASACT= basact; + } + } + else if(ob->type==OB_MBALL) { + + if(nr==1) { + ob= find_basis_mball(ob); + + if(ob->disp.first && !(ob->flag&OB_DONE)) { + + ob->flag |= OB_DONE; + + ob1= copy_object(ob); + + basen= MEM_mallocN(sizeof(Base), "duplibase"); + *basen= *base; + BLI_addhead(&G.scene->base, basen); /* addhead: anders oneindige lus */ + basen->object= ob1; + basen->flag &= ~SELECT; + + mb= ob1->data; + mb->id.us--; + + ob1->data= add_mesh(); + G.totmesh++; + ob1->type= OB_MESH; + + me= ob1->data; + me->totcol= mb->totcol; + if(ob1->totcol) { + me->mat= MEM_dupallocN(mb->mat); + for(a=0; a<ob1->totcol; a++) id_us_plus((ID *)me->mat[a]); + } + + mball_to_mesh(&ob->disp, ob1->data); + tex_space_mesh(me); + } + } + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWBUTSEDIT, 0); +} + +void copymenu_properties(Object *ob) +{ + bProperty *prop, *propn, *propc; + Base *base; + int nr, tot=0; + char *str; + + prop= ob->prop.first; + while(prop) { + tot++; + prop= prop->next; + } + + if(tot==0) { + error("No properties in Object"); + return; + } + + str= MEM_callocN(24+32*tot, "copymenu prop"); + + strcpy(str, "Copy Property %t"); + + tot= 0; + prop= ob->prop.first; + while(prop) { + tot++; + strcat(str, " |"); + strcat(str, prop->name); + prop= prop->next; + } + + nr= pupmenu(str); + if(nr>0) { + tot= 0; + prop= ob->prop.first; + while(prop) { + tot++; + if(tot==nr) break; + prop= prop->next; + } + if(prop) { + propc= prop; + + base= FIRSTBASE; + while(base) { + if(base != BASACT) { + if(TESTBASELIB(base)) { + prop= get_property(base->object, propc->name); + if(prop) { + free_property(prop); + BLI_remlink(&base->object->prop, prop); + } + propn= copy_property(propc); + BLI_addtail(&base->object->prop, propn); + } + } + base= base->next; + } + } + } + MEM_freeN(str); + allqueue(REDRAWVIEW3D, 0); +} + +void copymenu_logicbricks(Object *ob) +{ + Base *base; + + base= FIRSTBASE; + while(base) { + if(base->object != ob) { + if(TESTBASELIB(base)) { + + /* first: free all logic */ + free_sensors(&base->object->sensors); + unlink_controllers(&base->object->controllers); + free_controllers(&base->object->controllers); + unlink_actuators(&base->object->actuators); + free_actuators(&base->object->actuators); + + /* now copy it, this also works without logicbricks! */ + clear_sca_new_poins_ob(ob); + copy_sensors(&base->object->sensors, &ob->sensors); + copy_controllers(&base->object->controllers, &ob->controllers); + copy_actuators(&base->object->actuators, &ob->actuators); + set_sca_new_poins_ob(base->object); + + /* some menu settings */ + base->object->scavisflag= ob->scavisflag; + base->object->scaflag= ob->scaflag; + + } + } + base= base->next; + } +} + +void copymenu() +{ + Object *ob, *obt; + Base *base; + Curve *cu, *cu1; + void *poin1, *poin2=0; + short event; + char str[256]; + + if(G.scene->id.lib) return; + + if(OBACT==0) return; + if(G.obedit) { + /* obedit_copymenu(); */ + return; + } + + strcpy(str, "COPY %t|Loc%x1|Rot%x2|Size%x3|Drawtype%x4|TimeOffs%x5|Dupli%x6|%l|Mass%x7|Damping%x8|Properties%x9|Logic Bricks%x10"); + + ob= OBACT; + + if ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL) { + strcat(str, "|Tex Space%x17"); + if(ob->type==OB_MESH) poin2= &(((Mesh *)ob->data)->texflag); + else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) poin2= &(((Curve *)ob->data)->texflag); + else if(ob->type==OB_MBALL) poin2= &(((MetaBall *)ob->data)->texflag); + } + + if(ob->type == OB_FONT) strcat(str, "|Font Settings%x18|Bevel Settings%x19"); + if(ob->type == OB_CURVE) strcat(str, "|Bevel Settings%x19"); + + if(ob->type==OB_MESH){ + strcat(str, "|Subdiv%x21"); + } + + if( give_parteff(ob) ) strcat(str, "|Particle Settings%x20"); + + strcat (str, "|Object Constraints%x22"); + + event= pupmenu(str); + if(event<= 0) return; + + if(event==9) { + copymenu_properties(ob); + return; + } + else if(event==10) { + copymenu_logicbricks(ob); + return; + } + + base= FIRSTBASE; + while(base) { + if(base != BASACT) { + if(TESTBASELIB(base)) { + + if(event==1) { /* loc */ + VECCOPY(base->object->loc, ob->loc); + VECCOPY(base->object->dloc, ob->dloc); + } + else if(event==2) { /* rot */ + VECCOPY(base->object->rot, ob->rot); + VECCOPY(base->object->drot, ob->drot); + VECCOPY(base->object->quat, ob->quat); + VECCOPY(base->object->dquat, ob->dquat); + } + else if(event==3) { /* size */ + VECCOPY(base->object->size, ob->size); + VECCOPY(base->object->dsize, ob->dsize); + } + else if(event==4) { /* drawtype */ + base->object->dt= ob->dt; + base->object->dtx= ob->dtx; + } + else if(event==5) { /* time offs */ + base->object->sf= ob->sf; + } + else if(event==6) { /* dupli */ + base->object->dupon= ob->dupon; + base->object->dupoff= ob->dupoff; + base->object->dupsta= ob->dupsta; + base->object->dupend= ob->dupend; + + base->object->transflag &= ~OB_DUPLI; + base->object->transflag |= (ob->transflag & OB_DUPLI); + } + else if(event==7) { /* mass */ + base->object->mass= ob->mass; + } + else if(event==8) { /* damping */ + base->object->damping= ob->damping; + base->object->rdamping= ob->rdamping; + } + else if(event==17) { /* tex space */ + obt= base->object; + poin1= 0; + if(obt->type==OB_MESH) poin1= &(((Mesh *)obt->data)->texflag); + else if ELEM3(obt->type, OB_CURVE, OB_SURF, OB_FONT) poin1= &(((Curve *)obt->data)->texflag); + else if(obt->type==OB_MBALL) poin1= &(((MetaBall *)obt->data)->texflag); + + if(poin1) { + memcpy(poin1, poin2, 4+12+12+12); + + if(obt->type==OB_MESH) tex_space_mesh(obt->data); + else if(obt->type==OB_MBALL) tex_space_mball(obt); + else tex_space_curve(obt->data); + } + } + else if(event==18) { /* font settings */ + + if(base->object->type==ob->type) { + cu= ob->data; + cu1= base->object->data; + + cu1->spacemode= cu->spacemode; + cu1->spacing= cu->spacing; + cu1->linedist= cu->linedist; + cu1->shear= cu->shear; + cu1->fsize= cu->fsize; + cu1->xof= cu->xof; + cu1->yof= cu->yof; + cu1->textoncurve= cu->textoncurve; + if(cu1->vfont) cu1->vfont->id.us--; + cu1->vfont= cu->vfont; + id_us_plus((ID *)cu1->vfont); + text_to_curve(base->object, 0); + + strcpy(cu1->family, cu->family); + + makeDispList(base->object); + } + } + else if(event==19) { /* bevel settings */ + + if ELEM(base->object->type, OB_CURVE, OB_FONT) { + cu= ob->data; + cu1= base->object->data; + + cu1->bevobj= cu->bevobj; + cu1->width= cu->width; + cu1->bevresol= cu->bevresol; + cu1->ext1= cu->ext1; + cu1->ext2= cu->ext2; + + makeDispList(base->object); + } + } + else if(event==20) { /* particle settings */ + PartEff *pa1, *pa2; + char *p1, *p2; + + pa1= give_parteff(ob); + pa2= give_parteff(base->object); + + if(pa1==0 && pa2) { + BLI_remlink( &(base->object->effect), pa2); + free_effect( (Effect *) pa2); + } + else if(pa1 && pa2==0) { + free_effects(&(base->object->effect)); + copy_effects(&(base->object->effect), &ob->effect); + build_particle_system(base->object); + } + else if(pa1 && pa2) { + if(pa2->keys) MEM_freeN(pa2->keys); + + p1= (char *)pa1; p2= (char *)pa2; + memcpy( p2+8, p1+8, sizeof(PartEff) - 8); + pa2->keys= 0; + + build_particle_system(base->object); + } + } + else if(event==21){ + if (base->object->type==OB_MESH) { + Mesh *targetme= base->object->data; + Mesh *sourceme= ob->data; + + targetme->flag= (targetme->flag&~ME_SUBSURF) | (sourceme->flag&ME_SUBSURF); + targetme->subdiv= sourceme->subdiv; + targetme->subdivr= sourceme->subdivr; + makeDispList(base->object); + } + } + else if(event==22){ + /* Clear the constraints on the target */ + free_constraints(&base->object->constraints); + free_constraint_channels(&base->object->constraintChannels); + + /* Copy the constraint channels over */ + copy_constraints(&base->object->constraints, &ob->constraints); + if (U.dupflag&DUPIPO) + copy_constraint_channels(&base->object->constraintChannels, &ob->constraintChannels); + else + clone_constraint_channels (&base->object->constraintChannels, &ob->constraintChannels, NULL); + + base->object->activecon = NULL; + } + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); + if(event==20) { + allqueue(REDRAWBUTSANIM, 0); + } + +} + +void link_to_scene(unsigned short nr) +{ + Scene *sce= (Scene*) BLI_findlink(&G.main->scene, G.curscreen->scenenr-1); + Base *base, *nbase; + + if(sce==0) return; + if(sce->id.lib) return; + + base= FIRSTBASE; + while(base) { + if(TESTBASE(base)) { + + nbase= MEM_mallocN( sizeof(Base), "newbase"); + *nbase= *base; + BLI_addhead( &(sce->base), nbase); + id_us_plus((ID *)base->object); + } + base= base->next; + } +} + +void linkmenu() +{ + Object *ob, *obt; + Base *base, *nbase, *sbase; + Scene *sce = NULL; + ID *id; + Material ***matarar, ***obmatarar, **matar1, **matar2; + int a; + short event, *totcolp, nr; + char str[140], *strp; + + + if(OBACT==0) return; + ob= OBACT; + + strcpy(str, "MAKE LINKS %t|To scene...%x1|Object Ipo%x4"); + + if(ob->type==OB_MESH) + strcat(str, "|Mesh data%x2|Materials%x3"); + else if(ob->type==OB_CURVE) + strcat(str, "|Curve data%x2|Materials%x3"); + else if(ob->type==OB_FONT) + strcat(str, "|Font data%x2|Materials%x3"); + else if(ob->type==OB_SURF) + strcat(str, "|Surf data%x2|Materials%x3"); + else if(ob->type==OB_MBALL) + strcat(str, "|Materials%x3"); + else if(ob->type==OB_CAMERA) + strcat(str, "|Camera data%x2"); + else if(ob->type==OB_LAMP) + strcat(str, "|Lamp data%x2"); + else if(ob->type==OB_LATTICE) + strcat(str, "|Lattice data%x2"); + else if(ob->type==OB_ARMATURE) + strcat(str, "|Armature data%x2"); + event= pupmenu(str); + if(event<= 0) return; + + if(event==1) { + IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->scene), 0, &nr); + + if(strncmp(strp, "DataBrow", 8)==0) { + MEM_freeN(strp); + + activate_databrowse((ID *)G.scene, ID_SCE, 0, B_INFOSCE, &(G.curscreen->scenenr), link_to_scene ); + + return; + } + else { + event= pupmenu(strp); + MEM_freeN(strp); + + if(event<= 0) return; + + nr= 1; + sce= G.main->scene.first; + while(sce) { + if(nr==event) break; + nr++; + sce= sce->id.next; + } + if(sce==G.scene) { + error("This is current scene"); + return; + } + if(sce==0 || sce->id.lib) return; + + /* denk eraan: is verderop nog nodig */ + event= 1; + } + } + + base= FIRSTBASE; + while(base) { + if(event==1 || base != BASACT) { + + obt= base->object; + + if(TESTBASE(base)) { + + if(event==1) { /* to scene */ + + /* testen of het soms al gelinkt is */ + sbase= sce->base.first; + while(sbase) { + if(sbase->object==base->object) break; + sbase= sbase->next; + } + if(sbase) { /* eruit */ + base= base->next; + continue; + } + + nbase= MEM_mallocN( sizeof(Base), "newbase"); + *nbase= *base; + BLI_addhead( &(sce->base), nbase); + id_us_plus((ID *)base->object); + } + } + if(TESTBASELIB(base)) { + if(event==2 || event==5) { /* obdata */ + if(ob->type==obt->type) { + + id= obt->data; + id->us--; + + id= ob->data; + id_us_plus(id); + obt->data= id; + + /* als aantal mat indices veranderd zijn: */ + test_object_materials(obt->data); + } + } + else if(event==4) { /* ob ipo */ + if(obt->ipo) obt->ipo->id.us--; + obt->ipo= ob->ipo; + if(obt->ipo) { + id_us_plus((ID *)obt->ipo); + do_ob_ipo(obt); + } + } + else if(event==3) { /* materials */ + + /* alleen als obt geen materiaal heeft: arrays maken */ + /* van ob naar obt! */ + + obmatarar= give_matarar(ob); + matarar= give_matarar(obt); + totcolp= give_totcolp(obt); + + /* als 1 van de 2 nul is: geen renderbaar object */ + if( matarar && obmatarar) { + + /* voorzichtig met users! Dus eerst kopie orig: */ + + if(ob->totcol) { + matar1= MEM_dupallocN(ob->mat); + matar2= MEM_dupallocN(*obmatarar); + } + else { + matar1= matar2= 0; + } + + /* alles van obt los linken */ + for(a=0; a<obt->totcol; a++) { + if(obt->mat[a]) obt->mat[a]->id.us--; + if( (*matarar)[a]) (*matarar)[a]->id.us--; + } + + /* vrijgeven */ + if(obt->mat) MEM_freeN(obt->mat); + if(*matarar) MEM_freeN(*matarar); + + /* hangen kopie er aan */ + obt->mat= matar1; + *matarar= matar2; + obt->totcol= ob->totcol; + *totcolp= ob->totcol; + + /* users ophogen */ + for(a=0; a<obt->totcol; a++) { + if(obt->mat[a]) id_us_plus((ID *)obt->mat[a]); + if( (*matarar)[a]) id_us_plus((ID *)(*matarar)[a]); + } + + obt->colbits= ob->colbits; + + /* als aantal mat indices veranderd zijn: */ + test_object_materials(obt->data); + } + } + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWBUTSHEAD, 0); +} + +void make_duplilist_real() +{ + Base *base, *basen; + Object *ob; + extern ListBase duplilist; + + if(okee("Make dupli's real")==0) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + + if(base->object->transflag & OB_DUPLI) { + + make_duplilist(G.scene, base->object); + ob= duplilist.first; + while(ob) { + + /* font dupli's kunnen totcol hebben zonder mat, halen ze van parent af + * dit zou netter moeten + */ + if(ob->mat==0) ob->totcol= 0; + + basen= MEM_dupallocN(base); + basen->flag &= ~OB_FROMDUPLI; + BLI_addhead(&G.scene->base, basen); /* addhead: anders oneindige lus */ + ob->ipo= 0; /* zeker weten dat de apply werkt */ + ob->parent= ob->track= 0; + ob->disp.first= ob->disp.last= 0; + ob->transflag &= ~OB_DUPLI; + basen->object= copy_object(ob); + + apply_obmat(basen->object); + ob= ob->id.next; + } + + free_duplilist(); + + base->object->transflag &= ~OB_DUPLI; + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); +} + +void apply_object() +{ + Base *base, *basact; + Object *ob; + Mesh *me; + Curve *cu; + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + MVert *mvert; + float mat[3][3]; + int a; + + if(G.scene->id.lib) return; + if(G.obedit) return; + basact= BASACT; + + if(G.qual & LR_SHIFTKEY) { + ob= OBACT; + if(ob==0) return; + + if(ob->transflag & OB_DUPLI) make_duplilist_real(); + else if(ob->parent && ob->parent->type==OB_LATTICE) apply_lattice(); + + return; + } + + if(okee("Apply size/rot")==0) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + ob= base->object; + + if(ob->type==OB_MESH) { + object_to_mat3(ob, mat); + me= ob->data; + + if(me->id.us>1) { + error("Can't do multi user mesh"); + return; + } + if(me->key) { + error("Can't do key && mesh"); + return; + } + + mvert= me->mvert; + for(a=0; a<me->totvert; a++, mvert++) { + Mat3MulVecfl(mat, mvert->co); + } + ob->size[0]= ob->size[1]= ob->size[2]= 1.0; + ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0; + QuatOne(ob->quat); + + where_is_object(ob); + + /* texspace en normalen */ + BASACT= base; + enter_editmode(); + exit_editmode(1); + BASACT= basact; + + } + else if (ob->type==OB_ARMATURE){ + bArmature *arm; + + object_to_mat3(ob, mat); + arm= ob->data; + if(arm->id.us>1) { + error("Can't do multi user armature"); + return; + } + + apply_rot_armature (ob, mat); + /* Reset the object's transforms */ + ob->size[0]= ob->size[1]= ob->size[2]= 1.0; + ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0; + QuatOne(ob->quat); + + where_is_object(ob); + } + else if ELEM(ob->type, OB_CURVE, OB_SURF) { + object_to_mat3(ob, mat); + cu= ob->data; + + if(cu->id.us>1) { + error("Can't do multi user curve"); + return; + } + if(cu->key) { + error("Can't do keys"); + return; + } + + nu= cu->nurb.first; + while(nu) { + if( (nu->type & 7)==1) { + a= nu->pntsu; + bezt= nu->bezt; + while(a--) { + Mat3MulVecfl(mat, bezt->vec[0]); + Mat3MulVecfl(mat, bezt->vec[1]); + Mat3MulVecfl(mat, bezt->vec[2]); + bezt++; + } + } + else { + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a--) { + Mat3MulVecfl(mat, bp->vec); + bp++; + } + } + nu= nu->next; + } + + ob->size[0]= ob->size[1]= ob->size[2]= 1.0; + ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0; + QuatOne(ob->quat); + + where_is_object(ob); + + /* texspace en normalen */ + BASACT= base; + enter_editmode(); + exit_editmode(1); + BASACT= basact; + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); +} + + + +/* ************ ALGEMENE *************** */ + +static Object *is_a_parent_selected_int(Object *startob, Object *ob, GHash *done_hash) { + if (ob!=startob && TESTBASE(ob)) + return ob; + + if (BLI_ghash_haskey(done_hash, ob)) + return NULL; + else + BLI_ghash_insert(done_hash, ob, NULL); + + if (ob->parent) { + Object *par= is_a_parent_selected_int(startob, ob->parent, done_hash); + if (par) + return par; + } + + /* IK is more complex in parents... */ + + /* XXX, should we be handling armatures or constraints here? - zr */ + + if(ob->type==OB_IKA) { + Ika *ika= ob->data; + + if (ika->def) { + int i; + + for (i=0; i<ika->totdef; i++) { + Deform *def= &ika->def[i]; + + if (def->ob && ob!=def->ob && def->ob!=startob) { + Object *par= is_a_parent_selected_int(startob, def->ob, done_hash); + if (par) + return par; + } + } + } + + if (ika->parent) { + Object *par= is_a_parent_selected_int(startob, ika->parent, done_hash); + if (par) + return par; + } + } + + return NULL; +} + +static Object *is_a_parent_selected(Object *ob) { + GHash *gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + Object *res= is_a_parent_selected_int(ob, ob, gh); + BLI_ghash_free(gh, NULL, NULL); + + return res; +} + +static void setbaseflags_for_editing(int mode) /* 0,'g','r','s' */ +{ + /* + if base selected and has parent selected: + base->flag= BA_WASSEL+BA_PARSEL + if base not selected and parent selected: + base->flag= BA_PARSEL + + */ + GHash *object_to_base_hash= NULL; /* built on demand, see below - zr */ + Base *base; + + copy_baseflags(); + + for (base= FIRSTBASE; base; base= base->next) { + base->flag &= ~(BA_PARSEL+BA_WASSEL); + + if( (base->lay & G.vd->lay) && base->object->id.lib==0) { + Object *ob= base->object; + Object *parsel= is_a_parent_selected(ob); + + /* hier ook parentkey? */ + + if(parsel) { + if(base->flag & SELECT) { + base->flag &= ~SELECT; + base->flag |= (BA_PARSEL+BA_WASSEL); + } + else base->flag |= BA_PARSEL; + } + + if(mode=='g') { + if(ob->track && TESTBASE(ob->track) && (base->flag & SELECT)==0) + base->flag |= BA_PARSEL; + } + + /* updates? */ + /* ivm automatische portals */ + if(ob->type==OB_IKA) { + Ika *ika= ob->data; + if(ika->parent && parsel) base->flag |= BA_WHERE_UPDATE; + } + + if(base->flag & (SELECT | BA_PARSEL)) { + + base->flag |= BA_WHERE_UPDATE; + + if(ob->parent) { + if(ob->parent->type==OB_LATTICE) base->flag |= BA_DISP_UPDATE; + if(ob->parent->type==OB_IKA && ob->partype==PARSKEL) base->flag |= BA_DISP_UPDATE; + if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) base->flag |= BA_DISP_UPDATE; + } + if(ob->track) { + ; + } + + if( give_parteff(ob) ) base->flag |= BA_DISP_UPDATE; + + if(ob->type==OB_MBALL) { + Base *b; + + /* Only bother building the object to base + * hash if we are going to be needing it... - zr + */ + if (!object_to_base_hash) { + object_to_base_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + + for (b= FIRSTBASE; b; b= b->next) + BLI_ghash_insert(object_to_base_hash, b->object, b); + } + + b= BLI_ghash_lookup(object_to_base_hash, find_basis_mball(ob)); + b->flag |= BA_DISP_UPDATE; + } + } + } + } + + if (object_to_base_hash) + BLI_ghash_free(object_to_base_hash, NULL, NULL); +} + + +void clearbaseflags_for_editing() +{ + Base *base; + + base= FIRSTBASE; + while(base) { + if(base->flag & BA_WASSEL) base->flag |= SELECT; + base->flag &= ~(BA_PARSEL+BA_WASSEL); + + base->flag &= ~(BA_DISP_UPDATE+BA_WHERE_UPDATE+BA_DO_IPO); + + base= base->next; + } + copy_baseflags(); +} + +void ob_to_transob(Object *ob, TransOb *tob) +{ + float totmat[3][3]; + Object *tr; + void *cfirst, *clast; + + tob->ob= ob; + + cfirst = ob->constraints.first; + clast = ob->constraints.last; + + ob->constraints.first=ob->constraints.last=NULL; + + tr= ob->track; + ob->track= 0; + where_is_object(ob); + ob->track= tr; + ob->constraints.first = cfirst; + ob->constraints.last = clast; + + + + tob->loc= ob->loc; + VECCOPY(tob->oldloc, tob->loc); + + tob->rot= ob->rot; + VECCOPY(tob->oldrot, ob->rot); + VECCOPY(tob->olddrot, ob->drot); + + tob->quat= ob->quat; + QUATCOPY(tob->oldquat, ob->quat); + QUATCOPY(tob->olddquat, ob->dquat); + + tob->size= ob->size; + VECCOPY(tob->oldsize, ob->size); + + VECCOPY(tob->olddsize, ob->dsize); + + /* alleen object, geen parent */ + object_to_mat3(ob, tob->obmat); + Mat3Inv(tob->obinv, tob->obmat); + + Mat3CpyMat4(totmat, ob->obmat); + + /* dit is totmat zonder obmat: dus parmat */ + Mat3MulMat3(tob->parmat, totmat, tob->obinv); + Mat3Inv(tob->parinv, tob->parmat); + + Mat3MulMat3(tob->axismat, tob->parmat, tob->obmat); // New! + Mat3Ortho(tob->axismat); + + VECCOPY(tob->obvec, ob->obmat[3]); + + centroid[0]+= tob->obvec[0]; + centroid[1]+= tob->obvec[1]; + centroid[2]+= tob->obvec[2]; + + tob->eff= 0; + + if(ob->type==OB_IKA) { + Ika *ika=ob->data; + + calc_ika(ika, 0); + + ika->effn[0]= ika->eff[0]; + ika->effn[1]= ika->eff[1]; + ika->effn[2]= 0.0; + + VecMat4MulVecfl(ika->effg, ob->obmat, ika->effn); + + if(ika->flag & IK_GRABEFF) { + + tob->eff= ika->effg; + VECCOPY(tob->oldeff, tob->eff); + tob->flag |= TOB_IKA; + + /* zodat alleen eff update wordt */ + tob->loc= 0; + } + + /* set_ika_undo_vals(); */ + } +} + +void ob_to_tex_transob(Object *ob, TransOb *tob) +{ + Mesh *me; + Curve *cu; + MetaBall *mb; + ID *id; + + ob_to_transob(ob, tob); + + id= ob->data; + if(id==0); + else if( GS(id->name)==ID_ME) { + me= ob->data; + me->texflag &= ~AUTOSPACE; + tob->loc= me->loc; + tob->rot= me->rot; + tob->size= me->size; + } + else if( GS(id->name)==ID_CU) { + cu= ob->data; + cu->texflag &= ~AUTOSPACE; + tob->loc= cu->loc; + tob->rot= cu->rot; + tob->size= cu->size; + } + else if( GS(id->name)==ID_MB) { + mb= ob->data; + mb->texflag &= ~AUTOSPACE; + tob->loc= mb->loc; + tob->rot= mb->rot; + tob->size= mb->size; + } + + VECCOPY(tob->oldloc, tob->loc); + VECCOPY(tob->oldrot, tob->rot); + VECCOPY(tob->oldsize, tob->size); +} + +void make_trans_objects() +{ + Base *base; + Object *ob; + TransOb *tob = NULL; + ListBase elems; + IpoKey *ik; + float cfraont, min[3], max[3]; + int ipoflag; + + tottrans= 0; + + INIT_MINMAX(min, max); + centroid[0]=centroid[1]=centroid[2]= 0.0; + + /* aantal tellen */ + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + ob= base->object; + + if(transmode==TRANS_TEX) { + if(ob->dtx & OB_TEXSPACE) tottrans++; + } + else { + if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { + elems.first= elems.last= 0; + make_ipokey_transform(ob, &elems, 1); /* '1' alleen selected keys */ + + pushdata(&elems, sizeof(ListBase)); + + ik= elems.first; + while(ik) { + tottrans++; + ik= ik->next; + } + if(elems.first==0) tottrans++; + } + else tottrans++; + } + } + base= base->next; + } + + if(tottrans) tob= transmain= MEM_mallocN(tottrans*sizeof(TransOb), "transmain"); + + reset_slowparents(); + + + /* dit hieronder wel doen als tottrans==0, i.v.m. vrijgeven pushpop en ipokeys */ + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + ob= base->object; + + if(transmode==TRANS_TEX) { + if(ob->dtx & OB_TEXSPACE) { + tob->flag= 0; + + ob_to_tex_transob(ob, tob); + DO_MINMAX(tob->obvec, min, max); + + tob++; + } + } + else { + + /* van belang! (o.a. bevobj) */ + if(base->flag & SELECT) ob->flag|= SELECT; else ob->flag &= ~SELECT; + + if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { + + popfirst(&elems); + + if(elems.first) { + base->flag |= BA_DO_IPO+BA_WASSEL; + base->flag &= ~SELECT; + + cfraont= CFRA; + set_no_parent_ipo(1); + ipoflag= ob->ipoflag; + ob->ipoflag &= ~OB_OFFS_OB; + + pushdata(ob->loc, 7*3*4); + + ik= elems.first; + while(ik) { + + CFRA= ik->val/G.scene->r.framelen; + + do_ob_ipo(ob); + where_is_object(ob); + + ob_to_transob(ob, tob); + DO_MINMAX(tob->obvec, min, max); + + /* doet ook tob->flag en oldvals, moet NA ob_to_transob()! */ + set_ipo_pointers_transob(ik, tob); + + tob++; + ik= ik->next; + } + free_ipokey(&elems); + + poplast(ob->loc); + set_no_parent_ipo(0); + + CFRA= cfraont; + ob->ipoflag= ipoflag; + } + else { + tob->flag= 0; + + ob_to_transob(ob, tob); + DO_MINMAX(tob->obvec, min, max); + + tob++; + } + } + else { + tob->flag= 0; + + ob_to_transob(ob, tob); + DO_MINMAX(tob->obvec, min, max); + + tob++; + } + } + + } + base= base->next; + } + + pushpop_test(); /* alleen voor debug & zekerheid */ + + if(tottrans==0) return; + + centroid[0]/= tottrans; + centroid[1]/= tottrans; + centroid[2]/= tottrans; + + centre[0]= (min[0]+max[0])/2.0; + centre[1]= (min[1]+max[1])/2.0; + centre[2]= (min[2]+max[2])/2.0; +} + +/* mode: 1 = proportional */ +void make_trans_verts(float *min, float *max, int mode) +{ +/* extern Lattice *editLatt; already in BKE_lattice.h */ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + TransVert *tv; + MetaElem *ml; + EditVert *eve; + int a; + EditBone *ebo; + tottrans= 0; + + INIT_MINMAX(min, max); + centroid[0]=centroid[1]=centroid[2]= 0.0; + + countall(); + if(mode) tottrans= G.totvert; + else tottrans= G.totvertsel; + + if(G.totvertsel==0) { + tottrans= 0; + return; + } + + tv=transvmain= MEM_callocN(tottrans*sizeof(TransVert), "maketransverts"); + + /* we count again because of hide */ + tottrans= 0; + + if(G.obedit->type==OB_MESH) { + eve= G.edve.first; + while(eve) { + if(eve->h==0) { + if(mode==1 || (eve->f & 1)) { + VECCOPY(tv->oldloc, eve->co); + tv->loc= eve->co; + tv->nor= eve->no; + tv->flag= eve->f & 1; + tv++; + tottrans++; + } + } + eve= eve->next; + } + } + else if (G.obedit->type==OB_ARMATURE){ + for (ebo=G.edbo.first;ebo;ebo=ebo->next){ + if (ebo->flag & BONE_TIPSEL){ + VECCOPY (tv->oldloc, ebo->tail); + tv->loc= ebo->tail; + tv->nor= NULL; + tv->flag= 1; + tv++; + tottrans++; + } + + /* Only add the root if there is no selected IK parent */ + if (ebo->flag & BONE_ROOTSEL){ + if (!(ebo->parent && (ebo->flag & BONE_IK_TOPARENT) && ebo->parent->flag & BONE_TIPSEL)){ + VECCOPY (tv->oldloc, ebo->head); + tv->loc= ebo->head; + tv->nor= NULL; + tv->flag= 1; + tv++; + tottrans++; + } + } + + } + } + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + a= nu->pntsu; + bezt= nu->bezt; + while(a--) { + if(bezt->hide==0) { + if(mode==1 || (bezt->f1 & 1)) { + VECCOPY(tv->oldloc, bezt->vec[0]); + tv->loc= bezt->vec[0]; + tv->flag= bezt->f1 & 1; + tv++; + tottrans++; + } + if(mode==1 || (bezt->f2 & 1)) { + VECCOPY(tv->oldloc, bezt->vec[1]); + tv->loc= bezt->vec[1]; + tv->val= &(bezt->alfa); + tv->oldval= bezt->alfa; + tv->flag= bezt->f2 & 1; + tv++; + tottrans++; + } + if(mode==1 || (bezt->f3 & 1)) { + VECCOPY(tv->oldloc, bezt->vec[2]); + tv->loc= bezt->vec[2]; + tv->flag= bezt->f3 & 1; + tv++; + tottrans++; + } + } + bezt++; + } + } + else { + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a--) { + if(bp->hide==0) { + if(mode==1 || (bp->f1 & 1)) { + VECCOPY(tv->oldloc, bp->vec); + tv->loc= bp->vec; + tv->val= &(bp->alfa); + tv->oldval= bp->alfa; + tv->flag= bp->f1 & 1; + tv++; + tottrans++; + } + } + bp++; + } + } + nu= nu->next; + } + } + else if(G.obedit->type==OB_MBALL) { + ml= editelems.first; + while(ml) { + if(ml->flag & SELECT) { + tv->loc= &ml->x; + VECCOPY(tv->oldloc, tv->loc); + tv->val= &(ml->rad); + tv->oldval= ml->rad; + tv->flag= 1; + tv++; + tottrans++; + } + ml= ml->next; + } + } + else if(G.obedit->type==OB_LATTICE) { + bp= editLatt->def; + + a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + + while(a--) { + if(mode==1 || (bp->f1 & 1)) { + if(bp->hide==0) { + VECCOPY(tv->oldloc, bp->vec); + tv->loc= bp->vec; + tv->flag= bp->f1 & 1; + tv++; + tottrans++; + } + } + bp++; + } + } + + /* cent enz berekenen */ + tv= transvmain; + for(a=0; a<tottrans; a++, tv++) { + if(tv->flag) { + centroid[0]+= tv->oldloc[0]; + centroid[1]+= tv->oldloc[1]; + centroid[2]+= tv->oldloc[2]; + + DO_MINMAX(tv->oldloc, min, max); + } + } + centroid[0]/= G.totvertsel; + centroid[1]/= G.totvertsel; + centroid[2]/= G.totvertsel; + + centre[0]= (min[0]+max[0])/2.0; + centre[1]= (min[1]+max[1])/2.0; + centre[2]= (min[2]+max[2])/2.0; + +} + +void draw_prop_circle() +{ + float tmat[4][4], imat[4][4]; + + if(G.moving) { + setlinestyle(1); + cpack(0x303030); + mygetmatrix(tmat); + Mat4Invert(imat, tmat); + setlinestyle(2); + drawcircball(prop_cent, prop_size, imat); + myloadmatrix(G.vd->viewmat); + setlinestyle(0); + } +} + +void set_proportional_weight(TransVert *tv, float *min, float *max) +{ + float dist, xdist, ydist, zdist; + + if(tv->oldloc[0]<min[0]) xdist= tv->oldloc[0]-min[0]; + else if(tv->oldloc[0]>max[0]) xdist= tv->oldloc[0]-max[0]; + else xdist= 0.0; + + if(tv->oldloc[1]<min[1]) ydist= tv->oldloc[1]-min[1]; + else if(tv->oldloc[1]>max[1]) ydist= tv->oldloc[1]-max[1]; + else ydist= 0.0; + + if(tv->oldloc[2]<min[2]) zdist= tv->oldloc[2]-min[2]; + else if(tv->oldloc[2]>max[2]) zdist= tv->oldloc[2]-max[2]; + else zdist= 0.0; + + dist= sqrt(xdist*xdist + ydist*ydist + zdist*zdist); + if(dist==0.0) tv->fac= 1.0; + else if(dist > prop_size) tv->fac= 0.0; + else { + dist= (prop_size-dist)/prop_size; + if(prop_mode==1) tv->fac= 3.0*dist*dist - 2.0*dist*dist*dist; + else tv->fac= dist*dist; + } +} + +void special_trans_update(int keyflags) +{ +/* extern Lattice *editLatt; already in BKE_lattice.h */ + Base *base; + Curve *cu; + IpoCurve *icu; + + if(G.obedit) { + if(G.obedit->type==OB_CURVE) { + cu= G.obedit->data; + if(cu->flag & CU_3D) makeBevelList(G.obedit); + + calc_curvepath(G.obedit); + } + else if(G.obedit->type==OB_ARMATURE){ + EditBone *ebo; + + /* Ensure all bones are correctly adjusted */ + for (ebo=G.edbo.first; ebo; ebo=ebo->next){ + + if ((ebo->flag & BONE_IK_TOPARENT) && ebo->parent){ + /* If this bone has a parent tip that has been moved */ + if (ebo->parent->flag & BONE_TIPSEL){ + VECCOPY (ebo->head, ebo->parent->tail); + } + /* If this bone has a parent tip that has NOT been moved */ + else{ + VECCOPY (ebo->parent->tail, ebo->head); + } + } + } + } + else if(G.obedit->type==OB_LATTICE) { + + if(editLatt->flag & LT_OUTSIDE) outside_lattice(editLatt); + + base= FIRSTBASE; + while(base) { + if(base->lay & G.vd->lay) { + if(base->object->parent==G.obedit) { + makeDispList(base->object); + } + } + base= base->next; + } + } + } + else if(G.obpose){ + int i; + bPoseChannel *chan; + + if (!G.obpose->pose) G.obpose->pose= MEM_callocN(sizeof(bPose), "pose"); + + switch (G.obpose->type){ + case OB_ARMATURE: + + /* Make channels for the transforming bones (in posemode) */ + for (i=0; i< tottrans; i++){ + chan = MEM_callocN (sizeof (bPoseChannel), "transPoseChannel"); + + if (keyflags & KEYFLAG_ROT){ + chan->flag |= POSE_ROT; + memcpy (chan->quat, transmain[i].quat, sizeof (chan->quat)); + } + if (keyflags & KEYFLAG_LOC){ + chan->flag |= POSE_LOC; + memcpy (chan->loc, transmain[i].loc, sizeof (chan->loc)); + } + if (keyflags & KEYFLAG_SIZE){ + chan->flag |= POSE_SIZE; + memcpy (chan->size, transmain[i].size, sizeof (chan->size)); + } + + strcpy (chan->name, ((Bone*) transmain[i].data)->name); + + set_pose_channel (G.obpose->pose, chan); + } + break; + } + } + else { + base= FIRSTBASE; + while(base) { + if(base->flag & BA_DO_IPO) { + + base->object->ctime= -1234567.0; + + icu= base->object->ipo->curve.first; + while(icu) { + calchandles_ipocurve(icu); + icu= icu->next; + } + + } + if(base->object->partype & PARSLOW) { + base->object->partype -= PARSLOW; + where_is_object(base->object); + base->object->partype |= PARSLOW; + } + else if(base->flag & BA_WHERE_UPDATE) { + where_is_object(base->object); + if(base->object->type==OB_IKA) { + itterate_ika(base->object); + } + + } + + base= base->next; + } + + base= FIRSTBASE; + while(base) { + + if(base->flag & BA_DISP_UPDATE) makeDispList(base->object); + + base= base->next; + } + + } + +#if 0 + if (G.obpose && G.obpose->type == OB_ARMATURE) + make_displists_by_armature(G.obpose); +#endif + + if(G.vd->drawtype == OB_SHADED) reshadeall_displist(); + +} + + +void special_aftertrans_update(char mode, int flip, short canceled, int keyflags) +{ + Object *ob; + Base *base; + MetaBall *mb; + Curve *cu; + Ika *ika; + int doit,redrawipo=0; + + + /* displaylisten e.d. */ + + if(G.obedit) { + if(G.obedit->type==OB_MBALL) { + mb= G.obedit->data; + if(mb->flag != MB_UPDATE_ALWAYS) makeDispList(G.obedit); + } + else if(G.obedit->type==OB_MESH) { + if(flip) flip_editnormals(); + + recalc_editnormals(); + } + } + else if (G.obpose){ + bAction *act; + bPose *pose; + bPoseChannel *pchan; + + if (U.flag & (0x01<<14) && !canceled){ + act=G.obpose->action; + pose=G.obpose->pose; + + if (!act) + act=G.obpose->action=add_empty_action(); + + collect_pose_garbage(G.obpose); + filter_pose_keys (); + for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){ + if (pchan->flag & POSE_KEY){ + if (keyflags & KEYFLAG_ROT){ + set_action_key(act, pchan, AC_QUAT_X, 1); + set_action_key(act, pchan, AC_QUAT_Y, 1); + set_action_key(act, pchan, AC_QUAT_Z, 1); + set_action_key(act, pchan, AC_QUAT_W, 1); + } + if (keyflags & KEYFLAG_SIZE){ + set_action_key(act, pchan, AC_SIZE_X, 1); + set_action_key(act, pchan, AC_SIZE_Y, 1); + set_action_key(act, pchan, AC_SIZE_Z, 1); + } + if (keyflags & KEYFLAG_LOC){ + set_action_key(act, pchan, AC_LOC_X, 1); + set_action_key(act, pchan, AC_LOC_Y, 1); + set_action_key(act, pchan, AC_LOC_Z, 1); + } + } + } + + + remake_action_ipos (act); + allspace(REMAKEIPO, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWNLA, 0); + } + } + else { + base= FIRSTBASE; + while(base) { + + ob= base->object; + + if(base->flag & BA_WHERE_UPDATE) { + + where_is_object(ob); + + if(ob->type==OB_IKA) { + ika= ob->data; + /* vooral voor ika NIET in GRABEFF mode, updaten van globale effector */ + VecMat4MulVecfl(ika->effg, ob->obmat, ika->eff); + itterate_ika(ob); + } + } + if(base->flag & BA_DISP_UPDATE) { + if(ob->type==OB_MBALL) { + mb= ob->data; + if(mb->flag != MB_UPDATE_ALWAYS) makeDispList(ob); + } + if( give_parteff(ob) ) build_particle_system(ob); + } + if(base->flag & BA_DO_IPO) redrawipo= 1; + + if(mode=='s' && ob->type==OB_FONT) { + doit= 0; + cu= ob->data; + + if(cu->bevobj && (cu->bevobj->flag & SELECT) ) doit= 1; + else if(cu->textoncurve) { + if(cu->textoncurve->flag & SELECT) doit= 1; + else if(ob->flag & SELECT) doit= 1; + } + + if(doit) { + text_to_curve(ob, 0); + makeDispList(ob); + } + } + if(mode=='s' && ob->type==OB_CURVE) { + doit= 0; + cu= ob->data; + + if(cu->bevobj && (cu->bevobj->flag & SELECT) ) + makeDispList(ob); + } + + where_is_object(ob); /* altijd ivm track eytc */ + + /* Set autokey if necessary */ + if ((U.flag & (0x01<<15)) && (!canceled) && (base->flag & SELECT)){ + if (keyflags & KEYFLAG_ROT){ + insertkey(&base->object->id, OB_ROT_X); + insertkey(&base->object->id, OB_ROT_Y); + insertkey(&base->object->id, OB_ROT_Z); + } + if (keyflags & KEYFLAG_LOC){ + insertkey(&base->object->id, OB_LOC_X); + insertkey(&base->object->id, OB_LOC_Y); + insertkey(&base->object->id, OB_LOC_Z); + } + if (keyflags & KEYFLAG_SIZE){ + insertkey(&base->object->id, OB_SIZE_X); + insertkey(&base->object->id, OB_SIZE_Y); + insertkey(&base->object->id, OB_SIZE_Z); + } + + remake_object_ipos (ob); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWNLA, 0); + } + + base= base->next; + } + + } + + if(redrawipo) { + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + } + + if(G.vd->drawtype == OB_SHADED) reshadeall_displist(); + +} + + + +void calc_trans_verts(void) +{ + if (ELEM(G.obedit->type, OB_MESH, OB_MBALL)) + makeDispList(G.obedit); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + Nurb *nu= editNurb.first; + while(nu) { + test2DNurb(nu); + testhandlesNurb(nu); /* test ook op bezier */ + nu= nu->next; + } + makeDispList(G.obedit); + } +} + + +static int test_midtog_proj(short xn, short yn, short *mval) +{ + float x,y,z; + + /* welke beweging is het grootst? die wordt het */ + xn= (xn-mval[0]); + yn= (yn-mval[1]); + x = fabs(G.vd->persinv[0][0]*xn + G.vd->persinv[1][0]*yn); + y = fabs(G.vd->persinv[0][1]*xn + G.vd->persinv[1][1]*yn); + z = fabs(G.vd->persinv[0][2]*xn + G.vd->persinv[1][2]*yn); + + if(x>=y && x>=z) return 0; + else if(y>=x && y>=z) return 1; + else return 2; +} + +void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert) +{ + /* fac1 is voor 'niets', fac2 voor CTRL fac3 voor SHIFT */ + int ctrl; + + if(invert) { + if(G.qual & LR_CTRLKEY) ctrl= 0; + else ctrl= 1; + } + else ctrl= (G.qual & LR_CTRLKEY); + + if(ctrl && (G.qual & LR_SHIFTKEY)) { + if(fac3!= 0.0) *val= fac3*floor(*val/fac3 +.5); + } + else if(ctrl) { + if(fac2!= 0.0) *val= fac2*floor(*val/fac2 +.5); + } + else { + if(fac1!= 0.0) *val= fac1*floor(*val/fac1 +.5); + } + +} + + +void compatible_eul(float *eul, float *oldrot) +{ + float dx, dy, dz; + + /* verschillen van ong 360 graden eerst corrigeren */ + + dx= eul[0] - oldrot[0]; + dy= eul[1] - oldrot[1]; + dz= eul[2] - oldrot[2]; + +/* printf("komt binnen: \n"); */ +/* PRINT3(f, f, f, eul[0], eul[1], eul[2]); */ +/* PRINT3(f, f, f, dx, dy, dz); */ + + while( fabs(dx) > 5.1) { + if(dx > 0.0) eul[0] -= 2.0*M_PI; else eul[0]+= 2.0*M_PI; + dx= eul[0] - oldrot[0]; + } + while( fabs(dy) > 5.1) { + if(dy > 0.0) eul[1] -= 2.0*M_PI; else eul[1]+= 2.0*M_PI; + dy= eul[1] - oldrot[1]; + } + while( fabs(dz) > 5.1 ) { + if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI; + dz= eul[2] - oldrot[2]; + } + +/* PRINT3(f, f, f, oldrot[0], oldrot[1], oldrot[2]); */ + + + /* is 1 van de asrotaties groter dan 180 graden en de andere klein? GEEN ELSEIF!! */ + if( fabs(dx) > 3.2 && fabs(dy)<1.6 && fabs(dz)<1.6 ) { + if(dx > 0.0) eul[0] -= 2.0*M_PI; else eul[0]+= 2.0*M_PI; + } + if( fabs(dy) > 3.2 && fabs(dz)<1.6 && fabs(dx)<1.6 ) { + if(dy > 0.0) eul[1] -= 2.0*M_PI; else eul[1]+= 2.0*M_PI; + } + if( fabs(dz) > 3.2 && fabs(dx)<1.6 && fabs(dy)<1.6 ) { + if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI; + } + +return; + /* opnieuw berekenen */ + dx= eul[0] - oldrot[0]; + dy= eul[1] - oldrot[1]; + dz= eul[2] - oldrot[2]; + + /* dit is een bijzonder geval, voor x-z getest */ + + if( (fabs(dx) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dz) > 3.1 ) ) { + if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI; + if(eul[1] > 0.0) eul[1]= M_PI - eul[1]; else eul[1]= -M_PI - eul[1]; + if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI; + + } + else if( (fabs(dx) > 3.1 && fabs(dy) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dy) > 3.1 ) ) { + if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI; + if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI; + if(eul[2] > 0.0) eul[2]= M_PI - eul[2]; else eul[2]= -M_PI - eul[2]; + } + else if( (fabs(dy) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dy) > 1.5 && fabs(dz) > 3.1 ) ) { + if(eul[0] > 0.0) eul[0]= M_PI - eul[0]; else eul[0]= -M_PI - eul[0]; + if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI; + if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI; + } + +/* PRINT3(f, f, f, eul[0], eul[1], eul[2]); */ +/* printf("\n"); */ +} + +void headerprint(char *str) +{ + areawinset(curarea->headwin); + + headerbox(0xA09090, curarea->winx); + cpack(0x0); + glRasterPos2i(20+curarea->headbutofs, 6); + BMF_DrawString(G.font, str); + + curarea->head_swap= WIN_BACK_OK; + areawinset(curarea->win); +} + +void add_ipo_tob_poin(float *poin, float *old, float delta) +{ + if(poin) { + poin[0]= old[0]+delta; + poin[-3]= old[3]+delta; + poin[3]= old[6]+delta; + } +} + +void restore_tob(TransOb *tob) +{ + + if(tob->flag & TOB_IPO) { + add_ipo_tob_poin(tob->locx, tob->oldloc, 0.0); + add_ipo_tob_poin(tob->locy, tob->oldloc+1, 0.0); + add_ipo_tob_poin(tob->locz, tob->oldloc+2, 0.0); +/* QUAT! */ + add_ipo_tob_poin(tob->rotx, tob->oldrot+3, 0.0); + add_ipo_tob_poin(tob->roty, tob->oldrot+4, 0.0); + add_ipo_tob_poin(tob->rotz, tob->oldrot+5, 0.0); + + add_ipo_tob_poin(tob->sizex, tob->oldsize, 0.0); + add_ipo_tob_poin(tob->sizey, tob->oldsize+1, 0.0); + add_ipo_tob_poin(tob->sizez, tob->oldsize+2, 0.0); + + } + else { + if(tob->eff) VECCOPY(tob->eff, tob->oldeff); + if(tob->loc) VECCOPY(tob->loc, tob->oldloc); + if(tob->rot) VECCOPY(tob->rot, tob->oldrot); + + QUATCOPY(tob->quat, tob->oldquat); + VECCOPY(tob->size, tob->oldsize); + } +} + +int cylinder_intersect_test(void) +{ + extern float editbutsize; + float *oldloc, speed[3], s, t, labda, labdacor, dist, len, len2, axis[3], *base, rc[3], n[3], o[3]; + EditVert *v1; + + v1= G.edve.first; + + base= v1->co; + v1= v1->next; + VecSubf(axis, v1->co, base); + + v1= v1->next; + oldloc= v1->co; + v1= v1->next; + VecSubf(speed, v1->co, oldloc); + + VecSubf(rc, oldloc, base); + + /* als we nou speed normaliseren (kan van te voren! */ + + /* en de axis ook alvast */ + len2= Normalise(axis); + + Crossf(n, speed, axis); + len= Normalise(n); + if(len==0.0) return 0; + + dist= fabs( rc[0]*n[0] + rc[1]*n[1] + rc[2]*n[2] ); + + if( dist>=editbutsize ) return 0; + + Crossf(o, rc, axis); + t= -(o[0]*n[0] + o[1]*n[1] + o[2]*n[2])/len; + + Crossf(o, n, axis); + s= fabs(sqrt(editbutsize*editbutsize-dist*dist) / (o[0]*speed[0] + o[1]*speed[1] + o[2]*speed[2])); + + labdacor= t-s; + labda= t+s; + + /* twee gevallen waarbij geen snijpunt is */ + if(labdacor>=1.0 && labda>=1.0) return 0; + if(labdacor<=0.0 && labda<=0.0) return 0; + + /* normaalvector berekenen */ + /* snijpunt: */ + + rc[0]= oldloc[0] + labdacor*speed[0] - base[0]; + rc[1]= oldloc[1] + labdacor*speed[1] - base[1]; + rc[2]= oldloc[2] + labdacor*speed[2] - base[2]; + + s= (rc[0]*axis[0] + rc[1]*axis[1] + rc[2]*axis[2]) ; + + if(s<0.0 || s>len2) return 0; + + n[0]= (rc[0] - s*axis[0]); + n[1]= (rc[1] - s*axis[1]); + n[2]= (rc[2] - s*axis[2]); + + printf("var1: %f, var2: %f, var3: %f\n", labdacor, len2, s); + printf("var1: %f, var2: %f, var3: %f\n", rc[0], rc[1], rc[2]); + printf("var1: %f, var2: %f, var3: %f\n", n[0], n[1], n[2]); + + return 1; +} + +int sphere_intersect_test(void) +{ + extern float editbutsize; + float *oldloc, speed[3], labda, labdacor, len, bsq, u, disc, *base, rc[3]; + EditVert *v1; + + v1= G.edve.first; + base= v1->co; + + v1= v1->next; + oldloc= v1->co; + + v1= v1->next; + VecSubf(speed, v1->co, oldloc); + len= Normalise(speed); + if(len==0.0) return 0; + + VecSubf(rc, oldloc, base); + bsq= rc[0]*speed[0] + rc[1]*speed[1] + rc[2]*speed[2]; + u= rc[0]*rc[0] + rc[1]*rc[1] + rc[2]*rc[2] - editbutsize*editbutsize; + + disc= bsq*bsq - u; + + if(disc>=0.0) { + disc= sqrt(disc); + labdacor= (-bsq - disc)/len; /* intrede */ + labda= (-bsq + disc)/len; + + printf("var1: %f, var2: %f, var3: %f\n", labdacor, labda, editbutsize); + } + else return 0; + + /* snijpunt en normaal */ + rc[0]= oldloc[0] + labdacor*speed[0] - base[0]; + rc[1]= oldloc[1] + labdacor*speed[1] - base[1]; + rc[2]= oldloc[2] + labdacor*speed[2] - base[2]; + + + return 1; +} + +#ifndef CLOCKS_PER_SEC +#define CLOCKS_PER_SEC 1000000 +#endif + +int my_clock(void) +{ + float ftime; + + ftime= (float)clock(); + ftime*= 100.0/CLOCKS_PER_SEC; + + return (int)ftime; +} + +#define XROT 0x01 +#define YROT 0x02 +#define ZROT 0x04 +#define ROTLOCAL 0x80 +#define XROTLOCAL (XROT|ROTLOCAL) +#define YROTLOCAL (YROT|ROTLOCAL) +#define ZROTLOCAL (ZROT|ROTLOCAL) + +void transform(int mode) /* 'g' 'G' 'r' 'R' 's' 'S' 't' or 'w' 'N' */ +{ + short canceled = 0; + TransOb *tob; + TransVert *tv; + float vec[3], min[3], max[3], dvec[3], d_dvec[3], dvecp[3], rot0[3], rot1[3], rot2[3], axis[3]; + float totmat[3][3], omat[3][3], imat[3][3], mat[3][3], tmat[3][3], phi, dphi; + + float persinv[3][3], persmat[3][3], viewinv[4][4], imat4[4][4]; + float *curs, dx1, dx2, dy1, dy2, eul[3], quat[4], rot[3], phi0, phi1, deler, rad = 0.0; + float sizefac, size[3], sizelo[3], smat[3][3], xref=1.0, yref=1.0, zref= 1.0; + float si, co, dist, startomtrekfac = 0.0, omtrekfac, oldval[3]; + int rotmode=0, time, fast=0, a, midtog=0, firsttime=1, proj= 0, fout= 0, cameragrab= 0, gridflag; + unsigned short event=0; + short mval[2], afbreek=0, doit, xn, yn, xc, yc, xo, yo = 0, val; + char str[100]; + int keyflags = 0; + + if(G.obedit && (G.f & G_PROPORTIONAL)) { + if(mode=='g') mode= 'G'; + if(mode=='r') mode= 'R'; + if(mode=='s') mode= 'C'; + } + /* form duplicate routines */ + if(mode=='d') mode= 'g'; + + /* kan floating exception veroorzaken op alpha */ + d_dvec[0]= d_dvec[1]= d_dvec[2]= 0.0; + dvec[0]= dvec[1]= dvec[2]= 0.0; + + if(G.scene->id.lib) return; + + if(mode=='t') { + if(G.obedit==0 || G.obedit->type!=OB_CURVE) return; + } + if(mode=='w' && G.obedit==0) return; + + /* welke data wordt behandeld? */ + if(G.obedit) { + if(mode=='N') vertexnormals(0); + + /* min en max zijn nodig voor de warp */ + if(mode=='G' || mode=='R' || mode=='C') make_trans_verts(min, max, 1); + else make_trans_verts(min, max, 0); + } + else if (G.obpose){ + + switch (G.obpose->type) { + case OB_ARMATURE: + make_trans_bones(mode); + break; + } + } + else { + int opt= 0; + if (mode=='g' || mode=='G') opt= 'g'; + else if (mode=='r' || mode=='R') opt= 'r'; + else if (mode=='s' || mode=='S') opt= 's'; + + setbaseflags_for_editing(opt); + + make_trans_objects(); + } + + if(tottrans==0) { + if(G.obedit==0) clearbaseflags_for_editing(); + return; + } + + if(G.obedit==0 && mode=='S') return; + + if(G.vd->around==V3D_LOCAL) { + if(G.obedit) { + centre[0]= centre[1]= centre[2]= 0.0; + } + + } + if(G.vd->around==V3D_CENTROID) { + VECCOPY(centre, centroid); + } + else if(G.vd->around==V3D_CURSOR) { + curs= give_cursor(); + VECCOPY(centre, curs); + + if(G.obedit) { + VecSubf(centre, centre, G.obedit->obmat[3]); + Mat3CpyMat4(mat, G.obedit->obmat); + Mat3Inv(imat, mat); + Mat3MulVecfl(imat, centre); + } + + } + + /* Always rotate around object centroid */ + if (G.obpose){ + VECCOPY (centre, centroid); + } + + /* moving: onderscheid i.v.m. drawobj */ + if(G.obedit) G.moving= 2; + else G.moving= 1; + + areawinset(curarea->win); + + /* de persinv is vervuild met translatie, niet gebruiken!! */ + Mat3CpyMat4(persmat, G.vd->persmat); + Mat3Inv(persinv, persmat); + + VECCOPY(rot0, persinv[0]); + Normalise(rot0); + VECCOPY(rot1, persinv[1]); + Normalise(rot1); + VECCOPY(rot2, persinv[2]); + Normalise(rot2); + + /* init vars */ + + Mat4Invert(viewinv, G.vd->viewmat); + + if(transvmain) { + VECCOPY(vec, centre); + Mat4MulVecfl(G.obedit->obmat, vec); + initgrabz(vec[0], vec[1], vec[2]); + project_short_noclip(vec, mval); + } + else { + /* voor pannen vanuit cameraview */ + if( G.vd->camera==OBACT && G.vd->persp>1) { + /* 6.0 = 6 grideenheden */ + centre[0]+= -6.0*rot2[0]; + centre[1]+= -6.0*rot2[1]; + centre[2]+= -6.0*rot2[2]; + } + + initgrabz(centre[0], centre[1], centre[2]); + project_short_noclip(centre, mval); + + if( G.vd->camera==OBACT && G.vd->persp>1) { + centre[0]+= 6.0*rot2[0]; + centre[1]+= 6.0*rot2[1]; + centre[2]+= 6.0*rot2[2]; + } + } + + VECCOPY(prop_cent, centre); + + xc= mval[0]; + yc= mval[1]; + + if(G.obedit) { + Mat3CpyMat4(omat, G.obedit->obmat); + Mat3Inv(imat, omat); + + Mat4Invert(imat4, G.obedit->obmat); + } + + else if(G.obpose) { + Mat3CpyMat4(omat, G.obpose->obmat); + Mat3Inv(imat, omat); + + Mat4Invert(imat4, G.obpose->obmat); + } + + else { + if(transmain) { + if(OBACT && G.vd->persp>1 && G.vd->camera==OBACT) { + cameragrab= 1; + xc= curarea->winx/2; + yc= curarea->winy/2; + } + } + } + + if((mode=='r' || mode=='s' || mode=='S') && xc==32000) { + error("centre far out of view"); + fout= 1; + } + + if(mode=='w' && G.obedit) { + Mat4MulVecfl(G.obedit->obmat, min); + Mat4MulVecfl(G.vd->viewmat, min); + Mat4MulVecfl(G.obedit->obmat, max); + Mat4MulVecfl(G.vd->viewmat, max); + + centre[0]= (min[0]+max[0])/2.0; + centre[1]= (min[1]+max[1])/2.0; + centre[2]= (min[2]+max[2])/2.0; + + /* middelpunt is cursor */ + curs= give_cursor(); + VECCOPY(axis, curs); + Mat4MulVecfl(G.vd->viewmat, axis); + rad= sqrt( (axis[0]-centre[0])*(axis[0]-centre[0])+(axis[1]-centre[1])*(axis[1]-centre[1]) ); + dist= max[0]-centre[0]; + if(dist==0.0) fout= 1; + else startomtrekfac= (90*rad*M_PI)/(360.0*dist); + } + + getmouseco_areawin(mval); + xn=xo= mval[0]; + yn=xo= mval[1]; + dx1= xc-xn; + dy1= yc-yn; + phi= phi0= phi1= 0.0; + + sizefac= sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) ); + if(sizefac<2.0) sizefac= 2.0; + + gridflag= U.flag; + + while(fout==0 && afbreek==0) { + + getmouseco_areawin(mval); + if(mval[0]!=xo || mval[1]!=yo || firsttime) { + if(firsttime) { + + /* niet zo netjes, maar toch! */ + oldval[0]= oldval[1]= oldval[2]= MAXFLOAT; + + /* proportional precalc */ + if(mode=='G' || mode=='R' || mode=='C') { + if(transvmain) { + tv= transvmain; + for(a=0; a<tottrans; a++, tv++) { + set_proportional_weight(tv, min, max); + } + } + } + } + firsttime= 0; + + if(mode=='g' || mode=='G') { + + keyflags |= KEYFLAG_LOC; + /* if(G.edve.first) sphere_intersect_test(); */ + + if(midtog) { + if(cameragrab) { + dx1= 0.002*(mval[1]-yn)*G.vd->grid; + dvec[0]-= dx1*G.vd->viewinv[2][0]; + dvec[1]-= dx1*G.vd->viewinv[2][1]; + dvec[2]-= dx1*G.vd->viewinv[2][2]; + firsttime= 1; /* blijftie lopen */ + } + else { + window_to_3d(dvec, mval[0]-xn, mval[1]-yn); + if(proj==0) dvec[1]=dvec[2]= 0.0; + if(proj==1) dvec[0]=dvec[2]= 0.0; + if(proj==2) dvec[0]=dvec[1]= 0.0; + } + } + else window_to_3d(dvec, mval[0]-xn, mval[1]-yn); + + /* grids */ + if(G.qual & LR_SHIFTKEY) { + dvec[0]= 0.1*(dvec[0]-d_dvec[0])+d_dvec[0]; + dvec[1]= 0.1*(dvec[1]-d_dvec[1])+d_dvec[1]; + dvec[2]= 0.1*(dvec[2]-d_dvec[2])+d_dvec[2]; + } + apply_keyb_grid(dvec, 0.0, G.vd->grid, 0.1*G.vd->grid, gridflag & AUTOGRABGRID); + apply_keyb_grid(dvec+1, 0.0, G.vd->grid, 0.1*G.vd->grid, gridflag & AUTOGRABGRID); + apply_keyb_grid(dvec+2, 0.0, G.vd->grid, 0.1*G.vd->grid, gridflag & AUTOGRABGRID); + + if(dvec[0]!=oldval[0] ||dvec[1]!=oldval[1] ||dvec[2]!=oldval[2]) { + VECCOPY(oldval, dvec); + + /* speedup for vertices */ + if (G.obedit) { + VECCOPY(dvecp, dvec); + Mat3MulVecfl(imat, dvecp); + } + + + /* apply */ + tob= transmain; + tv= transvmain; + for(a=0; a<tottrans; a++, tob++, tv++) { + + if(transmain) { + VECCOPY(dvecp, dvec); + + if(transmode==TRANS_TEX) Mat3MulVecfl(tob->obinv, dvecp); + + if(tob->flag & TOB_IKA) { + VecAddf(tob->eff, tob->oldeff, dvecp); + } + else + Mat3MulVecfl(tob->parinv, dvecp); + + if(tob->flag & TOB_IPO) { + add_ipo_tob_poin(tob->locx, tob->oldloc, dvecp[0]); + add_ipo_tob_poin(tob->locy, tob->oldloc+1, dvecp[1]); + add_ipo_tob_poin(tob->locz, tob->oldloc+2, dvecp[2]); + } + else if(tob->loc) { + VecAddf(tob->loc, tob->oldloc, dvecp); + } + } + else { + if(mode=='G') { + tv->loc[0]= tv->oldloc[0]+tv->fac*dvecp[0]; + tv->loc[1]= tv->oldloc[1]+tv->fac*dvecp[1]; + tv->loc[2]= tv->oldloc[2]+tv->fac*dvecp[2]; + } + else VecAddf(tv->loc, tv->oldloc, dvecp); + } + + } + sprintf(str, "Dx: %.4f Dy: %.4f Dz: %.4f", dvec[0], dvec[1], dvec[2]); + headerprint(str); + + time= my_clock(); + + if(G.obedit) calc_trans_verts(); + special_trans_update(keyflags); + + if(fast==0) { + force_draw(); + time= my_clock()-time; + if(time>50) fast= 1; + } + else { + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } + } + } + else if(mode=='r' || mode=='t' || mode=='R') { + doit= 0; + keyflags |= KEYFLAG_ROT; + dx2= xc-mval[0]; + dy2= yc-mval[1]; + + if(midtog && (mode=='r' || mode=='R')) { + phi0+= .007*(float)(dy2-dy1); + phi1+= .007*(float)(dx1-dx2); + + apply_keyb_grid(&phi0, 0.0, (5.0/180)*M_PI, (1.0/180)*M_PI, gridflag & AUTOROTGRID); + apply_keyb_grid(&phi1, 0.0, (5.0/180)*M_PI, (1.0/180)*M_PI, gridflag & AUTOROTGRID); + + + if(oldval[0]!=phi0 || oldval[1]!=phi1) { + VecRotToMat3(rot0, phi0, smat); + VecRotToMat3(rot1, phi1, totmat); + + Mat3MulMat3(mat, smat, totmat); + dx1= dx2; + dy1= dy2; + oldval[0]= phi0; + oldval[1]= phi1; + doit= 1; + } + } + else { + deler= sqrt( (dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2)); + if(deler>1.0) { + + dphi= (dx1*dx2+dy1*dy2)/deler; + dphi= saacos(dphi); + if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi; + + if(G.qual & LR_SHIFTKEY) phi+= dphi/30.0; + else phi+= dphi; + + apply_keyb_grid(&phi, 0.0, (5.0/180)*M_PI, (1.0/180)*M_PI, gridflag & AUTOROTGRID); + + if(oldval[2]!=phi) { + dx1= dx2; + dy1= dy2; + oldval[2]= phi; + doit= 1; + if(rotmode) { + + if(rotmode==XROT) vec[0]= -1.0; else vec[0]= 0.0; + if(rotmode==YROT) vec[1]= 1.0; else vec[1]= 0.0; + if(rotmode==ZROT) vec[2]= -1.0; else vec[2]= 0.0; + + VecRotToMat3(vec, phi, mat); + } + else VecRotToMat3(rot2, phi, mat); + } + } + + } + if(doit) { + /* apply */ + tob= transmain; + tv= transvmain; + + for(a=0; a<tottrans; a++, tob++, tv++) { + if(transmain) { + /* rotatie in drie stappen: + * 1. editrot corrigeren voor parent + * 2. hier de euler uit destilleren. Deze stap moet omdat de MatToEul nogal zwak is + * 3. deze vermenigvuldigen met eigen rot, euler berekenen. + */ + + /* Roll around local axis */ + if (mode=='r' || mode=='R'){ + if (tob && rotmode){ + if (rotmode == XROTLOCAL){ + VECCOPY(vec, tob->axismat[0]); + } + if (rotmode == YROTLOCAL){ + VECCOPY(vec, tob->axismat[1]); + } + if (rotmode == ZROTLOCAL){ + VECCOPY(vec, tob->axismat[2]); + } + + /* Correct the vector */ + if ((rotmode & ROTLOCAL) && ((G.vd->viewmat[0][2] * vec[0]+G.vd->viewmat[1][2] * vec[1]+G.vd->viewmat[2][2] * vec[2])>0)){ + vec[0]*=-1; + vec[1]*=-1; + vec[2]*=-1; + } + + VecRotToMat3(vec, phi, mat); + } + } + Mat3MulSerie(smat, tob->parmat, mat, tob->parinv, 0, 0, 0, 0, 0); + + /* 2 */ + if( (tob->ob->transflag & OB_QUAT) == 0 && tob->rot){ + Mat3ToEul(smat, eul); + EulToMat3(eul, smat); + } + + /* 3 */ + /* we werken even met de rot+drot */ + + if(tob->ob->transflag & OB_QUAT || !tob->rot) + { + /* drot+rot NOG DOEN! */ + Mat3ToQuat(smat, quat); // Original + QuatMul(tob->quat, quat, tob->oldquat); + + if(tob->flag & TOB_IPO) { + + if(tob->flag & TOB_IPODROT) { + /* VecSubf(rot, eul, tob->oldrot); */ + } + else { + /* VecSubf(rot, eul, tob->olddrot); */ +// VecSubf(rot, eul, tob->olddrot); + } + + /* VecMulf(rot, 9.0/M_PI_2); */ + /* VecSubf(rot, rot, tob->oldrot+3); */ + + /* add_ipo_tob_poin(tob->rotx, tob->oldrot+3, rot[0]); */ + /* add_ipo_tob_poin(tob->roty, tob->oldrot+4, rot[1]); */ + /* add_ipo_tob_poin(tob->rotz, tob->oldrot+5, rot[2]); */ + + } + else { + /* QuatSub(tob->quat, quat, tob->oldquat); */ +// QuatSub(tob->quat, quat, tob->oldquat); + } + } + else { + VecAddf(eul, tob->oldrot, tob->olddrot); + EulToMat3(eul, tmat); + + Mat3MulMat3(totmat, smat, tmat); + + Mat3ToEul(totmat, eul); + + /* Eul mag niet te gek afwijken van oude eul. + * Dit is alleen nog maar getest voor dx && dz + */ + + compatible_eul(eul, tob->oldrot); + + if(tob->flag & TOB_IPO) { + + if(tob->flag & TOB_IPODROT) { + VecSubf(rot, eul, tob->oldrot); + } + else { + VecSubf(rot, eul, tob->olddrot); + } + + VecMulf(rot, 9.0/M_PI_2); + VecSubf(rot, rot, tob->oldrot+3); + + + add_ipo_tob_poin(tob->rotx, tob->oldrot+3, rot[0]); + add_ipo_tob_poin(tob->roty, tob->oldrot+4, rot[1]); + add_ipo_tob_poin(tob->rotz, tob->oldrot+5, rot[2]); + + } + else { + VecSubf(tob->rot, eul, tob->olddrot); + } + + /* See if we've moved */ + if (!VecCompare (tob->loc, tob->oldloc, 0.01)){ + keyflags |= KEYFLAG_LOC; + } + + } + + if(G.vd->around!=V3D_LOCAL && (!G.obpose)) { + /* translatie */ + VecSubf(vec, tob->obvec, centre); + Mat3MulVecfl(mat, vec); + VecAddf(vec, vec, centre); + /* vec is nu de plek waar het object moet komen */ + VecSubf(vec, vec, tob->obvec); + Mat3MulVecfl(tob->parinv, vec); + + if(tob->flag & TOB_IPO) { + add_ipo_tob_poin(tob->locx, tob->oldloc, vec[0]); + add_ipo_tob_poin(tob->locy, tob->oldloc+1, vec[1]); + add_ipo_tob_poin(tob->locz, tob->oldloc+2, vec[2]); + } + else if(tob->loc) { + VecAddf(tob->loc, tob->oldloc, vec); + } + } + } + else { + if(mode=='t') { + if(tv->val) *(tv->val)= tv->oldval-phi; + } + else { + + if(mode=='R') { + + if(midtog) { + VecRotToMat3(rot0, tv->fac*phi0, smat); + VecRotToMat3(rot1, tv->fac*phi1, totmat); + Mat3MulMat3(mat, smat, totmat); + } + else VecRotToMat3(rot2, tv->fac*phi, mat); + + } + + Mat3MulMat3(totmat, mat, omat); + Mat3MulMat3(smat, imat, totmat); + + VecSubf(vec, tv->oldloc, centre); + Mat3MulVecfl(smat, vec); + + VecAddf(tv->loc, vec, centre); + } + } + } + + if(midtog) sprintf(str, "Rotx: %.2f Roty: %.2f", 180.0*phi0/M_PI, 180.0*phi1/M_PI); + else if(rotmode) { + if(rotmode==XROT) sprintf(str, "Rot X: %.2f", 180.0*phi/M_PI); + else if(rotmode==YROT) sprintf(str, "Rot Y: %.2f", 180.0*phi/M_PI); + else if(rotmode==ZROT) sprintf(str, "Rot Z: %.2f", 180.0*phi/M_PI); + else if(rotmode==XROTLOCAL) sprintf(str, "Local Rot X: %.2f", 180.0*phi/M_PI); + else if(rotmode==YROTLOCAL) sprintf(str, "Local Rot Y: %.2f", 180.0*phi/M_PI); + else if(rotmode==ZROTLOCAL) sprintf(str, "Local Rot Z: %.2f", 180.0*phi/M_PI); + } + else sprintf(str, "Rot: %.2f", 180.0*phi/M_PI); + headerprint(str); + + time= my_clock(); + + if(G.obedit) calc_trans_verts(); + special_trans_update(keyflags); + + if(fast==0) { + force_draw(); + time= my_clock()-time; + if(time>50) fast= 1; + } + else { + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } + if(tottrans>1 || G.vd->around==V3D_CURSOR) helpline(centre); + else if (G.obpose) helpline (centre); + } + } + else if(mode=='s' || mode=='S' || mode=='C' || mode=='N') { + keyflags |= KEYFLAG_SIZE; + + if(mode=='S') { + size[0]= 1.0-(float)(xn-mval[0])*0.005; + size[1]= 1.0-(float)(yn-mval[1])*0.005; + size[2]= 1.0; + } + else size[0]=size[1]=size[2]= (sqrt( (float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc)) ))/sizefac; + + if(midtog && mode=='s') { + /* shear has no midtog */ + if(proj==0) size[1]=size[2]= 1.0; + if(proj==1) size[0]=size[2]= 1.0; + if(proj==2) size[1]=size[0]= 1.0; + } + +/* X en Y flip, twee methodes: bij |**| commentaar weghalen maakt flips lokaal */ + +/**/ /* if(transvmain) { */ + + /* x flip */ + val= test_midtog_proj(mval[0]+10, mval[1], mval); + size[val]*= xref; + /* y flip */ + val= test_midtog_proj(mval[0], mval[1]+10, mval); + size[val]*= yref; + +/**/ /* } */ + + + /* grid */ + apply_keyb_grid(size, 0.0, 0.1, 0.01, gridflag & AUTOSIZEGRID); + apply_keyb_grid(size+1, 0.0, 0.1, 0.01, gridflag & AUTOSIZEGRID); + apply_keyb_grid(size+2, 0.0, 0.1, 0.01, gridflag & AUTOSIZEGRID); + + if(transmain) { + size[0]= MINSIZE(size[0], 0.01); + size[1]= MINSIZE(size[1], 0.01); + size[2]= MINSIZE(size[2], 0.01); + } + + if(size[0]!=oldval[0] ||size[1]!=oldval[1] ||size[2]!=oldval[2]) { + VECCOPY(oldval, size); + + SizeToMat3(size, mat); + + /* apply */ + tob= transmain; + tv= transvmain; + + for(a=0; a<tottrans; a++, tob++, tv++) { + if(transmain) { + /* size moet lokaal t.o.v. ouder EN van eigen rotatie */ + /* lokaal tov. ouder: */ + + + + Mat3MulSerie(smat, tob->parmat, mat, tob->parinv, 0, 0,0 ,0, 0); + + /* lokaal tov. eigen rot: */ + Mat3MulSerie(totmat, tob->obmat, smat, tob->obinv, 0, 0, 0,0 ,0); + + /* XXX this can yield garbage in case of inverted sizes (< 0.0) + */ + if(!midtog) { + sizelo[0]= size[0]; + sizelo[1]= size[1]; + sizelo[2]= size[2]; + } else { + /* dan klopt de vorige berekening van de juiste size niet meer precies */ + sizelo[0]= totmat[0][0]; + sizelo[1]= totmat[1][1]; + sizelo[2]= totmat[2][2]; + apply_keyb_grid(sizelo, 0.0, 0.1, 0.01, gridflag & AUTOSIZEGRID); + apply_keyb_grid(sizelo+1, 0.0, 0.1, 0.01, gridflag & AUTOSIZEGRID); + apply_keyb_grid(sizelo+2, 0.0, 0.1, 0.01, gridflag & AUTOSIZEGRID); + } + + /* x flip */ +/**/ /* sizelo[0]*= xref; */ + /* y flip */ +/**/ /* sizelo[1]*= yref; */ + /* z flip */ +/**/ /* sizelo[2]*= zref; */ + + + /* what you see is what you want; not what you get! */ + /* correctie voor delta size */ + if(tob->flag & TOB_IPO) { + /* deltasize berekenen (gelijk voor size en dsize) */ + + vec[0]= (tob->oldsize[0]+tob->olddsize[0])*(sizelo[0] -1.0); + vec[1]= (tob->oldsize[1]+tob->olddsize[1])*(sizelo[1] -1.0); + vec[2]= (tob->oldsize[2]+tob->olddsize[2])*(sizelo[2] -1.0); + + add_ipo_tob_poin(tob->sizex, tob->oldsize+3, vec[0]); + add_ipo_tob_poin(tob->sizey, tob->oldsize+4, vec[1]); + add_ipo_tob_poin(tob->sizez, tob->oldsize+5, vec[2]); + + } + else { + tob->size[0]= (tob->oldsize[0]+tob->olddsize[0])*sizelo[0] -tob->olddsize[0]; + tob->size[1]= (tob->oldsize[1]+tob->olddsize[1])*sizelo[1] -tob->olddsize[1]; + tob->size[2]= (tob->oldsize[2]+tob->olddsize[2])*sizelo[2] -tob->olddsize[2]; + } + + if(G.vd->around!=V3D_LOCAL && !G.obpose) { + /* translatie */ + VecSubf(vec, tob->obvec, centre); + Mat3MulVecfl(mat, vec); + VecAddf(vec, vec, centre); + /* vec is nu de plek waar het object moet komen */ + VecSubf(vec, vec, tob->obvec); + Mat3MulVecfl(tob->parinv, vec); + + if(tob->flag & TOB_IPO) { + add_ipo_tob_poin(tob->locx, tob->oldloc, vec[0]); + add_ipo_tob_poin(tob->locy, tob->oldloc+1, vec[1]); + add_ipo_tob_poin(tob->locz, tob->oldloc+2, vec[2]); + } + else if(tob->loc) { + if(transmode==TRANS_TEX) ; + else VecAddf(tob->loc, tob->oldloc, vec); + } + } + } + else { /* vertices */ + + /* for print */ + VECCOPY(sizelo, size); + + if(mode=='C') { + size[0]= tv->fac*size[0]+ 1.0-tv->fac;; + size[1]= tv->fac*size[1]+ 1.0-tv->fac;; + size[2]= tv->fac*size[2]+ 1.0-tv->fac;; + SizeToMat3(size, mat); + VECCOPY(size, oldval); + } + + if(mode=='S') { /* shear */ + Mat3One(tmat); + tmat[0][0]= tmat[2][2]= tmat[1][1]= 1.0; + tmat[1][0]= size[0]-1.0; + + Mat3MulMat3(totmat, persmat, omat); + Mat3MulMat3(mat, tmat, totmat); + Mat3MulMat3(totmat, persinv, mat); + Mat3MulMat3(smat, imat, totmat); + } + else { + Mat3MulMat3(totmat, mat, omat); + Mat3MulMat3(smat, imat, totmat); + } + + if(mode=='N' && tv->nor!=NULL) { + tv->loc[0]= tv->oldloc[0] + (size[0]-1.0)*tv->nor[0]; + tv->loc[1]= tv->oldloc[1] + (size[1]-1.0)*tv->nor[1]; + tv->loc[2]= tv->oldloc[2] + (size[2]-1.0)*tv->nor[2]; + } + else { + VecSubf(vec, tv->oldloc, centre); + Mat3MulVecfl(smat, vec); + VecAddf(tv->loc, vec, centre); + + if(G.obedit->type==OB_MBALL) *(tv->val)= size[0]*tv->oldval; + } + } + } + if(mode=='s') + sprintf(str, "Sizex: %.3f Sizey: %.3f Sizez: %.3f", sizelo[0], sizelo[1], sizelo[2]); + else if (mode=='S') + sprintf(str, "Shear: %.3f ", sizelo[0]); + else if (mode=='C') + sprintf(str, "Size: %.3f ", sizelo[0]); + else if (mode=='N') + sprintf(str, "Shrink/Fatten: %.3f ", size[0]); + + headerprint(str); + + time= my_clock(); + + if(G.obedit) calc_trans_verts(); + special_trans_update(keyflags); + + + if(fast==0) { + force_draw(); + time= my_clock()-time; + if(time>50) fast= 1; + } + else { + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } + if(tottrans>1 || G.vd->around==V3D_CURSOR) helpline(centre); + } + } + else if(mode=='w') { + + window_to_3d(dvec, 1, 1); + + omtrekfac= startomtrekfac+ 0.05*( mval[1] - yn)*Normalise(dvec); + + /* berekenen hoek voor print */ + dist= max[0]-centre[0]; + phi0= 360*omtrekfac*dist/(rad*M_PI); + + if(G.qual & LR_CTRLKEY) { + phi0= 5.0*floor(phi0/5.0); + omtrekfac= (phi0*rad*M_PI)/(360.0*dist); + } + + + sprintf(str, "Warp %3.3f", phi0); + headerprint(str); + + /* elke vertex moet apart geroteerd */ + tob= transmain; + tv= transvmain; + + for(a=0; a<tottrans; a++, tob++, tv++) { + if(transvmain) { + + /* punt transleren naar centre, zodanig roteren dat omtrekafstand==afstand */ + + VECCOPY(vec, tv->oldloc); + Mat4MulVecfl(G.obedit->obmat, vec); + Mat4MulVecfl(G.vd->viewmat, vec); + + dist= vec[0]-centre[0]; + + phi0= (omtrekfac*dist/rad) - 0.5*M_PI; + + co= cos(phi0); + si= sin(phi0); + + vec[0]= (centre[0]-axis[0]); + vec[1]= (vec[1]-axis[1]); + + tv->loc[0]= si*vec[0]+co*vec[1]+axis[0]; + + tv->loc[1]= co*vec[0]-si*vec[1]+axis[1]; + tv->loc[2]= vec[2]; + + Mat4MulVecfl(viewinv, tv->loc); + Mat4MulVecfl(imat4, tv->loc); + + } + } + + if(G.obedit) calc_trans_verts(); + special_trans_update(keyflags); + + if(fast==0) { + time= my_clock(); + force_draw(); + time= my_clock()-time; + if(time>50) fast= 1; + } + else { + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } + } + } + + while( qtest() ) { + event= extern_qread(&val); + + if(val) { + switch(event) { + case ESCKEY: + case LEFTMOUSE: + case RIGHTMOUSE: + case SPACEKEY: + case RETKEY: + afbreek= 1; + break; + case MIDDLEMOUSE: + midtog= ~midtog; + if(midtog) { + proj= test_midtog_proj(xn, yn, mval); + phi0= phi1= 0.0; + if(cameragrab) { + dvec[0]= dvec[1]= dvec[2]= 0.0; + } + } + firsttime= 1; + break; + case GKEY: + case RKEY: + case SKEY: + getmouseco_areawin(mval); + xn=xo= mval[0]; + yn=xo= mval[1]; + dx1= xc-xn; + dy1= yc-yn; + phi= phi0= phi1= 0.0; + sizefac= sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) ); + if(sizefac<2.0) sizefac= 2.0; + + if (G.obedit && (G.f & G_PROPORTIONAL)) { + if(event==GKEY) mode= 'G'; + else if(event==RKEY) mode= 'R'; + else if(event==SKEY) mode= 'C'; + } else { + if(event==GKEY) mode= 'g'; + else if(event==RKEY) mode= 'r'; + else if(event==SKEY) mode= 's'; + } + + firsttime= 1; + + tob= transmain; + tv= transvmain; + for(a=0; a<tottrans; a++, tob++, tv++) { + if(transmain) { + restore_tob(tob); + } + else { + VECCOPY(tv->loc, tv->oldloc); + } + } + break; + + case XKEY: + if (rotmode==XROT) + rotmode=XROTLOCAL; + else if (rotmode==XROTLOCAL) + rotmode=0; + else{ + xref= -xref; + rotmode= XROT; + } + firsttime=1; + break; + + case YKEY: + if (rotmode==YROT) + rotmode=YROTLOCAL; + else if (rotmode==YROTLOCAL) + rotmode=0; + else{ + yref= -yref; + rotmode= YROT; + } + firsttime=1; + break; + + case ZKEY: + if (rotmode==ZROT) + rotmode=ZROTLOCAL; + else if (rotmode==ZROTLOCAL) + rotmode=0; + else{ + zref= -zref; + rotmode= ZROT; + } + firsttime=1; + break; + + case PADPLUSKEY: + if(G.f & G_PROPORTIONAL) { + prop_size*= 1.1; + firsttime= 1; + } + break; + case PADMINUS: + if(G.f & G_PROPORTIONAL) { + prop_size*= 0.90909090; + firsttime= 1; + } + break; + + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + VECCOPY(d_dvec, dvec); + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + firsttime= 1; + break; + } + + arrows_move_cursor(event); + } + if(event==0 || afbreek) break; + + } + xo= mval[0]; + yo= mval[1]; + + if( qtest()==0) PIL_sleep_ms(1); + + } + G.moving= 0; + + if(event==ESCKEY || event==RIGHTMOUSE) { + canceled=1; + tv= transvmain; + tob= transmain; + for(a=0; a<tottrans; a++, tob++, tv++) { + if(transmain) { + restore_tob(tob); + } + else { + VECCOPY(tv->loc, tv->oldloc); + if(tv->val) *(tv->val)= tv->oldval; + } + } + if(G.obedit) calc_trans_verts(); + special_trans_update(keyflags); + } + + a= 0; + if(xref<0) a++; + if(yref<0) a++; + if(zref<0) a++; + special_aftertrans_update(mode, a & 1, canceled, keyflags); + + allqueue(REDRAWVIEW3D, 0); + scrarea_queue_headredraw(curarea); + + clearbaseflags_for_editing(); + + if(transmain) MEM_freeN(transmain); + transmain= 0; + if(transvmain) MEM_freeN(transvmain); + transvmain= 0; + + tottrans= 0; +} + +void std_rmouse_transform(void (*xf_func)(int)) +{ + short mval[2]; + short xo, yo; + + getmouseco_areawin(mval); + xo= mval[0]; + yo= mval[1]; + + while(get_mbut()&R_MOUSE) { + getmouseco_areawin(mval); + if(abs(mval[0]-xo)+abs(mval[1]-yo) > 10) { + xf_func('g'); + while(get_mbut()&R_MOUSE) BIF_wait_for_statechange(); + return; + } + + BIF_wait_for_statechange(); + } +} + +void rightmouse_transform(void) +{ + std_rmouse_transform(transform); +} + + +/* ************************************** */ + + +void single_object_users(int flag) + /* hierna wel clear_id_newpoins() aanroepen */ +{ + Base *base; + Object *ob, *obn; + + clear_sca_new_poins(); /* sensor/contr/act */ + + /* dupliceren */ + base= FIRSTBASE; + while(base) { + ob= base->object; + + if( (base->flag & flag)==flag) { + + if(ob->id.lib==0 && ob->id.us>1) { + + obn= copy_object(ob); + ob->id.us--; + base->object= obn; + } + } + base= base->next; + } + + ID_NEW(G.scene->camera); + if(G.vd) ID_NEW(G.vd->camera); + + /* evt object pointers */ + base= FIRSTBASE; + while(base) { + ob= base->object; + if(ob->id.lib==0) { + if( (base->flag & flag)==flag) { + + ID_NEW(ob->parent); + ID_NEW(ob->track); + + } + } + base= base->next; + } + + set_sca_new_poins(); +} + +void new_id_matar(Material **matar, int totcol) +{ + ID *id; + int a; + + for(a=0; a<totcol; a++) { + id= (ID *)matar[a]; + if(id && id->lib==0) { + if(id->newid) { + matar[a]= (Material *)id->newid; + id_us_plus(id->newid); + id->us--; + } + else if(id->us>1) { + matar[a]= copy_material(matar[a]); + id->us--; + id->newid= (ID *)matar[a]; + } + } + } +} + +void single_obdata_users(int flag) +{ + Object *ob; + Lamp *la; + Curve *cu; + Ika *ika; + Deform *def; + Base *base; + Mesh *me; + ID *id; + int a; + + base= FIRSTBASE; + while(base) { + ob= base->object; + if(ob->id.lib==0 && (base->flag & flag)==flag ) { + id= ob->data; + + if(id && id->us>1 && id->lib==0) { + + switch(ob->type) { + case OB_LAMP: + if(id && id->us>1 && id->lib==0) { + ob->data= la= copy_lamp(ob->data); + for(a=0; a<8; a++) { + if(la->mtex[a]) { + ID_NEW(la->mtex[a]->object); + } + } + } + break; + case OB_CAMERA: + ob->data= copy_camera(ob->data); + break; + case OB_MESH: + ob->data= copy_mesh(ob->data); + break; + case OB_MBALL: + ob->data= copy_mball(ob->data); + break; + case OB_CURVE: + case OB_SURF: + case OB_FONT: + ob->data= cu= copy_curve(ob->data); + ID_NEW(cu->bevobj); + makeDispList(ob); + break; + case OB_LATTICE: + ob->data= copy_lattice(ob->data); + break; + case OB_ARMATURE: + ob->data=copy_armature(ob->data); + break; + case OB_IKA: + /* this never occurs? IK is always single user */ + ob->data= ika= copy_ika(ob->data); + ID_NEW(ika->parent); + + if(ika->totdef) { + a= ika->totdef; + def= ika->def; + while(a--) { + ID_NEW(def->ob); + def++; + } + } + + break; + default: + printf("ERROR single_obdata_users: %s\n", id->name); + error("Read console"); + return; + } + + id->us--; + id->newid= ob->data; + + } + + id= (ID *)ob->action; + if (id && id->us>1 && id->lib==0){ + if(id->newid){ + ob->action= (bAction *)id->newid; + id_us_plus(id->newid); + } + else { + ob->action=copy_action(ob->action); + ob->activecon=NULL; + id->us--; + id->newid=(ID *)ob->action; + } + } + id= (ID *)ob->ipo; + if(id && id->us>1 && id->lib==0) { + if(id->newid) { + ob->ipo= (Ipo *)id->newid; + id_us_plus(id->newid); + } + else { + ob->ipo= copy_ipo(ob->ipo); + id->us--; + id->newid= (ID *)ob->ipo; + } + } + switch(ob->type) { + case OB_LAMP: + la= ob->data; + if(la->ipo && la->ipo->id.us>1) { + la->ipo->id.us--; + la->ipo= copy_ipo(la->ipo); + } + } + + } + base= base->next; + } + + me= G.main->mesh.first; + while(me) { + ID_NEW(me->texcomesh); + me= me->id.next; + } +} + + +void single_mat_users(int flag) +{ + Object *ob; + Base *base; + Material *ma, *man; + Tex *tex; + int a, b; + + + base= FIRSTBASE; + while(base) { + ob= base->object; + if(ob->id.lib==0 && (flag==0 || (base->flag & SELECT)) ) { + + for(a=1; a<=ob->totcol; a++) { + ma= give_current_material(ob, a); + if(ma) { + /* hier niet LIB_NEW testen: deze fie geeft gegarandeerde single_users! */ + + if(ma->id.us>1) { + man= copy_material(ma); + + man->id.us= 0; + assign_material(ob, man, a); + + if(ma->ipo) { + man->ipo= copy_ipo(ma->ipo); + ma->ipo->id.us--; + } + + for(b=0; b<8; b++) { + if(ma->mtex[b] && ma->mtex[b]->tex) { + tex= ma->mtex[b]->tex; + if(tex->id.us>1) { + ma->mtex[b]->tex= copy_texture(tex); + tex->id.us--; + } + } + } + + } + } + } + } + base= base->next; + } +} + +void do_single_tex_user(Tex **from) +{ + Tex *tex, *texn; + + tex= *from; + if(tex==0) return; + + if(tex->id.newid) { + *from= (Tex *)tex->id.newid; + id_us_plus(tex->id.newid); + tex->id.us--; + } + else if(tex->id.us>1) { + texn= copy_texture(tex); + tex->id.newid= (ID *)texn; + tex->id.us--; + *from= texn; + } + +} + +void single_tex_users_expand() +{ + /* alleen als 'ouder' blokken LIB_NEW zijn */ + Material *ma; + Lamp *la; + World *wo; + int b; + + ma= G.main->mat.first; + while(ma) { + if(ma->id.flag & LIB_NEW) { + for(b=0; b<8; b++) { + if(ma->mtex[b] && ma->mtex[b]->tex) { + do_single_tex_user( &(ma->mtex[b]->tex) ); + } + } + } + ma= ma->id.next; + } + + la= G.main->lamp.first; + while(la) { + if(la->id.flag & LIB_NEW) { + for(b=0; b<6; b++) { + if(la->mtex[b] && la->mtex[b]->tex) { + do_single_tex_user( &(la->mtex[b]->tex) ); + } + } + } + la= la->id.next; + } + wo= G.main->world.first; + while(wo) { + if(wo->id.flag & LIB_NEW) { + for(b=0; b<6; b++) { + if(wo->mtex[b] && wo->mtex[b]->tex) { + do_single_tex_user( &(wo->mtex[b]->tex) ); + } + } + } + wo= wo->id.next; + } +} + +void single_mat_users_expand(void) +{ + /* alleen als 'ouder' blokken LIB_NEW zijn */ + + Object *ob; + Mesh *me; + Curve *cu; + MetaBall *mb; + Material *ma; + int a; + + ob= G.main->object.first; + while(ob) { + if(ob->id.flag & LIB_NEW) { + new_id_matar(ob->mat, ob->totcol); + } + ob= ob->id.next; + } + + me= G.main->mesh.first; + while(me) { + if(me->id.flag & LIB_NEW) { + new_id_matar(me->mat, me->totcol); + } + me= me->id.next; + } + + cu= G.main->curve.first; + while(cu) { + if(cu->id.flag & LIB_NEW) { + new_id_matar(cu->mat, cu->totcol); + } + cu= cu->id.next; + } + + mb= G.main->mball.first; + while(mb) { + if(mb->id.flag & LIB_NEW) { + new_id_matar(mb->mat, mb->totcol); + } + mb= mb->id.next; + } + + /* material imats */ + ma= G.main->mat.first; + while(ma) { + if(ma->id.flag & LIB_NEW) { + for(a=0; a<8; a++) { + if(ma->mtex[a]) { + ID_NEW(ma->mtex[a]->object); + } + } + } + ma= ma->id.next; + } +} + +void single_user(void) +{ + int nr; + + if(G.scene->id.lib) return; + + nr= pupmenu("Make Single User%t|Object|Object & ObData|Object & ObData & Materials+Tex|Materials+Tex"); + if(nr>0) { + + if(nr==1) single_object_users(1); + + else if(nr==2) { + single_object_users(1); + single_obdata_users(1); + } + else if(nr==3) { + single_object_users(1); + single_obdata_users(1); + single_mat_users(1); /* ook tex */ + + } + else if(nr==4) { + single_mat_users(1); + } + + clear_id_newpoins(); + + countall(); + allqueue(REDRAWALL, 0); + } +} + +/* ************************************************************* */ + + +void make_local(void) +{ + Base *base; + Object *ob; + Material *ma, ***matarar; + Lamp *la; + Curve *cu; + ID *id; + int a, b, mode; + + /* LETOP: de functie new_id(..) voegt het id blok opnieuw in!!! */ + + if(G.scene->id.lib) return; + + mode= pupmenu("Make Local%t|Selected %x1|All %x2"); + + if(mode==2) { + all_local(); + allqueue(REDRAWALL, 0); + return; + } + else if(mode!=1) return; + + clear_id_newpoins(); + + base= FIRSTBASE; + while(base) { + ob= base->object; + if( (base->flag & SELECT)) { + if(ob->id.lib) { + make_local_object(ob); + } + } + base= base->next; + } + + /* evt object pointers */ + base= FIRSTBASE; + while(base) { + ob= base->object; + if( (base->flag & SELECT)) { + if(ob->id.lib==0) { + ID_NEW(ob->parent); + ID_NEW(ob->track); + } + } + base= base->next; + } + + base= FIRSTBASE; + while(base) { + ob= base->object; + if( (base->flag & SELECT) ) { + + id= ob->data; + + if(id) { + + switch(ob->type) { + case OB_LAMP: + make_local_lamp((Lamp *)id); + + la= ob->data; + id= (ID *)la->ipo; + if(id && id->lib) make_local_ipo(la->ipo); + + break; + case OB_CAMERA: + make_local_camera((Camera *)id); + break; + case OB_MESH: + make_local_mesh((Mesh *)id); + make_local_key( ((Mesh *)id)->key ); + break; + case OB_MBALL: + make_local_mball((MetaBall *)id); + break; + case OB_CURVE: + case OB_SURF: + case OB_FONT: + cu= (Curve *)id; + make_local_curve(cu); + id= (ID *)cu->ipo; + if(id && id->lib) make_local_ipo(cu->ipo); + make_local_key( cu->key ); + break; + case OB_LATTICE: + make_local_lattice((Lattice *)id); + make_local_key( ((Lattice *)id)->key ); + break; + case OB_ARMATURE: + make_local_armature ((bArmature *)id); + break; + } + } + id= (ID *)ob->ipo; + if(id && id->lib) make_local_ipo(ob->ipo); + + id= (ID *)ob->action; + if(id && id->lib) make_local_action(ob->action); + } + base= base->next; + } + + base= FIRSTBASE; + while(base) { + ob= base->object; + if(base->flag & SELECT ) { + + if(ob->type==OB_LAMP) { + la= ob->data; + for(b=0; b<8; b++) { + if(la->mtex[b] && la->mtex[b]->tex) { + make_local_texture(la->mtex[b]->tex); + } + } + } + else { + + for(a=0; a<ob->totcol; a++) { + ma= ob->mat[a]; + if(ma) { + make_local_material(ma); + + for(b=0; b<8; b++) { + if(ma->mtex[b] && ma->mtex[b]->tex) { + make_local_texture(ma->mtex[b]->tex); + } + } + id= (ID *)ma->ipo; + if(id && id->lib) make_local_ipo(ma->ipo); + } + } + + matarar= (Material ***)give_matarar(ob); + + for(a=0; a<ob->totcol; a++) { + ma= (*matarar)[a]; + if(ma) { + make_local_material(ma); + + for(b=0; b<8; b++) { + if(ma->mtex[b] && ma->mtex[b]->tex) { + make_local_texture(ma->mtex[b]->tex); + } + } + id= (ID *)ma->ipo; + if(id && id->lib) make_local_ipo(ma->ipo); + } + } + } + } + base= base->next; + } + + + allqueue(REDRAWALL, 0); + +} + + +void adduplicate(float *dtrans) +/* dtrans is 3 x 3xfloat dloc, drot en dsize */ +{ + Base *base, *basen; + Object *ob, *obn; + Ika *ika; + Deform *def; + Material ***matarar, *ma, *mao; + ID *id; + bConstraintChannel *chan; + int a, didit, dupflag; + + if(G.scene->id.lib) return; + clear_id_newpoins(); + clear_sca_new_poins(); /* sensor/contr/act */ + + if( G.qual & LR_ALTKEY ) dupflag= 0; + else dupflag= U.dupflag; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + + ob= base->object; + obn= copy_object(ob); + + basen= MEM_mallocN(sizeof(Base), "duplibase"); + *basen= *base; + BLI_addhead(&G.scene->base, basen); /* addhead: anders oneindige lus */ + basen->object= obn; + base->flag &= ~SELECT; + basen->flag &= ~OB_FROMGROUP; + + if(BASACT==base) BASACT= basen; + + /* duplicates ahv userflags */ + + if(dupflag & DUPIPO) { + id= (ID *)obn->ipo; + if(id) { + ID_NEW_US( obn->ipo) + else obn->ipo= copy_ipo(obn->ipo); + id->us--; + } + /* Handle constraint ipos */ + for (chan=obn->constraintChannels.first; chan; chan=chan->next){ + id= (ID *)chan->ipo; + if(id) { + ID_NEW_US( chan->ipo) + else chan->ipo= copy_ipo(chan->ipo); + id->us--; + } + } + } + if(dupflag & DUPACT){ + id= (ID *)obn->action; + if (id){ + ID_NEW_US(obn->action) + else{ + obn->action= copy_action(obn->action); + obn->activecon=NULL; + } + id->us--; + } + } + if(dupflag & DUPMAT) { + for(a=0; a<obn->totcol; a++) { + id= (ID *)obn->mat[a]; + if(id) { + ID_NEW_US(obn->mat[a]) + else obn->mat[a]= copy_material(obn->mat[a]); + id->us--; + } + } + } + + id= obn->data; + didit= 0; + + switch(obn->type) { + case OB_MESH: + if(dupflag & DUPMESH) { + ID_NEW_US2( obn->data ) + else { + obn->data= copy_mesh(obn->data); + didit= 1; + } + id->us--; + } + break; + case OB_CURVE: + if(dupflag & DUPCURVE) { + ID_NEW_US2(obn->data ) + else { + obn->data= copy_curve(obn->data); + makeDispList(ob); + didit= 1; + } + id->us--; + } + break; + case OB_SURF: + if(dupflag & DUPSURF) { + ID_NEW_US2( obn->data ) + else { + obn->data= copy_curve(obn->data); + makeDispList(ob); + didit= 1; + } + id->us--; + } + break; + case OB_FONT: + if(dupflag & DUPFONT) { + ID_NEW_US2( obn->data ) + else { + obn->data= copy_curve(obn->data); + makeDispList(ob); + didit= 1; + } + id->us--; + } + break; + case OB_MBALL: + if(dupflag & DUPMBALL) { + ID_NEW_US2(obn->data ) + else { + obn->data= copy_mball(obn->data); + didit= 1; + } + id->us--; + } + break; + case OB_LAMP: + if(dupflag & DUPLAMP) { + ID_NEW_US2(obn->data ) + else obn->data= copy_lamp(obn->data); + id->us--; + } + break; + + case OB_ARMATURE: + if(dupflag & DUPARM) { + ID_NEW_US2(obn->data ) + else { + obn->data= copy_armature(obn->data); + didit= 1; + } + id->us--; + } + break; + /* always dupli's */ + + case OB_LATTICE: + ID_NEW_US2(obn->data ) + else obn->data= copy_lattice(obn->data); + id->us--; + break; + case OB_CAMERA: + ID_NEW_US2(obn->data ) + else obn->data= copy_camera(obn->data); + id->us--; + break; + case OB_IKA: + ID_NEW_US2(obn->data ) + else obn->data= copy_ika(obn->data); + id->us--; + break; + } + + if(dupflag & DUPMAT) { + matarar= give_matarar(obn); + if(didit && matarar) { + for(a=0; a<obn->totcol; a++) { + id= (ID *)(*matarar)[a]; + if(id) { + ID_NEW_US( (*matarar)[a] ) + else (*matarar)[a]= copy_material((*matarar)[a]); + + id->us--; + } + } + } + } + + } + base= base->next; + } + + /* evt object pointers */ + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + + { + bPoseChannel *chan; + + relink_constraints(&base->object->constraints); + if (base->object->pose){ + for (chan = base->object->pose->chanbase.first; chan; chan=chan->next){ + relink_constraints(&chan->constraints); + } + } + } + ID_NEW(base->object->parent); + ID_NEW(base->object->track); + + if(base->object->type==OB_IKA) { + ika= base->object->data; + ID_NEW(ika->parent); + + a= ika->totdef; + def= ika->def; + while(a--) { + ID_NEW(def->ob); + def++; + } + } + } + base= base->next; + } + + /* materialen */ + if( dupflag & DUPMAT) { + mao= G.main->mat.first; + while(mao) { + if(mao->id.newid) { + + ma= (Material *)mao->id.newid; + + if(dupflag & DUPTEX) { + for(a=0; a<8; a++) { + if(ma->mtex[a]) { + id= (ID *)ma->mtex[a]->tex; + if(id) { + ID_NEW_US(ma->mtex[a]->tex) + else ma->mtex[a]->tex= copy_texture(ma->mtex[a]->tex); + id->us--; + } + } + } + } + id= (ID *)ma->ipo; + if(id) { + ID_NEW_US(ma->ipo) + else ma->ipo= copy_ipo(ma->ipo); + id->us--; + } + } + mao= mao->id.next; + } + } + + sort_baselist(G.scene); + set_sca_new_poins(); + + clear_id_newpoins(); + + countall(); + if(dtrans==0) transform('g'); + + set_active_base(BASACT); + + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); /* ook oops */ + allqueue(REDRAWIPO, 0); /* ook oops */ +} + + +void selectlinks(void) +{ + Object *ob; + Base *base; + void *obdata = NULL; + Ipo *ipo = NULL; + Material *mat = NULL, *mat1; + Tex *tex=0; + int a, b, nr; + + ob= OBACT; + if(ob==0) return; + nr= pupmenu("Select links%t|Object Ipo|Object Data|Current Material|Current texture"); + + if(nr==1) { + ipo= ob->ipo; + if(ipo==0) return; + } + else if(nr==2) { + if(ob->data==0) return; + obdata= ob->data; + } + else if(nr==3 || nr==4) { + mat= give_current_material(ob, ob->actcol); + if(mat==0) return; + if(nr==4) { + if(mat->mtex[ mat->texact ]) tex= mat->mtex[ mat->texact ]->tex; + if(tex==0) return; + } + } + else return; + + base= FIRSTBASE; + while(base) { + if(base->lay & G.vd->lay) { + if(nr==1) { + if(base->object->ipo==ipo) base->flag |= SELECT; + } + else if(nr==2) { + if(base->object->data==obdata) base->flag |= SELECT; + } + else if(nr==3 || nr==4) { + ob= base->object; + + for(a=1; a<=ob->totcol; a++) { + mat1= give_current_material(ob, a); + if(nr==3) { + if(mat1==mat) base->flag |= SELECT; + } + else if(mat1 && nr==4) { + for(b=0; b<8; b++) { + if(mat1->mtex[b]) { + if(tex==mat1->mtex[b]->tex) base->flag |= SELECT; + } + } + } + } + } + base->object->flag= base->flag; + } + base= base->next; + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWDATASELECT, 0); + allqueue(REDRAWOOPS, 0); +} + +void image_aspect(void) +{ + /* alle geselecteerde objecten die imap hebben: scalen in ima verhouding */ + Base *base; + Object *ob; + Material *ma; + Tex *tex; + Mesh *me; + Curve *cu; + float x, y, space; + int a, b, done; + + if(G.obedit) return; + if(G.scene->id.lib) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + ob= base->object; + done= 0; + + for(a=1; a<=ob->totcol; a++) { + ma= give_current_material(ob, a); + if(ma) { + for(b=0; b<8; b++) { + if(ma->mtex[b] && ma->mtex[b]->tex) { + tex= ma->mtex[b]->tex; + if(tex->type==TEX_IMAGE && tex->ima && tex->ima->ibuf) { + /* texturespace */ + space= 1.0; + if(ob->type==OB_MESH) { + me= ob->data; + space= me->size[0]/me->size[1]; + } + else if ELEM3(ob->type, OB_CURVE, OB_FONT, OB_SURF) { + cu= ob->data; + space= cu->size[0]/cu->size[1]; + } + + x= tex->ima->ibuf->x/space; + y= tex->ima->ibuf->y; + + if(x>y) ob->size[0]= ob->size[1]*x/y; + else ob->size[1]= ob->size[0]*y/x; + + done= 1; + } + } + if(done) break; + } + } + if(done) break; + } + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); +} + +void set_ob_ipoflags(void) +{ + Base *base; + int set= 1; + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + if(base->object->ipoflag & OB_DRAWKEY) { + set= 0; + break; + } + } + base= base->next; + } + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + if(set) { + base->object->ipoflag |= OB_DRAWKEY; + if(base->object->ipo) base->object->ipo->showkey= 1; + } + else { + base->object->ipoflag &= ~OB_DRAWKEY; + } + } + base= base->next; + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSANIM, 0); + if(set) { + allqueue(REDRAWNLA, 0); + allqueue (REDRAWACTION, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); + } +} + +void select_select_keys(void) +{ + Base *base; + IpoCurve *icu; + BezTriple *bezt; + int a; + + if(G.scene->id.lib) return; + + if(okee("show and select all keys")==0) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base->object->ipo) { + base->object->ipoflag |= OB_DRAWKEY; + base->object->ipo->showkey= 1; + icu= base->object->ipo->curve.first; + while(icu) { + a= icu->totvert; + bezt= icu->bezt; + while(a--) { + bezt->f1 |= SELECT; + bezt->f2 |= SELECT; + bezt->f3 |= SELECT; + bezt++; + } + icu= icu->next; + } + } + } + base= base->next; + } + + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWVIEW3D, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); + +} + + +MVert *verg_vert; + +int verg_hoogste_zco(const void *a1, const void *a2) +{ + const MFace *x1=a1, *x2=a2; + float z1, z2; + MVert *v1, *v2, *v3; + + v1= verg_vert+x1->v1; + v2= verg_vert+x1->v2; + v3= verg_vert+x1->v3; + z1= MAX3(v1->co[2], v2->co[2], v3->co[2]); + + v1= verg_vert+x2->v1; + v2= verg_vert+x2->v2; + v3= verg_vert+x2->v3; + z2= MAX3(v1->co[2], v2->co[2], v3->co[2]); + + if( z1 > z2 ) return 1; + else if( z1 < z2) return -1; + return 0; +} + + + +void sortfaces(void) +{ + Mesh *me; + + if(G.scene->id.lib) return; + + if(G.obedit!=0 || BASACT==0 || OBACT->type!= OB_MESH) return; + if(okee("Sort faces")==0) return; + + me= OBACT->data; + verg_vert= me->mvert; + + qsort(me->mface, me->totface, sizeof(MFace), verg_hoogste_zco); +} + +int vergbaseco(const void *a1, const void *a2) +{ + Base **x1, **x2; + + x1= (Base **) a1; + x2= (Base **) a2; + + if( (*x1)->sy > (*x2)->sy ) return 1; + else if( (*x1)->sy < (*x2)->sy) return -1; + else if( (*x1)->sx > (*x2)->sx ) return 1; + else if( (*x1)->sx < (*x2)->sx ) return -1; + + return 0; +} + + +void auto_timeoffs(void) +{ + Base *base, **basesort, **bs; + float start, delta; + int tot=0, a; + short offset=25; + + if(BASACT==0) return; + if(button(&offset, 0, 1000,"Total time")==0) return; + + /* maak array van alle bases, xco yco (scherm) */ + base= FIRSTBASE; + while(base) { + if(TESTBASELIB(base)) { + tot++; + } + base= base->next; + } + + delta= (float)offset/(float)tot; + start= OBACT->sf; + + bs= basesort= MEM_mallocN(sizeof(void *)*tot,"autotimeoffs"); + base= FIRSTBASE; + + while(base) { + if(TESTBASELIB(base)) { + *bs= base; + bs++; + } + base= base->next; + } + qsort(basesort, tot, sizeof(void *), vergbaseco); + + bs= basesort; + for(a=0; a<tot; a++) { + + (*bs)->object->sf= start; + start+= delta; + + bs++; + } + MEM_freeN(basesort); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSANIM, 0); +} + +void texspace_edit(void) +{ + Base *base; + int nr=0; + + /* eerst testen of van de zichtbare en geselecteerde ob's + * wel de texspacedraw aanstaat: + */ + + if(G.obedit) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + break; + } + base= base->next; + } + + if(base==0) { + return; + } + + /* nr= pupmenu("Texture space %t|Grabber%x1|Size%x2|Rotate%x3"); */ + nr= pupmenu("Texture space %t|Grabber%x1|Size%x2"); + if(nr<1) return; + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + base->object->dtx |= OB_TEXSPACE; + } + base= base->next; + } + + + transmode= TRANS_TEX; + + if(nr==1) transform('g'); + else if(nr==2) transform('s'); + else if(nr==3) transform('r'); + + transmode= 0; +} + +void first_base(void) +{ + /* maakt de select bases los en insert ze aan begin */ + Base *base, *next; + + if(okee("make first base")==0) return; + + base= FIRSTBASE; + while(base) { + next= base->next; + + if(base->flag & SELECT) { + BLI_remlink(&G.scene->base, base); + BLI_addtail(&G.scene->base, base); + } + + base= next; + } + +} + +void make_displists_by_obdata(void *obdata) { + Base *base; + + for (base= FIRSTBASE; base; base= base->next) + if (obdata==base->object->data) + makeDispList(base->object); +} + diff --git a/source/blender/src/editoops.c b/source/blender/src/editoops.c new file mode 100644 index 00000000000..9ec2001ce5f --- /dev/null +++ b/source/blender/src/editoops.c @@ -0,0 +1,595 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <math.h> +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_oops_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" + +#include "BKE_global.h" +#include "BKE_scene.h" +#include "BKE_material.h" + +#include "BIF_space.h" +#include "BIF_screen.h" +#include "BIF_editoops.h" +#include "BIF_editview.h" +#include "BIF_drawscene.h" +#include "BIF_mywindow.h" + +#include "BDR_editobject.h" + +#include "BSE_edit.h" +#include "BSE_drawipo.h" + +#include "blendef.h" +#include "mydevice.h" + + +typedef struct TransOops { + float *loc; + float oldloc[2]; +} TransOops; + + +static void oops_to_select_objects(void) +{ + Oops *oops; + Base *base; + Object *ob; + + if(G.soops==0) return; + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if(oops->type==ID_OB) { + ob= (Object *)oops->id; + if(oops->flag & SELECT) ob->flag |= SELECT; + else ob->flag &= ~SELECT; + } + } + oops= oops->next; + } + base= FIRSTBASE; + while(base) { + if(base->flag != base->object->flag) { + base->flag= base->object->flag; + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); +} + +void swap_select_all_oops(void) +{ + Oops *oops; + int sel= 0; + + if(G.soops==0) return; + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if(oops->flag & SELECT) { + sel= 1; + break; + } + } + oops= oops->next; + } + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if(sel) oops->flag &= ~SELECT; + else oops->flag |= SELECT; + } + oops= oops->next; + } + + oops_to_select_objects(); /* ook redr */ + + G.soops->lockpoin= 0; +} + +/* never used... check CVS 1.12 for the code */ +/* static void select_swap_oops(void) */ + +static void deselect_all_oops(void) +{ + Oops *oops; + + if(G.soops==0) return; + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + oops->flag &= ~SELECT; + } + oops= oops->next; + } + G.soops->lockpoin= 0; +} + +void set_select_flag_oops(void) /* alle areas */ +{ + SpaceOops *so; + ScrArea *sa; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==SPACE_OOPS) { + so= sa->spacedata.first; + so->flag |= SO_NEWSELECTED; + } + sa= sa->next; + } + if(G.soops) G.soops->lockpoin= 0; +} + +void deselect_all_area_oops(void) /* alle areas */ +{ + SpaceOops *so; + Oops *oops; + ScrArea *sa; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==SPACE_OOPS) { + so= sa->spacedata.first; + + oops= so->oops.first; + while(oops) { + oops->flag &= ~SELECT; + oops= oops->next; + } + } + sa= sa->next; + } + + if(G.soops) G.soops->lockpoin= 0; +} + +void transform_oops(int mode) +{ + TransOops *transmain, *tv; + Oops *oops; + float dx, dy, div, dvec[3], cent[3], min[3], max[3]; + float sizefac, size[2], xref=1.0, yref=1.0; + int a, tot= 0, midtog= 0; + unsigned short event = 0; + short firsttime= 1, proj = 0, afbreek=0, xc, yc, xo, yo, xn, yn, mval[2]; + short val; + char str[32]; + + if(G.soops==0) return; + + /* welke oopsen doen mee */ + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if(oops->flag & SELECT) { + tot++; + } + } + oops= oops->next; + } + + if(tot==0) return; + + G.moving= 1; + + INIT_MINMAX(min, max); + + tv=transmain= MEM_callocN(tot*sizeof(TransOops), "transmain"); + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if(oops->flag & SELECT) { + tv->loc= &oops->x; + tv->oldloc[0]= tv->loc[0]; + tv->oldloc[1]= tv->loc[1]; + DO_MINMAX2(tv->loc, min, max); + tv++; + } + } + oops= oops->next; + } + + cent[0]= (min[0]+max[0])/2.0; + cent[1]= (min[1]+max[1])/2.0; + + ipoco_to_areaco_noclip(G.v2d, cent, mval); + xc= mval[0]; + yc= mval[1]; + + getmouseco_areawin(mval); + xo= xn= mval[0]; + yo= yn= mval[1]; + dvec[0]= dvec[1]= 0.0; + + sizefac= sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) ); + if(sizefac<2.0) sizefac= 2.0; + + while(afbreek==0) { + getmouseco_areawin(mval); + if(mval[0]!=xo || mval[1]!=yo || firsttime) { + + if(mode=='g') { + + dx= mval[0]- xo; + dy= mval[1]- yo; + + div= G.v2d->mask.xmax-G.v2d->mask.xmin; + dvec[0]+= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div; + + div= G.v2d->mask.ymax-G.v2d->mask.ymin; + dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div; + + if(midtog) dvec[proj]= 0.0; + + tv= transmain; + for(a=0; a<tot; a++, tv++) { + + tv->loc[0]= tv->oldloc[0]+dvec[0]; + tv->loc[1]= tv->oldloc[1]+dvec[1]; + + } + + sprintf(str, "X: %.2f Y: %.2f ", dvec[0], dvec[1]); + headerprint(str); + } + else if(mode=='s') { + size[0]=size[1]= (sqrt( (float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc)) ))/sizefac; + + if(midtog) size[proj]= 1.0; + size[0]*= xref; + size[1]*= yref; + + tv= transmain; + for(a=0; a<tot; a++, tv++) { + + tv->loc[0]= size[0]*(tv->oldloc[0]-cent[0])+ cent[0]; + tv->loc[1]= size[1]*(tv->oldloc[1]-cent[1])+ cent[1]; + + } + + sprintf(str, "sizeX: %.3f sizeY: %.3f ", size[0], size[1]); + headerprint(str); + } + + + xo= mval[0]; + yo= mval[1]; + + force_draw(); + + firsttime= 0; + + } + else BIF_wait_for_statechange(); + + while(qtest()) { + event= extern_qread(&val); + if(val) { + switch(event) { + case ESCKEY: + case LEFTMOUSE: + case SPACEKEY: + case RETKEY: + afbreek= 1; + break; + case MIDDLEMOUSE: + + midtog= ~midtog; + if(midtog) { + if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1; + else proj= 0; + firsttime= 1; + } + + break; + default: + arrows_move_cursor(event); + } + } + if(afbreek) break; + } + } + + if(event==ESCKEY) { + tv= transmain; + for(a=0; a<tot; a++, tv++) { + tv->loc[0]= tv->oldloc[0]; + tv->loc[1]= tv->oldloc[1]; + } + } + MEM_freeN(transmain); + + G.moving= 0; + + scrarea_queue_redraw(curarea); +} + +static Oops *find_nearest_oops(void) +{ + Oops *oops; + float x, y; + short mval[2]; + + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide == 0) { + if(oops->x <=x && oops->x+OOPSX >= x) { + if(oops->y <=y && oops->y+OOPSY >= y) { + return oops; + } + } + } + oops= oops->next; + } + return 0; +} + +static void do_activate_oops(Oops *oops) +{ + Base *base; + Object *ob; + + switch(oops->type) { + case ID_SCE: + if(oops->id) set_scene((Scene *)oops->id); + break; + case ID_OB: + base= FIRSTBASE; + while(base) { + if(base->object == (Object *)oops->id) break; + base= base->next; + } + if(base) { + set_active_base(base); /* editview.c */ + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWINFO, 1); + } + break; + case ID_MA: + ob= OBACT; + if(ob && oops->id) { + assign_material(ob, (Material *)oops->id, ob->actcol); + allqueue(REDRAWBUTSMAT, 0); + scrarea_queue_winredraw(curarea); + } + break; + + } +} + +void mouse_select_oops(void) +{ + Oops *oops; + extern float oopslastx, oopslasty; /* oops.c */ + + if(G.soops==0) return; + + /* welke oopsen doen mee */ + oops= G.soops->oops.first; + + oops= find_nearest_oops(); + if(oops==0) return; + + if((G.qual & LR_SHIFTKEY)==0) deselect_all_oops(); + + if(oops) { + /* last_seq= seq; */ + + if(G.qual==0) { + oops->flag |= SELECT; + } + else { + if(oops->flag & SELECT) { + oops->flag &= ~SELECT; + } + else { + oops->flag |= SELECT; + } + } + + oopslastx= oops->x; + oopslasty= oops->y; + + if(G.qual & LR_CTRLKEY) do_activate_oops(oops); + G.soops->lockpoin= oops; + } + + oops_to_select_objects(); /* ook redr */ + scrarea_queue_headredraw(curarea); + + force_draw(); + + std_rmouse_transform(transform_oops); +} + +void borderselect_oops(void) +{ + Oops *oops; + rcti rect; + rctf rectf, rq; + int val; + short mval[2]; + + if(G.soops==0) return; + + val= get_border(&rect, 3); + + if(val) { + mval[0]= rect.xmin; + mval[1]= rect.ymin; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + mval[0]= rect.xmax; + mval[1]= rect.ymax; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide == 0) { + + rq.xmin= oops->x; + rq.xmax= oops->x+OOPSX; + rq.ymin= oops->y; + rq.ymax= oops->y+OOPSY; + + if(BLI_isect_rctf(&rq, &rectf, 0)) { + if(val==LEFTMOUSE) { + oops->flag |= SELECT; + } + else { + oops->flag &= ~SELECT; + } + } + } + oops= oops->next; + } + + oops_to_select_objects(); /* ook redr */ + } +} + +static void select_oops_lib(ID *id) +{ + Oops *oops; + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if(oops->id->lib== (Library *)id) oops->flag |= OOPS_DOSELECT; + } + oops= oops->next; + } +} + +void select_linked_oops(void) +{ + Oops *oops; + OopsLink *ol; + + if(G.soops==0) return; + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if(oops->flag & SELECT) { + if(oops->type==ID_LI) select_oops_lib(oops->id); + ol= oops->link.first; + while(ol) { + if(ol->to && ol->to->hide==0) ol->to->flag |= OOPS_DOSELECT; + ol= ol->next; + } + } + } + oops= oops->next; + } + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if(oops->flag & OOPS_DOSELECT) { + oops->flag |= SELECT; + oops->flag &= ~OOPS_DOSELECT; + } + } + oops= oops->next; + } + + oops_to_select_objects(); /* ook redr */ + +} + +void select_backlinked_oops(void) +{ + Oops *oops; + OopsLink *ol; + + if(G.soops==0) return; + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if( (oops->flag & SELECT)==0) { + ol= oops->link.first; + while(ol) { + if(ol->to && ol->to->hide==0) { + if(ol->to->flag & SELECT) oops->flag |= OOPS_DOSELECT; + } + ol= ol->next; + } + } + } + oops= oops->next; + } + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + if(oops->flag & OOPS_DOSELECT) { + oops->flag |= SELECT; + oops->flag &= ~OOPS_DOSELECT; + } + } + oops= oops->next; + } + + oops_to_select_objects(); /* ook redr */ + +} diff --git a/source/blender/src/editsca.c b/source/blender/src/editsca.c new file mode 100644 index 00000000000..6357a4c7ac2 --- /dev/null +++ b/source/blender/src/editsca.c @@ -0,0 +1,2647 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <math.h> + +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_action_types.h" +#include "DNA_material_types.h" +#include "DNA_sensor_types.h" +#include "DNA_actuator_types.h" +#include "DNA_controller_types.h" +#include "DNA_property_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_sound_types.h" +#include "DNA_text_types.h" +#include "DNA_view3d_types.h" +#include "DNA_mesh_types.h" + +#include "BKE_library.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_sca.h" +#include "BKE_property.h" + +#include "BIF_gl.h" +#include "BIF_resources.h" +#include "BIF_space.h" +#include "BIF_interface.h" +#include "BIF_screen.h" +#include "BIF_editsca.h" +#include "BIF_keyval.h" +#include "BIF_editsound.h" + +#include "BDR_editcurve.h" +#include "BSE_buttons.h" + +#include "blendef.h" +#include "mydevice.h" +#include "interface.h" +#include "nla.h" /* For __NLA : Important, do not remove */ + +#include "license_key.h" +extern int LICENSE_KEY_VALID; + +#define B_DIFF 1 +#define B_ADD_PROP 2701 +#define B_CHANGE_PROP 2702 + +#define B_ADD_SENS 2703 +#define B_CHANGE_SENS 2704 +#define B_DEL_SENS 2705 + +#define B_ADD_CONT 2706 +#define B_CHANGE_CONT 2707 +#define B_DEL_CONT 2708 + +#define B_ADD_ACT 2709 +#define B_CHANGE_ACT 2710 +#define B_DEL_ACT 2711 + +#define B_SOUNDACT_BROWSE 2712 + +/* internals */ + +/****/ + +static ID **get_selected_and_linked_obs(short *count, short scavisflag); +static char *actuator_pup(Object *owner); + +/****/ + +static void del_property(void *selpropv, void *data2_unused) +{ + bProperty *prop, *selprop= selpropv; + Object *ob; + int a=0; + + ob= OBACT; + if(ob==NULL) return; + + prop= ob->prop.first; + while(prop) { + if(prop==selprop) { + if (strcmp(prop->name,"Text") == 0) { + allqueue(REDRAWVIEW3D, 0); + } + BLI_remlink(&ob->prop, prop); + free_property(prop); + break; + } + a++; + prop= prop->next; + } + allqueue(REDRAWBUTSGAME, 0); + +} + +static int vergname(const void *v1, const void *v2) +{ + char **x1, **x2; + + x1= (char **)v1; + x2= (char **)v2; + + return strcmp(*x1, *x2); +} + +void make_unique_prop_names(char *str) +{ + Object *ob; + bProperty *prop; + bSensor *sens; + bController *cont; + bActuator *act; + ID **idar; + short a, obcount, propcount=0, nr; + char **names; + + /* this function is called by a Button, and gives the current + * stringpointer as an argument, this is the one that can change + */ + + idar= get_selected_and_linked_obs(&obcount, BUTS_SENS_SEL|BUTS_SENS_ACT|BUTS_ACT_SEL|BUTS_ACT_ACT|BUTS_CONT_SEL|BUTS_CONT_ACT); + + /* for each object, make properties and sca names unique */ + + /* count total names */ + for(a=0; a<obcount; a++) { + ob= (Object *)idar[a]; + propcount+= BLI_countlist(&ob->prop); + propcount+= BLI_countlist(&ob->sensors); + propcount+= BLI_countlist(&ob->controllers); + propcount+= BLI_countlist(&ob->actuators); + } + if(propcount==0) { + if(idar) MEM_freeN(idar); + return; + } + + /* make names array for sorting */ + names= MEM_callocN(propcount*sizeof(void *), "names"); + + /* count total names */ + nr= 0; + for(a=0; a<obcount; a++) { + ob= (Object *)idar[a]; + prop= ob->prop.first; + while(prop) { + names[nr++]= prop->name; + prop= prop->next; + } + sens= ob->sensors.first; + while(sens) { + names[nr++]= sens->name; + sens= sens->next; + } + cont= ob->controllers.first; + while(cont) { + names[nr++]= cont->name; + cont= cont->next; + } + act= ob->actuators.first; + while(act) { + names[nr++]= act->name; + act= act->next; + } + } + + qsort(names, propcount, sizeof(void *), vergname); + + /* now we check for double names, and change them */ + + for(nr=0; nr<propcount; nr++) { + if(names[nr]!=str && strcmp( names[nr], str )==0 ) { + BLI_newname(str, +1); + } + } + + MEM_freeN(idar); + MEM_freeN(names); +} + +static void make_unique_prop_names_cb(void *strv, void *redraw_view3d_flagv) +{ + char *str= strv; + int redraw_view3d_flag= (int) redraw_view3d_flagv; + + make_unique_prop_names(str); + if (redraw_view3d_flag) allqueue(REDRAWVIEW3D, 0); +} + +static void sca_move_sensor(void *datav, void *data2_unused) +{ + bSensor *sens_to_delete= datav; + int val; + Base *base; + bSensor *sens; + + val= pupmenu("Move up%x1|Move down %x2"); + + if(val>0) { + /* now find out which object has this ... */ + base= FIRSTBASE; + while(base) { + + sens= base->object->sensors.first; + while(sens) { + if(sens == sens_to_delete) break; + sens= sens->next; + } + + if(sens) { + if( val==1 && sens->prev) { + BLI_remlink(&base->object->sensors, sens); + BLI_insertlinkbefore(&base->object->sensors, sens->prev, sens); + } + else if( val==2 && sens->next) { + BLI_remlink(&base->object->sensors, sens); + BLI_insertlink(&base->object->sensors, sens->next, sens); + } + allqueue(REDRAWBUTSGAME, 0); + break; + } + + base= base->next; + } + } +} + +static void sca_move_controller(void *datav, void *data2_unused) +{ + bController *controller_to_del= datav; + int val; + Base *base; + bController *cont; + + val= pupmenu("Move up%x1|Move down %x2"); + + if(val>0) { + /* now find out which object has this ... */ + base= FIRSTBASE; + while(base) { + + cont= base->object->controllers.first; + while(cont) { + if(cont == controller_to_del) break; + cont= cont->next; + } + + if(cont) { + if( val==1 && cont->prev) { + BLI_remlink(&base->object->controllers, cont); + BLI_insertlinkbefore(&base->object->controllers, cont->prev, cont); + } + else if( val==2 && cont->next) { + BLI_remlink(&base->object->controllers, cont); + BLI_insertlink(&base->object->controllers, cont->next, cont); + } + allqueue(REDRAWBUTSGAME, 0); + break; + } + + base= base->next; + } + } +} + +static void sca_move_actuator(void *datav, void *data2_unused) +{ + bActuator *actuator_to_move= datav; + int val; + Base *base; + bActuator *act; + + val= pupmenu("Move up%x1|Move down %x2"); + + if(val>0) { + /* now find out which object has this ... */ + base= FIRSTBASE; + while(base) { + + act= base->object->actuators.first; + while(act) { + if(act == actuator_to_move) break; + act= act->next; + } + + if(act) { + if( val==1 && act->prev) { + BLI_remlink(&base->object->actuators, act); + BLI_insertlinkbefore(&base->object->actuators, act->prev, act); + } + else if( val==2 && act->next) { + BLI_remlink(&base->object->actuators, act); + BLI_insertlink(&base->object->actuators, act->next, act); + } + allqueue(REDRAWBUTSGAME, 0); + break; + } + + base= base->next; + } + } +} + +void do_gamebuts(unsigned short event) +{ + bProperty *prop; + bSensor *sens; + bController *cont; + bActuator *act; + Base *base; + Object *ob; + int didit; + + ob= OBACT; + if(ob==0) return; + + switch(event) { + + case B_ADD_PROP: + prop= new_property(PROP_FLOAT); + make_unique_prop_names(prop->name); + BLI_addtail(&ob->prop, prop); + allqueue(REDRAWBUTSGAME, 0); + break; + + case B_CHANGE_PROP: + prop= ob->prop.first; + while(prop) { + if(prop->type!=prop->otype) { + init_property(prop); + if (strcmp(prop->name, "Text") == 0) { + allqueue(REDRAWVIEW3D, 0); + } + } + prop= prop->next; + } + allqueue(REDRAWBUTSGAME, 0); + break; + + case B_ADD_SENS: + base= FIRSTBASE; + while(base) { + if(base->object->scaflag & OB_ADDSENS) { + base->object->scaflag &= ~OB_ADDSENS; + sens= new_sensor(SENS_ALWAYS); + BLI_addtail(&(base->object->sensors), sens); + make_unique_prop_names(sens->name); + base->object->scaflag |= OB_SHOWSENS; + } + base= base->next; + } + + allqueue(REDRAWBUTSGAME, 0); + break; + + case B_CHANGE_SENS: + base= FIRSTBASE; + while(base) { + sens= base->object->sensors.first; + while(sens) { + if(sens->type != sens->otype) { + init_sensor(sens); + sens->otype= sens->type; + break; + } + sens= sens->next; + } + base= base->next; + } + allqueue(REDRAWBUTSGAME, 0); + break; + + case B_DEL_SENS: + base= FIRSTBASE; + while(base) { + sens= base->object->sensors.first; + while(sens) { + if(sens->flag & SENS_DEL) { + BLI_remlink(&(base->object->sensors), sens); + free_sensor(sens); + break; + } + sens= sens->next; + } + base= base->next; + } + allqueue(REDRAWBUTSGAME, 0); + break; + + case B_ADD_CONT: + base= FIRSTBASE; + while(base) { + if(base->object->scaflag & OB_ADDCONT) { + base->object->scaflag &= ~OB_ADDCONT; + cont= new_controller(CONT_LOGIC_AND); + make_unique_prop_names(cont->name); + base->object->scaflag |= OB_SHOWCONT; + BLI_addtail(&(base->object->controllers), cont); + } + base= base->next; + } + allqueue(REDRAWBUTSGAME, 0); + break; + + case B_CHANGE_CONT: + base= FIRSTBASE; + while(base) { + cont= base->object->controllers.first; + while(cont) { + if(cont->type != cont->otype) { + init_controller(cont); + cont->otype= cont->type; + break; + } + cont= cont->next; + } + base= base->next; + } + allqueue(REDRAWBUTSGAME, 0); + break; + + + case B_DEL_CONT: + base= FIRSTBASE; + while(base) { + cont= base->object->controllers.first; + while(cont) { + if(cont->flag & CONT_DEL) { + BLI_remlink(&(base->object->controllers), cont); + unlink_controller(cont); + free_controller(cont); + break; + } + cont= cont->next; + } + base= base->next; + } + allqueue(REDRAWBUTSGAME, 0); + break; + + case B_ADD_ACT: + base= FIRSTBASE; + while(base) { + if(base->object->scaflag & OB_ADDACT) { + base->object->scaflag &= ~OB_ADDACT; + act= new_actuator(ACT_OBJECT); + make_unique_prop_names(act->name); + BLI_addtail(&(base->object->actuators), act); + base->object->scaflag |= OB_SHOWACT; + } + base= base->next; + } + allqueue(REDRAWBUTSGAME, 0); + break; + + case B_CHANGE_ACT: + base= FIRSTBASE; + while(base) { + act= base->object->actuators.first; + while(act) { + if(act->type != act->otype) { + init_actuator(act); + act->otype= act->type; + break; + } + act= act->next; + } + base= base->next; + } + allqueue(REDRAWBUTSGAME, 0); + break; + + case B_DEL_ACT: + base= FIRSTBASE; + while(base) { + act= base->object->actuators.first; + while(act) { + if(act->flag & ACT_DEL) { + BLI_remlink(&(base->object->actuators), act); + unlink_actuator(act); + free_actuator(act); + break; + } + act= act->next; + } + base= base->next; + } + allqueue(REDRAWBUTSGAME, 0); + break; + + case B_SOUNDACT_BROWSE: + /* since we don't know which... */ + didit= 0; + base= FIRSTBASE; + while(base) + { + act= base->object->actuators.first; + while(act) + { + if(act->type==ACT_SOUND) + { + bSoundActuator *sa= act->data; + if(sa->sndnr) + { + bSound *sound= G.main->sound.first; + int nr= 1; + + while(sound) + { + if(nr==sa->sndnr) + break; + nr++; + sound= sound->id.next; + } + + if(sa->sound) + sa->sound->id.us--; + + sa->sound= sound; + + if(sound) + sound->id.us++; + + sa->sndnr= 0; + didit= 1; + } + } + act= act->next; + } + if(didit) + break; + base= base->next; + } + allqueue(REDRAWBUTSGAME, 0); + allqueue(REDRAWSOUND, 0); + + break; + + } +} + + +static char *sensor_name(int type) +{ + switch (type) { + case SENS_ALWAYS: + return "Always"; + case SENS_TOUCH: + return "Touch"; + case SENS_NEAR: + return "Near"; + case SENS_KEYBOARD: + return "Keyboard"; + case SENS_PROPERTY: + return "Property"; + case SENS_MOUSE: + return "Mouse"; + case SENS_COLLISION: + return "Collision"; + case SENS_RADAR: + return "Radar"; + case SENS_RANDOM: + return "Random"; + case SENS_RAY: + return "Ray"; + case SENS_MESSAGE: + return "Message"; + } + return "unknown"; +} + +static char *sensor_pup(void) +{ + /* the number needs to match defines in game.h */ + return "Sensors %t|Always %x0|Keyboard %x3|Mouse %x5|" + "Touch %x1|Collision %x6|Near %x2|Radar %x7|" + "Property %x4|Random %x8|Ray %x9|Message %x10"; +} + +static char *controller_name(int type) +{ + switch (type) { + case CONT_LOGIC_AND: + return "AND"; + case CONT_LOGIC_OR: + return "OR"; + case CONT_EXPRESSION: + return "Expression"; + case CONT_PYTHON: + return "Python"; + } + return "unknown"; +} + +static char *controller_pup(void) +{ + return "Controllers %t|AND %x0|OR %x1|Expression %x2|Python %x3"; +} + +static char *actuator_name(int type) +{ + switch (type) { + case ACT_ACTION: + return "Action"; + case ACT_OBJECT: + return "Motion"; + case ACT_IPO: + return "Ipo"; + case ACT_LAMP: + return "Lamp"; + case ACT_CAMERA: + return "Camera"; + case ACT_MATERIAL: + return "Material"; + case ACT_SOUND: + return "Sound"; + case ACT_CD: + return "CD"; + case ACT_PROPERTY: + return "Property"; + case ACT_EDIT_OBJECT: + return "Edit Object"; + case ACT_CONSTRAINT: + return "Constraint"; + case ACT_SCENE: + return "Scene"; + case ACT_GROUP: + return "Group"; + case ACT_RANDOM: + return "Random"; + case ACT_MESSAGE: + return "Message"; + case ACT_GAME: + return "Game"; + case ACT_VISIBILITY: + return "Game"; + } + return "unknown"; +} + + + + +static char *actuator_pup(Object *owner) +{ + if (LICENSE_KEY_VALID) + { + switch (owner->type) + { + case OB_ARMATURE: + return "Actuators %t|Action %x15|Motion %x0|Constraint %x9|Ipo %x1" + "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10" + "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17" + "|Visibility %x18"; + break; + default: + return "Actuators %t|Motion %x0|Constraint %x9|Ipo %x1" + "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10" + "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17" + "|Visibility %x18"; + } + } + else + { + switch (owner->type) + { + case OB_ARMATURE: + return "Actuators %t|Action %x15|Motion %x0|Constraint %x9|Ipo %x1" + "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10" + "|Scene %x11|Random %x13|Message %x14|Visibility %x18"; + break; + default: + return "Actuators %t|Motion %x0|Constraint %x9|Ipo %x1" + "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10" + "|Scene %x11|Random %x13|Message %x14|Visibility %x18"; + } + } + +} + + + +static void set_sca_ob(Object *ob) +{ + bController *cont; + bActuator *act; + + cont= ob->controllers.first; + while(cont) { + cont->mynew= (bController *)ob; + cont= cont->next; + } + act= ob->actuators.first; + while(act) { + act->mynew= (bActuator *)ob; + act= act->next; + } +} + +static ID **get_selected_and_linked_obs(short *count, short scavisflag) +{ + Base *base; + Object *ob, *obt; + ID **idar; + bSensor *sens; + bController *cont; + unsigned int lay; + int a, nr, doit; + + /* we need a sorted object list */ + /* set scavisflags flags in Objects to indicate these should be evaluated */ + /* also hide ob pointers in ->new entries of controllerss/actuators */ + + *count= 0; + + if(G.scene==NULL) return NULL; + + ob= G.main->object.first; + while(ob) { + ob->scavisflag= 0; + set_sca_ob(ob); + ob= ob->id.next; + } + + if(G.vd) lay= G.vd->lay; + else lay= G.scene->lay; + + base= FIRSTBASE; + while(base) { + if(base->lay & lay) { + if(base->flag & SELECT) { + if(scavisflag & BUTS_SENS_SEL) base->object->scavisflag |= OB_VIS_SENS; + if(scavisflag & BUTS_CONT_SEL) base->object->scavisflag |= OB_VIS_CONT; + if(scavisflag & BUTS_ACT_SEL) base->object->scavisflag |= OB_VIS_ACT; + } + } + base= base->next; + } + + if(OBACT) { + if(scavisflag & BUTS_SENS_ACT) OBACT->scavisflag |= OB_VIS_SENS; + if(scavisflag & BUTS_CONT_ACT) OBACT->scavisflag |= OB_VIS_CONT; + if(scavisflag & BUTS_ACT_ACT) OBACT->scavisflag |= OB_VIS_ACT; + } + + if(scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK)) { + doit= 1; + while(doit) { + doit= 0; + + ob= G.main->object.first; + while(ob) { + + /* 1st case: select sensor when controller selected */ + if((scavisflag & BUTS_SENS_LINK) && (ob->scavisflag & OB_VIS_SENS)==0) { + sens= ob->sensors.first; + while(sens) { + for(a=0; a<sens->totlinks; a++) { + if(sens->links[a]) { + obt= (Object *)sens->links[a]->mynew; + if(obt && (obt->scavisflag & OB_VIS_CONT)) { + doit= 1; + ob->scavisflag |= OB_VIS_SENS; + break; + } + } + } + if(doit) break; + sens= sens->next; + } + } + + /* 2nd case: select cont when act selected */ + if((scavisflag & BUTS_CONT_LINK) && (ob->scavisflag & OB_VIS_CONT)==0) { + cont= ob->controllers.first; + while(cont) { + for(a=0; a<cont->totlinks; a++) { + if(cont->links[a]) { + obt= (Object *)cont->links[a]->mynew; + if(obt && (obt->scavisflag & OB_VIS_ACT)) { + doit= 1; + ob->scavisflag |= OB_VIS_CONT; + break; + } + } + } + if(doit) break; + cont= cont->next; + } + } + + /* 3rd case: select controller when sensor selected */ + if((scavisflag & BUTS_CONT_LINK) && (ob->scavisflag & OB_VIS_SENS)) { + sens= ob->sensors.first; + while(sens) { + for(a=0; a<sens->totlinks; a++) { + if(sens->links[a]) { + obt= (Object *)sens->links[a]->mynew; + if(obt && (obt->scavisflag & OB_VIS_CONT)==0) { + doit= 1; + obt->scavisflag |= OB_VIS_CONT; + } + } + } + sens= sens->next; + } + } + + /* 4th case: select actuator when controller selected */ + if( (scavisflag & BUTS_ACT_LINK) && (ob->scavisflag & OB_VIS_CONT)) { + cont= ob->controllers.first; + while(cont) { + for(a=0; a<cont->totlinks; a++) { + if(cont->links[a]) { + obt= (Object *)cont->links[a]->mynew; + if(obt && (obt->scavisflag & OB_VIS_ACT)==0) { + doit= 1; + obt->scavisflag |= OB_VIS_ACT; + } + } + } + cont= cont->next; + } + + } + ob= ob->id.next; + } + } + } + + /* now we count */ + ob= G.main->object.first; + while(ob) { + if( ob->scavisflag ) (*count)++; + ob= ob->id.next; + } + + if(*count==0) return NULL; + if(*count>24) *count= 24; /* temporal */ + + idar= MEM_callocN( (*count)*sizeof(void *), "idar"); + + ob= G.main->object.first; + nr= 0; + while(ob) { + if( ob->scavisflag ) { + idar[nr]= (ID *)ob; + nr++; + } + if(nr>=24) break; + ob= ob->id.next; + } + + /* just to be sure... these were set in set_sca_done_ob() */ + clear_sca_new_poins(); + + return idar; +} + + +static BIFColorID get_col_sensor(int type) +{ + switch(type) { + case SENS_ALWAYS: return BUTACTION; + case SENS_TOUCH: return BUTCAMERA; + case SENS_COLLISION: return BUTCAMERA; + case SENS_NEAR: return BUTRANDOM; + case SENS_KEYBOARD: return BUTIPO; + case SENS_PROPERTY: return BUTPROPERTY; + case SENS_MOUSE: return BUTAUDIO; + case SENS_RADAR: return BUTEDITOBJECT; + case SENS_RANDOM: return BUTSCENE; + case SENS_RAY: return BUTMOTION; + case SENS_MESSAGE: return BUTMESSAGE; + default: return BUTGREY; + } +} +static void set_col_sensor(int type, int medium) +{ + BIFColorID col= get_col_sensor(type); + BIF_set_color(col, medium?COLORSHADE_MEDIUM:COLORSHADE_GREY); +} + +/** + * Draws a toggle for pulse mode, a frequency fiels and a toggle to invert + * the value of this sensor. Operates on the shared data block of sensors. + */ +static void draw_default_sensor_header(bSensor *sens, + uiBlock *block, + short x, + short y, + short w) +{ + /* Pulsing and frequency */ + uiDefIconButS(block, TOG|BIT|0, 1, ICON_DOTSUP, + (short)(x + 10), (short)(y - 19), (short)(0.15 * (w-20)), 19, + &sens->pulse, 0.0, 0.0, 0, 0, + "Activate TRUE pulse mode"); + uiDefIconButS(block, TOG|BIT|2, 1, ICON_DOTSDOWN, + (short)(x + 10 + 0.15 * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19, + &sens->pulse, 0.0, 0.0, 0, 0, + "Activate FALSE pulse mode"); + uiDefButS(block, NUM, 1, "f:", + (short)(x + 10 + 0.3 * (w-20)), (short)(y - 19), (short)(0.275 * (w-20)), 19, + &sens->freq, 0.0, 10000.0, 0, 0, + "Frequency of pulses (in 1/50 sec)"); + + /* value or shift? */ + uiDefButS(block, TOG, 1, "Inv", + (short)(x + 10 + 0.85 * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19, + &sens->invert, 1.0, SENS_NOT, 0, 0, + "Invert the output of this sensor"); +} + +static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short yco, short width,char* objectname) +{ + bNearSensor *ns = NULL; + bTouchSensor *ts = NULL; + bKeyboardSensor *ks = NULL; + bPropertySensor *ps = NULL; + bMouseSensor *ms = NULL; + bCollisionSensor *cs = NULL; + bRadarSensor *rs = NULL; + bRandomSensor *randomSensor = NULL; + bRaySensor *raySens = NULL; + bMessageSensor *mes = NULL; + short ysize; + char *str; + + /* yco is at the top of the rect, draw downwards */ + + uiBlockSetEmboss(block, UI_EMBOSSW); + + set_col_sensor(sens->type, 0); + + switch (sens->type) + { + case SENS_ALWAYS: + { + ysize= 24; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + draw_default_sensor_header(sens, block, xco, yco, width); + + yco-= ysize; + + break; + } + case SENS_TOUCH: + { + ysize= 48; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + draw_default_sensor_header(sens, block, xco, yco, width); + + ts= sens->data; + + /* uiDefBut(block, TEX, 1, "Property:", xco,yco-22,width, 19, &ts->name, 0, 31, 0, 0, "Only look for Objects with this property"); */ + uiDefIDPoinBut(block, test_matpoin_but, 1, "MA:",(short)(xco + 10),(short)(yco-44), (short)(width - 20), 19, &ts->ma, "Only look for floors with this Material"); + ///* uiDefButF(block, NUM, 1, "Margin:", xco+width/2,yco-44,width/2, 19, &ts->dist, 0.0, 10.0, 100, 0, "Extra margin (distance) for larger sensitivity"); + yco-= ysize; + break; + } + case SENS_COLLISION: + { + ysize= 48; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + draw_default_sensor_header(sens, block, xco, yco, width); + cs= sens->data; + + /* The collision sensor will become a generic collision (i.e. it */ + /* absorb the old touch sensor). */ + uiDefButS(block, TOG|BIT|0, B_REDR, "M/P",(short)(xco + 10),(short)(yco - 44), + (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0, + "Toggle collision on material or property."); + + if (cs->mode & SENS_COLLISION_MATERIAL) { + uiDefBut(block, TEX, 1, "Material:", (short)(xco + 10 + 0.20 * (width-20)), + (short)(yco-44), (short)(0.8*(width-20)), 19, &cs->materialName, 0, 31, 0, 0, + "Only look for Objects with this material"); + } else { + uiDefBut(block, TEX, 1, "Property:", (short)(xco + 10 + 0.20 * (width-20)), (short)(yco-44), + (short)(0.8*(width-20)), 19, &cs->name, 0, 31, 0, 0, + "Only look for Objects with this property"); + } + + /* uiDefButS(block, NUM, 1, "Damp:", xco+10+width-90,yco-24, 70, 19, &cs->damp, 0, 250, 0, 0, "For 'damp' time don't detect another collision"); */ + + yco-= ysize; + break; + } + case SENS_NEAR: + { + ysize= 72; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + draw_default_sensor_header(sens, block, xco, yco, width); + ns= sens->data; + + uiDefBut(block, TEX, 1, "Property:",(short)(10+xco),(short)(yco-44), (short)(width-20), 19, + &ns->name, 0, 31, 0, 0, "Only look for Objects with this property"); + uiDefButF(block, NUM, 1, "Dist",(short)(10+xco),(short)(yco-68),(short)((width-22)/2), 19, + &ns->dist, 0.0, 1000.0, 1000, 0, "Trigger distance"); + uiDefButF(block, NUM, 1, "Reset",(short)(10+xco+(width-22)/2), (short)(yco-68), (short)((width-22)/2), 19, + &ns->resetdist, 0.0, 1000.0, 1000, 0, "Reset distance"); + yco-= ysize; + break; + } + case SENS_RADAR: + { + ysize= 72; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + draw_default_sensor_header(sens, block, xco, yco, width); + + rs= sens->data; + + uiDefBut(block, TEX, 1, "Prop:", + (short)(10+xco),(short)(yco-44), (short)(0.7 * (width-20)), 19, + &rs->name, 0, 31, 0, 0, + "Only look for Objects with this property"); + uiDefButS(block, ROW, 1, "X", + (short)(10+xco+0.7 * (width-20)),(short)(yco-44), (short)(0.1 * (width-22)),19, + &rs->axis, 2.0, 0, 0, 0, + "Cast the cone along the object's positive x-axis"); + uiDefButS(block, ROW, 1, "Y", + (short)(10+xco+0.8 * (width-20)),(short)(yco-44),(short)(0.1 * (width-22)), 19, + &rs->axis, 2.0, 1, 0, 0, + "Cast the cone along the object's positive y-axis"); + uiDefButS(block, ROW, 1, "Z", + (short)(10+xco+0.9 * (width-20)), (short)(yco-44), (short)(0.1 * (width-22)), 19, + &rs->axis, 2.0, 2, 0, 0, + "Cast the cone along the object's positive z-axis"); + uiDefButF(block, NUM, 1, "Ang:", + (short)(10+xco), (short)(yco-68), (short)((width-20)/2), 19, + &rs->angle, 0.0, 179.9, 10, 0, + "Opening angle of the radar cone."); + uiDefButF(block, NUM, 1, "Dist:", + (short)(xco+10 + (width-20)/2), (short)(yco-68), (short)((width-20)/2), 19, + &rs->range, 0.01, 10000.0, 100, 0, + "Depth of the radar cone"); + yco-= ysize; + break; + } + case SENS_KEYBOARD: + { + /* 5 lines: 120 height */ + ysize= 120; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + /* header line */ + draw_default_sensor_header(sens, block, xco, yco, width); + ks= sens->data; + + /* line 2: hotkey and allkeys toggle */ + uiDefKeyevtButS(block, B_DIFF, "", xco+40, yco-44, (width)/2, 19, &ks->key, "Key code"); + + /* line 3: two key modifyers (qual1, qual2) */ + uiDefKeyevtButS(block, B_DIFF, "", xco+40, yco-68, (width-50)/2, 19, &ks->qual, "Modifier key code"); + uiDefKeyevtButS(block, B_DIFF, "", xco+40+(width-50)/2, yco-68, (width-50)/2, 19, &ks->qual2, "Second Modifier key code"); + + /* labels for line 1 and 2 */ + uiDefBut(block, LABEL, 0, "Key", xco, yco-44, 40, 19, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Hold", xco, yco-68, 40, 19, NULL, 0, 0, 0, 0, ""); + + /* part of line 1 */ + uiBlockSetCol(block, BUTPURPLE); + uiDefButS(block, TOG|BIT|0, 0, "All keys", xco+40+(width/2), yco-44, (width/2)-50, 19, + &ks->type, 0, 0, 0, 0, ""); + + /* line 4: toggle property for string logging mode */ + uiDefBut(block, TEX, 1, "LogToggle: ", + xco+10, yco-92, (width-20), 19, + ks->toggleName, 0, 31, 0, 0, + "Property that indicates whether to log " + "keystrokes as a string."); + + /* line 5: target property for string logging mode */ + uiDefBut(block, TEX, 1, "Target: ", + xco+10, yco-116, (width-20), 19, + ks->targetName, 0, 31, 0, 0, + "Property that receives the keystrokes in case " + "a string is logged."); + + yco-= ysize; + break; + } + case SENS_PROPERTY: + { + ysize= 96; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, + (float)xco+width, (float)yco, 1); + + draw_default_sensor_header(sens, block, xco, yco, width); + ps= sens->data; + + str= "Type %t|Equal %x0|Not Equal %x1|Interval %x2|Changed %x3"; + /* str= "Type %t|Equal %x0|Not Equal %x1"; */ + uiDefButI(block, MENU, B_REDR, str, xco+30,yco-44,width-60, 19, + &ps->type, 0, 31, 0, 0, "Type"); + + if (ps->type != SENS_PROP_EXPRESSION) + { + uiDefBut(block, TEX, 1, "Prop: ", xco+30,yco-68,width-60, 19, + ps->name, 0, 31, 0, 0, "Property name"); + } + + if(ps->type == SENS_PROP_INTERVAL) + { + uiDefBut(block, TEX, 1, "Min: ", xco,yco-92,width/2, 19, + ps->value, 0, 31, 0, 0, "test for value"); + uiDefBut(block, TEX, 1, "Max: ", xco+width/2,yco-92,width/2, 19, + ps->maxvalue, 0, 31, 0, 0, "test for max value"); + } + else if(ps->type == SENS_PROP_CHANGED); + else + { + uiDefBut(block, TEX, 1, "Value: ", xco+30,yco-92,width-60, 19, + ps->value, 0, 31, 0, 0, "test for value"); + } + + yco-= ysize; + break; + } + case SENS_MOUSE: + { + ms= sens->data; + /* Two lines: 48 pixels high. */ + ysize = 48; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + /* line 1: header */ + draw_default_sensor_header(sens, block, xco, yco, width); + + /* Line 2: type selection. The number are a bit mangled to get + * proper compatibility with older .blend files. */ + str= "Type %t|Left button %x1|Middle button %x2|" + "Right button %x4|Movement %x8|Mouse over %x16"; + uiDefButS(block, MENU, B_REDR, str, xco+10, yco-44, width-20, 19, + &ms->type, 0, 31, 0, 0, + "Specify the type of event this mouse sensor should trigger on."); + + yco-= ysize; + break; + } + case SENS_RANDOM: + { + ysize = 48; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + draw_default_sensor_header(sens, block, xco, yco, width); + randomSensor = sens->data; + /* some files were wrongly written, avoid crash now */ + if (randomSensor) + { + uiDefButI(block, NUM, 1, "Seed: ", xco+10,yco-44,(width-20), 19, + &randomSensor->seed, 0, 1000, 0, 0, + "Initial seed of the generator. (Choose 0 for not random)"); + } + yco-= ysize; + break; + } + case SENS_RAY: + { + ysize = 72; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + draw_default_sensor_header(sens, block, xco, yco, width); + raySens = sens->data; + + /* 1. property or material */ + uiDefButS(block, TOG|BIT|0, B_REDR, "M/P", + xco + 10,yco - 44, 0.20 * (width-20), 19, + &raySens->mode, 0.0, 0.0, 0, 0, + "Toggle collision on material or property."); + + if (raySens->mode & SENS_COLLISION_MATERIAL) + { + uiDefBut(block, TEX, 1, "Material:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19, + &raySens->matname, 0, 31, 0, 0, + "Only look for Objects with this material"); + } + else + { + uiDefBut(block, TEX, 1, "Property:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19, + &raySens->propname, 0, 31, 0, 0, + "Only look for Objects with this property"); + } + + /* 2. sensing range */ + uiDefButF(block, NUM, 1, "Range", xco+10, yco-68, 0.6 * (width-20), 19, + &raySens->range, 0.01, 10000.0, 100, 0, + "Sense objects no farther than this distance"); + + /* 3. axis choice */ + str = "Type %t|+ X axis %x1|+ Y axis %x0|+ Z axis %x2|- X axis %x3|- Y axis %x4|- Z axis %x5"; + uiDefButI(block, MENU, B_REDR, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, + &raySens->axisflag, 2.0, 31, 0, 0, + "Specify along which axis the ray is cast."); + + yco-= ysize; + break; + } + case SENS_MESSAGE: + { + mes = sens->data; + ysize = 2 * 24; /* total number of lines * 24 pixels/line */ + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, + (float)xco+width, (float)yco, 1); + + /* line 1: header line */ + draw_default_sensor_header(sens, block, xco, yco, width); + + /* line 2: Subject filter */ + uiDefBut(block, TEX, 1, "Subject: ", + (xco+10), (yco-44), (width-20), 19, + mes->subject, 0, 31, 0, 0, + "Optional subject filter: only accept messages with this subject" + ", or empty for all"); + + yco -= ysize; + break; + } + } + + uiBlockSetEmboss(block, UI_EMBOSSM); + uiBlockSetCol(block, BUTGREY); + + return yco-4; +} + + + +static short draw_controllerbuttons(bController *cont, uiBlock *block, short xco, short yco, short width) +{ + bExpressionCont *ec; + bPythonCont *pc; + short ysize; + + uiBlockSetEmboss(block, UI_EMBOSSW); + + switch (cont->type) { + case CONT_EXPRESSION: + ysize= 28; + + BIF_set_color(BUTPROPERTY, COLORSHADE_GREY); + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + /* uiDefBut(block, LABEL, 1, "Not yet...", xco,yco-24,80, 19, NULL, 0, 0, 0, 0, ""); */ + ec= cont->data; + /* uiDefBut(block, BUT, 1, "Variables", xco,yco-24,80, 19, NULL, 0, 0, 0, 0, "Available variables for expression"); */ + uiDefBut(block, TEX, 1, "Exp:", xco + 10 , yco-21, width-20, 19, + ec->str, 0, 127, 0, 0, + "Expression"); + + yco-= ysize; + break; + case CONT_PYTHON: + ysize= 28; + + if(cont->data==NULL) init_controller(cont); + pc= cont->data; + + BIF_set_color(BUTMESSAGE, COLORSHADE_GREY); + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scriptpoin_but, 1, "Script: ", xco+45,yco-24,width-90, 19, &pc->text, ""); + + yco-= ysize; + break; + + default: + ysize= 4; + + BIF_set_color(BUTIPO, COLORSHADE_GREY); + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + yco-= ysize; + } + + uiBlockSetEmboss(block, UI_EMBOSSM); + uiBlockSetCol(block, BUTGREY); + + return yco; +} + +static BIFColorID get_col_actuator(int type) +{ + switch(type) { + case ACT_ACTION: return BUTACTION; + case ACT_OBJECT: return BUTMOTION; + case ACT_IPO: return BUTIPO; + case ACT_PROPERTY: return BUTPROPERTY; + case ACT_SOUND: return BUTAUDIO; + case ACT_CD: return BUTCD; + case ACT_CAMERA: return BUTCAMERA; + case ACT_EDIT_OBJECT: return BUTEDITOBJECT; + case ACT_GROUP: return BUTYELLOW; + case ACT_RANDOM: return BUTRANDOM; + case ACT_SCENE: return BUTSCENE; + case ACT_MESSAGE: return BUTMESSAGE; + case ACT_GAME: return BUTGAME; + case ACT_VISIBILITY: return BUTVISIBILITY; + default: return BUTGREY; + } +} +static void set_col_actuator(int item, int medium) +{ + if (item==ACT_CONSTRAINT) { + BIF_set_color(BUTRUST, medium?COLORSHADE_HILITE:COLORSHADE_MEDIUM); + } else { + BIFColorID col= get_col_actuator(item); + BIF_set_color(col, medium?COLORSHADE_MEDIUM:COLORSHADE_GREY); + } +} + +static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, short yco, short width) +{ + bSoundActuator *sa = NULL; + bCDActuator *cda = NULL; + bObjectActuator *oa = NULL; + bIpoActuator *ia = NULL; + bPropertyActuator *pa = NULL; + bCameraActuator *ca = NULL; + bEditObjectActuator *eoa = NULL; + bConstraintActuator *coa = NULL; + bSceneActuator *sca = NULL; + bGroupActuator *ga = NULL; + bRandomActuator *randAct = NULL; + bMessageActuator *ma = NULL; + bActionActuator *aa = NULL; + bGameActuator *gma = NULL; + bVisibilityActuator *visAct = NULL; + + float *fp; + short ysize = 0, wval; + char *str; + int myline; + + /* yco is at the top of the rect, draw downwards */ + uiBlockSetEmboss(block, UI_EMBOSSW); + set_col_actuator(act->type, 0); + + switch (act->type) + { + case ACT_OBJECT: + { + ysize= 129; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiBlockSetCol(block, BUTGREY); + + oa = act->data; + wval = (width-100)/3; + + uiDefBut(block, LABEL, 0, "Force", xco, yco-22, 55, 19, NULL, 0, 0, 0, 0, "Sets the force"); + uiDefButF(block, NUM, 0, "", xco+45, yco-22, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-22, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-22, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefBut(block, LABEL, 0, "Torque", xco, yco-41, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque"); + uiDefButF(block, NUM, 0, "", xco+45, yco-41, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-41, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-41, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefBut(block, LABEL, 0, "dLoc", xco, yco-64, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc"); + uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefBut(block, LABEL, 0, "dRot", xco, yco-83, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot"); + uiDefButF(block, NUM, 0, "", xco+45, yco-83, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-83, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-83, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefBut(block, LABEL, 0, "linV", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity"); + uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefBut(block, LABEL, 0, "angV", xco, yco-125, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity"); + uiDefButF(block, NUM, 0, "", xco+45, yco-125, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-125, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-125, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, ""); + + uiBlockSetCol(block, BUTGREEN); + uiDefButI(block, TOG|BIT|0, 0, "L", xco+45+3*wval, yco-22, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButI(block, TOG|BIT|1, 0, "L", xco+45+3*wval, yco-41, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButI(block, TOG|BIT|2, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButI(block, TOG|BIT|3, 0, "L", xco+45+3*wval, yco-83, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButI(block, TOG|BIT|4, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButI(block, TOG|BIT|5, 0, "L", xco+45+3*wval, yco-125, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + + uiBlockSetCol(block, BUTGREEN); + uiDefButI(block, TOG|BIT|6, 0, "add",xco+45+3*wval+15, yco-106, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV"); + uiBlockSetCol(block, BUTGREY); + + yco-= ysize; + break; + } + case ACT_ACTION: + { + /* DrawAct */ +#ifdef __NLA_ACTION_BY_MOTION_ACTUATOR + ysize = 112; +#else + ysize= 92; +#endif + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + aa = act->data; + wval = (width-60)/3; + + uiBlockSetCol(block, BUTGREY); + // str= "Action types %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6"; +#ifdef __NLA_ACTION_BY_MOTION_ACTUATOR + str= "Action types %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6|Displacement %x7"; +#else + str= "Action types %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6"; +#endif + uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, width-60, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type"); + uiDefIDPoinBut(block, test_actionpoin_but, 1, "AC: ", xco+30, yco-44, width-60, 19, &aa->act, "Action name"); + + if(aa->type == ACT_ACTION_FROM_PROP) + { + uiDefBut(block, TEX, 0, "Prop: ",xco+30, yco-64, width-60, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position"); + } + else + { + uiDefButS(block, NUM, 0, "Sta: ",xco+30, yco-64, (width-60)/2, 19, &aa->sta, 0.0, 18000.0, 0, 0, "Start frame"); + uiDefButS(block, NUM, 0, "End: ",xco+30+(width-60)/2, yco-64, (width-60)/2, 19, &aa->end, 0.0, 18000.0, 0, 0, "End frame"); + } + + + + uiDefButS(block, NUM, 0, "Blendin: ", xco+30, yco-84, (width-60)/2, 19, &aa->blendin, 0.0, 18000.0, 0.0, 0.0, "Number of frames of motion blending"); + uiDefButS(block, NUM, 0, "Priority: ", xco+30+(width-60)/2, yco-84, (width-60)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers"); + +#ifdef __NLA_ACTION_BY_MOTION_ACTUATOR + if(aa->type == ACT_ACTION_MOTION) + { + uiDefButF(block, NUM, 0, "Cycle: ",xco+30, yco-104, (width-60)/2, 19, &aa->stridelength, 0.0, 2500.0, 0, 0, "Distance covered by a single cycle of the action"); + } +#endif + + yco-=ysize; + break; + } + case ACT_IPO: + { + ia= act->data; + + if(ia->type==ACT_IPO_KEY2KEY) + ysize= 72; + else + ysize= 52; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + str = "Ipo types %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6"; + + uiDefButS(block, MENU, B_REDR, str, xco+20, yco-24, width-40 - (width-40)/3, 19, &ia->type, 0, 0, 0, 0, ""); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|ACT_IPOCHILD_BIT, B_REDR, + "Child", xco+20+0.666*(width-40), yco-24, (width-40)/3, 19, + &ia->flag, 0, 0, 0, 0, + "Add all children Objects as well"); + uiBlockSetCol(block, BUTGREY); + /* + Key2key was disabled.... the settings below should not be reused without + thought, because they interfere with other variables. + + if(ia->type==ACT_IPO_KEY2KEY) { + uiBlockSetCol(block, BUTGREEN); + + uiDefButS(block, TOG|BIT|0, 0, "Prev", xco+20, yco-44, (width-40)/3, 19, &ia->flag, 0, 0, 0, 0, "Play backwards"); + uiDefButS(block, TOG|BIT|1, 0, "Cycl", xco+20+(width-40)/3, yco-44, (width-40)/3, 19, &ia->flag, 0, 0, 0, 0, "Play cyclic"); + uiDefButS(block, TOG|BIT|3, 0, "Hold", xco+20+2*(width-40)/3, yco-44, (width-40)/3, 19, &ia->flag, 0, 0, 0, 0, "Keep playing while activated"); + + uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-66, width-40, 19, ia->name, 0.0, 31.0, 0, 0, "Set property to key position"); + } else + */ + if(ia->type==ACT_IPO_FROM_PROP) { + uiDefBut(block, TEX, 0, + "Prop: ", xco+20, yco-44, width-40, 19, + ia->name, 0.0, 31.0, 0, 0, + "Use this property to define the Ipo position"); + } + else { + uiDefButS(block, NUM, 0, + "Sta", xco+20, yco-44, (width-100)/2, 19, + &ia->sta, 0.0, 18000.0, 0, 0, + "Start frame"); + uiDefButS(block, NUM, 0, + "End", xco+18+(width-90)/2, yco-44, (width-100)/2, 19, + &ia->end, 0.0, 18000.0, 0, 0, + "End frame"); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|ACT_IPOFORCE_BIT, B_REDR, + "Force", xco+width-78, yco-44, 43, 19, + &ia->flag, 0, 0, 0, 0, + "Convert Ipo to force"); + + /* Only show the do-force-local toggle if force is requested */ + if (ia->flag & ACT_IPOFORCE) { + uiDefButS(block, TOG|BIT|ACT_IPOFORCE_LOCAL_BIT, 0, + "L", xco+width-35, yco-44, 15, 19, + &ia->flag, 0, 0, 0, 0, + "Let the force-ipo act in local coordinates."); + } + + } + yco-= ysize; + break; + } + case ACT_PROPERTY: + { + ysize= 68; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + pa= act->data; + + str= "Type %t|Assign %x0|Add %x1|Copy %x2"; + uiDefButI(block, MENU, B_REDR, str, xco+30,yco-24,width-60, 19, &pa->type, 0, 31, 0, 0, "Type"); + + uiDefBut(block, TEX, 1, "Prop: ", xco+30,yco-44,width-60, 19, pa->name, 0, 31, 0, 0, "Property name"); + + if(pa->type==ACT_PROP_COPY) { + uiDefIDPoinBut(block, test_obpoin_but, 1, "OB:", xco+10, yco-64, (width-20)/2, 19, &(pa->ob), "Copy from this Object"); + uiDefBut(block, TEX, 1, "Prop: ", xco+10+(width-20)/2, yco-64, (width-20)/2, 19, pa->value, 0, 31, 0, 0, "Copy this property"); + } + else { + uiDefBut(block, TEX, 1, "Value: ", xco+30,yco-64,width-60, 19, pa->value, 0, 31, 0, 0, "change with this value"); + } + yco-= ysize; + + break; + } + case ACT_SOUND: + { + ysize = 70; + + sa = act->data; + sa->sndnr = 0; + + wval = (width-20)/2; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + IDnames_to_pupstring(&str, "Sound files", NULL, &(G.main->sound), (ID *)sa->sound, &(sa->sndnr)); + + if(str[0]) + { + /* reset this value, it is for handling the event */ + sa->sndnr = 0; + uiDefButS(block, MENU, B_SOUNDACT_BROWSE, str, xco+10,yco-22,20,19, &(sa->sndnr), 0, 0, 0, 0, ""); + + if(sa->sound) + { + char dummy_str[] = "Sound mode %t|Play Stop %x0|Play End %x1|Loop Stop %x2|Loop End %x3|Loop Ping Pong Stop %x5|Loop Ping Pong %x4"; + uiDefBut(block, TEX, B_IDNAME, "SO:",xco+30,yco-22,width-40,19, sa->sound->id.name+2, 0.0, 18.0, 0, 0, ""); + uiDefButS(block, MENU, 1, dummy_str,xco+10,yco-44,width-20, 19, &sa->type, 0.0, 0.0, 0, 0, ""); + uiDefButF(block, NUM, 0, "Volume:", xco+10,yco-66,wval, 19, &sa->sound->volume, 0.0, 1.0, 0, 0, "Sets the volume of this sound"); + uiDefButF(block, NUM, 0, "Pitch:",xco+wval+10,yco-66,wval, 19, &sa->sound->pitch,-12.0, 12.0, 0, 0, "Sets the pitch of this sound"); + } + } + else + { + uiDefBut(block, LABEL, 0, "Use Sound window to load files", xco, yco-24, width, 19, NULL, 0, 0, 0, 0, ""); + } + + MEM_freeN(str); + + yco-= ysize; + + break; + } + case ACT_CD: + { + char cd_type_str[] = "Sound mode %t|Play all tracks %x0|Play one track %x1|" + "Volume %x3|Stop %x4|Pause %x5|Resume %x6"; + cda = act->data; + + if (cda) + { + if (cda->track == 0) + { + cda->track = 1; + cda->volume = 1; + cda->type = ACT_CD_PLAY_ALL; + } + + if (cda->type == ACT_CD_PLAY_TRACK || cda->type == ACT_CD_LOOP_TRACK) + { + ysize = 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefButS(block, NUM, 0, "Track:", xco+10,yco-44,width-20, 19, &cda->track, 1, 99, 0, 0, "Select the track to be played"); + } + else if (cda->type == ACT_CD_VOLUME) + { + ysize = 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefButF(block, NUM, 0, "Volume:", xco+10,yco-44,width-20, 19, &cda->volume, 0, 1, 0, 0, "Set the volume for CD playback"); + } + else + { + ysize = 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + } + uiDefButS(block, MENU, B_REDR, cd_type_str,xco+10,yco-22,width-20, 19, &cda->type, 0.0, 0.0, 0, 0, ""); + } + yco-= ysize; + break; + } + case ACT_CAMERA: + + ysize= 48; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + ca= act->data; + + uiDefIDPoinBut(block, test_obpoin_but, 1, "OB:", xco+10, yco-24, (width-20)/2, 19, &(ca->ob), "Look at this Object"); + uiDefButF(block, NUM, 0, "Height:", xco+10+(width-20)/2, yco-24, (width-20)/2, 19, &ca->height, 0.0, 20.0, 0, 0, ""); + + uiDefButF(block, NUM, 0, "Min:", xco+10, yco-44, (width-60)/2, 19, &ca->min, 0.0, 20.0, 0, 0, ""); + + if(ca->axis==0) ca->axis= 'x'; + uiDefButS(block, ROW, 0, "X", xco+10+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'x', 0, 0, "Camera tries to get behind the X axis"); + uiDefButS(block, ROW, 0, "Y", xco+30+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'y', 0, 0, "Camera tries to get behind the Y axis"); + + uiDefButF(block, NUM, 0, "Max:", xco+20+(width)/2, yco-44, (width-60)/2, 19, &ca->max, 0.0, 20.0, 0, 0, ""); + + yco-= ysize; + + break; + + case ACT_EDIT_OBJECT: + + eoa= act->data; + + if(eoa->type==ACT_EDOB_ADD_OBJECT) { + int wval; /* just a temp width */ + ysize = 72; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_obpoin_but, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object"); + uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the new Object lives"); + + wval= (width-60)/3; + uiDefBut(block, LABEL, 0, "linV", xco, yco-68, 45, 19, + NULL, 0, 0, 0, 0, + "Velocity upon creation."); + uiDefButF(block, NUM, 0, "", xco+45, yco-68, wval, 19, + eoa->linVelocity, -100.0, 100.0, 10, 0, + "Velocity upon creation, x component."); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-68, wval, 19, + eoa->linVelocity+1, -100.0, 100.0, 10, 0, + "Velocity upon creation, y component."); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-68, wval, 19, + eoa->linVelocity+2, -100.0, 100.0, 10, 0, + "Velocity upon creation, z component."); + uiDefButS(block, TOG|BIT|1, 0, "L", xco+45+3*wval, yco-68, 15, 19, + &eoa->localflag, 0.0, 0.0, 0, 0, + "Apply the transformation locally"); + + } + else if(eoa->type==ACT_EDOB_END_OBJECT) { + ysize= 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + } + else if(eoa->type==ACT_EDOB_REPLACE_MESH) { + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_meshpoin_but, 1, "ME:", xco+40, yco-44, (width-80), 19, &(eoa->me), "Add this Object"); + } + else if(eoa->type==ACT_EDOB_TRACK_TO) { + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_obpoin_but, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Track to this Object"); + uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2-40, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the tracking takes"); + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG, 0, "3D", xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking"); + uiBlockSetCol(block, BUTGREY); + } + + str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3"; + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, ""); + + yco-= ysize; + + break; + + case ACT_CONSTRAINT: + + ysize= 44; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + coa= act->data; + +/* str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */ + str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4"; + uiDefButS(block, MENU, 1, str, xco+10, yco-40, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, ""); + + uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-20, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Min", xco+80, yco-20, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Max", xco+80+(width-90)/2, yco-20, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); + + if(coa->flag & ACT_CONST_LOCX) fp= coa->minloc; + else if(coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1; + else if(coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2; + else if(coa->flag & ACT_CONST_ROTX) fp= coa->minrot; + else if(coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1; + else fp= coa->minrot+2; + + uiDefButF(block, NUM, 0, "", xco+80, yco-40, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+80+(width-90)/2, yco-40, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, ""); + + yco-= ysize; + + break; + + case ACT_SCENE: + sca= act->data; + + if(sca->type==ACT_SCENE_RESTART) { + ysize= 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + } + else if(sca->type==ACT_SCENE_CAMERA) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_obpoin_but, 1, "OB:", xco+40, yco-44, (width-80), 19, &(sca->camera), "Set this Camera"); + } + else if(sca->type==ACT_SCENE_SET) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Set this Scene"); + } + else if(sca->type==ACT_SCENE_ADD_FRONT) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Add an Overlay Scene"); + } + else if(sca->type==ACT_SCENE_ADD_BACK) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Add a Background Scene"); + } + else if(sca->type==ACT_SCENE_REMOVE) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Remove a Scene"); + } + else if(sca->type==ACT_SCENE_SUSPEND) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Pause a Scene"); + } + else if(sca->type==ACT_SCENE_RESUME) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Unpause a Scene"); + } + + str= "Scene %t|Restart %x0|Set Scene %x1|Set Camera %x2|Add OverlayScene %x3|Add BackgroundScene %x4|Remove Scene %x5|Suspend Scene %x6|Resume Scene %x7"; + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &sca->type, 0.0, 0.0, 0, 0, ""); + + yco-= ysize; + break; + case ACT_GAME: + { + gma = act->data; + if (gma->type == ACT_GAME_LOAD) + { + //ysize = 68; + ysize = 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, 63, 0, 0, "Load this file"); +// uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, 63, 0, 0, "Use this loadinganimation"); + } +/* else if (gma->type == ACT_GAME_START) + { + ysize = 68; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, 63, 0, 0, "Load this file"); + uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, 63, 0, 0, "Use this loadinganimation"); + } +*/ else if (gma->type == ACT_GAME_RESTART) + { + ysize = 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + } + else if (gma->type == ACT_GAME_QUIT) + { + ysize = 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + } + + //str = "Scene %t|Load game%x0|Start loaded game%x1|Restart this game%x2|Quit this game %x3"; + str = "Scene %t|Start new game%x0|Restart this game%x2|Quit this game %x3"; + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &gma->type, 0.0, 0.0, 0, 0, ""); + + yco -= ysize; + break; + } + case ACT_GROUP: + ga= act->data; + + ysize= 52; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + str= "GroupKey types %t|Set Key %x6|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x5"; + + uiDefButS(block, MENU, 1, str, xco+20, yco-24, width-40, 19, &ga->type, 0, 0, 0, 0, ""); + if(ga->type==ACT_GROUP_SET) { + uiDefBut(block, TEX, 0, "Key: ", xco+20, yco-44, (width-10)/2, 19, ga->name, 0.0, 31.0, 0, 0, "This name defines groupkey to be set"); + uiDefButS(block, NUM, 0, "Frame:", xco+20+(width-10)/2, yco-44, (width-70)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Set this frame"); + } + else if(ga->type==ACT_GROUP_FROM_PROP) { + uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-44, width-40, 19, ga->name, 0.0, 31.0, 0, 0, "Use this property to define the Group position"); + } + else { + uiDefButS(block, NUM, 0, "Sta", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame"); + uiDefButS(block, NUM, 0, "End", xco+20+(width-40)/2, yco-44, (width-40)/2, 19, &ga->end, 0.0, 2500.0, 0, 0, "End frame"); + } + yco-= ysize; + break; + + case ACT_VISIBILITY: + ysize = 24; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, + (float)yco-ysize, (float)xco+width, (float)yco, 1); + + visAct = act->data; + + str= "Visibility %t|Visible %x0|Invisible %x1"; + + uiDefButI(block, MENU, B_REDR, str, + xco + 10, yco - 24, width - 20, 19, &visAct->flag, + 0.0, 0.0, 0, 0, + "Make the object invisible or visible."); +/* + uiDefButI(block, TOG|BIT|ACT_VISIBILITY_INVISIBLE_BIT, 0, + "Invisible", + xco + 10, yco - 24, width - 20, 19, &visAct->flag, + 0.0, 0.0, 0, 0, + "Make the object invisible or visible."); +*/ + yco-= ysize; + + break; + + case ACT_RANDOM: + ysize = 69; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, + (float)yco-ysize, (float)xco+width, (float)yco, 1); + + randAct = act->data; + + /* 1. seed */ + uiDefButI(block, NUM, 1, "Seed: ", (xco+10),yco-24, 0.4 *(width-20), 19, + &randAct->seed, 0, 1000, 0, 0, + "Initial seed of the random generator. Use Python for more freedom. " + " (Choose 0 for not random)"); + + /* 2. distribution type */ + /* One pick per distribution. These numbers MUST match the #defines */ + /* in game.h !!! */ + str= "Distribution %t|Bool Constant %x0|Bool Uniform %x1" + "|Bool Bernoulli %x2|Int Constant %x3|Int Uniform %x4" + "|Int Poisson %x5|Float Constant %x6|Float Uniform %x7" + "|Float Normal %x8|Float Neg. Exp. %x9"; + uiDefButI(block, MENU, B_REDR, str, (xco+10) + 0.4 * (width-20), yco-24, 0.6 * (width-20), 19, + &randAct->distribution, 0.0, 0.0, 0, 0, + "Choose the type of distribution"); + + /* 3. property */ + uiDefBut(block, TEX, 1, "Property:", (xco+10), yco-44, (width-20), 19, + &randAct->propname, 0, 31, 0, 0, + "Assign the random value to this property"); + + /*4. and 5. arguments for the distribution*/ + switch (randAct->distribution) { + case ACT_RANDOM_BOOL_CONST: + uiDefButI(block, TOG|BIT|0, 1, "Always true", (xco+10), yco-64, (width-20), 19, + &randAct->int_arg_1, 2.0, 1, 0, 0, + "Always false or always true"); + break; + case ACT_RANDOM_BOOL_UNIFORM: + uiDefBut(block, LABEL, 0, " Do a 50-50 pick.", (xco+10), yco-64, (width-20), 19, + NULL, 0, 0, 0, 0, + "Choose between true and false, 50%% chance each."); + break; + case ACT_RANDOM_BOOL_BERNOUILLI: + uiDefButF(block, NUM, 1, "Chance", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.0, 1.0, 0, 0, + "Pick a number between 0 and 1. Success if you stay " + "below this value"); + break; + case ACT_RANDOM_INT_CONST: + uiDefButI(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19, + &randAct->int_arg_1, -1000, 1000, 0, 0, + "Always return this number"); + break; + case ACT_RANDOM_INT_UNIFORM: + uiDefButI(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, + &randAct->int_arg_1, -1000, 1000, 0, 0, + "Choose a number from a range. " + "Lower boundary of the range."); + uiDefButI(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, + &randAct->int_arg_2, -1000, 1000, 0, 0, + "Choose a number from a range. " + "Upper boundary of the range."); + break; + case ACT_RANDOM_INT_POISSON: + uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.01, 100.0, 0, 0, + "Expected mean value of the distribution."); + break; + case ACT_RANDOM_FLOAT_CONST: + uiDefButF(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.0, 1.0, 0, 0, + "Always return this number"); + break; + case ACT_RANDOM_FLOAT_UNIFORM: + uiDefButF(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, + &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, + "Choose a number from a range. " + "Lower boundary of the range."); + uiDefButF(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, + &randAct->float_arg_2, -10000.0, 10000.0, 0, 0, + "Choose a number from a range. " + "Upper boundary of the range."); + break; + case ACT_RANDOM_FLOAT_NORMAL: + uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20)/2, 19, + &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, + "A normal distribution. Mean of the distribution."); + uiDefButF(block, NUM, 1, "SD: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, + &randAct->float_arg_2, 0.0, 10000.0, 0, 0, + "A normal distribution. Standard deviation of the " + "distribution."); + break; + case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL: + uiDefButF(block, NUM, 1, "Half-life time: ", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.001, 10000.0, 0, 0, + "Negative exponential dropoff."); + break; + default: + ; /* don't know what this distro is... can be useful for testing */ + /* though :) */ + } + + yco-= ysize; + break; + case ACT_MESSAGE: + ma = act->data; + +#define MESSAGE_SENSOR_TO_FIELD_WORKS /* Really? Not really. Don't remove this ifdef yet */ + +#ifdef MESSAGE_SENSOR_TO_FIELD_WORKS + ysize = 4 + (3 * 24); /* footer + number of lines * 24 pixels/line */ +#else + ysize = 4 + (2 * 24); /* footer + number of lines * 24 pixels/line */ +#endif + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, + (float)xco+width, (float)yco, 1); + + myline=1; + + +#ifdef MESSAGE_SENSOR_TO_FIELD_WORKS + /* line 1: To */ + uiDefBut(block, TEX, 1, "To: ", + (xco+10), (yco-(myline++*24)), (width-20), 19, + &ma->toPropName, 0, 31, 0, 0, + "Optional send message to objects with this property only" + ", or empty to broadcast"); + +#endif + + /* line 2: Message Subject */ + uiDefBut(block, TEX, 1, "Subject: ", + (xco+10), (yco-(myline++*24)), (width-20), 19, + &ma->subject, 0, 31, 0, 0, + "Optional message subject. This is what can be filtered on."); + + /* line 3: Text/Property */ + uiDefButS(block, TOG|BIT|0, B_REDR, "T/P", + (xco+10),(yco-(myline*24)), (0.20 * (width-20)), 19, + &ma->bodyType, 0.0, 0.0, 0, 0, + "Toggle message type: either Text or a PropertyName."); + + if (ma->bodyType == ACT_MESG_MESG) + { + /* line 3: Message Body */ + uiDefBut(block, TEX, 1, "Body: ", + (xco+10+(0.20*(width-20))),(yco-(myline++*24)),(0.8*(width-20)),19, + &ma->body, 0, 31, 0, 0, + "Optional message body Text"); + } else + { + /* line 3: Property body (set by property) */ + uiDefBut(block, TEX, 1, "Propname: ", + (xco+10+(0.20*(width-20))),(yco-(myline++*24)),(0.8*(width-20)),19, + &ma->body, 0, 31, 0, 0, + "The message body will be set by the Property Value"); + } + + yco -= ysize; + break; + default: + ysize= 4; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + yco-= ysize; + break; + } + + uiBlockSetEmboss(block, UI_EMBOSSM); + uiBlockSetCol(block, BUTGREY); + + return yco-4; +} + +static void do_sensor_menu(void *arg, int event) +{ + ID **idar; + Object *ob; + bSensor *sens; + short count, a; + + idar= get_selected_and_linked_obs(&count, G.buts->scaflag); + + for(a=0; a<count; a++) { + ob= (Object *)idar[a]; + if(event==0 || event==2) ob->scaflag |= OB_SHOWSENS; + else if(event==1) ob->scaflag &= ~OB_SHOWSENS; + } + + for(a=0; a<count; a++) { + ob= (Object *)idar[a]; + sens= ob->sensors.first; + while(sens) { + if(event==2) sens->flag |= SENS_SHOW; + else if(event==3) sens->flag &= ~SENS_SHOW; + sens= sens->next; + } + } + + if(idar) MEM_freeN(idar); + allqueue(REDRAWBUTSGAME, 0); +} + +static uiBlock *sensor_menu(void *arg_unused) +{ + uiBlock *block; + int yco=0; + + block= uiNewBlock(&curarea->uiblocks, "filemenu", UI_EMBOSSP, UI_HELV, curarea->win); + uiBlockSetButmFunc(block, do_sensor_menu, NULL); + + uiDefBut(block, BUTM, 1, "Show Objects", 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, 1, "Hide Objects", 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefBut(block, SEPR, 0, "", 0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Show Sensors", 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, ""); + uiDefBut(block, BUTM, 1, "Hide Sensors", 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, ""); + + uiBlockSetDirection(block, UI_TOP); + + return block; +} + +static void do_controller_menu(void *arg, int event) +{ + ID **idar; + Object *ob; + bController *cont; + short count, a; + + idar= get_selected_and_linked_obs(&count, G.buts->scaflag); + + for(a=0; a<count; a++) { + ob= (Object *)idar[a]; + if(event==0 || event==2) ob->scaflag |= OB_SHOWCONT; + else if(event==1) ob->scaflag &= ~OB_SHOWCONT; + } + + for(a=0; a<count; a++) { + ob= (Object *)idar[a]; + cont= ob->controllers.first; + while(cont) { + if(event==2) cont->flag |= CONT_SHOW; + else if(event==3) cont->flag &= ~CONT_SHOW; + cont= cont->next; + } + } + + if(idar) MEM_freeN(idar); + allqueue(REDRAWBUTSGAME, 0); +} + +static uiBlock *controller_menu(void *arg_unused) +{ + uiBlock *block; + int yco=0; + + block= uiNewBlock(&curarea->uiblocks, "filemenu", UI_EMBOSSP, UI_HELV, curarea->win); + uiBlockSetButmFunc(block, do_controller_menu, NULL); + + uiDefBut(block, BUTM, 1, "Show Objects", 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, 1, "Hide Objects", 0,(short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefBut(block, SEPR, 0, "", 0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Show Controllers", 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 2, 2, ""); + uiDefBut(block, BUTM, 1, "Hide Controllers", 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 3, 3, ""); + + uiBlockSetDirection(block, UI_TOP); + + return block; +} + +static void do_actuator_menu(void *arg, int event) +{ + ID **idar; + Object *ob; + bActuator *act; + short count, a; + + idar= get_selected_and_linked_obs(&count, G.buts->scaflag); + + for(a=0; a<count; a++) { + ob= (Object *)idar[a]; + if(event==0 || event==2) ob->scaflag |= OB_SHOWACT; + else if(event==1) ob->scaflag &= ~OB_SHOWACT; + } + + for(a=0; a<count; a++) { + ob= (Object *)idar[a]; + act= ob->actuators.first; + while(act) { + if(event==2) act->flag |= ACT_SHOW; + else if(event==3) act->flag &= ~ACT_SHOW; + act= act->next; + } + } + + if(idar) MEM_freeN(idar); + allqueue(REDRAWBUTSGAME, 0); +} + +static uiBlock *actuator_menu(void *arg_unused) +{ + uiBlock *block; + int xco=0; + + block= uiNewBlock(&curarea->uiblocks, "filemenu", UI_EMBOSSP, UI_HELV, curarea->win); + uiBlockSetButmFunc(block, do_actuator_menu, NULL); + + uiDefBut(block, BUTM, 1, "Show Objects", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, 1, "Hide Objects", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefBut(block, SEPR, 0, "", 0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Show Actuators", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, ""); + uiDefBut(block, BUTM, 1, "Hide Actuators", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, ""); + + uiBlockSetDirection(block, UI_TOP); + + return block; +} + +/* never used, see CVS 1.134 for the code */ +/* static FreeCamera *new_freecamera(void) */ + +/* never used, see CVS 1.120 for the code */ +/* static uiBlock *freecamera_menu(void) */ + +void gamebuts(void) +{ + ID **idar; + Object *ob; + bProperty *prop; + bSensor *sens; + bController *cont; + bActuator *act; + uiBlock *block; + uiBut *but; + int a; + short xco, yco, count, width, ycoo; + char *pupstr, name[32]; + int butreturn = 0; + + ob= OBACT; + + if(ob==0) return; + uiSetButLock(ob->id.lib!=0, "Can't edit library data"); + + sprintf(name, "buttonswin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, name, UI_EMBOSSX, UI_HELV, curarea->win); + + uiBlockSetCol(block, BUTPURPLE); + // uiDefButI(block, TOG|BIT|0, B_REDR, "X", + // 15,205,10,19, &ob->gameflag2, 0, 0, 0, 0, + // "Toggle to always ignore activity culling."); + uiDefButI(block, TOG|BIT|2, B_REDR, "Actor", + 25,205,60,19, &ob->gameflag, 0, 0, 0, 0, + "Objects that are evaluated by the engine "); + + if(ob->gameflag & OB_ACTOR) { + uiDefButI(block, TOG|BIT|9, B_REDR, "Ghost", 85,205,65,19, &ob->gameflag, 0, 0, 0, 0, "Objects that don't restitute collisions (like a ghost)"); + uiDefButI(block, TOG|BIT|0, B_REDR, "Dynamic", 150,205,65,19, &ob->gameflag, 0, 0, 0, 0, "Motion defined by laws of physics"); + + if(ob->gameflag & OB_DYNAMIC) { + + uiDefButI(block, TOG|BIT|10, B_REDR, "Rigid Body", 215,205,135,19, &ob->gameflag, 0, 0, 0, 0, ""); + + uiDefButI(block, TOG|BIT|6, B_DIFF, "Do Fh", 10,185,50,19, &ob->gameflag, 0, 0, 0, 0, "Use Fh settings in Materials"); + uiDefButI(block, TOG|BIT|7, B_DIFF, "Rot Fh", 60,185,50,19, &ob->gameflag, 0, 0, 0, 0, "Use face normal to rotate Object"); + + uiBlockSetCol(block, BUTGREY); + + uiDefButF(block, NUM, B_DIFF, "Mass:", 110, 185, 80, 19, &ob->mass, 0.01, 100.0, 10, 0, "The mass of the Object"); + uiDefButF(block, NUM, REDRAWVIEW3D, "Size:", 190, 185, 80, 19, &ob->inertia, 0.01, 10.0, 10, 0, "Bounding sphere size"); + uiDefButF(block, NUM, B_DIFF, "Form:", 270, 185, 80, 19, &ob->formfactor, 0.01, 100.0, 10, 0, "Form factor"); + + uiDefButF(block, NUM, B_DIFF, "Damp:", 10, 165, 100, 19, &ob->damping, 0.0, 1.0, 10, 0, "General movement damping"); + uiDefButF(block, NUM, B_DIFF, "RotDamp:", 110, 165, 120, 19, &ob->rdamping, 0.0, 1.0, 10, 0, "General rotation damping"); + uiDefButI(block, TOG|BIT|8, B_REDR, "Anisotropic", 230, 165, 120, 19, + &ob->gameflag, 0.0, 1.0, 10, 0, + "Enable anisotropic friction"); + } + } + + if (ob->gameflag & OB_ANISOTROPIC_FRICTION) { + uiDefButF(block, NUM, B_DIFF, "x friction:", 10, 145, 114, 19, + &ob->anisotropicFriction[0], 0.0, 1.0, 10, 0, + "Relative friction coefficient in the x-direction."); + uiDefButF(block, NUM, B_DIFF, "y friction:", 124, 145, 113, 19, + &ob->anisotropicFriction[1], 0.0, 1.0, 10, 0, + "Relative friction coefficient in the y-direction."); + uiDefButF(block, NUM, B_DIFF, "z friction:", 237, 145, 113, 19, + &ob->anisotropicFriction[2], 0.0, 1.0, 10, 0, + "Relative friction coefficient in the z-direction."); + } + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_ADD_PROP, "ADD property", 10, 110, 340, 24, + NULL, 0.0, 100.0, 100, 0, + ""); + + pupstr= "Types %t|Bool %x0|Int %x1|Float %x2|String %x3|Timer %x5"; + + a= 0; + prop= ob->prop.first; + while(prop) { + + uiBlockSetCol(block, BUTSALMON); + but= uiDefBut(block, BUT, 1, "Del", 10, (short)(90-20*a), 40, 19, NULL, 0.0, 0.0, 1, (float)a, ""); + uiButSetFunc(but, del_property, prop, NULL); + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, MENU, B_CHANGE_PROP, pupstr, 50, (short)(90-20*a), 60, 19, &prop->type, 0, 0, 0, 0, ""); + but= uiDefBut(block, TEX, 1, "Name:", 110, (short)(90-20*a), 105, 19, prop->name, 0, 31, 0, 0, ""); + uiButSetFunc(but, make_unique_prop_names_cb, prop->name, (void*) 1); + + if (strcmp(prop->name, "Text") == 0) { + butreturn = REDRAWVIEW3D; + } else { + butreturn = 0; + } + + if(prop->type==PROP_BOOL) { + uiBlockSetCol(block, BUTGREEN); + uiDefButI(block, TOG|BIT|0, B_REDR, "True", 215, (short)(90-20*a), 55, 19, &prop->data, 0, 0, 0, 0, ""); + uiDefButI(block, TOGN|BIT|0, B_REDR, "False", 270, (short)(90-20*a), 55, 19, &prop->data, 0, 0, 0, 0, ""); + uiBlockSetCol(block, BUTGREY); + } + else if(prop->type==PROP_INT) + uiDefButI(block, NUM, butreturn, "", 215, (short)(90-20*a), 110, 19, &prop->data, -10000, 10000, 0, 0, ""); + else if(prop->type==PROP_FLOAT) + uiDefButF(block, NUM, butreturn, "", 215, (short)(90-20*a), 110, 19, (float*) &prop->data, -10000, 10000, 100, 0, ""); + else if(prop->type==PROP_STRING) + uiDefBut(block, TEX, butreturn, "", 215, (short)(90-20*a), 110, 19, prop->poin, 0, 127, 0, 0, ""); + else if(prop->type==PROP_TIME) + uiDefButF(block, NUM, butreturn, "", 215, (short)(90-20*a), 110, 19, (float*) &prop->data, -10000, 10000, 0, 0, ""); + + uiDefButS(block, TOG|BIT|0, 0, "D", 325, (short)(90-20*a), 20, 19, &prop->flag, 0, 0, 0, 0, "Print Debug info"); + + a++; + prop= prop->next; + } + + uiClearButLock(); + + idar= get_selected_and_linked_obs(&count, G.buts->scaflag); + + /* ******************************* */ + xco= 375; yco= 170; width= 230; + + uiBlockSetCol(block, BUTGREY); + uiBlockSetEmboss(block, UI_EMBOSSM); + uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 80, 19, ""); + uiBlockSetCol(block, BUTGREEN); + uiBlockSetEmboss(block, UI_EMBOSSX); + uiDefButS(block, TOG|BIT|0, B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects"); + uiDefButS(block, TOG|BIT|1, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object"); + uiDefButS(block, TOG|BIT|2, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller"); + + for(a=0; a<count; a++) { + ob= (Object *)idar[a]; + uiClearButLock(); + uiSetButLock(ob->id.lib!=0, "Can't edit library data"); + + if( (ob->scavisflag & OB_VIS_SENS) == 0) continue; + + /* presume it is only objects for now */ + uiBlockSetEmboss(block, UI_EMBOSSX); + uiBlockSetCol(block, BUTGREY); + if(ob->sensors.first) uiSetCurFont(block, UI_HELVB); + uiBlockSetCol(block, MIDGREY); + uiDefButS(block, TOG|BIT|6, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors"); + if(ob->sensors.first) uiSetCurFont(block, UI_HELV); + uiBlockSetCol(block, BUTSALMON); + uiDefButS(block, TOG|BIT|8, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor"); + yco-=20; + + if(ob->scaflag & OB_SHOWSENS) { + + sens= ob->sensors.first; + while(sens) { + uiBlockSetEmboss(block, UI_EMBOSSW); + uiBlockSetCol(block, BUTSALMON); + uiDefIconButS(block, TOG|BIT|1, B_DEL_SENS, ICON_X, xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor"); + uiBlockSetCol(block, BUTGREY); + uiDefIconButS(block, ICONTOG|BIT|0, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings"); + + ycoo= yco; + if(sens->flag & SENS_SHOW) + { + uiBlockSetCol(block, BUTYELLOW); + + uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(), (short)(xco+22), yco, 100, 19, &sens->type, 0, 0, 0, 0, "Sensor type"); + but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, sens->name, 0, 31, 0, 0, "Sensor name"); + uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0); + + sens->otype= sens->type; + uiBlockSetCol(block, BUTGREY); + yco= draw_sensorbuttons(sens, block, xco, yco, width,ob->id.name); + if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2; + } + else { + set_col_sensor(sens->type, 1); + glRecti(xco+22, yco, xco+width-22,yco+19); + but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 100, 19, sens, 0, 0, 0, 0, ""); + uiButSetFunc(but, sca_move_sensor, sens, NULL); + but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+122), yco, (short)(width-144), 19, sens, 0, 31, 0, 0, ""); + uiButSetFunc(but, sca_move_sensor, sens, NULL); + } + + but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, ""); + uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER); + + yco-=20; + + sens= sens->next; + } + yco-= 6; + } + } + + /* ******************************* */ + xco= 675; yco= 170; width= 230; + + uiBlockSetCol(block, BUTGREY); + uiBlockSetEmboss(block, UI_EMBOSSM); + uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, 19, ""); + uiBlockSetCol(block, BUTGREEN); + uiBlockSetEmboss(block, UI_EMBOSSX); + uiDefButS(block, TOG|BIT|3, B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects"); + uiDefButS(block, TOG|BIT|4, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object"); + uiDefButS(block, TOG|BIT|5, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator"); + + ob= OBACT; + + for(a=0; a<count; a++) { + ob= (Object *)idar[a]; + uiClearButLock(); + uiSetButLock(ob->id.lib!=0, "Can't edit library data"); + if( (ob->scavisflag & OB_VIS_CONT) == 0) continue; + + /* presume it is only objects for now */ + uiBlockSetEmboss(block, UI_EMBOSSX); + uiBlockSetCol(block, BUTSALMON); + uiDefButS(block, TOG|BIT|9, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller"); + uiBlockSetCol(block, MIDGREY); + if(ob->controllers.first) uiSetCurFont(block, UI_HELVB); + uiDefButS(block, TOG|BIT|11, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 0, 0, 0, "Active Object name"); + if(ob->controllers.first) uiSetCurFont(block, UI_HELV); + yco-=20; + + if(ob->scaflag & OB_SHOWCONT) { + + cont= ob->controllers.first; + while(cont) { + uiBlockSetEmboss(block, UI_EMBOSSW); + uiBlockSetCol(block, BUTSALMON); + uiDefIconButS(block, TOG|BIT|1, B_DEL_CONT, ICON_X, xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller"); + uiBlockSetCol(block, BUTGREY); + uiDefIconButS(block, ICONTOG|BIT|0, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings"); + + if(cont->flag & CONT_SHOW) { + uiBlockSetCol(block, BUTYELLOW); + cont->otype= cont->type; + uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 100, 19, &cont->type, 0, 0, 0, 0, "Controller type"); + but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, cont->name, 0, 31, 0, 0, "Controller name"); + uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0); + uiBlockSetCol(block, BUTGREY); + + ycoo= yco; + yco= draw_controllerbuttons(cont, block, xco, yco, width); + if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2; + } + else { + cpack(0x999999); + glRecti(xco+22, yco, xco+width-22,yco+19); + but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 100, 19, cont, 0, 0, 0, 0, "Controller type"); + uiButSetFunc(but, sca_move_controller, cont, NULL); + but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+122), yco,(short)(width-144), 19, cont, 0, 0, 0, 0, "Controller name"); + uiButSetFunc(but, sca_move_controller, cont, NULL); + ycoo= yco; + } + + but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, ""); + uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR); + + uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, cont, LINK_CONTROLLER, 0, 0, 0, ""); + + yco-=20; + + cont= cont->next; + } + yco-= 6; + } + } + + /* ******************************* */ + xco= 985; yco= 170; width= 280; + + uiBlockSetCol(block, BUTGREY); + uiBlockSetEmboss(block, UI_EMBOSSM); + uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 100, 19, ""); + uiBlockSetCol(block, BUTGREEN); + uiBlockSetEmboss(block, UI_EMBOSSX); + uiDefButS(block, TOG|BIT|6, B_REDR, "Sel", xco+110, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects"); + uiDefButS(block, TOG|BIT|7, B_REDR, "Act", xco+110+(width-110)/3, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object"); + uiDefButS(block, TOG|BIT|8, B_REDR, "Link", xco+110+2*(width-110)/3, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller"); + + for(a=0; a<count; a++) { + ob= (Object *)idar[a]; + uiClearButLock(); + uiSetButLock(ob->id.lib!=0, "Can't edit library data"); + if( (ob->scavisflag & OB_VIS_ACT) == 0) continue; + + /* presume it is only objects for now */ + uiBlockSetEmboss(block, UI_EMBOSSX); + uiBlockSetCol(block, BUTGREY); + if(ob->actuators.first) uiSetCurFont(block, UI_HELVB); + uiBlockSetCol(block, MIDGREY); + uiDefButS(block, TOG|BIT|7, B_REDR, ob->id.name+2,(short)(xco-10), yco,(short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide actuators"); + if(ob->actuators.first) uiSetCurFont(block, UI_HELV); + uiBlockSetCol(block, BUTSALMON); + uiDefButS(block, TOG|BIT|10, B_ADD_ACT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Actuator"); + yco-=20; + + if(ob->scaflag & OB_SHOWACT) { + + act= ob->actuators.first; + while(act) { + uiBlockSetEmboss(block, UI_EMBOSSW); + uiBlockSetCol(block, BUTSALMON); + uiDefIconButS(block, TOG|BIT|1, B_DEL_ACT, ICON_X, xco, yco, 22, 19, &act->flag, 0, 0, 0, 0, "Delete Actuator"); + uiBlockSetCol(block, BUTGREY); + uiDefIconButS(block, ICONTOG|BIT|0, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Actuator settings"); + + if(act->flag & ACT_SHOW) { + uiBlockSetCol(block, BUTYELLOW); + act->otype= act->type; + uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob), (short)(xco+22), yco, 100, 19, &act->type, 0, 0, 0, 0, "Actuator type"); + but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, act->name, 0, 31, 0, 0, "Actuator name"); + uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0); + uiBlockSetCol(block, BUTGREY); + + ycoo= yco; + yco= draw_actuatorbuttons(act, block, xco, yco, width); + if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2; + } + else { + set_col_actuator(act->type, 1); + glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19)); + but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 100, 19, act, 0, 0, 0, 0, "Actuator type"); + uiButSetFunc(but, sca_move_actuator, act, NULL); + but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+122), yco, (short)(width-144), 19, act, 0, 0, 0, 0, "Actuator name"); + uiButSetFunc(but, sca_move_actuator, act, NULL); + ycoo= yco; + } + + uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, act, LINK_ACTUATOR, 0, 0, 0, ""); + + yco-=20; + + act= act->next; + } + yco-= 6; + } + } + + uiComposeLinks(block); + uiDrawBlock(block); + + if(idar) MEM_freeN(idar); +} + diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c new file mode 100644 index 00000000000..d71ae8c8e3d --- /dev/null +++ b/source/blender/src/editscreen.c @@ -0,0 +1,2931 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * All screen functions that are related to the interface + * handling and drawing. Might be split up as well later... + */ + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "nla.h" + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <math.h> + +#include "MEM_guardedalloc.h" + +#include "PIL_time.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "DNA_action_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_sound_types.h" +#include "DNA_view3d_types.h" +#include "DNA_userdef_types.h" + +#include "BLO_writefile.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_blender.h" +#include "BKE_screen.h" + +#include "BIF_editsound.h" +#include "BIF_glutil.h" +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_interface.h" +#include "BIF_mainqueue.h" +#include "BIF_mywindow.h" +#include "BIF_renderwin.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_toets.h" +#include "BIF_toolbox.h" +#include "BIF_usiblender.h" +#include "BIF_keyval.h" + +#include "BSE_edit.h" +#include "BSE_filesel.h" +#include "BSE_headerbuttons.h" +#include "BSE_view.h" + +#include "license_key.h" +#include "interface.h" +#include "mydevice.h" +#include "blendef.h" +#include "render.h" + +#include "winlay.h" + +/* TIPS: + * + * - LET OP DE EDGES, VERTICES ERVAN MOETEN IN VOLGORDE + (laagste pointer eerst). Anders onvoorspelbare effecten! + * - probleem: flags zijn nog niet echt netjes. Altijd na gebruik + op nul zetten. + */ + +static void testareas(void); +static void area_autoplayscreen(void); +static void wait_for_event(void); + +/* ********* Globals *********** */ + +static Window *mainwin= NULL; +static int prefsizx= 0, prefsizy= 0, prefstax= 0, prefstay= 0, start_maximized= 1; +static short dodrawscreen= 0; +static ScrArea *areawinar[MAXWIN]; +static ScrArea *g_activearea= NULL; +short winqueue_break= 0; +ScrArea *curarea= 0; + +/**********************************************************************/ + +static void screen_set_cursor(bScreen *sc) +{ + if (sc->winakt>3) { + ScrArea *sa= areawinar[sc->winakt]; + + set_cursor(sa->cursor); + } else { + set_cursor(CURSOR_STD); + } +} + +void waitcursor(int val) +{ + if(val) { + set_cursor(CURSOR_WAIT); + } else { + screen_set_cursor(G.curscreen); + } +} + +static int choose_cursor(ScrArea *sa) +{ + if (sa->spacetype==SPACE_VIEW3D) { + if(G.obedit) return CURSOR_EDIT; + else if(G.f & G_VERTEXPAINT) return CURSOR_VPAINT; + else if(G.f & G_WEIGHTPAINT) return CURSOR_VPAINT; + else if(G.f & G_FACESELECT) return CURSOR_FACESEL; + else return CURSOR_STD; + } else { + return CURSOR_STD; + } +} + +void wich_cursor(ScrArea *sa) +{ + sa->cursor= choose_cursor(sa); + + screen_set_cursor(G.curscreen); +} + + +void setcursor_space(int spacetype, short cur) +{ + bScreen *sc; + ScrArea *sa; + + for (sc= G.main->screen.first; sc; sc= sc->id.next) + for (sa= sc->areabase.first; sa; sa= sa->next) + if(sa->spacetype==spacetype) + sa->cursor= cur; + + screen_set_cursor(G.curscreen); +} + + +/* ********* IN/OUT ************* */ + +void getmouseco_sc(short *mval) /* screen coordinaten */ +{ + getmouse(mval); +} + +void getmouseco_areawin(short *mval) /* interne area coordinaten */ +{ + getmouseco_sc(mval); + + if(g_activearea && g_activearea->win) { + mval[0]-= g_activearea->winrct.xmin; + mval[1]-= g_activearea->winrct.ymin; + } +} + +void getmouseco_headwin(short *mval) /* interne area coordinaten */ +{ + getmouseco_sc(mval); + + if(g_activearea && g_activearea->headwin) { + mval[0]-= g_activearea->headrct.xmin; + mval[1]-= g_activearea->headrct.ymin; + } +} + +/* *********** STUFF ************** */ + +static int scredge_is_horizontal(ScrEdge *se) +{ + return (se->v1->vec.y == se->v2->vec.y); +} + +static ScrEdge *screen_find_active_scredge(bScreen *sc, short *mval) +{ + ScrEdge *se; + + for (se= sc->edgebase.first; se; se= se->next) { + if (scredge_is_horizontal(se)) { + if (abs(mval[1]-se->v1->vec.y)<=EDGEWIDTH2 && + abs(mval[0]-se->v1->vec.x)<=abs(se->v2->vec.x-se->v1->vec.x)) + return se; + } else { + if (abs(mval[0]-se->v1->vec.x)<=EDGEWIDTH2 && + abs(mval[1]-se->v1->vec.y)<=abs(se->v2->vec.y-se->v1->vec.y)) + return se; + } + } + + return NULL; +} + +void areawinset(short win) +{ + if(win>3) { + curarea= areawinar[win]; + if(curarea==0) { + printf("error in areawinar %d ,areawinset\n", win); + return; + } + + switch(curarea->spacetype) { + case SPACE_VIEW3D: + G.vd= curarea->spacedata.first; + break; + case SPACE_IPO: + if(G.sipo != curarea->spacedata.first) allqueue(REDRAWBUTSANIM, 0); + G.sipo= curarea->spacedata.first; + G.v2d= &G.sipo->v2d; + break; + case SPACE_BUTS: + G.buts= curarea->spacedata.first; + G.v2d= &G.buts->v2d; + break; + case SPACE_SEQ: { + SpaceSeq *sseq= curarea->spacedata.first; + G.v2d= &sseq->v2d; + break; + } + case SPACE_OOPS: + G.soops= curarea->spacedata.first; + G.v2d= &G.soops->v2d; + break; + case SPACE_IMAGE: + G.sima= curarea->spacedata.first; + G.v2d= &G.sima->v2d; + case SPACE_SOUND: + G.ssound= curarea->spacedata.first; + G.v2d= &G.ssound->v2d; + break; + case SPACE_ACTION: + G.saction= curarea->spacedata.first; + G.v2d= &G.saction->v2d; + break; + case SPACE_NLA: + G.snla= curarea->spacedata.first; + G.v2d= &G.snla->v2d; + break; + default: + break; + } + } + + if(win) mywinset(win); +} + +void headerbox(int selcol, int width) +{ + if(selcol) glClearColor(.75, .75, .75, 0.0); + else glClearColor(.65, .65, .65, 0.0); + + glClear(GL_COLOR_BUFFER_BIT); + + glColor3ub(0, 0, 0); + sdrawbox(0, 0, width, HEADERY); + + glColor3ub(220, 220, 220); + sdrawline(0, HEADERY-1, width, HEADERY-1); + + glColor3ub(176, 176, 176); + sdrawline(0, HEADERY-2, width, HEADERY-2); + + glColor3ub(128, 128, 128); + sdrawline(0, 2, width, 2); + + glColor3ub(64, 64, 64); + sdrawline(0, 1, width, 1); + + glColor3ub(0, 0, 0); + sdrawline(0, 0, width, 0); +} + +int area_is_active_area(ScrArea *area) +{ + return (g_activearea && area==g_activearea); +} + +void scrarea_do_headdraw(ScrArea *area) +{ + areawinset(area->headwin); + + headerbox(area_is_active_area(area), area->winx+100); + + switch(area->spacetype) { + case SPACE_FILE: file_buttons(); break; + case SPACE_INFO: info_buttons(); break; + case SPACE_VIEW3D: view3d_buttons(); break; + case SPACE_IPO: ipo_buttons(); break; + case SPACE_BUTS: buts_buttons(); break; + case SPACE_SEQ: seq_buttons(); break; + case SPACE_IMAGE: image_buttons(); break; + case SPACE_IMASEL: imasel_buttons(); break; + case SPACE_OOPS: oops_buttons(); break; + case SPACE_TEXT: text_buttons(); break; + case SPACE_SOUND: sound_buttons(); break; + case SPACE_ACTION: action_buttons(); break; + case SPACE_NLA: nla_buttons(); break; + } + + area->head_swap= WIN_BACK_OK; +} +void scrarea_do_headchange(ScrArea *area) +{ + float ofs= area->headbutofs; + + if (area->headertype==HEADERDOWN) { + bwin_ortho2(area->headwin, 0.5+ofs, area->headrct.xmax-area->headrct.xmin-0.5+ofs, +0.6, area->headrct.ymax-area->headrct.ymin+0.6); + } else { + bwin_ortho2(area->headwin, -0.5+ofs, area->headrct.xmax-area->headrct.xmin-0.5+ofs, -0.5, area->headrct.ymax-area->headrct.ymin-0.5); + } +} + + +static void openheadwin(ScrArea *sa); +static void closeheadwin(ScrArea *sa); + +static void scrarea_change_headertype(ScrArea *sa, int newtype) +{ + sa->headertype= newtype; + + if (!newtype) { + if (sa->headwin) { + uiFreeBlocksWin(&sa->uiblocks, sa->headwin); + closeheadwin(sa); + } + } else { + if (!sa->headwin) { + openheadwin(sa); + } + } + + testareas(); + winqueue_break= 1; +} + +static void headmenu(ScrArea *sa) +{ + short val= pupmenu("Header %t|Top%x2|Bottom %x1|No Header %x0"); + + if(val> -1) { + scrarea_change_headertype(sa, val); + } +} + +static void addqueue_ext(short win, unsigned short event, short val, char ascii) +{ + if (win<4 || !areawinar[win]) { + printf("bad call to addqueue: %d (%d, %d)\n", win, event, val); + } else { + bwin_qadd(win, event, val, ascii); + } +} + +void addqueue(short win, unsigned short event, short val) +{ + addqueue_ext(win, event, val, 0); +} + +void scrarea_queue_winredraw(ScrArea *area) +{ + addqueue(area->win, REDRAW, 1); +} +void scrarea_queue_headredraw(ScrArea *area) +{ + if (area->headwin) addqueue(area->headwin, REDRAW, 1); +} +void scrarea_queue_redraw(ScrArea *area) +{ + scrarea_queue_winredraw(area); + scrarea_queue_headredraw(area); +} + +static void scrollheader(ScrArea *area); +static void scrarea_dispatch_header_events(ScrArea *sa) +{ + ScrArea *tempsa; + short do_redraw=0, do_change=0; + + areawinset(sa->headwin); + + while(bwin_qtest(sa->headwin)) { + char ascii; + short val; + unsigned short event= bwin_qread(sa->headwin, &val, &ascii); + + if(val) { + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) { + case UI_BUT_EVENT: + do_headerbuttons(val); + break; + + case LEFTMOUSE: + if (G.qual & LR_CTRLKEY) { + window_lower(mainwin); + } else { + window_raise(mainwin); + } + break; + + case MIDDLEMOUSE: + scrollheader(sa); + break; + case RIGHTMOUSE: + headmenu(sa); + break; + case REDRAW: + do_redraw= 1; + break; + case CHANGED: + sa->head_swap= 0; + do_change= 1; + do_redraw= 1; + break; + default: + if (winqueue_break == 0) { + scrarea_do_winhandle(sa, event, val, ascii); + if (winqueue_break == 0) areawinset(sa->headwin); + } + } + + if(winqueue_break) return; + } + } + + /* test: bestaat window nog */ + tempsa= areawinar[sa->headwin]; + if(tempsa==0) return; + + /* dit onderscheid loopt niet lekker... */ + if(do_change) scrarea_do_headchange(sa); + if(do_redraw) scrarea_do_headdraw(sa); +} + +static void scrarea_dispatch_events(ScrArea *sa) +{ + ScrArea *tempsa; + short do_redraw=0, do_change=0; + + if(sa!=curarea || sa->win!=mywinget()) areawinset(sa->win); + + while(bwin_qtest(sa->win)) { + char ascii; + short val; + unsigned short event= bwin_qread(sa->win, &val, &ascii); + + if(event==REDRAW) { + do_redraw= 1; + } + else if(event==CHANGED) { + sa->win_swap= 0; + do_change= 1; + do_redraw= 1; + } + else { + scrarea_do_winhandle(sa, event, val, ascii); + } + + if(winqueue_break) return; + } + + /* test: bestaat window nog */ + tempsa= areawinar[sa->win]; + if(tempsa==0) return; + + if (do_change || do_redraw) { + areawinset(sa->win); + if(do_change) + scrarea_do_winchange(curarea); + if(do_redraw) + scrarea_do_windraw(curarea); + } +} + +/***/ + + +void markdirty_all() +{ + ScrArea *sa; + + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + scrarea_queue_winredraw(sa); + sa->win_swap &= ~WIN_FRONT_OK; + + scrarea_queue_headredraw(sa); + sa->head_swap &= ~WIN_FRONT_OK; + } +} + +int is_allowed_to_change_screen(bScreen *new) +{ + /* niet als curscreen is full + * niet als obedit && old->scene!=new->scene + */ + + if(new==0) return 0; + if(G.curscreen->full != SCREENNORMAL) return 0; + if(curarea->full) return 0; + if(G.obedit) { + if(G.curscreen->scene!=new->scene) return 0; + } + return 1; +} + +void splash(void *data, int datasize, char *string) +{ + ImBuf *bbuf; + int oldwin; + short val; + + bbuf= IMB_ibImageFromMemory((int *)data, datasize, IB_rect); + + if (bbuf) { + + oldwin = mywinget(); + mywinset(G.curscreen->mainwin); + + if (string) { + int x, y, maxy; + unsigned int *rect; + + rect = bbuf->rect; + maxy = MIN2(bbuf->y, 18); + + for (y = 0; y < maxy; y++) { + for (x = 0; x < bbuf->x; x++) { + *rect = 0xffffffff; + rect++; + } + } + } + glDrawBuffer(GL_FRONT); + + /* + // this dims the whole screen a bit. I didn't like it afterall + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.0,0.0,0.0,0.3); + glRecti(0, 0, G.curscreen->sizex, G.curscreen->sizey); + glDisable(GL_BLEND); + */ + + glRasterPos2i((prefsizx-bbuf->x)/2, (prefsizy-bbuf->y)/2); + glDrawPixels(bbuf->x, bbuf->y, GL_RGBA, GL_UNSIGNED_BYTE, bbuf->rect); + + if (string) { + void *font; + int width; + + if (BMF_GetStringWidth(font= G.font, string) > bbuf->x) + if (BMF_GetStringWidth(font= G.fonts, string) > bbuf->x) + font= G.fontss; + + width= BMF_GetStringWidth(font, string); + + glColor3ub(0, 0, 0); + glRasterPos2i((prefsizx-width)/2, (prefsizy-bbuf->y)/2 + 6); + BMF_DrawString(font, string); + } + + glFinish(); + glDrawBuffer(GL_BACK); + + IMB_freeImBuf(bbuf); + + // flush input buffers .... + // this might break some things + + while (get_mbut()) { + BIF_wait_for_statechange(); + } + while(qtest()) { + extern_qread(&val); + } + + wait_for_event(); + + mywinset(oldwin); + markdirty_all(); + mainqenter(DRAWEDGES, 1); + } +} + +static void moveareas(ScrEdge *edge); +static void joinarea(ScrArea *sa, ScrEdge *onedge); +static void splitarea_interactive(ScrArea *area, ScrEdge *onedge); + +static void screen_edge_edit_event(ScrArea *actarea, ScrEdge *actedge, short evt, short val) { + if (val) { + // don't allow users to edit full screens + if (actarea && actarea->full) { + return; + } + + if (evt==LEFTMOUSE) { + moveareas(actedge); + } else if (evt==MIDDLEMOUSE || evt==RIGHTMOUSE) { + int edgeop; + + if (!actarea->headertype) { + edgeop= pupmenu("Split Area|Join Areas|Add header"); + } else { + edgeop= pupmenu("Split Area|Join Areas|No header"); + } + + if (edgeop==1) { + splitarea_interactive(actarea, actedge); + } else if (edgeop==2) { + joinarea(actarea, actedge); + } else if (edgeop==3) { + scrarea_change_headertype(actarea, actarea->headertype?0:HEADERDOWN); + } + } + } +} + +/***/ + +void mywindow_init_mainwin(Window *win, int orx, int ory, int sizex, int sizey); +void test_scale_screen(bScreen *); + +static void resize_screens(int x, int y, int w, int h) { + prefstax= x; + prefstay= y; + prefsizx= w; + prefsizy= h; + + test_scale_screen(G.curscreen); + testareas(); +} + +static void init_mainwin(void) +{ + int orx, ory, sizex, sizey; + + glEnable(GL_SCISSOR_TEST); + + window_get_position(mainwin, &orx, &ory); + window_get_size(mainwin, &sizex, &sizey); + + /* XXX, temporary stupid fix for minimize at windows */ + if (!sizex && !sizey) { + return; + } + + mywindow_init_mainwin(mainwin, orx, ory, sizex, sizey); + resize_screens(orx, ory, sizex, sizey); +} + +/***/ + +static short afterqueue[MAXQUEUE][3]; +static int nafterqitems= 0; + +void addafterqueue(short win, unsigned short evt, short val) +{ + if (nafterqitems<MAXQUEUE) { + afterqueue[nafterqitems][0]= win; + afterqueue[nafterqitems][1]= evt; + afterqueue[nafterqitems][2]= val; + nafterqitems++; + } +} + +static void append_afterqueue(void) +{ + while (nafterqitems) { + short win= afterqueue[nafterqitems-1][0]; + unsigned short evt= afterqueue[nafterqitems-1][1]; + short val= afterqueue[nafterqitems-1][2]; + + addqueue(win, evt, val); + + nafterqitems--; + } +} + +static char ext_load_str[256]= {0, 0}; +void add_readfile_event(char *filename) +{ + mainqenter(LOAD_FILE, 1); + strcpy(ext_load_str, filename); + BLI_convertstringcode(ext_load_str, G.sce, G.scene->r.cfra); +} + +static short ext_reshape= 0, ext_redraw=0, ext_inputchange=0, ext_mousemove=0; + +static void flush_extqd_events(void) { + if (ext_inputchange) { + mainqenter(INPUTCHANGE, ext_inputchange); + } else if (ext_reshape) { + mainqenter(RESHAPE, ext_redraw); + } else if (ext_redraw) { + mainqenter(REDRAW, ext_redraw); + } else if (ext_mousemove) { + short mouse[2]; + + getmouseco_sc(mouse); + + mainqenter(MOUSEX, mouse[0]); + mainqenter(MOUSEY, mouse[1]); + } + + ext_inputchange= ext_reshape= ext_redraw= ext_mousemove= 0; +} + +unsigned short qtest(void) +{ + if (!mainqtest()) { + winlay_process_events(0); + } + + return mainqtest(); +} + + /* return true if events are waiting anywhere */ +int anyqtest(void) +{ + ScrArea *sa; + + if (nafterqitems || qtest()) return 1; + + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + if (bwin_qtest(sa->win)) return 1; + if (sa->headwin && bwin_qtest(sa->headwin)) return 1; + } + + return 0; +} + +static void wait_for_event(void) +{ + while (!mainqtest()) { + winlay_process_events(1); + } +} + +unsigned short screen_qread(short *val, char *ascii) +{ + unsigned short event; + + wait_for_event(); + + event= mainqread(val, ascii); + + if(event==RIGHTSHIFTKEY || event==LEFTSHIFTKEY) { + if(*val) G.qual |= LR_SHIFTKEY; + else G.qual &= ~LR_SHIFTKEY; + } + else if(event==RIGHTALTKEY || event==LEFTALTKEY) { + if(*val) G.qual |= LR_ALTKEY; + else G.qual &= ~LR_ALTKEY; + } + else if(event==RIGHTCTRLKEY || event==LEFTCTRLKEY) { + if(*val) G.qual |= LR_CTRLKEY; + else G.qual &= ~LR_CTRLKEY; + } + + return event; +} + +unsigned short extern_qread_ext(short *val, char *ascii) +{ + /* bewaart de laatste INPUTCHANGE en de laatste REDRAW */ + unsigned short event; + + event= screen_qread(val, ascii); + if(event==RESHAPE) ext_reshape= *val; + else if(event==REDRAW) ext_redraw= *val; + else if(event==INPUTCHANGE) ext_inputchange= *val; + else if(event==MOUSEY || event==MOUSEX) ext_mousemove= 1; + else if((G.qual & LR_CTRLKEY) && event==F3KEY) { + BIF_screendump(); + } + + return event; +} +unsigned short extern_qread(short *val) +{ + char ascii; + return extern_qread_ext(val, &ascii); +} + +void reset_autosave(void) { + window_set_timer(mainwin, U.savetime*60*1000, AUTOSAVE_FILE); +} + +static void screen_dispatch_events(void) { + int events_remaining= 1; + ScrArea *sa; + + while (events_remaining) { + events_remaining= 0; + + winqueue_break= 0; + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + /* bewust eerst header afhandelen, dan rest. Header is soms init */ + if (sa->headwin && bwin_qtest(sa->headwin)) { + scrarea_dispatch_header_events(sa); + events_remaining= 1; + } + if (winqueue_break) break; + + if (bwin_qtest(sa->win)) { + scrarea_dispatch_events(sa); + events_remaining= 1; + } + if (winqueue_break) break; + } + + if (winqueue_break) break; + } + + if (dodrawscreen) { + drawscreen(); + dodrawscreen= 0; + } + + screen_swapbuffers(); +} + +static ScrArea *screen_find_area_for_pt(bScreen *sc, short *mval) +{ + ScrArea *sa; + + for (sa= sc->areabase.first; sa; sa= sa->next) + if (BLI_in_rcti(&sa->totrct, mval[0], mval[1])) + return sa; + + return NULL; +} + +void screenmain(void) +{ + int has_input= 1; + int firsttime = 1; + while (1) { + unsigned short event; + short val, towin; + char ascii; + + flush_extqd_events(); + if (nafterqitems && !qtest()) { + append_afterqueue(); + event= 0; + } else { + event= screen_qread(&val, &ascii); + } + + window_make_active(mainwin); + + if (event==INPUTCHANGE) { + has_input= val; + } + + if (has_input) { + ScrArea *newactarea; + int newactwin; + short mval[2]; + + getmouseco_sc(mval); + newactarea= screen_find_area_for_pt(G.curscreen, mval); + + if (newactarea) { + if (BLI_in_rcti(&newactarea->headrct, mval[0], mval[1])) { + newactwin= newactarea->headwin; + } else { + newactwin= newactarea->win; + } + } else { + newactwin= 0; + } + + if (newactarea && (newactarea != g_activearea)) { + if (g_activearea) scrarea_queue_headredraw(g_activearea); + scrarea_queue_headredraw(newactarea); + set_cursor(newactarea->cursor); + g_activearea= newactarea; + } + + G.curscreen->winakt= newactwin; + if (G.curscreen->winakt) { + areawinset(G.curscreen->winakt); + set_cursor(choose_cursor(g_activearea)); + } + } else { + if (g_activearea) { + scrarea_queue_headredraw(g_activearea); + } + g_activearea= NULL; + G.curscreen->winakt= 0; + } + + towin= 0; + if (event==WINCLOSE) { + exit_usiblender(); + } + else if (event==DRAWEDGES) { + dodrawscreen= 1; + } + else if (event==RESHAPE) { + init_mainwin(); + markdirty_all(); + dodrawscreen= 1; + } + else if (event==REDRAW) { + markdirty_all(); + dodrawscreen= 1; + } + else if (event==AUTOSAVE_FILE) { + BIF_write_autosave(); + } + else if (event==LOAD_FILE) { + BIF_read_file(ext_load_str); + sound_initialize_sounds(); + } + else { + towin= 1; + } + + if (!g_activearea) { + towin= 0; + } + else if (!G.curscreen->winakt) { + ScrEdge *actedge; + short mval[2]; + + getmouseco_sc(mval); + actedge= screen_find_active_scredge(G.curscreen, mval); + + if (actedge) { + if (scredge_is_horizontal(actedge)) { + set_cursor(CURSOR_Y_MOVE); + } else { + set_cursor(CURSOR_X_MOVE); + } + + screen_edge_edit_event(g_activearea, actedge, event, val); + } else { + set_cursor(CURSOR_STD); + } + + towin= 0; + } + else if (event==QKEY) { + if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT); + else { + if(val && okee("QUIT BLENDER")) exit_usiblender(); + towin= 0; + } + } + else if (event==ZKEY) { + if(val && G.qual==(LR_ALTKEY|LR_SHIFTKEY|LR_CTRLKEY)) { + extern void set_debug_swapbuffers_ovveride(bScreen *sc, int mode); + + int which= pupmenu("Swapbuffers%t|Simple|Debug|DebugSwap|Redraw|Default|KillSwap"); + + switch (which) { + case 1: set_debug_swapbuffers_ovveride(G.curscreen, 's'); break; + case 2: set_debug_swapbuffers_ovveride(G.curscreen, 'd'); break; + case 3: set_debug_swapbuffers_ovveride(G.curscreen, 'f'); break; + case 4: set_debug_swapbuffers_ovveride(G.curscreen, 'r'); break; + case 5: set_debug_swapbuffers_ovveride(G.curscreen, 0); break; + case 6: + if (g_activearea) { + g_activearea->head_swap= 0; + g_activearea->win_swap= 0; + } + break; + } + towin= 0; + } + } + else if (event==SPACEKEY) { + if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT); + else { + if(val) toolbox(); + towin= 0; + } + } + else if(ELEM(event, LEFTARROWKEY, RIGHTARROWKEY)) { + if(val && (G.qual & LR_CTRLKEY)) { + bScreen *sc= (event==LEFTARROWKEY)?G.curscreen->id.prev:G.curscreen->id.next; + if(is_allowed_to_change_screen(sc)) setscreen(sc); + g_activearea= NULL; + towin= 0; + } + } + else if(ELEM(event, UPARROWKEY, DOWNARROWKEY)) { + if(val && (G.qual & LR_CTRLKEY)) { + area_fullscreen(); + g_activearea= NULL; + towin= 0; + } + } + + if (towin) { + if (blenderqread(event, val)) + addqueue_ext(G.curscreen->winakt, event, val, ascii); + } + + /* only process subwindow queue's once the + * main queue has been emptyied. + */ + event= qtest(); + if (event==0 || event==EXECUTE) { + screen_dispatch_events(); + } + + /* Bizar hack. The event queue has mutated... */ + if ( (firsttime) && (event == 0) ) { + if (G.fileflags & G_FILE_AUTOPLAY) { + // SET AUTOPLAY in G.flags for + // other fileloads + + G.flags |= G_FLAGS_AUTOPLAY; + area_autoplayscreen(); + + // Let The Games Begin + // fake a 'p' keypress + + mainqenter(PKEY, 1); + } else { + extern char datatoc_splash_jpg[]; + extern int datatoc_splash_jpg_size; + extern char datatoc_ton[]; + extern int datatoc_tonize; + + if (! ((G.main->versionfile >= G.version) + || G.save_over)) { + if (LICENSE_KEY_VALID) { + splash((void *)datatoc_ton, + datatoc_tonize, + NULL); + } else { + splash((void *)datatoc_splash_jpg, + datatoc_splash_jpg_size, + NULL); + } + } + } + firsttime = 0; + } + } +} + +void mainwindow_raise(void) { + window_raise(mainwin); +} +void mainwindow_make_active(void) { + window_make_active(mainwin); +} +void mainwindow_close(void) { + window_destroy(mainwin); + mainwin= NULL; +} + +/* ********* AREAS ************* */ + +void setprefsize(int stax, int stay, int sizx, int sizy) +{ + int scrwidth, scrheight; + + winlay_get_screensize(&scrwidth, &scrheight); + + if(stax<0) stax= 0; + if(stay<0) stay= 0; + if(sizx<320) sizx= 320; + if(sizy<256) sizy= 256; + + if(stax+sizx>scrwidth) sizx= scrwidth-stax; + if(stay+sizy>scrheight) sizy= scrheight-stay; + if(sizx<320 || sizy<256) { + printf("ERROR: illegal prefsize\n"); + return; + } + + prefstax= stax; + prefstay= stay; + prefsizx= sizx; + prefsizy= sizy; + + start_maximized= 0; +} + + +static ScrVert *screen_addvert(bScreen *sc, short x, short y) +{ + ScrVert *sv= MEM_callocN(sizeof(ScrVert), "addscrvert"); + sv->vec.x= x; + sv->vec.y= y; + + BLI_addtail(&sc->vertbase, sv); + return sv; +} + +static void sortscrvert(ScrVert **v1, ScrVert **v2) +{ + ScrVert *tmp; + + if ((long)*v1 > (long)*v2) { + tmp= *v1; + *v1= *v2; + *v2= tmp; + } +} + +static ScrEdge *screen_addedge(bScreen *sc, ScrVert *v1, ScrVert *v2) +{ + ScrEdge *se= MEM_callocN(sizeof(ScrEdge), "addscredge"); + + sortscrvert(&v1, &v2); + se->v1= v1; + se->v2= v2; + + BLI_addtail(&sc->edgebase, se); + return se; +} + +static ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2) +{ + ScrEdge *se; + + sortscrvert(&v1, &v2); + for (se= sc->edgebase.first; se; se= se->next) + if(se->v1==v1 && se->v2==v2) + return se; + + return NULL; +} + +static void removedouble_scrverts(void) +{ + ScrVert *v1, *verg; + ScrEdge *se; + ScrArea *sa; + + verg= G.curscreen->vertbase.first; + while(verg) { + if(verg->newv==0) { /* !!! */ + v1= verg->next; + while(v1) { + if(v1->newv==0) { /* !?! */ + if(v1->vec.x==verg->vec.x && v1->vec.y==verg->vec.y) { + /* printf("doublevert\n"); */ + v1->newv= verg; + } + } + v1= v1->next; + } + } + verg= verg->next; + } + + /* vervang pointers in edges en vlakken */ + se= G.curscreen->edgebase.first; + while(se) { + if(se->v1->newv) se->v1= se->v1->newv; + if(se->v2->newv) se->v2= se->v2->newv; + /* edges zijn veranderd: dus.... */ + sortscrvert(&(se->v1), &(se->v2)); + se= se->next; + } + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->v1->newv) sa->v1= sa->v1->newv; + if(sa->v2->newv) sa->v2= sa->v2->newv; + if(sa->v3->newv) sa->v3= sa->v3->newv; + if(sa->v4->newv) sa->v4= sa->v4->newv; + sa= sa->next; + } + + /* verwijderen */ + verg= G.curscreen->vertbase.first; + while(verg) { + v1= verg->next; + if(verg->newv) { + BLI_remlink(&G.curscreen->vertbase, verg); + MEM_freeN(verg); + } + verg= v1; + } + +} + +static void removenotused_scrverts(void) +{ + ScrVert *sv, *svn; + ScrEdge *se; + + /* ga ervan uit dat de edges goed zijn */ + + se= G.curscreen->edgebase.first; + while(se) { + se->v1->flag= 1; + se->v2->flag= 1; + se= se->next; + } + + sv= G.curscreen->vertbase.first; + while(sv) { + svn= sv->next; + if(sv->flag==0) { + BLI_remlink(&G.curscreen->vertbase, sv); + MEM_freeN(sv); + } + else sv->flag= 0; + sv= svn; + } +} + +static void removedouble_scredges(void) +{ + ScrEdge *verg, *se, *sn; + + /* vergelijken */ + verg= G.curscreen->edgebase.first; + while(verg) { + se= verg->next; + while(se) { + sn= se->next; + if(verg->v1==se->v1 && verg->v2==se->v2) { + BLI_remlink(&G.curscreen->edgebase, se); + MEM_freeN(se); + } + se= sn; + } + verg= verg->next; + } +} + +static void removenotused_scredges(void) +{ + ScrEdge *se, *sen; + ScrArea *sa; + int a=0; + + /* zet flag als edge gebruikt wordt in area */ + sa= G.curscreen->areabase.first; + while(sa) { + se= screen_findedge(G.curscreen, sa->v1, sa->v2); + if(se==0) printf("error: area %d edge 1 bestaat niet\n", a); + else se->flag= 1; + se= screen_findedge(G.curscreen, sa->v2, sa->v3); + if(se==0) printf("error: area %d edge 2 bestaat niet\n", a); + else se->flag= 1; + se= screen_findedge(G.curscreen, sa->v3, sa->v4); + if(se==0) printf("error: area %d edge 3 bestaat niet\n", a); + else se->flag= 1; + se= screen_findedge(G.curscreen, sa->v4, sa->v1); + if(se==0) printf("error: area %d edge 4 bestaat niet\n", a); + else se->flag= 1; + sa= sa->next; + a++; + } + se= G.curscreen->edgebase.first; + while(se) { + sen= se->next; + if(se->flag==0) { + BLI_remlink(&G.curscreen->edgebase, se); + MEM_freeN(se); + } + else se->flag= 0; + se= sen; + } +} + +void calc_arearcts(ScrArea *sa) +{ + + if(sa->v1->vec.x>0) sa->totrct.xmin= sa->v1->vec.x+EDGEWIDTH2+1; + else sa->totrct.xmin= sa->v1->vec.x; + if(sa->v4->vec.x<G.curscreen->sizex-1) sa->totrct.xmax= sa->v4->vec.x-EDGEWIDTH2-1; + else sa->totrct.xmax= sa->v4->vec.x; + + if(sa->v1->vec.y>0) sa->totrct.ymin= sa->v1->vec.y+EDGEWIDTH2+1; + else sa->totrct.ymin= sa->v1->vec.y; + if(sa->v2->vec.y<G.curscreen->sizey-1) sa->totrct.ymax= sa->v2->vec.y-EDGEWIDTH2-1; + else sa->totrct.ymax= sa->v2->vec.y; + + sa->winrct= sa->totrct; + if(sa->headertype) { + sa->headrct= sa->totrct; + if(sa->headertype==HEADERDOWN) { + sa->headrct.ymax= sa->headrct.ymin+HEADERY-1; + sa->winrct.ymin= sa->headrct.ymax+1; + } + else if(sa->headertype==HEADERTOP) { + sa->headrct.ymin= sa->headrct.ymax-HEADERY+1; + sa->winrct.ymax= sa->headrct.ymin-1; + } + } + if(sa->winrct.ymin>sa->winrct.ymax) sa->winrct.ymin= sa->winrct.ymax; + + /* als speedup voor berekeningen */ + sa->winx= sa->winrct.xmax-sa->winrct.xmin+1; + sa->winy= sa->winrct.ymax-sa->winrct.ymin+1; +} + +static void openheadwin(ScrArea *sa) +{ + sa->headwin= myswinopen(G.curscreen->mainwin, + sa->headrct.xmin, sa->headrct.xmax, sa->headrct.ymin, sa->headrct.ymax); + + glMatrixMode(GL_MODELVIEW); + + areawinar[sa->headwin]= sa; /* anders doet addqueue het niet */ + addqueue(sa->headwin, CHANGED, 1); +} + +static void openareawin(ScrArea *sa) +{ + sa->win= myswinopen(G.curscreen->mainwin, + sa->winrct.xmin, sa->winrct.xmax, sa->winrct.ymin, sa->winrct.ymax); + + areawinar[sa->win]= sa; /* anders doet addqueue het niet */ + addqueue(sa->win, CHANGED, 1); +} + +static void closeheadwin(ScrArea *sa) +{ + if(sa->headwin) mywinclose(sa->headwin); + sa->headwin= 0; +} + +static void closeareawin(ScrArea *sa) +{ + uiFreeBlocksWin(&sa->uiblocks, sa->win); + + if(sa->win) mywinclose(sa->win); + sa->win= 0; +} + +static void del_area(ScrArea *sa) +{ + closeareawin(sa); + closeheadwin(sa); + + freespacelist(&sa->spacedata); + + uiFreeBlocks(&sa->uiblocks); + + if(sa==curarea) curarea= 0; + if(sa==g_activearea) g_activearea= 0; +} + +static void copy_areadata(ScrArea *sa1, ScrArea *sa2) +{ + sa1->headertype= sa2->headertype; + sa1->spacetype= sa2->spacetype; + Mat4CpyMat4(sa1->winmat, sa2->winmat); + + freespacelist(&sa1->spacedata); + + duplicatespacelist(sa1, &sa1->spacedata, &sa2->spacedata); +} + +static ScrArea *screen_addarea(bScreen *sc, ScrVert *v1, ScrVert *v2, ScrVert *v3, ScrVert *v4, short headertype, short spacetype) +{ + ScrArea *sa= MEM_callocN(sizeof(ScrArea), "addscrarea"); + sa->cursor= CURSOR_STD; + sa->v1= v1; + sa->v2= v2; + sa->v3= v3; + sa->v4= v4; + sa->headertype= headertype; + sa->spacetype= spacetype; + + calc_arearcts(sa); + + if (sa->headertype) openheadwin(sa); + openareawin(sa); + + BLI_addtail(&sc->areabase, sa); + return sa; +} + +static int rcti_eq(rcti *a, rcti *b) { + return ((a->xmin==b->xmin && a->xmax==b->xmax) && + (a->ymin==b->ymin && a->ymax==b->ymax)); +} + +static void testareas(void) +{ + ScrArea *sa; + + /* testen of header er moet zijn, of weg moet, of verplaatst */ + /* testen of window er moet zijn, of weg moet, of verplaatst */ + + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + rcti oldhr= sa->headrct; + rcti oldwr= sa->winrct; + + calc_arearcts(sa); + + /* test header */ + if (sa->headwin) { + if (!rcti_eq(&oldhr, &sa->headrct)) { + mywinposition(sa->headwin, sa->headrct.xmin, sa->headrct.xmax, sa->headrct.ymin, sa->headrct.ymax); + addqueue(sa->headwin, CHANGED, 1); + } + + if(sa->headbutlen<sa->winx) { + sa->headbutofs= 0; + addqueue(sa->headwin, CHANGED, 1); + } + else if(sa->headbutofs+sa->winx > sa->headbutlen) { + sa->headbutofs= sa->headbutlen-sa->winx; + addqueue(sa->headwin, CHANGED, 1); + } + } + + if (!rcti_eq(&oldwr, &sa->winrct)) { + mywinposition(sa->win, sa->winrct.xmin, sa->winrct.xmax, sa->winrct.ymin, sa->winrct.ymax); + addqueue(sa->win, CHANGED, 1); + } + } + + /* remake global windowarray */ + memset(areawinar, 0, sizeof(void *)*MAXWIN); + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + areawinar[sa->headwin]= sa; + areawinar[sa->win]= sa; + } + + /* test of winakt in orde is */ + if( areawinar[G.curscreen->winakt]==0) G.curscreen->winakt= 0; +} + +static ScrArea *test_edge_area(ScrArea *sa, ScrEdge *se) +{ + /* test of edge in area ligt, zo niet, + vind een area die 'm wel heeft */ + + ScrEdge *se1=0, *se2=0, *se3=0, *se4=0; + + if(sa) { + se1= screen_findedge(G.curscreen, sa->v1, sa->v2); + se2= screen_findedge(G.curscreen, sa->v2, sa->v3); + se3= screen_findedge(G.curscreen, sa->v3, sa->v4); + se4= screen_findedge(G.curscreen, sa->v4, sa->v1); + } + if(se1!=se && se2!=se && se3!=se && se4!=se) { + + sa= G.curscreen->areabase.first; + while(sa) { + /* een beetje optimaliseren? */ + if(se->v1==sa->v1 || se->v1==sa->v2 || se->v1==sa->v3 || se->v1==sa->v4) { + se1= screen_findedge(G.curscreen, sa->v1, sa->v2); + se2= screen_findedge(G.curscreen, sa->v2, sa->v3); + se3= screen_findedge(G.curscreen, sa->v3, sa->v4); + se4= screen_findedge(G.curscreen, sa->v4, sa->v1); + if(se1==se || se2==se || se3==se || se4==se) return sa; + } + sa= sa->next; + } + } + + return sa; /* is keurig 0 als niet gevonden */ +} + +ScrArea *closest_bigger_area(void) +{ + ScrArea *sa, *big=0; + float cent[3], vec[3],len, len1, len2, len3, dist=1000; + short mval[2]; + + getmouseco_sc(mval); + + cent[0]= mval[0]; + cent[1]= mval[1]; + cent[2]= vec[2]= 0; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa!=curarea) { + if(sa->winy>=curarea->winy) { + + /* mimimum van vier hoekpunten */ + vec[0]= sa->v1->vec.x; vec[1]= sa->v1->vec.y; + len= VecLenf(vec, cent); + vec[0]= sa->v2->vec.x; vec[1]= sa->v2->vec.y; + len1= VecLenf(vec, cent); + vec[0]= sa->v3->vec.x; vec[1]= sa->v3->vec.y; + len2= VecLenf(vec, cent); + vec[0]= sa->v4->vec.x; vec[1]= sa->v4->vec.y; + len3= VecLenf(vec, cent); + + len= MIN4(len, len1, len2, len3); + + /* plus centrum */ + vec[0]= (sa->v2->vec.x+sa->v3->vec.x)/2; + vec[1]= (sa->v1->vec.y+sa->v2->vec.y)/2; + + len+= 0.5*VecLenf(vec, cent); + + /* min afmeting */ + len-= sa->winy+sa->winx; + + if(len<dist) { + dist= len; + big= sa; + } + } + } + sa= sa->next; + } + + if(big) return big; + else return curarea; +} + +/* ************ SCREENBEHEER ************** */ + +static int statechanged= 0; +void BIF_wait_for_statechange(void) +{ + if (!statechanged) { + /* Safety, don't wait more than 0.1 seconds */ + double stime= PIL_check_seconds_timer(); + while (!statechanged) { + winlay_process_events(1); + if ((PIL_check_seconds_timer()-stime)>0.1) break; + } + statechanged= 0; + } +} +void getmouse(short *mval) +{ + winlay_process_events(0); + window_get_mouse(mainwin, mval); +} +short get_qual(void) +{ + winlay_process_events(0); + return window_get_qual(mainwin); +} +short get_mbut(void) +{ + winlay_process_events(0); + return window_get_mbut(mainwin); +} + +static unsigned short convert_for_nonumpad(unsigned short event) +{ + if (event>=ZEROKEY && event<=NINEKEY) { + return event - ZEROKEY + PAD0; + } else if (event==MINUSKEY) { + return PADMINUS; + } else if (event==EQUALKEY) { + return PADPLUSKEY; + } else if (event==BACKSLASHKEY) { + return PADSLASHKEY; + } else { + return event; + } +} + +void add_to_mainqueue(Window *win, void *user_data, short evt, short val, char ascii) +{ + short qual= window_get_qual(win); + + statechanged= 1; + + if (U.flag&NONUMPAD) { + evt= convert_for_nonumpad(evt); + } + + /* enforce some guarentees about ascii values... these should + * be enforced in ghost probably - zr + */ + + if (!val || !isprint(ascii) || (qual&~LR_SHIFTKEY)) { + ascii= '\0'; + } + + mainqenter_ext(evt, val, ascii); +} + +static bScreen *addscreen(char *name) /* gebruik de setprefsize() als je anders dan fullscreen wilt */ +{ + /* deze functie zet de variabele G.curscreen + * omdat alle hulpfuncties moeten weten welk screen + */ + bScreen *sc; + ScrVert *sv1, *sv2, *sv3, *sv4; + short startx, starty, endx, endy; + + sc= G.curscreen= alloc_libblock(&G.main->screen, ID_SCR, name); + + if (!prefsizx) { + prefstax= 0; + prefstay= 0; + + winlay_get_screensize(&prefsizx, &prefsizy); + } + + startx= prefstax; + starty= prefstay; + endx= prefstax+prefsizx-1; + endy= prefstay+prefsizy-1; + + sc->startx= startx; sc->starty= starty; + sc->endx= endx; sc->endy= endy; + sc->sizex= sc->endx-sc->startx+1; + sc->sizey= sc->endy-sc->starty+1; + + sc->scene= G.scene; + + if (!mainwin) { + mainwin= window_open("Blender", sc->startx, sc->starty, sc->sizex, sc->sizey, start_maximized); + if (!mainwin) { + printf("ERROR: Unable to open Blender window\n"); + exit(1); + } + + window_set_handler(mainwin, add_to_mainqueue, NULL); + init_mainwin(); + mywinset(1); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + myortho2(-0.5, sc->sizex-0.5, -0.5, sc->sizey-0.5); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glDrawBuffer(GL_FRONT); + glClearColor(.45, .45, .45, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + glDrawBuffer(GL_BACK); + + warp_pointer(sc->sizex/2, sc->sizey/2); + + mainqenter(REDRAW, 1); + } + + sc->mainwin= 1; + + sv1= screen_addvert(sc, 0, 0); + sv2= screen_addvert(sc, 0, sc->endy-sc->starty); + sv3= screen_addvert(sc, sc->sizex-1, sc->sizey-1); + sv4= screen_addvert(sc, sc->sizex-1, 0); + + screen_addedge(sc, sv1, sv2); + screen_addedge(sc, sv2, sv3); + screen_addedge(sc, sv3, sv4); + screen_addedge(sc, sv4, sv1); + + screen_addarea(sc, sv1, sv2, sv3, sv4, HEADERDOWN, SPACE_INFO); + + G.curscreen= sc; + + return sc; +} + +void setscreen(bScreen *sc) +{ + bScreen *sc1; + ScrArea *sa; + short mval[2]; + + if(sc->full) { /* vind de bijhorende full */ + sc1= G.main->screen.first; + while(sc1) { + sa= sc1->areabase.first; + if(sa->full==sc) { + sc= sc1; + break; + } + sc1= sc1->id.next; + } + if(sc1==0) printf("setscreen error\n"); + } + + /* G.curscreen de-activeren */ + if (G.curscreen && G.curscreen != sc) { + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->win) mywinclose(sa->win); + sa->win= 0; + if(sa->headwin) mywinclose(sa->headwin); + sa->headwin= 0; + + uiFreeBlocks(&sa->uiblocks); + + sa= sa->next; + } + } + + if (G.curscreen != sc) { + mywinset(sc->mainwin); + } + + G.curscreen= sc; + + for (sa= sc->areabase.first; sa; sa= sa->next) { + /* XXX, fixme zr */ +/* if (sa->win || sa->headwin) */ +/* printf("error in setscreen (win): %d, %d\n", sa->win, sa->headwin); */ + if (!sa->win) + openareawin(sa); + if (!sa->headwin && sa->headertype) + openheadwin(sa); + } + + /* recalculate winakt */ + getmouseco_sc(mval); + + test_scale_screen(sc); + testareas(); + + for (sa= sc->areabase.first; sa; sa= sa->next) { + SpaceLink *sl; + + for (sl= sa->spacedata.first; sl; sl= sl->next) { + sl->area= sa; + + if (sl->spacetype==SPACE_OOPS) { + SpaceOops *soops= (SpaceOops*) sl; + + /* patch als deze in oude files zit */ + if (soops->v2d.cur.xmin==soops->v2d.cur.xmax) { + extern void init_v2d_oops(View2D*); + init_v2d_oops(&soops->v2d); + } + } + } + + sa->cursor= CURSOR_STD; + } + + G.scene= sc->scene; + countall(); + + G.curscreen->winakt= 0; + curarea= sc->areabase.first; + + mainqenter(DRAWEDGES, 1); + dodrawscreen= 1; /* patch! even gets lost,,,? */ + + winqueue_break= 1; /* overal uit de queue's gaan */ +} + +static void splitarea(ScrArea *sa, char dir, float fac); + +void area_fullscreen(void) /* met curarea */ +{ + /* deze funktie toggelt: als area full is wordt de parent weer zichtbaar */ + bScreen *sc, *oldscreen; + ScrArea *newa, *old; + short headertype, fulltype; + + if(curarea->full) { + sc= curarea->full; /* de oude screen */ + fulltype = sc->full; + + // refuse to go out of SCREENAUTOPLAY as long as G_FLAGS_AUTOPLAY + // is set + + if (fulltype != SCREENAUTOPLAY || (G.flags & G_FLAGS_AUTOPLAY) == 0) { + sc->full= 0; + + /* vind oude area */ + old= sc->areabase.first; + while(old) { + if(old->full) break; + old= old->next; + } + if(old==0) {error("something wrong in areafullscreen"); return;} + + if (fulltype == SCREENAUTOPLAY) { + // in autoplay screens the headers are disabled by + // default. So use the old headertype instead + headertype = old->headertype; + } else { + // normal fullscreen. Use current headertype + headertype = curarea->headertype; + } + + copy_areadata(old, curarea); + old->headertype = headertype; + + old->full= 0; + + unlink_screen(G.curscreen); + free_libblock(&G.main->screen, G.curscreen); + G.curscreen= NULL; + + setscreen(sc); + } + + } + else { + /* is er maar 1 area? */ + if(G.curscreen->areabase.first==G.curscreen->areabase.last) return; + if(curarea->spacetype==SPACE_INFO) return; + + G.curscreen->full = SCREENFULL; + + old= curarea; + oldscreen= G.curscreen; + sc= addscreen("temp"); /* deze zet G.curscreen */ + + splitarea( (ScrArea *)sc->areabase.first, 'h', 0.99); + newa= sc->areabase.first; + newspace(newa->next, SPACE_INFO); + + curarea= old; + G.curscreen= oldscreen; /* moet voor setscreen */ + + /* area kopieeren */ + copy_areadata(newa, curarea); + + curarea->full= oldscreen; + newa->full= oldscreen; + newa->next->full= oldscreen; + + setscreen(sc); + wich_cursor(newa); + } +} + +static void area_autoplayscreen(void) +{ + bScreen *sc, *oldscreen; + ScrArea *newa, *old, *sa; + + if (curarea->full) { + area_fullscreen(); + } + + if (curarea->full == NULL) { + sa = G.curscreen->areabase.first; + while (sa) { + if (sa->spacetype == SPACE_VIEW3D) { + break; + } + sa= sa->next; + } + + if (sa) { + areawinset(sa->win); + G.curscreen->full = SCREENAUTOPLAY; + + old= curarea; + oldscreen= G.curscreen; + sc= addscreen("temp"); /* deze zet G.curscreen */ + + newa= sc->areabase.first; + + curarea= old; + G.curscreen= oldscreen; /* moet voor setscreen */ + + /* copy area settings */ + copy_areadata(newa, curarea); + newa->headertype= 0; + + curarea->full= oldscreen; + newa->full= oldscreen; + + setscreen(sc); + wich_cursor(newa); + } + } +} + +static void copy_screen(bScreen *to, bScreen *from) +{ + ScrVert *s1, *s2; + ScrEdge *se; + ScrArea *sa; + ListBase lbase; + + /* alles van to vrijgeven */ + free_screen(to); + winqueue_break= 1; /* overal uit queue's gaan */ + + duplicatelist(&to->vertbase, &from->vertbase); + duplicatelist(&to->edgebase, &from->edgebase); + duplicatelist(&to->areabase, &from->areabase); + + s1= from->vertbase.first; + s2= to->vertbase.first; + while(s1) { + s1->newv= s2; + s2= s2->next; + s1= s1->next; + } + se= to->edgebase.first; + while(se) { + se->v1= se->v1->newv; + se->v2= se->v2->newv; + sortscrvert(&(se->v1), &(se->v2)); + se= se->next; + } + + sa= to->areabase.first; + while(sa) { + sa->v1= sa->v1->newv; + sa->v2= sa->v2->newv; + sa->v3= sa->v3->newv; + sa->v4= sa->v4->newv; + sa->win= 0; + sa->headwin= 0; + + sa->uiblocks.first= sa->uiblocks.last= NULL; + + duplicatespacelist(sa, &lbase, &sa->spacedata); + sa->spacedata= lbase; + + sa= sa->next; + } + + /* op nul zetten (nodig?) */ + s1= from->vertbase.first; + while(s1) { + s1->newv= 0; + s1= s1->next; + } +} + +void duplicate_screen(void) +{ + bScreen *sc, *oldscreen; + + if(G.curscreen->full != SCREENNORMAL) return; + + /* nieuw screen maken: */ + + oldscreen= G.curscreen; + sc= addscreen(oldscreen->id.name+2); /* deze zet G.curscreen */ + copy_screen(sc, oldscreen); + + G.curscreen= oldscreen; + setscreen(sc); + +} + + +/* ************ END SCREENBEHEER ************** */ +/* ************ JOIN/SPLIT/MOVE ************** */ + +static void joinarea(ScrArea *sa, ScrEdge *onedge) +{ + ScrArea *sa2; + ScrArea *up=0, *down=0, *right=0, *left=0; + ScrEdge *setest; + short val=0; + + sa= test_edge_area(sa, onedge); + if (sa==0) return; + + /* welke edges kunnen ermee? */ + /* vind richtingen met zelfde edge */ + sa2= G.curscreen->areabase.first; + while(sa2) { + if(sa2 != sa) { + setest= screen_findedge(G.curscreen, sa2->v1, sa2->v2); + if(onedge==setest) right= sa2; + setest= screen_findedge(G.curscreen, sa2->v2, sa2->v3); + if(onedge==setest) down= sa2; + setest= screen_findedge(G.curscreen, sa2->v3, sa2->v4); + if(onedge==setest) left= sa2; + setest= screen_findedge(G.curscreen, sa2->v4, sa2->v1); + if(onedge==setest) up= sa2; + } + sa2= sa2->next; + } + + sa2= 0; + setest= 0; + + if(left) val++; + if(up) val++; + if(right) val++; + if(down) val++; + + if(val==0) return; + else if(val==1) { + if(left) sa2= left; + else if(up) sa2= up; + else if(right) sa2= right; + else if(down) sa2= down; + } + + + if(sa2) { + /* nieuwe area is oude sa */ + if(sa2==left) { + sa->v1= sa2->v1; + sa->v2= sa2->v2; + screen_addedge(G.curscreen, sa->v2, sa->v3); + screen_addedge(G.curscreen, sa->v1, sa->v4); + } + else if(sa2==up) { + sa->v2= sa2->v2; + sa->v3= sa2->v3; + screen_addedge(G.curscreen, sa->v1, sa->v2); + screen_addedge(G.curscreen, sa->v3, sa->v4); + } + else if(sa2==right) { + sa->v3= sa2->v3; + sa->v4= sa2->v4; + screen_addedge(G.curscreen, sa->v2, sa->v3); + screen_addedge(G.curscreen, sa->v1, sa->v4); + } + else if(sa2==down) { + sa->v1= sa2->v1; + sa->v4= sa2->v4; + screen_addedge(G.curscreen, sa->v1, sa->v2); + screen_addedge(G.curscreen, sa->v3, sa->v4); + } + + /* edge en area weg */ + /* remlink(&G.curscreen->edgebase, setest); */ + /* freeN(setest); */ + del_area(sa2); + BLI_remlink(&G.curscreen->areabase, sa2); + MEM_freeN(sa2); + + removedouble_scredges(); + removenotused_scredges(); + removenotused_scrverts(); /* moet als laatste */ + + testareas(); + mainqenter(DRAWEDGES, 1); + /* test cursor en inputwindow */ + mainqenter(MOUSEY, -1); + } +} + +static short testsplitpoint(ScrArea *sa, char dir, float fac) +/* return 0: geen split mogelijk */ +/* else return (integer) screencoordinaat splitpunt */ +{ + short x, y; + + /* area groot genoeg? */ + if(sa->v4->vec.x- sa->v1->vec.x <= 2*AREAMINX) return 0; + if(sa->v2->vec.y- sa->v1->vec.y <= 2*AREAMINY) return 0; + + /* voor zekerheid */ + if(fac<0.0) fac= 0.0; + if(fac>1.0) fac= 1.0; + + if(dir=='h') { + y= sa->v1->vec.y+ fac*(sa->v2->vec.y- sa->v1->vec.y); + + if(sa->v2->vec.y==G.curscreen->sizey-1 && sa->v2->vec.y- y < HEADERY+EDGEWIDTH2) + y= sa->v2->vec.y- HEADERY-EDGEWIDTH2; + + else if(sa->v1->vec.y==0 && y- sa->v1->vec.y < HEADERY+EDGEWIDTH2) + y= sa->v1->vec.y+ HEADERY+EDGEWIDTH2; + + else if(y- sa->v1->vec.y < AREAMINY) y= sa->v1->vec.y+ AREAMINY; + else if(sa->v2->vec.y- y < AREAMINY) y= sa->v2->vec.y- AREAMINY; + else y-= (y % AREAGRID); + + return y; + } + else { + x= sa->v1->vec.x+ fac*(sa->v4->vec.x- sa->v1->vec.x); + if(x- sa->v1->vec.x < AREAMINX) x= sa->v1->vec.x+ AREAMINX; + else if(sa->v4->vec.x- x < AREAMINX) x= sa->v4->vec.x- AREAMINX; + else x-= (x % AREAGRID); + + return x; + } +} + +static void splitarea(ScrArea *sa, char dir, float fac) +{ + bScreen *sc; + ScrArea *newa; + ScrVert *sv1, *sv2; + short split; + + if(sa==0) return; + + split= testsplitpoint(sa, dir, fac); + if(split==0) return; + + sc= G.curscreen; + + areawinset(sa->win); + + if(dir=='h') { + /* nieuwe vertices */ + sv1= screen_addvert(sc, sa->v1->vec.x, split); + sv2= screen_addvert(sc, sa->v4->vec.x, split); + + /* nieuwe edges */ + screen_addedge(sc, sa->v1, sv1); + screen_addedge(sc, sv1, sa->v2); + screen_addedge(sc, sa->v3, sv2); + screen_addedge(sc, sv2, sa->v4); + screen_addedge(sc, sv1, sv2); + + /* nieuwe areas: boven */ + newa= screen_addarea(sc, sv1, sa->v2, sa->v3, sv2, sa->headertype, sa->spacetype); + copy_areadata(newa, sa); + + /* area onder */ + sa->v2= sv1; + sa->v3= sv2; + + } + else { + /* nieuwe vertices */ + sv1= screen_addvert(sc, split, sa->v1->vec.y); + sv2= screen_addvert(sc, split, sa->v2->vec.y); + + /* nieuwe edges */ + screen_addedge(sc, sa->v1, sv1); + screen_addedge(sc, sv1, sa->v4); + screen_addedge(sc, sa->v2, sv2); + screen_addedge(sc, sv2, sa->v3); + screen_addedge(sc, sv1, sv2); + + /* nieuwe areas: links */ + newa= screen_addarea(sc, sa->v1, sa->v2, sv2, sv1, sa->headertype, sa->spacetype); + copy_areadata(newa, sa); + + /* area rechts */ + sa->v1= sv1; + sa->v2= sv2; + } + + /* dubbele vertices en edges verwijderen */ + removedouble_scrverts(); + removedouble_scredges(); + removenotused_scredges(); + + mainqenter(DRAWEDGES, 1); + dodrawscreen= 1; /* patch! even gets lost,,,? */ + testareas(); +} + +static void scrarea_draw_splitpoint(ScrArea *sa, char dir, float fac) +{ + int split= testsplitpoint(sa, dir, fac); + + if (split) { + if(dir=='h') { + glutil_draw_front_xor_line(sa->totrct.xmin, split, sa->totrct.xmax, split); + glutil_draw_front_xor_line(sa->totrct.xmin, split-1, sa->totrct.xmax, split-1); + } else { + glutil_draw_front_xor_line(split, sa->totrct.ymin, split, sa->totrct.ymax); + glutil_draw_front_xor_line(split-1, sa->totrct.ymin, split-1, sa->totrct.ymax); + } + } +} + +static void splitarea_interactive(ScrArea *area, ScrEdge *onedge) +{ + ScrArea *sa= area; + float fac; + unsigned short event; + short ok= 0, val, split = 0, mval[2], mvalo[2], first= 1; + char dir; + + if(sa->win==0) return; + if(sa->full) return; + + dir= scredge_is_horizontal(onedge)?'v':'h'; + + mywinset(G.curscreen->mainwin); + /* hoort al goede matrix te hebben */ + + /* rekening houden met grid en minsize */ + while(ok==0) { + getmouseco_sc(mval); + + if (first || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + if (!first) { + scrarea_draw_splitpoint(sa, dir, fac); + } + + if(dir=='h') { + fac= mval[1]- (sa->v1->vec.y); + fac/= sa->v2->vec.y- sa->v1->vec.y; + } else { + fac= mval[0]- sa->v1->vec.x; + fac/= sa->v4->vec.x- sa->v1->vec.x; + } + + split= testsplitpoint(sa, dir, fac); + if (split) { + scrarea_draw_splitpoint(sa, dir, fac); + } else { + ok= -1; + } + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + first= 0; + } + + event= extern_qread(&val); + if(val && event==LEFTMOUSE) { + if(dir=='h') { + fac= split- (sa->v1->vec.y); + fac/= sa->v2->vec.y- sa->v1->vec.y; + } + else { + fac= split- sa->v1->vec.x; + fac/= sa->v4->vec.x- sa->v1->vec.x; + } + ok= 1; + } + if(val && event==ESCKEY) { + ok= -1; + } + } + + if (!first) { + scrarea_draw_splitpoint(sa, dir, fac); + } + + if(ok==1) { + splitarea(sa, dir, fac); + mainqenter(DRAWEDGES, 1); + dodrawscreen= 1; /* patch! even gets lost,,,? */ + } +} + +View3D *find_biggest_view3d(void) +{ + ScrArea *sa= find_biggest_area_of_type(SPACE_VIEW3D); + + if (sa) { + return (View3D*) sa->spacedata.first; + } else { + return NULL; + } +} + +ScrArea *find_biggest_area_of_type(int spacecode) +{ + ScrArea *sa, *biggest= NULL; + int bigsize; + + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + if (spacecode==0 || sa->spacetype==spacecode) { + int x= sa->v3->vec.x - sa->v1->vec.x; + int y= sa->v3->vec.y - sa->v1->vec.y; + int size= x*x + y*y; + + if (!biggest || size>bigsize) { + biggest= sa; + bigsize= size; + } + } + } + + return biggest; +} + +ScrArea *find_biggest_area(void) +{ + return find_biggest_area_of_type(0); +} + +static void select_connected_scredge(bScreen *sc, ScrEdge *edge) +{ + ScrEdge *se; + ScrVert *sv; + int oneselected; + char dir; + + /* select connected, alleen in de juiste richting */ + /* 'dir' is de richting van de EDGE */ + + if(edge->v1->vec.x==edge->v2->vec.x) dir= 'v'; + else dir= 'h'; + + sv= sc->vertbase.first; + while(sv) { + sv->flag= 0; + sv= sv->next; + } + + edge->v1->flag= 1; + edge->v2->flag= 1; + + oneselected= 1; + while(oneselected) { + se= sc->edgebase.first; + oneselected= 0; + while(se) { + if(se->v1->flag + se->v2->flag==1) { + if(dir=='h') if(se->v1->vec.y==se->v2->vec.y) { + se->v1->flag= se->v2->flag= 1; + oneselected= 1; + } + if(dir=='v') if(se->v1->vec.x==se->v2->vec.x) { + se->v1->flag= se->v2->flag= 1; + oneselected= 1; + } + } + se= se->next; + } + } +} + +void test_scale_screen(bScreen *sc) +/* testen of screenvertices vergroot/verkleind moeten worden */ +/* testen of offset nog klopt */ +{ + ScrVert *sv=0; + ScrEdge *se; + ScrArea *sa, *san; + int yval; + float facx, facy, tempf, min[2], max[2]; + + sc->startx= prefstax; + sc->starty= prefstay; + sc->endx= prefstax+prefsizx-1; + sc->endy= prefstay+prefsizy-1; + + /* calculate size */ + sv= sc->vertbase.first; + min[0]= min[1]= 0.0; + max[0]= sc->sizex; + max[1]= sc->sizey; + while(sv) { + min[0]= MIN2(min[0], sv->vec.x); + min[1]= MIN2(min[1], sv->vec.y); + max[0]= MAX2(max[0], sv->vec.x); + max[1]= MAX2(max[1], sv->vec.y); + sv= sv->next; + } + + /* always make 0.0 left under */ + sv= sc->vertbase.first; + while(sv) { + sv->vec.x -= min[0]; + sv->vec.y -= min[1]; + sv= sv->next; + } + + + sc->sizex= max[0]-min[0]; + sc->sizey= max[1]-min[1]; + + if(sc->sizex!= prefsizx || sc->sizey!= prefsizy) { + facx= prefsizx; + facx/= (float)sc->sizex; + facy= prefsizy; + facy/= (float)sc->sizey; + + /* make sure it fits! */ + sv= sc->vertbase.first; + while(sv) { + tempf= ((float)sv->vec.x)*facx; + sv->vec.x= (short)(tempf+0.5); + sv->vec.x+= AREAGRID-1; + sv->vec.x-= (sv->vec.x % AREAGRID); + + CLAMP(sv->vec.x, 0, prefsizx); + + tempf= ((float)sv->vec.y )*facy; + sv->vec.y= (short)(tempf+0.5); + sv->vec.y+= AREAGRID-1; + sv->vec.y-= (sv->vec.y % AREAGRID); + + CLAMP(sv->vec.y, 0, prefsizy); + + sv= sv->next; + } + + sc->sizex= prefsizx; + sc->sizey= prefsizy; + } + + /* test for collapsed areas. This could happen in some blender version... */ + sa= sc->areabase.first; + while(sa) { + san= sa->next; + if(sa->v1==sa->v2 || sa->v3==sa->v4 || sa->v2==sa->v3) { + del_area(sa); + BLI_remlink(&sc->areabase, sa); + MEM_freeN(sa); + } + sa= san; + } + + /* make each window at least HEADERY high */ + + sa= sc->areabase.first; + while(sa) { + + if(sa->v1->vec.y+HEADERY > sa->v2->vec.y) { + /* lower edge */ + se= screen_findedge(sc, sa->v4, sa->v1); + if(se && sa->v1!=sa->v2 ) { + select_connected_scredge(sc, se); + + /* all selected vertices get the right offset */ + yval= sa->v2->vec.y-HEADERY; + sv= sc->vertbase.first; + while(sv) { + /* if is a collapsed area */ + if(sv!=sa->v2 && sv!=sa->v3) { + if(sv->flag) sv->vec.y= yval; + } + sv= sv->next; + } + } + } + + sa= sa->next; + } + +} + +static void draw_front_xor_dirdist_line(char dir, int dist, int start, int end) +{ + if (dir=='h') { + glutil_draw_front_xor_line(start, dist, end, dist); + glutil_draw_front_xor_line(start, dist+1, end, dist+1); + } else { + glutil_draw_front_xor_line(dist, start, dist, end); + glutil_draw_front_xor_line(dist+1, start, dist+1, end); + } +} + +static void moveareas(ScrEdge *edge) +{ + ScrVert *v1; + ScrArea *sa; + short mvalo[2]; + short edge_start, edge_end, edge_position; + short bigger, smaller, headery, areaminy; + int delta, doit; + char dir; + + if(edge->border) return; + + dir= scredge_is_horizontal(edge)?'h':'v'; + + select_connected_scredge(G.curscreen, edge); + + edge_position= (dir=='h')?edge->v1->vec.y:edge->v1->vec.x; + edge_start= 10000; + edge_end= -10000; + for (v1= G.curscreen->vertbase.first; v1; v1= v1->next) { + if (v1->flag) { + if (dir=='h') { + edge_start= MIN2(edge_start, v1->vec.x); + edge_end= MAX2(edge_end, v1->vec.x); + } else { + edge_start= MIN2(edge_start, v1->vec.y); + edge_end= MAX2(edge_end, v1->vec.y); + } + } + } + + /* nu zijn alle vertices met 'flag==1' degene die verplaatst kunnen worden. */ + /* we lopen de areas af en testen vrije ruimte met MINSIZE */ + bigger= smaller= 10000; + sa= G.curscreen->areabase.first; + while(sa) { + if(dir=='h') { /* als top of down edge select, test hoogte */ + if(sa->headertype) { + headery= HEADERY; + areaminy= AREAMINY; + } + else { + headery= 0; + areaminy= EDGEWIDTH; + } + + if(sa->v1->flag && sa->v4->flag) { + int y1; + if(sa->v2->vec.y==G.curscreen->sizey-1) /* bovenste edge */ + y1= sa->v2->vec.y - sa->v1->vec.y-headery-EDGEWIDTH; + else + y1= sa->v2->vec.y - sa->v1->vec.y-areaminy; + bigger= MIN2(bigger, y1); + } + else if(sa->v2->flag && sa->v3->flag) { + int y1; + if(sa->v1->vec.y==0) /* onderste edge */ + y1= sa->v2->vec.y - sa->v1->vec.y-headery-EDGEWIDTH; + else + y1= sa->v2->vec.y - sa->v1->vec.y-areaminy; + smaller= MIN2(smaller, y1); + } + } + else { /* als left of right edge select, test breedte */ + if(sa->v1->flag && sa->v2->flag) { + int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX; + bigger= MIN2(bigger, x1); + } + else if(sa->v3->flag && sa->v4->flag) { + int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX; + smaller= MIN2(smaller, x1); + } + } + sa= sa->next; + } + + mywinset(G.curscreen->mainwin); + + doit= delta= 0; + getmouseco_sc(mvalo); + draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end); + while (!doit) { + short val; + unsigned short event= extern_qread(&val); + + if (event==MOUSEY) { + short mval[2]; + + getmouseco_sc(mval); + + draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end); + + delta= (dir=='h')?(mval[1]-mvalo[1]):(mval[0]-mvalo[0]); + delta= CLAMPIS(delta, -smaller, bigger); + + draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end); + } else if (event==LEFTMOUSE) { + doit= 1; + } else if (val) { + if (ELEM(event, ESCKEY, RIGHTMOUSE)) + doit= -1; + else if (ELEM(event, SPACEKEY, RETKEY)) + doit= 1; + } + } + draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end); + + if (doit==1) { + for (v1= G.curscreen->vertbase.first; v1; v1= v1->next) { + if (v1->flag) { + /* zo is AREAGRID netjes */ + if((dir=='v') && v1->vec.x>0 && v1->vec.x<G.curscreen->sizex-1) { + v1->vec.x+= delta; + if(delta != bigger && delta != -smaller) v1->vec.x-= (v1->vec.x % AREAGRID); + } + if((dir=='h') && v1->vec.y>0 && v1->vec.y<G.curscreen->sizey-1) { + v1->vec.y+= delta; + + /* with these lines commented out you can pull the top bar exact to the screen border. */ + /* if(delta != bigger && delta != -smaller) { */ + v1->vec.y+= AREAGRID-1; + v1->vec.y-= (v1->vec.y % AREAGRID); + + /* } */ + } + } + v1->flag= 0; + } + + removedouble_scrverts(); + removedouble_scredges(); + testareas(); + } + + glDrawBuffer(GL_BACK); + mainqenter(DRAWEDGES, 1); + dodrawscreen= 1; /* patch! even gets lost,,,? */ +} + +static void scrollheader(ScrArea *area) +{ + short mval[2], mvalo[2]; + + if(area->headbutlen<area->winx) { + area->headbutofs= 0; + } + else if(area->headbutofs+area->winx > area->headbutlen) { + area->headbutofs= area->headbutlen-area->winx; + } + + getmouseco_sc(mvalo); + + while(get_mbut() & M_MOUSE) { + getmouseco_sc(mval); + if(mval[0]!=mvalo[0]) { + area->headbutofs-= (mval[0]-mvalo[0]); + + if(area->headbutlen-area->winx < area->headbutofs) area->headbutofs= area->headbutlen-area->winx; + if(area->headbutofs<0) area->headbutofs= 0; + + scrarea_do_headchange(area); + scrarea_do_headdraw(area); + + screen_swapbuffers(); + + mvalo[0]= mval[0]; + } else { + BIF_wait_for_statechange(); + } + } +} + +int select_area(int spacetype) +{ + /* vanuit editroutines aanroepen, als er meer area's + * zijn van type 'spacetype' kan er een area aangegeven worden + */ + ScrArea *sa, *sact = NULL; + int tot=0; + unsigned short event = 0; + short val, mval[2]; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==spacetype) { + sact= sa; + tot++; + } + sa= sa->next; + } + + if(tot==0) { + error("Can't do this! Open correct window"); + return 0; + } + + if(tot==1) { + if(curarea!=sact) areawinset(sact->win); + return 1; + } + else if(tot>1) { + set_cursor(CURSOR_HELP); + while(1) { + event= extern_qread(&val); + + if (val) { + if(event==ESCKEY) break; + if(event==LEFTMOUSE) break; + if(event==SPACEKEY) break; + } else { + BIF_wait_for_statechange(); + } + } + screen_set_cursor(G.curscreen); + + /* recalculate winakt */ + getmouseco_sc(mval); + + if(event==LEFTMOUSE) { + ScrArea *sa= screen_find_area_for_pt(G.curscreen, mval); + + if (sa &&sa->spacetype==spacetype) { + G.curscreen->winakt= sa->win; + areawinset(G.curscreen->winakt); + } else { + error("wrong window"); + return 0; + } + } + } + + if(event==LEFTMOUSE) return 1; + else return 0; +} + +/* ************ END JOIN/SPLIT/MOVE ************** */ +/* **************** DRAW SCREENEDGES ***************** */ + +#define EDGE_EXTEND 3 + +void drawedge(short x1, short y1, short x2, short y2) +{ + static unsigned int edcol[EDGEWIDTH]= {0x0, 0x505050, 0x909090, 0xF0F0F0, 0x0}; + int a; + + if(x1==x2) { /* vertical */ + if (y2<y1) + y1^= y2^= y1^= y2; + + if (y1==0) y1-= EDGE_EXTEND; + if (y2==G.curscreen->sizey) y2+= EDGE_EXTEND; + + x1+= EDGEWIDTH2; + x2+= EDGEWIDTH2; + + glBegin(GL_LINES); + for(a=0; a<EDGEWIDTH; a++) { + int rounding= abs(a-EDGEWIDTH2); + + cpack(edcol[a]); + glVertex2i(x1-a, y1+rounding); + glVertex2i(x2-a, y2-rounding); + } + glEnd(); + } + else { /* horizontal */ + if (x2<x1) + x1^= x2^= x1^= x2; + + if (x1==0) x1-= EDGE_EXTEND; + if (x2==G.curscreen->sizex) x2+= EDGE_EXTEND; + + y1-= EDGEWIDTH2; + y2-= EDGEWIDTH2; + + glBegin(GL_LINES); + for(a=0; a<EDGEWIDTH; a++) { + int rounding= abs(a-EDGEWIDTH2); + + cpack(edcol[a]); + glVertex2i(x1+rounding, y1+a); + glVertex2i(x2-rounding, y2+a); + } + glEnd(); + } +} + +static void drawscredge(ScrEdge *se) +{ + bScreen *sc; + vec2s *v1, *v2; + + sc= G.curscreen; + + v1= &(se->v1->vec); + v2= &(se->v2->vec); + + /* borders screen niet tekenen */ + /* vanwege resolutie verschillen (PC/SGI files) de linit een + * beetje afronden? + */ + se->border= 1; + if(v1->x<=1 && v2->x<=1) return; + if(v1->x>=sc->sizex-2 && v2->x>=sc->sizex-2) return; + if(v1->y<=1 && v2->y<=1) return; + if(v1->y>=sc->sizey-2 && v2->y>=sc->sizey-2) return; + se->border= 0; + + drawedge(v1->x, v1->y, v2->x, v2->y); +} + +void drawscreen(void) +{ + ScrEdge *se; + + mywinset(G.curscreen->mainwin); + myortho2(-0.5, (float)G.curscreen->sizex-0.5, -0.5, (float)G.curscreen->sizey-0.5); + + /* two times, because there is no 'win_swap' for this available */ + glDrawBuffer(GL_FRONT); + se= G.curscreen->edgebase.first; + while(se) { + drawscredge(se); + se= se->next; + } + + glDrawBuffer(GL_BACK); + se= G.curscreen->edgebase.first; + while(se) { + drawscredge(se); + se= se->next; + } +} + +/* ********************************* */ + +bScreen *default_twosplit() +{ + bScreen *sc= addscreen("screen"); + ScrArea *sa; + + splitarea( (ScrArea *)sc->areabase.first, 'h', 0.99); + sa= sc->areabase.first; + newspace(sa, SPACE_VIEW3D); + newspace(sa->next, SPACE_INFO); + + return sc; +} + +void initscreen(void) +{ + default_twosplit(); +} + +/***/ + +void screen_draw_info_text(bScreen *sc, char *text) { + Window *oldactwin= winlay_get_active_window(); + ScrArea *sa; + + /* + * Because this is called from within rendering + * internals it is possible our window is not + * active. + */ + window_make_active(mainwin); + + for (sa= sc->areabase.first; sa; sa= sa->next) { + if (sa->spacetype==SPACE_INFO) { + int x= sa->headbutlen - 28; + int y= 6; + + areawinset(sa->headwin); + glDrawBuffer(GL_FRONT); + + cpack(0xA08060); + glRecti(x-11, y-6, x+55, y+13); + + cpack(0x909090); + glRecti(x+55, y-6, x+1280, y+14); + + cpack(0x0); + glRasterPos2i(x, y); + BMF_DrawString(G.fonts, text); + + glFinish(); + glDrawBuffer(GL_BACK); + + sa->head_swap= WIN_FRONT_OK; + } + } + + if (oldactwin && oldactwin!=mainwin) window_make_active(oldactwin); +} + +static int curcursor; + +int get_cursor(void) { + return curcursor; +} + +void set_cursor(int curs) { + if (!(R.flag & R_RENDERING)) { + if (curs!=curcursor) { + curcursor= curs; + window_set_cursor(mainwin, curs); + } + } +} + +void unlink_screen(bScreen *sc) { + ScrArea *sa; + + for (sa= sc->areabase.first; sa; sa= sa->next) + del_area(sa); +} + +void warp_pointer(int x, int y) +{ + window_warp_pointer(mainwin, x, y); +} + +void set_timecursor(int nr) +{ + /* 10 8x8 digits */ + static char number_bitmaps[10][8]= { + {0, 56, 68, 68, 68, 68, 68, 56}, + {0, 24, 16, 16, 16, 16, 16, 56}, + {0, 60, 66, 32, 16, 8, 4, 126}, + {0, 124, 32, 16, 56, 64, 66, 60}, + {0, 32, 48, 40, 36, 126, 32, 32}, + {0, 124, 4, 60, 64, 64, 68, 56}, + {0, 56, 4, 4, 60, 68, 68, 56}, + {0, 124, 64, 32, 16, 8, 8, 8}, + {0, 60, 66, 66, 60, 66, 66, 60}, + {0, 56, 68, 68, 120, 64, 68, 56} + }; + unsigned char mask[16][2]; + unsigned char bitmap[16][2]; + int i, idx; + + memset(&bitmap, 0x00, sizeof(bitmap)); + memset(&mask, 0xFF, sizeof(mask)); + + /* print number bottom right justified */ + for (idx= 3; nr && idx>=0; idx--) { + char *digit= number_bitmaps[nr%10]; + int x = idx%2; + int y = idx/2; + + for (i=0; i<8; i++) + bitmap[i + y*8][x]= digit[i]; + nr/= 10; + } + + curcursor= CURSOR_NONE; + window_set_custom_cursor(mainwin, mask, bitmap); + BIF_renderwin_set_custom_cursor(mask, bitmap); +} + diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c new file mode 100644 index 00000000000..608988458d0 --- /dev/null +++ b/source/blender/src/editseq.c @@ -0,0 +1,1855 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <math.h> +#include <string.h> +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif +#include <sys/types.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_storage_types.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "DNA_ipo_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_sequence_types.h" +#include "DNA_view2d_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_utildefines.h" +#include "BKE_plugin_types.h" +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_library.h" +#include "BKE_main.h" + +#include "BIF_space.h" +#include "BIF_interface.h" +#include "BIF_screen.h" +#include "BIF_drawseq.h" +#include "BIF_editseq.h" +#include "BIF_mywindow.h" +#include "BIF_toolbox.h" +#include "BIF_writemovie.h" +#include "BIF_editview.h" +#include "BIF_scrarea.h" + +#include "BSE_edit.h" +#include "BSE_sequence.h" +#include "BSE_filesel.h" +#include "BSE_drawipo.h" + +#include "BDR_editobject.h" + +#include "blendef.h" +#include "mydevice.h" +#include "interface.h" /* MAART: for button types, pupmenu */ + +Sequence *last_seq=0; +char last_imagename[80]= "/"; + +/* void transform_seq(int mode); already in BIF_editseq.h */ + +#define SEQ_DESEL ~(SELECT+SEQ_LEFTSEL+SEQ_RIGHTSEL) + +static int test_overlap_seq(Sequence *); +static void shuffle_seq(Sequence *); + +static void change_plugin_seq(char *str) /* aangeroepen vanuit fileselect */ +{ +/* extern Sequence *last_seq; already done few lines before !!!*/ + + if(last_seq && last_seq->type!=SEQ_PLUGIN) return; + + free_plugin_seq(last_seq->plugin); + + last_seq->plugin= (PluginSeq *)add_plugin_seq(str, last_seq->name+2); + + last_seq->machine= MAX3(last_seq->seq1->machine, last_seq->seq2->machine, last_seq->seq3->machine); + if( test_overlap_seq(last_seq) ) shuffle_seq(last_seq); +} + + +void boundbox_seq(void) +{ + Sequence *seq; + Editing *ed; + float min[2], max[2]; + + ed= G.scene->ed; + if(ed==0) return; + + min[0]= 0.0; + max[0]= EFRA+1; + min[1]= 0.0; + max[1]= 8.0; + + seq= ed->seqbasep->first; + while(seq) { + + if( min[0] > seq->startdisp-1) min[0]= seq->startdisp-1; + if( max[0] < seq->enddisp+1) max[0]= seq->enddisp+1; + if( max[1] < seq->machine+2.0) max[1]= seq->machine+2.0; + + seq= seq->next; + } + + G.v2d->tot.xmin= min[0]; + G.v2d->tot.xmax= max[0]; + G.v2d->tot.ymin= min[1]; + G.v2d->tot.ymax= max[1]; + +} + +Sequence *find_nearest_seq(int *hand) +{ + Sequence *seq; + Editing *ed; + float x, y, facx, facy; + short mval[2]; + + *hand= 0; + + ed= G.scene->ed; + if(ed==0) return 0; + + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + + seq= ed->seqbasep->first; + while(seq) { + if(seq->machine == (int)y) { + if(seq->startdisp<=x && seq->enddisp>=x) { + + if(seq->type < SEQ_EFFECT) { + if( seq->handsize+seq->startdisp >=x ) { + /* binnen de driehoek? */ + facx= (x-seq->startdisp)/seq->handsize; + if( (y - (int)y) <0.5) { + facy= (y - 0.2 - (int)y)/0.3; + if( facx < facy ) *hand= 1; + } + else { + facy= (y - 0.5 - (int)y)/0.3; + if( facx+facy < 1.0 ) *hand= 1; + } + + } + else if( -seq->handsize+seq->enddisp <=x ) { + /* binnen de driehoek? */ + facx= 1.0 - (seq->enddisp-x)/seq->handsize; + if( (y - (int)y) <0.5) { + facy= (y - 0.2 - (int)y)/0.3; + if( facx+facy > 1.0 ) *hand= 2; + } + else { + facy= (y - 0.5 - (int)y)/0.3; + if( facx > facy ) *hand= 2; + } + } + } + + return seq; + } + } + seq= seq->next; + } + return 0; +} + +void clear_last_seq(void) +{ + /* vanuit (bijv) ipo: als ie veranderd is, ook meteen de effecten metzelfde ipo */ + Sequence *seq; + Editing *ed; + StripElem *se; + int a; + + if(last_seq) { + + ed= G.scene->ed; + if(ed==0) return; + + WHILE_SEQ(&ed->seqbase) { + if(seq==last_seq || (last_seq->ipo && seq->ipo==last_seq->ipo)) { + a= seq->len; + se= seq->strip->stripdata; + if(se) { + while(a--) { + if(se->ibuf) IMB_freeImBuf(se->ibuf); + se->ibuf= 0; + se->ok= 1; + se++; + } + } + } + } + END_SEQ + } +} + +static int test_overlap_seq(Sequence *test) +{ + Sequence *seq; + Editing *ed; + + ed= G.scene->ed; + if(ed==0) return 0; + + seq= ed->seqbasep->first; + while(seq) { + if(seq!=test) { + if(test->machine==seq->machine) { + if(test->depth==seq->depth) { + if( (test->enddisp <= seq->startdisp) || (test->startdisp >= seq->enddisp) ); + else return 1; + } + } + } + seq= seq->next; + } + return 0; +} + +static void shuffle_seq(Sequence *test) +{ + Editing *ed; + Sequence *seq; + int a, start; + + ed= G.scene->ed; + if(ed==0) return; + + /* als er meerdere select zijn: alleen y shuffelen */ + a=0; + seq= ed->seqbasep->first; + while(seq) { + if(seq->flag & SELECT) a++; + seq= seq->next; + } + + if(a<2 && test->type==SEQ_IMAGE) { + start= test->start; + + for(a= 1; a<50; a++) { + test->start= start+a; + calc_sequence(test); + if( test_overlap_seq(test)==0) return; + test->start= start-a; + calc_sequence(test); + if( test_overlap_seq(test)==0) return; + } + test->start= start; + } + + test->machine++; + calc_sequence(test); + while( test_overlap_seq(test) ) { + if(test->machine >= MAXSEQ) { + error("No space to add sequence "); + + BLI_remlink(ed->seqbasep, test); + free_sequence(test); + return; + } + test->machine++; + calc_sequence(test); + } +} + +static void deselect_all_seq(void) +{ + Sequence *seq; + Editing *ed; + + ed= G.scene->ed; + if(ed==0) return; + + WHILE_SEQ(ed->seqbasep) { + seq->flag &= SEQ_DESEL; + } + END_SEQ +} + +static void recurs_sel_seq(Sequence *seqm) +{ + Sequence *seq; + + seq= seqm->seqbase.first; + while(seq) { + + if(seqm->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL)) seq->flag &= SEQ_DESEL; + else if(seqm->flag & SELECT) seq->flag |= SELECT; + else seq->flag &= SEQ_DESEL; + + if(seq->seqbase.first) recurs_sel_seq(seq); + + seq= seq->next; + } +} + +void swap_select_seq(void) +{ + Sequence *seq; + Editing *ed; + int sel=0; + + ed= G.scene->ed; + if(ed==0) return; + + WHILE_SEQ(ed->seqbasep) { + if(seq->flag & SELECT) sel= 1; + } + END_SEQ + + WHILE_SEQ(ed->seqbasep) { + /* alles voor zekerheid altijd deselecteren */ + seq->flag &= SEQ_DESEL; + if(sel==0) seq->flag |= SELECT; + } + END_SEQ + + allqueue(REDRAWSEQ, 0); +} + +void mouse_select_seq(void) +{ + Sequence *seq; + int hand; + + seq= find_nearest_seq(&hand); + + if(G.qual==0) deselect_all_seq(); + + if(seq) { + last_seq= seq; + + if ELEM(seq->type, SEQ_IMAGE, SEQ_MOVIE) { + if(seq->strip) strcpy(last_imagename, seq->strip->dir); + } + + if(G.qual==0) { + seq->flag |= SELECT; + if(hand==1) seq->flag |= SEQ_LEFTSEL; + if(hand==2) seq->flag |= SEQ_RIGHTSEL; + } + else { + if(seq->flag & SELECT) { + if(hand==0) seq->flag &= SEQ_DESEL; + else if(hand==1) { + if(seq->flag & SEQ_LEFTSEL) seq->flag &= ~SEQ_LEFTSEL; + else seq->flag |= SEQ_LEFTSEL; + } + else if(hand==2) { + if(seq->flag & SEQ_RIGHTSEL) seq->flag &= ~SEQ_RIGHTSEL; + else seq->flag |= SEQ_RIGHTSEL; + } + } + else { + seq->flag |= SELECT; + if(hand==1) seq->flag |= SEQ_LEFTSEL; + if(hand==2) seq->flag |= SEQ_RIGHTSEL; + } + } + recurs_sel_seq(seq); + } + + force_draw(); + + if(last_seq) allqueue(REDRAWIPO, 0); + + std_rmouse_transform(transform_seq); +} + +static Sequence *alloc_sequence(int cfra, int machine) +{ + Editing *ed; + Sequence *seq; + + ed= G.scene->ed; + + seq= MEM_callocN( sizeof(Sequence), "addseq"); + BLI_addtail(ed->seqbasep, seq); + + last_seq= seq; + + *( (short *)seq->name )= ID_SEQ; + seq->name[2]= 0; + + seq->flag= SELECT; + seq->start= cfra; + seq->machine= machine; + + return seq; +} + +static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int last) +{ + Sequence *seq; + Strip *strip; + StripElem *se; + int totsel, a; + + /* zijn er geselecteerde files? */ + totsel= 0; + for(a=0; a<sfile->totfile; a++) { + if(sfile->filelist[a].flags & ACTIVE) { + if( (sfile->filelist[a].type & S_IFDIR)==0 ) { + totsel++; + } + } + } + + if(last) { + /* of anders een aangegeven file? */ + if(totsel==0 && sfile->file[0]) totsel= 1; + } + + if(totsel==0) return 0; + + /* seq maken */ + seq= alloc_sequence(cfra, machine); + seq->len= totsel; + + if(totsel==1) { + seq->startstill= 25; + seq->endstill= 24; + } + + calc_sequence(seq); + + /* strip en stripdata */ + seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); + strip->len= totsel; + strip->us= 1; + strcpy(strip->dir, sfile->dir); + strip->stripdata= se= MEM_callocN(totsel*sizeof(StripElem), "stripelem"); + + for(a=0; a<sfile->totfile; a++) { + if(sfile->filelist[a].flags & ACTIVE) { + if( (sfile->filelist[a].type & S_IFDIR)==0 ) { + strcpy(se->name, sfile->filelist[a].relname); + se->ok= 1; + se++; + } + } + } + /* geen geselecteerde file: */ + if(totsel==1 && se==strip->stripdata) { + strcpy(se->name, sfile->file); + se->ok= 1; + } + + /* laatste aktieve naam */ + strcpy(last_imagename, seq->strip->dir); + + return seq; +} + +static void sfile_to_mv_sequence(SpaceFile *sfile, int cfra, int machine) +{ + Sequence *seq; + struct anim *anim; + Strip *strip; + StripElem *se; + int totframe, a; + char str[256]; + + totframe= 0; + + strcpy(str, sfile->dir); + strcat(str, sfile->file); + + /* is er sprake van een movie */ + anim = openanim(str, IB_rect); + if(anim==0) { + error("Not a movie"); + return; + } + + totframe= IMB_anim_get_duration(anim); + + /* seq maken */ + seq= alloc_sequence(cfra, machine); + seq->len= totframe; + seq->type= SEQ_MOVIE; + seq->anim= anim; + + calc_sequence(seq); + + /* strip en stripdata */ + seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); + strip->len= totframe; + strip->us= 1; + strcpy(strip->dir, sfile->dir); + strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem"); + + /* naam movie in eerste strip */ + strcpy(se->name, sfile->file); + + for(a=1; a<=totframe; a++, se++) { + se->ok= 1; + se->nr= a; + } + + /* laatste aktieve naam */ + strcpy(last_imagename, seq->strip->dir); +} + +static void add_image_strips(char *name) +{ + SpaceFile *sfile; + struct direntry *files; + float x, y; + int a, totfile, cfra, machine; + short mval[2]; + + deselect_all_seq(); + + /* is voor restore windowmatrices */ + areawinset(curarea->win); + drawseqspace(); + + /* sfile zoeken */ + sfile= scrarea_find_space_of_type(curarea, SPACE_FILE); + if(sfile==0) return; + + /* waar komen ze */ + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + cfra= (int)(x+0.5); + machine= (int)(y+0.5); + + waitcursor(1); + + /* ook inhoud van geselecteerde directories lezen */ + files= sfile->filelist; + totfile= sfile->totfile; + sfile->filelist= 0; + sfile->totfile= 0; + + for(a=0; a<totfile; a++) { + if(files[a].flags & ACTIVE) { + if( (files[a].type & S_IFDIR) ) { + strcat(sfile->dir, files[a].relname); + strcat(sfile->dir,"/"); + read_dir(sfile); + + /* selecteer alles */ + swapselect_file(sfile); + + if ( sfile_to_sequence(sfile, cfra, machine, 0) ) machine++; + + parent(sfile); + } + } + } + + sfile->filelist= files; + sfile->totfile= totfile; + + /* directory zelf lezen */ + sfile_to_sequence(sfile, cfra, machine, 1); + + waitcursor(0); + + transform_seq('g'); + +} + +static void add_movie_strip(char *name) +{ + SpaceFile *sfile; + float x, y; + int cfra, machine; + short mval[2]; + + deselect_all_seq(); + + /* is voor restore windowmatrices */ + areawinset(curarea->win); + drawseqspace(); + + /* sfile zoeken */ + sfile= scrarea_find_space_of_type(curarea, SPACE_FILE); + if(sfile==0) return; + + /* waar komen ze */ + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + cfra= (int)(x+0.5); + machine= (int)(y+0.5); + + waitcursor(1); + + /* directory zelf lezen */ + sfile_to_mv_sequence(sfile, cfra, machine); + + waitcursor(0); + + transform_seq('g'); + +} + +static void reload_image_strip(char *name) +{ + Editing *ed; + Sequence *seq, *seqact; + SpaceFile *sfile; + + ed= G.scene->ed; + + if(last_seq==0 || last_seq->type!=SEQ_IMAGE) return; + seqact= last_seq; /* last_seq verandert in alloc_sequence */ + + /* sfile zoeken */ + sfile= scrarea_find_space_of_type(curarea, SPACE_FILE); + if(sfile==0) return; + + waitcursor(1); + + seq= sfile_to_sequence(sfile, seqact->start, seqact->machine, 1); + if(seq && seq!=seqact) { + free_strip(seqact->strip); + + seqact->strip= seq->strip; + + seqact->len= seq->len; + calc_sequence(seqact); + + seq->strip= 0; + free_sequence(seq); + BLI_remlink(ed->seqbasep, seq); + + seq= ed->seqbasep->first; + while(seq) { + if(seq->type & SEQ_EFFECT) { + /* new_stripdata is clear */ + if(seq->seq1==seqact || seq->seq2==seqact || seq->seq3==seqact) { + calc_sequence(seq); + new_stripdata(seq); + } + } + seq= seq->next; + } + } + waitcursor(0); + + allqueue(REDRAWSEQ, 0); +} + +static int event_to_efftype(int event) +{ + if(event==2) return SEQ_CROSS; + if(event==3) return SEQ_GAMCROSS; + if(event==4) return SEQ_ADD; + if(event==5) return SEQ_SUB; + if(event==6) return SEQ_MUL; + if(event==7) return SEQ_ALPHAOVER; + if(event==8) return SEQ_ALPHAUNDER; + if(event==9) return SEQ_OVERDROP; + if(event==10) return SEQ_PLUGIN; + return 0; +} + +static int add_seq_effect(int type) +{ + Editing *ed; + Sequence *seq, *seq1, *seq2, *seq3; + Strip *strip; + float x, y; + int cfra, machine; + short mval[2]; + + if(G.scene->ed==0) return 0; + ed= G.scene->ed; + + /* behalve de last_seq moet er nog een of twee geselecteerde seq zijn */ + seq1= seq3= 0; + seq2= last_seq; /* last_seq verandert bij alloc_seq! */ + seq= ed->seqbasep->first; + while(seq) { + if(seq->flag & SELECT) { + if(seq != seq2) { + if(seq1==0) seq1= seq; + else if(seq3==0) seq3= seq; + else { + seq1= 0; + break; + } + } + } + seq= seq->next; + } + + if(type==10) { /* plugin: minimaal 1 select */ + if(seq2==0) { + error("Need minimum one active sequence"); + return 0; + } + if(seq1==0) seq1= seq2; + if(seq3==0) seq3= seq2; + } + else { + if(seq1==0 || seq2==0) { + error("Need 2 selected sequences"); + return 0; + } + if(seq3==0) seq3= seq2; + } + + deselect_all_seq(); + + /* waar komt ie (cfra is eigenlijk niet nodig) */ + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + cfra= (int)(x+0.5); + machine= (int)(y+0.5); + + seq= alloc_sequence(cfra, machine); + + seq->type= event_to_efftype(type); + + if(seq->type==SEQ_ALPHAUNDER || seq->type==SEQ_ALPHAOVER) { + seq->seq2= seq1; + seq->seq1= seq2; + } + else { + seq->seq1= seq1; + seq->seq2= seq2; + } + seq->seq3= seq3; + calc_sequence(seq); + + seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); + strip->len= seq->len; + strip->us= 1; + if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); + + return 1; +} + +static void load_plugin_seq(char *str) /* aangeroepen vanuit fileselect */ +{ +/* extern Sequence *last_seq; already present in this file... */ + Editing *ed; + + add_seq_effect(10); /* deze zet last_seq */ + + free_plugin_seq(last_seq->plugin); + + last_seq->plugin= (PluginSeq *)add_plugin_seq(str, last_seq->name+2); + + if(last_seq->plugin==0) { + ed= G.scene->ed; + BLI_remlink(ed->seqbasep, last_seq); + free_sequence(last_seq); + last_seq= 0; + } + else { + last_seq->machine= MAX3(last_seq->seq1->machine, last_seq->seq2->machine, last_seq->seq3->machine); + if( test_overlap_seq(last_seq) ) shuffle_seq(last_seq); + + transform_seq('g'); + } +} + +void add_sequence(int type) +{ + Editing *ed; + Sequence *seq; + Strip *strip; + Scene *sce; + float x, y; + int cfra, machine; + short nr, event, mval[2]; + char *str; + + event= pupmenu("Add sequence%t|Images%x1|Movie%x102|Scene%x101|Plugin%x10|Cross%x2|GammaCross%x3|Add%x4|Sub%x5|Mul%x6|AlphaOver%x7|AlphaUnder%x8|AlphaOverDrop%x9"); + + if(event<1) return; + + if(G.scene->ed==0) { + ed= G.scene->ed= MEM_callocN( sizeof(Editing), "addseq"); + ed->seqbasep= &ed->seqbase; + } + else ed= G.scene->ed; + + switch(event) { + case 1: + + activate_fileselect(FILE_SPECIAL, "SELECT IMAGES", last_imagename, add_image_strips); + break; + case 102: + + activate_fileselect(FILE_SPECIAL, "SELECT MOVIE", last_imagename, add_movie_strip); + break; + case 101: + /* nieuwe menu: */ + IDnames_to_pupstring(&str, NULL, NULL, &G.main->scene, (ID *)G.scene, &nr); + + event= pupmenu(str); + + if(event> -1) { + nr= 1; + sce= G.main->scene.first; + while(sce) { + if( event==nr) break; + nr++; + sce= sce->id.next; + } + if(sce) { + + deselect_all_seq(); + + /* waar komt ie ? */ + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + cfra= (int)(x+0.5); + machine= (int)(y+0.5); + + seq= alloc_sequence(cfra, machine); + seq->type= SEQ_SCENE; + seq->scene= sce; + seq->sfra= sce->r.sfra; + seq->len= sce->r.efra - sce->r.sfra + 1; + + seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); + strip->len= seq->len; + strip->us= 1; + if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); + + transform_seq('g'); + } + } + MEM_freeN(str); + + break; + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + + if(last_seq==0) error("Need minimum one active sequence"); + else if(event==10) { + activate_fileselect(FILE_SPECIAL, "SELECT PLUGIN", U.plugseqdir, load_plugin_seq); + } + else { + if( add_seq_effect(event) ) transform_seq('g'); + } + + break; + } +} + +void change_sequence(void) +{ + Scene *sce; + short event; + + if(last_seq==0) return; + + if(last_seq->type & SEQ_EFFECT) { + event= pupmenu("Change effect%t|Switch a-b %x1|Switch b-c %x10|Plugin%x11|Recalculate%x12|Cross%x2|GammaCross%x3|Add%x4|Sub%x5|Mul%x6|AlphaOver%x7|AlphaUnder%x8|AlphaOverdrop%x9"); + if(event>0) { + if(event==1) { + SWAP(Sequence *, last_seq->seq1, last_seq->seq2); + } + else if(event==10) { + SWAP(Sequence *, last_seq->seq2, last_seq->seq3); + } + else if(event==11) { + activate_fileselect(FILE_SPECIAL, "SELECT PLUGIN", U.plugseqdir, change_plugin_seq); + } + else if(event==12); /* recalculate: alleen new_stripdata */ + else { + /* voor zekerheid plugin vrijgeven */ + free_plugin_seq(last_seq->plugin); + last_seq->plugin= 0; + last_seq->type= event_to_efftype(event); + } + new_stripdata(last_seq); + allqueue(REDRAWSEQ, 0); + } + } + else if(last_seq->type == SEQ_IMAGE) { + if(okee("Change images")) { + activate_fileselect(FILE_SPECIAL, "SELECT IMAGES", last_imagename, reload_image_strip); + } + } + else if(last_seq->type == SEQ_MOVIE) { + ; + } + else if(last_seq->type == SEQ_SCENE) { + event= pupmenu("Change Scene%t|Update Start and End"); + + if(event==1) { + sce= last_seq->scene; + + last_seq->len= sce->r.efra - sce->r.sfra + 1; + last_seq->sfra= sce->r.sfra; + new_stripdata(last_seq); + calc_sequence(last_seq); + + allqueue(REDRAWSEQ, 0); + } + } + +} + +static int is_a_sequence(Sequence *test) +{ + Sequence *seq; + Editing *ed; + + ed= G.scene->ed; + if(ed==0 || test==0) return 0; + + seq= ed->seqbasep->first; + while(seq) { + if(seq==test) return 1; + seq= seq->next; + } + + return 0; +} + +static void recurs_del_seq(ListBase *lb) +{ + Sequence *seq, *seqn; + + seq= lb->first; + while(seq) { + seqn= seq->next; + if(seq->flag & SELECT) { + BLI_remlink(lb, seq); + if(seq==last_seq) last_seq= 0; + if(seq->type==SEQ_META) recurs_del_seq(&seq->seqbase); + if(seq->ipo) seq->ipo->id.us--; + free_sequence(seq); + } + seq= seqn; + } +} + +void del_seq(void) +{ + Sequence *seq, *seqn; + MetaStack *ms; + Editing *ed; + int doit; + + if(okee("Erase selected")==0) return; + + ed= G.scene->ed; + if(ed==0) return; + + recurs_del_seq(ed->seqbasep); + + /* effecten testen */ + doit= 1; + while(doit) { + doit= 0; + seq= ed->seqbasep->first; + while(seq) { + seqn= seq->next; + if(seq->type & SEQ_EFFECT) { + if( is_a_sequence(seq->seq1)==0 || is_a_sequence(seq->seq2)==0 || is_a_sequence(seq->seq3)==0 ) { + BLI_remlink(ed->seqbasep, seq); + if(seq==last_seq) last_seq= 0; + free_sequence(seq); + doit= 1; + } + } + seq= seqn; + } + } + + /* lengtes en zo updaten */ + seq= ed->seqbasep->first; + while(seq) { + calc_sequence(seq); + seq= seq->next; + } + + /* parent meta's vrijgeven */ + ms= ed->metastack.last; + while(ms) { + ms->parseq->strip->len= 0; /* forceer nieuwe alloc */ + calc_sequence(ms->parseq); + ms= ms->prev; + } + + allqueue(REDRAWSEQ, 0); +} + + + +static void recurs_dupli_seq(ListBase *old, ListBase *new) +{ + Sequence *seq, *seqn; + StripElem *se; + int a; + + seq= old->first; + + while(seq) { + seq->newseq= 0; + if(seq->flag & SELECT) { + + if(seq->type==SEQ_META) { + seqn= MEM_dupallocN(seq); + seq->newseq= seqn; + BLI_addtail(new, seqn); + + seqn->strip= MEM_dupallocN(seq->strip); + + if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); + + seq->flag &= SEQ_DESEL; + seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL); + + seqn->seqbase.first= seqn->seqbase.last= 0; + recurs_dupli_seq(&seq->seqbase, &seqn->seqbase); + + } + else if(seq->type == SEQ_SCENE) { + seqn= MEM_dupallocN(seq); + seq->newseq= seqn; + BLI_addtail(new, seqn); + + seqn->strip= MEM_dupallocN(seq->strip); + + if(seq->len>0) seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); + + seq->flag &= SEQ_DESEL; + seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL); + } + else if(seq->type == SEQ_MOVIE) { + seqn= MEM_dupallocN(seq); + seq->newseq= seqn; + BLI_addtail(new, seqn); + + seqn->strip= MEM_dupallocN(seq->strip); + seqn->anim= 0; + + if(seqn->len>0) { + seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); + /* kopie eerste elem */ + *seqn->strip->stripdata= *seq->strip->stripdata; + se= seqn->strip->stripdata; + a= seq->len; + while(a--) { + se->ok= 1; + se++; + } + } + + seq->flag &= SEQ_DESEL; + seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL); + } + else if(seq->type < SEQ_EFFECT) { + seqn= MEM_dupallocN(seq); + seq->newseq= seqn; + BLI_addtail(new, seqn); + + seqn->strip->us++; + seq->flag &= SEQ_DESEL; + + seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL); + } + else { + if(seq->seq1->newseq) { + + seqn= MEM_dupallocN(seq); + seq->newseq= seqn; + BLI_addtail(new, seqn); + + seqn->seq1= seq->seq1->newseq; + if(seq->seq2 && seq->seq2->newseq) seqn->seq2= seq->seq2->newseq; + if(seq->seq3 && seq->seq3->newseq) seqn->seq3= seq->seq3->newseq; + + if(seqn->ipo) seqn->ipo->id.us++; + + if(seq->plugin) { + seqn->plugin= MEM_dupallocN(seq->plugin); + open_plugin_seq(seqn->plugin, seqn->name+2); + } + seqn->strip= MEM_dupallocN(seq->strip); + + if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); + + seq->flag &= SEQ_DESEL; + + seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL); + } + } + + } + seq= seq->next; + } +} + +void add_duplicate_seq(void) +{ + Editing *ed; + ListBase new; + + ed= G.scene->ed; + if(ed==0) return; + + new.first= new.last= 0; + + recurs_dupli_seq(ed->seqbasep, &new); + addlisttolist(ed->seqbasep, &new); + + transform_seq('g'); +} + +int insert_gap(int gap, int cfra) +{ + Sequence *seq; + Editing *ed; + int done=0; + + /* alle strips >= cfra opschuiven */ + ed= G.scene->ed; + if(ed==0) return 0; + + WHILE_SEQ(ed->seqbasep) { + if(seq->startdisp >= cfra) { + seq->start+= gap; + calc_sequence(seq); + done= 1; + } + } + END_SEQ + + return done; +} + +void touch_seq_files(void) +{ + Sequence *seq; + Editing *ed; +/* int done=0; */ + char str[256]; + + /* alle strips movies touchen */ + ed= G.scene->ed; + if(ed==0) return; + + if(okee("Touch & print selected Movies")==0) return; + + waitcursor(1); + + WHILE_SEQ(ed->seqbasep) { + if(seq->flag & SELECT) { + if(seq->type==SEQ_MOVIE) { + if(seq->strip && seq->strip->stripdata) { + BLI_make_file_string(G.sce, str, seq->strip->dir, seq->strip->stripdata->name); + BLI_touch(seq->name); + } + } + + } + } + END_SEQ + + waitcursor(0); +} + +void set_filter_seq(void) +{ + Sequence *seq; + Editing *ed; +/* int done=0; */ + + ed= G.scene->ed; + if(ed==0) return; + + if(okee("Set FilterY")==0) return; + + WHILE_SEQ(ed->seqbasep) { + if(seq->flag & SELECT) { + if(seq->type==SEQ_MOVIE) { + seq->flag |= SEQ_FILTERY; + } + + } + } + END_SEQ + +} + + + +void no_gaps(void) +{ + Editing *ed; + int cfra, first= 0, done; + + ed= G.scene->ed; + if(ed==0) return; + + for(cfra= CFRA; cfra<=EFRA; cfra++) { + if(first==0) { + if( evaluate_seq_frame(cfra) ) first= 1; + } + else { + done= 1; + while( evaluate_seq_frame(cfra) == 0) { + done= insert_gap(-1, cfra); + if(done==0) break; + } + if(done==0) break; + } + } + allqueue(REDRAWSEQ, 0); +} + + +/* ****************** META ************************* */ + +void make_meta(void) +{ + Sequence *seq, *seqm, *next; + Editing *ed; + int tot; + + ed= G.scene->ed; + if(ed==0) return; + + /* is er wel meer dan 1 select */ + tot= 0; + seq= ed->seqbasep->first; + while(seq) { + if(seq->flag & SELECT) tot++; + seq= seq->next; + } + if(tot < 2) return; + + if(okee("Make Meta")==0) return; + + /* samenhang testen */ + seq= ed->seqbasep->first; + while(seq) { + if(seq->flag & SELECT) { + if(seq->type & SEQ_EFFECT) { + if((seq->seq1->flag & SELECT)==0) tot= 0; + if((seq->seq2->flag & SELECT)==0) tot= 0; + if((seq->seq3->flag & SELECT)==0) tot= 0; + } + } + else if(seq->type & SEQ_EFFECT) { + if(seq->seq1->flag & SELECT) tot= 0; + if(seq->seq2->flag & SELECT) tot= 0; + if(seq->seq3->flag & SELECT) tot= 0; + } + if(tot==0) break; + seq= seq->next; + } + if(tot==0) { + error("Select all related strips"); + return; + } + + /* alle select uit hoofdlijst halen en in meta stoppen */ + + seqm= alloc_sequence(1, 1); + seqm->type= SEQ_META; + seqm->flag= SELECT; + + seq= ed->seqbasep->first; + while(seq) { + next= seq->next; + if(seq!=seqm && (seq->flag & SELECT)) { + BLI_remlink(ed->seqbasep, seq); + BLI_addtail(&seqm->seqbase, seq); + } + seq= next; + } + calc_sequence(seqm); + + seqm->strip= MEM_callocN(sizeof(Strip), "metastrip"); + seqm->strip->len= seqm->len; + seqm->strip->us= 1; + if(seqm->len) seqm->strip->stripdata= MEM_callocN(seqm->len*sizeof(StripElem), "metastripdata"); + + set_meta_stripdata(seqm); + + allqueue(REDRAWSEQ, 0); +} + +void un_meta(void) +{ + Editing *ed; + Sequence *seq, *seqn; + int doit; + + ed= G.scene->ed; + if(ed==0) return; + + if(last_seq==0 || last_seq->type!=SEQ_META) return; + + if(okee("Un Meta")==0) return; + + addlisttolist(ed->seqbasep, &last_seq->seqbase); + + last_seq->seqbase.first= 0; + last_seq->seqbase.last= 0; + + BLI_remlink(ed->seqbasep, last_seq); + free_sequence(last_seq); + + /* effecten testen */ + doit= 1; + while(doit) { + doit= 0; + seq= ed->seqbasep->first; + while(seq) { + seqn= seq->next; + if(seq->type & SEQ_EFFECT) { + if( is_a_sequence(seq->seq1)==0 || is_a_sequence(seq->seq2)==0 || is_a_sequence(seq->seq3)==0 ) { + BLI_remlink(ed->seqbasep, seq); + if(seq==last_seq) last_seq= 0; + free_sequence(seq); + doit= 1; + } + } + seq= seqn; + } + } + + + /* testen op effects en overlap */ + WHILE_SEQ(ed->seqbasep) { + if(seq->flag & SELECT) { + seq->flag &= ~SEQ_OVERLAP; + if( test_overlap_seq(seq) ) { + shuffle_seq(seq); + } + } + } + END_SEQ; + + allqueue(REDRAWSEQ, 0); + +} + +static void exit_meta(void) +{ + Sequence *seq; + MetaStack *ms; + Editing *ed; + + ed= G.scene->ed; + if(ed==0) return; + + if(ed->metastack.first==0) return; + + ms= ed->metastack.last; + BLI_remlink(&ed->metastack, ms); + + ed->seqbasep= ms->oldbasep; + + /* de hele meta herberekenen */ + set_meta_stripdata(ms->parseq); + + /* allemaal herberekenen: de meta kan effecten eraan hebben hangen */ + seq= ed->seqbasep->first; + while(seq) { + calc_sequence(seq); + seq= seq->next; + } + + last_seq= ms->parseq; + + last_seq->flag= SELECT; + recurs_sel_seq(last_seq); + + MEM_freeN(ms); + allqueue(REDRAWSEQ, 0); +} + + +void enter_meta(void) +{ + MetaStack *ms; + Editing *ed; + + ed= G.scene->ed; + if(ed==0) return; + + if(last_seq==0 || last_seq->type!=SEQ_META || last_seq->flag==0) { + exit_meta(); + return; + } + + ms= MEM_mallocN(sizeof(MetaStack), "metastack"); + BLI_addtail(&ed->metastack, ms); + ms->parseq= last_seq; + ms->oldbasep= ed->seqbasep; + + ed->seqbasep= &last_seq->seqbase; + + last_seq= 0; + allqueue(REDRAWSEQ, 0); +} + + +/* ****************** END META ************************* */ + + +typedef struct TransSeq { + int start, machine; + int startstill, endstill; + int startofs, endofs; +} TransSeq; + +void transform_seq(int mode) +{ + Sequence *seq; + Editing *ed; + float dx, dy, dvec[2], div; + TransSeq *transmain, *ts; + int tot=0, ix, iy, firsttime=1, afbreek=0, midtog= 0, proj= 0; + unsigned short event = 0; + short mval[2], val, xo, yo, xn, yn; + char str[32]; + + if(mode!='g') return; /* vanuit gesture */ + + /* welke seqs doen mee */ + ed= G.scene->ed; + if(ed==0) return; + + WHILE_SEQ(ed->seqbasep) { + if(seq->flag & SELECT) tot++; + } + END_SEQ + + if(tot==0) return; + + G.moving= 1; + + ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq"); + + WHILE_SEQ(ed->seqbasep) { + + if(seq->flag & SELECT) { + + ts->start= seq->start; + ts->machine= seq->machine; + ts->startstill= seq->startstill; + ts->endstill= seq->endstill; + ts->startofs= seq->startofs; + ts->endofs= seq->endofs; + + ts++; + } + } + END_SEQ + + getmouseco_areawin(mval); + xo=xn= mval[0]; + yo=yn= mval[1]; + dvec[0]= dvec[1]= 0.0; + + while(afbreek==0) { + getmouseco_areawin(mval); + if(mval[0]!=xo || mval[1]!=yo || firsttime) { + firsttime= 0; + + if(mode=='g') { + + dx= mval[0]- xo; + dy= mval[1]- yo; + + div= G.v2d->mask.xmax-G.v2d->mask.xmin; + dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div; + + div= G.v2d->mask.ymax-G.v2d->mask.ymin; + dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div; + + if(G.qual & LR_SHIFTKEY) { + if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0; + } + + dvec[0]+= dx; + dvec[1]+= dy; + + if(midtog) dvec[proj]= 0.0; + ix= floor(dvec[0]+0.5); + iy= floor(dvec[1]+0.5); + + + ts= transmain; + + WHILE_SEQ(ed->seqbasep) { + if(seq->flag & SELECT) { + if(seq->flag & SEQ_LEFTSEL) { + if(ts->startstill) { + seq->startstill= ts->startstill-ix; + if(seq->startstill<0) seq->startstill= 0; + } + else if(ts->startofs) { + seq->startofs= ts->startofs+ix; + if(seq->startofs<0) seq->startofs= 0; + } + else { + if(ix>0) { + seq->startofs= ix; + seq->startstill= 0; + } + else { + seq->startstill= -ix; + seq->startofs= 0; + } + } + if(seq->len <= seq->startofs+seq->endofs) { + seq->startofs= seq->len-seq->endofs-1; + } + } + if(seq->flag & SEQ_RIGHTSEL) { + if(ts->endstill) { + seq->endstill= ts->endstill+ix; + if(seq->endstill<0) seq->endstill= 0; + } + else if(ts->endofs) { + seq->endofs= ts->endofs-ix; + if(seq->endofs<0) seq->endofs= 0; + } + else { + if(ix<0) { + seq->endofs= -ix; + seq->endstill= 0; + } + else { + seq->endstill= ix; + seq->endofs= 0; + } + } + if(seq->len <= seq->startofs+seq->endofs) { + seq->endofs= seq->len-seq->startofs-1; + } + } + if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) { + if(seq->type<SEQ_EFFECT) seq->start= ts->start+ ix; + + if(seq->depth==0) seq->machine= ts->machine+ iy; + + if(seq->machine<1) seq->machine= 1; + else if(seq->machine>= MAXSEQ) seq->machine= MAXSEQ; + } + + calc_sequence(seq); + + ts++; + } + } + END_SEQ + + sprintf(str, "X: %d Y: %d ", ix, iy); + headerprint(str); + } + + xo= mval[0]; + yo= mval[1]; + + /* testen op effect en overlap */ + + WHILE_SEQ(ed->seqbasep) { + if(seq->flag & SELECT) { + seq->flag &= ~SEQ_OVERLAP; + if( test_overlap_seq(seq) ) { + seq->flag |= SEQ_OVERLAP; + } + } + else if(seq->type & SEQ_EFFECT) { + if(seq->seq1->flag & SELECT) calc_sequence(seq); + else if(seq->seq2->flag & SELECT) calc_sequence(seq); + else if(seq->seq3->flag & SELECT) calc_sequence(seq); + } + } + END_SEQ; + + force_draw(); + } + else BIF_wait_for_statechange(); + + while(qtest()) { + event= extern_qread(&val); + if(val) { + switch(event) { + case ESCKEY: + case LEFTMOUSE: + case SPACEKEY: + afbreek= 1; + break; + case MIDDLEMOUSE: + midtog= ~midtog; + if(midtog) { + if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1; + else proj= 0; + firsttime= 1; + } + break; + default: + arrows_move_cursor(event); + } + } + if(afbreek) break; + } + } + + if(event==ESCKEY) { + + ts= transmain; + WHILE_SEQ(ed->seqbasep) { + if(seq->flag & SELECT) { + seq->start= ts->start; + seq->machine= ts->machine; + seq->startstill= ts->startstill; + seq->endstill= ts->endstill; + seq->startofs= ts->startofs; + seq->endofs= ts->endofs; + + calc_sequence(seq); + seq->flag &= ~SEQ_OVERLAP; + + ts++; + } else if(seq->type & SEQ_EFFECT) { + if(seq->seq1->flag & SELECT) calc_sequence(seq); + else if(seq->seq2->flag & SELECT) calc_sequence(seq); + else if(seq->seq3->flag & SELECT) calc_sequence(seq); + } + + } + END_SEQ + } + else { + + /* images, effecten en overlap */ + WHILE_SEQ(ed->seqbasep) { + if(seq->type == SEQ_META) { + calc_sequence(seq); + seq->flag &= ~SEQ_OVERLAP; + if( test_overlap_seq(seq) ) shuffle_seq(seq); + } + else if(seq->flag & SELECT) { + calc_sequence(seq); + seq->flag &= ~SEQ_OVERLAP; + if( test_overlap_seq(seq) ) shuffle_seq(seq); + } + else if(seq->type & SEQ_EFFECT) calc_sequence(seq); + } + END_SEQ + + /* als laatste: */ + sort_seq(); + } + + G.moving= 0; + MEM_freeN(transmain); + + allqueue(REDRAWSEQ, 0); +} + + +void clever_numbuts_seq(void) +{ + PluginSeq *pis; + StripElem *se; + VarStruct *varstr; + int a; + + if(last_seq==0) return; + if(last_seq->type==SEQ_PLUGIN) { + pis= last_seq->plugin; + if(pis->vars==0) return; + + varstr= pis->varstr; + if(varstr) { + for(a=0; a<pis->vars; a++, varstr++) { + add_numbut(a, varstr->type, varstr->name, varstr->min, varstr->max, &(pis->data[a]), varstr->tip); + } + + if( do_clever_numbuts(pis->pname, pis->vars, REDRAW) ) { + new_stripdata(last_seq); + free_imbuf_effect_spec(CFRA); + allqueue(REDRAWSEQ, 0); + } + } + } + else if(last_seq->type==SEQ_MOVIE) { + + if(last_seq->mul==0.0) last_seq->mul= 1.0; + + add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0); + add_numbut(1, TOG|SHO|BIT|4, "FilterY", 0.0, 1.0, &last_seq->flag, 0); + /* waarschuwing: alleen een enkele bitjes-button mogelijk: er wordt op kopiedata gewerkt! */ + add_numbut(2, NUM|FLO, "Mul", 0.01, 5.0, &last_seq->mul, 0); + + if( do_clever_numbuts("Movie", 3, REDRAW) ) { + se= last_seq->curelem; + + if(se && se->ibuf ) { + IMB_freeImBuf(se->ibuf); + se->ibuf= 0; + } + allqueue(REDRAWSEQ, 0); + } + } + else if(last_seq->type==SEQ_META) { + + add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0); + + if( do_clever_numbuts("Meta", 1, REDRAW) ) { + allqueue(REDRAWSEQ, 0); + } + } +} + +void seq_snapmenu(void) +{ + Editing *ed; + Sequence *seq; + short event; + + ed= G.scene->ed; + if(ed==0) return; + + event= pupmenu("Snap %t|Seq to frame%x1"); + + if(event<1) return; + + /* problem: contents of meta's are all shifted to the same position... */ + + /* ook meta's aflopen */ + WHILE_SEQ(ed->seqbasep) { + if(seq->flag & SELECT) { + if(seq->type<SEQ_EFFECT) seq->start= CFRA-seq->startofs+seq->startstill; + calc_sequence(seq); + } + } + END_SEQ + + + /* testen op effects en overlap */ + WHILE_SEQ(ed->seqbasep) { + if(seq->flag & SELECT) { + seq->flag &= ~SEQ_OVERLAP; + if( test_overlap_seq(seq) ) { + shuffle_seq(seq); + } + } + else if(seq->type & SEQ_EFFECT) { + if(seq->seq1->flag & SELECT) calc_sequence(seq); + else if(seq->seq2->flag & SELECT) calc_sequence(seq); + else if(seq->seq3->flag & SELECT) calc_sequence(seq); + } + } + END_SEQ; + + /* als laatste: */ + sort_seq(); + + allqueue(REDRAWSEQ, 0); +} + +void borderselect_seq(void) +{ + Sequence *seq; + Editing *ed; + rcti rect; + rctf rectf, rq; + int val; + short mval[2]; + + ed= G.scene->ed; + if(ed==0) return; + + val= get_border(&rect, 3); + + if(val) { + mval[0]= rect.xmin; + mval[1]= rect.ymin; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + mval[0]= rect.xmax; + mval[1]= rect.ymax; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + seq= ed->seqbasep->first; + while(seq) { + + if(seq->startstill) rq.xmin= seq->start; + else rq.xmin= seq->startdisp; + rq.ymin= seq->machine+0.2; + if(seq->endstill) rq.xmax= seq->start+seq->len; + else rq.xmax= seq->enddisp; + rq.ymax= seq->machine+0.8; + + if(BLI_isect_rctf(&rq, &rectf, 0)) { + if(val==LEFTMOUSE) { + seq->flag |= SELECT; + } + else { + seq->flag &= ~SELECT; + } + } + + seq= seq->next; + } + + addqueue(curarea->win, REDRAW, 1); + } +} diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c new file mode 100644 index 00000000000..3aa2f43d19f --- /dev/null +++ b/source/blender/src/editsima.c @@ -0,0 +1,905 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <math.h> + +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "IMB_imbuf_types.h" + +#include "DNA_mesh_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" +#include "DNA_space_types.h" +#include "DNA_image_types.h" +#include "DNA_object_types.h" // only for uvedit_selectionCB() (struct Object) + +#include "BKE_global.h" +#include "BKE_mesh.h" + +#include "BIF_gl.h" +#include "BIF_interface.h" +#include "BIF_screen.h" +#include "BIF_drawimage.h" +#include "BIF_editview.h" +#include "BIF_space.h" +#include "BIF_editsima.h" +#include "BIF_toolbox.h" +#include "BIF_mywindow.h" + +#include "BSE_drawipo.h" +#include "BSE_edit.h" +#include "BSE_trans_types.h" + +#include "BDR_editobject.h" + +#include "blendef.h" +#include "mydevice.h" +#include "interface.h" + +static int is_uv_tface_editing_allowed(void) +{ + Mesh *me; + + if(G.obedit) {error("Unable to perform function in EditMode"); return 0;} + if(G.sima->mode!=SI_TEXTURE) return 0; + if(!(G.f & G_FACESELECT)) return 0; + me= get_mesh(OBACT); + if(me==0 || me->tface==0) return 0; + + return 1; +} + +void clever_numbuts_sima(void) +{ + float ocent[2], cent[2]= {0.0, 0.0}; + int imx, imy; + int i, nactive= 0; + Mesh *me; + + if( is_uv_tface_editing_allowed()==0 ) return; + me= get_mesh(OBACT); + + if (G.sima->image && G.sima->image->ibuf) { + imx= G.sima->image->ibuf->x; + imy= G.sima->image->ibuf->y; + } else + imx= imy= 256; + + for (i=0; i<me->totface; i++) { + MFace *mf= &((MFace*) me->mface)[i]; + TFace *tf= &((TFace*) me->tface)[i]; + + if (!mf->v3 || !(tf->flag & TF_SELECT)) + continue; + + if (tf->flag & TF_SEL1) { + cent[0]+= tf->uv[0][0]; + cent[1]+= tf->uv[0][1]; + nactive++; + } + if (tf->flag & TF_SEL2) { + cent[0]+= tf->uv[1][0]; + cent[1]+= tf->uv[1][1]; + nactive++; + } + if (tf->flag & TF_SEL3) { + cent[0]+= tf->uv[2][0]; + cent[1]+= tf->uv[2][1]; + nactive++; + } + if (mf->v4 && (tf->flag & TF_SEL4)) { + cent[0]+= tf->uv[3][0]; + cent[1]+= tf->uv[3][1]; + nactive++; + } + } + + if (nactive) { + cent[0]= (cent[0]*imx)/nactive; + cent[1]= (cent[1]*imy)/nactive; + + add_numbut(0, NUM|FLO, "LocX:", -imx*20, imx*20, ¢[0], NULL); + add_numbut(1, NUM|FLO, "LocY:", -imy*20, imy*20, ¢[1], NULL); + + ocent[0]= cent[0]; + ocent[1]= cent[1]; + if (do_clever_numbuts((nactive==1)?"Active Vertex":"Selected Center", 2, REDRAW)) { + float delta[2]; + + delta[0]= (cent[0]-ocent[0])/imx; + delta[1]= (cent[1]-ocent[1])/imy; + + for (i=0; i<me->totface; i++) { + MFace *mf= &((MFace*) me->mface)[i]; + TFace *tf= &((TFace*) me->tface)[i]; + + if (!mf->v3 || !(tf->flag & TF_SELECT)) + continue; + + if (tf->flag & TF_SEL1) { + tf->uv[0][0]+= delta[0]; + tf->uv[0][1]+= delta[1]; + } + if (tf->flag & TF_SEL2) { + tf->uv[1][0]+= delta[0]; + tf->uv[1][1]+= delta[1]; + } + if (tf->flag & TF_SEL3) { + tf->uv[2][0]+= delta[0]; + tf->uv[2][1]+= delta[1]; + } + if (mf->v4 && (tf->flag & TF_SEL4)) { + tf->uv[3][0]+= delta[0]; + tf->uv[3][1]+= delta[1]; + } + } + + allqueue(REDRAWVIEW3D, 0); + } + } +} + +static void sima_pixelgrid(float *loc, float sx, float sy) +{ + float y; + float x; + + if(G.sima->image && G.sima->image->ibuf) { + x= G.sima->image->ibuf->x; + y= G.sima->image->ibuf->y; + + sx= floor(x*sx)/x; + if(G.sima->flag & SI_CLIP_UV) { + CLAMP(sx, 0, 1.0); + } + loc[0]= sx; + + sy= floor(y*sy)/y; + if(G.sima->flag & SI_CLIP_UV) { + CLAMP(sy, 0, 1.0); + } + loc[1]= sy; + } + else { + loc[0]= sx; + loc[1]= sy; + } +} + + +static void be_square_tface_uv(Mesh *me) +{ + TFace *tface; + MFace *mface; + int a; + + /* als 1 punt select: doit (met het select punt) */ + for(a=me->totface, mface= me->mface, tface= me->tface; a>0; a--, tface++, mface++) { + if(mface->v4) { + if(tface->flag & TF_SELECT) { + if(tface->flag & TF_SEL1) { + if( tface->uv[1][0] == tface->uv[2][0] ) { + tface->uv[1][1]= tface->uv[0][1]; + tface->uv[3][0]= tface->uv[0][0]; + } + else { + tface->uv[1][0]= tface->uv[0][0]; + tface->uv[3][1]= tface->uv[0][1]; + } + + } + if(tface->flag & TF_SEL2) { + if( tface->uv[2][1] == tface->uv[3][1] ) { + tface->uv[2][0]= tface->uv[1][0]; + tface->uv[0][1]= tface->uv[1][1]; + } + else { + tface->uv[2][1]= tface->uv[1][1]; + tface->uv[0][0]= tface->uv[1][0]; + } + + } + if(tface->flag & TF_SEL3) { + if( tface->uv[3][0] == tface->uv[0][0] ) { + tface->uv[3][1]= tface->uv[2][1]; + tface->uv[1][0]= tface->uv[2][0]; + } + else { + tface->uv[3][0]= tface->uv[2][0]; + tface->uv[1][1]= tface->uv[2][1]; + } + } + if(tface->flag & TF_SEL4) { + if( tface->uv[0][1] == tface->uv[1][1] ) { + tface->uv[0][0]= tface->uv[3][0]; + tface->uv[2][1]= tface->uv[3][1]; + } + else { + tface->uv[0][1]= tface->uv[3][1]; + tface->uv[2][0]= tface->uv[3][0]; + } + + } + } + } + } + +} + +void tface_do_clip(void) +{ + Mesh *me; + TFace *tface; + int a, b; + + if( is_uv_tface_editing_allowed()==0 ) return; + me= get_mesh(OBACT); + tface= me->tface; + + for(a=0; a<me->totface; a++, tface++) { + if(tface->flag & TF_SELECT) { + for(b=0; b<4; b++) { + CLAMP(tface->uv[b][0], 0.0, 1.0); + CLAMP(tface->uv[b][1], 0.0, 1.0); + } + } + } + +} + +void transform_tface_uv(int mode) +{ + MFace *mface; + TFace *tface; + Mesh *me; + TransVert *transmain, *tv; + float asp, dx1, dx2, dy1, dy2, phi, dphi, co, si; + float xref=1.0, yref=1.0, size[2], sizefac; + float dx, dy, dvec2[2], dvec[2], div, cent[2]; + float x, y, min[2], max[2], vec[2], xtra[2], ivec[2]; + int xim, yim, tot=0, a, b, firsttime=1, afbreek=0, midtog= 0, proj = 0; + unsigned short event = 0; + short mval[2], val, xo, yo, xn, yn, xc, yc; + char str[32]; + + if( is_uv_tface_editing_allowed()==0 ) return; + me= get_mesh(OBACT); + + min[0]= min[1]= 10000.0; + max[0]= max[1]= -10000.0; + + calc_image_view(G.sima, 'f'); + + if(G.sima->image && G.sima->image->ibuf) { + xim= G.sima->image->ibuf->x; + yim= G.sima->image->ibuf->y; + } + else { + xim= yim= 256; + } + /* welke vertices doen mee */ + + for(a=me->totface, tface= me->tface, mface= me->mface; a>0; a--, tface++, mface++) { + if((tface->flag & TF_SELECT) && mface->v3) { + if(tface->flag & TF_SEL1) tot++; + if(tface->flag & TF_SEL2) tot++; + if(tface->flag & TF_SEL3) tot++; + if(tface->flag & TF_SEL4) tot++; + } + } + if(tot==0) return; + + tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain"); + + for(a=me->totface, tface= me->tface, mface= me->mface; a>0; a--, tface++, mface++) { + if((tface->flag & TF_SELECT) && mface->v3) { + if(tface->flag & TF_SEL1) { + tv->loc= tface->uv[0]; + tv++; + } + if(tface->flag & TF_SEL2) { + tv->loc= tface->uv[1]; + tv++; + } + if(tface->flag & TF_SEL3) { + tv->loc= tface->uv[2]; + tv++; + } + if(tface->flag & TF_SEL4) { + tv->loc= tface->uv[3]; + tv++; + } + } + } + + a= tot; + tv= transmain; + while(a--) { + tv->oldloc[0]= tv->loc[0]; + tv->oldloc[1]= tv->loc[1]; + DO_MINMAX2(tv->loc, min, max); + tv++; + } + + cent[0]= (min[0]+max[0])/2.0; + cent[1]= (min[1]+max[1])/2.0; + + ipoco_to_areaco_noclip(G.v2d, cent, mval); + xc= mval[0]; + yc= mval[1]; + + getmouseco_areawin(mval); + xo= xn= mval[0]; + yo= yn= mval[1]; + dvec[0]= dvec[1]= 0.0; + dx1= xc-xn; + dy1= yc-yn; + phi= 0.0; + + + sizefac= sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) ); + if(sizefac<2.0) sizefac= 2.0; + + while(afbreek==0) { + getmouseco_areawin(mval); + if(mval[0]!=xo || mval[1]!=yo || firsttime) { + + if(mode=='g') { + + dx= mval[0]- xo; + dy= mval[1]- yo; + + div= G.v2d->mask.xmax-G.v2d->mask.xmin; + dvec[0]+= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div; + + div= G.v2d->mask.ymax-G.v2d->mask.ymin; + dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div; + + if(midtog) dvec[proj]= 0.0; + + dvec2[0]= dvec[0]; + dvec2[1]= dvec[1]; + apply_keyb_grid(dvec2, 0.0, 1.0/8.0, 1.0/16.0, U.flag & AUTOGRABGRID); + apply_keyb_grid(dvec2+1, 0.0, 1.0/8.0, 1.0/16.0, U.flag & AUTOGRABGRID); + + vec[0]= dvec2[0]; + vec[1]= dvec2[1]; + + if(G.sima->flag & SI_CLIP_UV) { + if(vec[0]< -min[0]) vec[0]= -min[0]; + if(vec[1]< -min[1]) vec[1]= -min[1]; + if(vec[0]> 1.0-max[0]) vec[0]= 1.0-max[0]; + if(vec[1]> 1.0-max[1]) vec[1]= 1.0-max[1]; + } + tv= transmain; + for(a=0; a<tot; a++, tv++) { + + x= tv->oldloc[0]+vec[0]; + y= tv->oldloc[1]+vec[1]; + + sima_pixelgrid(tv->loc, x, y); + } + ivec[0]= (vec[0]*xim); + ivec[1]= (vec[1]*yim); + + if(G.sima->flag & SI_BE_SQUARE) be_square_tface_uv(me); + + sprintf(str, "X: %.4f Y: %.4f ", ivec[0], ivec[1]); + headerprint(str); + } + else if(mode=='r') { + + dx2= xc-mval[0]; + dy2= yc-mval[1]; + + div= sqrt( (dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2)); + if(div>1.0) { + + dphi= (dx1*dx2+dy1*dy2)/div; + dphi= saacos(dphi); + if( (dx1*dy2-dx2*dy1)<0.0 ) dphi= -dphi; + + if(G.qual & LR_SHIFTKEY) phi+= dphi/30.0; + else phi+= dphi; + + apply_keyb_grid(&phi, 0.0, (5.0/180)*M_PI, (1.0/180)*M_PI, U.flag & AUTOROTGRID); + + dx1= dx2; + dy1= dy2; + + co= cos(phi); + si= sin(phi); + asp= (float)yim/(float)xim; + + + tv= transmain; + for(a=0; a<tot; a++, tv++) { + + x= ( co*( tv->oldloc[0]-cent[0]) - si*asp*(tv->oldloc[1]-cent[1]) ) +cent[0]; + y= ( si*( tv->oldloc[0]-cent[0])/asp + co*(tv->oldloc[1]-cent[1]) ) +cent[1]; + sima_pixelgrid(tv->loc, x, y); + + if(G.sima->flag & SI_CLIP_UV) { + if(tv->loc[0]<0.0) tv->loc[0]= 0.0; + else if(tv->loc[0]>1.0) tv->loc[0]= 1.0; + if(tv->loc[1]<0.0) tv->loc[1]= 0.0; + else if(tv->loc[1]>1.0) tv->loc[1]= 1.0; + } + } + + + sprintf(str, "Rot: %.3f ", phi*180.0/M_PI); + headerprint(str); + } + } + else if(mode=='s') { + + size[0]=size[1]= (sqrt( (float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc)) ))/sizefac; + + if(midtog) size[proj]= 1.0; + + apply_keyb_grid(size, 0.0, 0.1, 0.01, U.flag & AUTOSIZEGRID); + apply_keyb_grid(size+1, 0.0, 0.1, 0.01, U.flag & AUTOSIZEGRID); + + size[0]*= xref; + size[1]*= yref; + + xtra[0]= xtra[1]= 0; + + if(G.sima->flag & SI_CLIP_UV) { + /* boundbox limit: four step plan: XTRA X */ + + a=b= 0; + if(size[0]*(min[0]-cent[0]) + cent[0] + xtra[0] < 0) + a= -size[0]*(min[0]-cent[0]) - cent[0]; + if(size[0]*(max[0]-cent[0]) + cent[0] + xtra[0] > 1.0) + b= 1.0 - size[0]*(max[0]-cent[0]) - cent[0]; + xtra[0]= (a+b)/2; + + /* SIZE X */ + if(size[0]*(min[0]-cent[0]) + cent[0] + xtra[0] < 0) + size[0]= (-cent[0]-xtra[0])/(min[0]-cent[0]); + if(size[0]*(max[0]-cent[0]) + cent[0] +xtra[0] > 1.0) + size[0]= (1.0-cent[0]-xtra[0])/(max[0]-cent[0]); + + /* XTRA Y */ + a=b= 0; + if(size[1]*(min[1]-cent[1]) + cent[1] + xtra[1] < 0) + a= -size[1]*(min[1]-cent[1]) - cent[1]; + if(size[1]*(max[1]-cent[1]) + cent[1] + xtra[1] > 1.0) + b= 1.0 - size[1]*(max[1]-cent[1]) - cent[1]; + xtra[1]= (a+b)/2; + + /* SIZE Y */ + if(size[1]*(min[1]-cent[1]) + cent[1] +xtra[1] < 0) + size[1]= (-cent[1]-xtra[1])/(min[1]-cent[1]); + if(size[1]*(max[1]-cent[1]) + cent[1] + xtra[1]> 1.0) + size[1]= (1.0-cent[1]-xtra[1])/(max[1]-cent[1]); + } + + /* if(midtog==0) { */ + /* if(size[1]>size[0]) size[1]= size[0]; */ + /* else if(size[0]>size[1]) size[0]= size[1]; */ + /* } */ + + tv= transmain; + for(a=0; a<tot; a++, tv++) { + + x= size[0]*(tv->oldloc[0]-cent[0])+ cent[0] + xtra[0]; + y= size[1]*(tv->oldloc[1]-cent[1])+ cent[1] + xtra[1]; + sima_pixelgrid(tv->loc, x, y); + } + + sprintf(str, "sizeX: %.3f sizeY: %.3f ", size[0], size[1]); + headerprint(str); + + } + + xo= mval[0]; + yo= mval[1]; + + if(G.sima->lock) force_draw_plus(SPACE_VIEW3D); + else force_draw(); + + firsttime= 0; + + } + else BIF_wait_for_statechange(); + + while(qtest()) { + event= extern_qread(&val); + if(val) { + switch(event) { + case ESCKEY: + case RIGHTMOUSE: + case LEFTMOUSE: + case SPACEKEY: + case RETKEY: + afbreek= 1; + break; + case MIDDLEMOUSE: + + midtog= ~midtog; + if(midtog) { + if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1; + else proj= 0; + firsttime= 1; + } + + break; + case XKEY: + case YKEY: + if(event==XKEY) xref= -xref; + else yref= -yref; + + firsttime= 1; + break; + default: + arrows_move_cursor(event); + } + } + if(afbreek) break; + } + } + + if(event==ESCKEY || event == RIGHTMOUSE) { + tv= transmain; + for(a=0; a<tot; a++, tv++) { + tv->loc[0]= tv->oldloc[0]; + tv->loc[1]= tv->oldloc[1]; + } + } + MEM_freeN(transmain); + + if(mode=='g') if(G.sima->flag & SI_BE_SQUARE) be_square_tface_uv(me); + + allqueue(REDRAWVIEW3D, 0); + scrarea_queue_headredraw(curarea); + scrarea_queue_winredraw(curarea); +} + +void select_swap_tface_uv(void) +{ + Mesh *me; + TFace *tface; + MFace *mface; + int a, sel=0; + + if( is_uv_tface_editing_allowed()==0 ) return; + me= get_mesh(OBACT); + + for(a=me->totface, tface= me->tface; a>0; a--, tface++) { + if(tface->flag & TF_SELECT) { + if(tface->flag & (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4)) { + sel= 1; + break; + } + } + } + + mface= me->mface; + for(a=me->totface, tface= me->tface; a>0; a--, tface++, mface++) { + if(tface->flag & TF_SELECT) { + if(mface->v4) { + if(sel) tface->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4); + else tface->flag |= (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4); + } + else if(mface->v3) { + if(sel) tface->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4); + else tface->flag |= (TF_SEL1+TF_SEL2+TF_SEL3); + } + } + } + + allqueue(REDRAWIMAGE, 0); +} + +void mouse_select_sima(void) +{ + Mesh *me; + TFace *tface; + MFace *mface; + int temp, dist=100; + int a; + short mval[2], uval[2], val = 0; + char *flagpoin =0; + + if( is_uv_tface_editing_allowed()==0 ) return; + me= get_mesh(OBACT); + + getmouseco_areawin(mval); + + mface= me->mface; + for(a=me->totface, tface= me->tface; a>0; a--, tface++, mface++) { + + if(tface->flag & TF_SELECT) { + + uvco_to_areaco_noclip(tface->uv[0], uval); + temp= abs(mval[0]- uval[0])+ abs(mval[1]- uval[1]); + if( tface->flag & TF_SEL1) temp+=5; + if(temp<dist) { + flagpoin= &tface->flag; + dist= temp; + val= TF_SEL1; + } + + uvco_to_areaco_noclip(tface->uv[1], uval); + temp= abs(mval[0]- uval[0])+ abs(mval[1]- uval[1]); + if( tface->flag & TF_SEL2) temp+=5; + if(temp<dist) { + flagpoin= &tface->flag; + dist= temp; + val= TF_SEL2; + } + + uvco_to_areaco_noclip(tface->uv[2], uval); + temp= abs(mval[0]- uval[0])+ abs(mval[1]- uval[1]); + if( tface->flag & TF_SEL3) temp+=5; + if(temp<dist) { + flagpoin= &tface->flag; + dist= temp; + val= TF_SEL3; + } + + if(mface->v4) { + uvco_to_areaco_noclip(tface->uv[3], uval); + temp= abs(mval[0]- uval[0])+ abs(mval[1]- uval[1]); + if( tface->flag & TF_SEL4) temp+=5; + if(temp<dist) { + flagpoin= &tface->flag; + dist= temp; + val= TF_SEL4; + } + } + + } + } + + if(flagpoin) { + if(G.qual & LR_SHIFTKEY) { + if(*flagpoin & val) *flagpoin &= ~val; + else *flagpoin |= val; + } + else { + for(a=me->totface, tface= me->tface; a>0; a--, tface++) { + if(tface->flag & TF_SELECT) { + tface->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4); + } + } + + *flagpoin |= val; + } + + + glDrawBuffer(GL_FRONT); + draw_tfaces(); + glDrawBuffer(GL_BACK); + + std_rmouse_transform(transform_tface_uv); + } +} + +void borderselect_sima(void) +{ + Mesh *me; + TFace *tface; + MFace *mface; + rcti rect; + rctf rectf; + int a, val; + short mval[2]; + + if( is_uv_tface_editing_allowed()==0 ) return; + me= get_mesh(OBACT); + + val= get_border(&rect, 3); + + if(val) { + mval[0]= rect.xmin; + mval[1]= rect.ymin; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + mval[0]= rect.xmax; + mval[1]= rect.ymax; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + mface= me->mface; + for(a=me->totface, tface= me->tface; a>0; a--, tface++, mface++) { + + if(tface->flag & TF_SELECT) { + + if(BLI_in_rctf(&rectf, (float)tface->uv[0][0], (float)tface->uv[0][1])) { + if(val==LEFTMOUSE) tface->flag |= TF_SEL1; + else tface->flag &= ~TF_SEL1; + } + if(BLI_in_rctf(&rectf, (float)tface->uv[1][0], (float)tface->uv[1][1])) { + if(val==LEFTMOUSE) tface->flag |= TF_SEL2; + else tface->flag &= ~TF_SEL2; + } + if(BLI_in_rctf(&rectf, (float)tface->uv[2][0], (float)tface->uv[2][1])) { + if(val==LEFTMOUSE) tface->flag |= TF_SEL3; + else tface->flag &= ~TF_SEL3; + } + if(mface->v4 && BLI_in_rctf(&rectf, (float)tface->uv[3][0], (float)tface->uv[3][1])) { + if(val==LEFTMOUSE) tface->flag |= TF_SEL4; + else tface->flag &= ~TF_SEL4; + } + } + + } + scrarea_queue_winredraw(curarea); + } +} + +/** This is an ugly function to set the Tface selection flags depending + * on whether its UV coordinates are inside the normalized + * area with radius rad and offset offset. These coordinates must be + * normalized to 1.0 + * Just for readability... + */ + +void sel_uvco_inside_radius(short sel, TFace *tface, int index, float *offset, float *ell, short select_mask) +{ + // normalized ellipse: ell[0] = scaleX, + // [1] = scaleY + + float *uv = tface->uv[index]; + float x, y, r2; + + x = (uv[0] - offset[0]) * ell[0]; + y = (uv[1] - offset[1]) * ell[1]; + + r2 = x * x + y * y; + if (r2 < 1.0) { + if (sel == LEFTMOUSE) tface->flag |= select_mask; + else tface->flag &= ~select_mask; + } +} + +// see below: +/** gets image dimensions of the 2D view 'v' */ +static void getSpaceImageDimension(SpaceImage *sima, float *xy) +{ + Image *img = sima->image; + float z; + + z = sima->zoom; + + if (img) { + xy[0] = img->ibuf->x * z; + xy[1] = img->ibuf->y * z; + } else { + xy[0] = 256 * z; + xy[1] = 256 * z; + } +} + +/** Callback function called by circle_selectCB to enable + * brush select in UV editor. + */ + +void uvedit_selectionCB(short selecting, Object *editobj, short *mval, float rad) +{ + float offset[2]; + Mesh *me; + MFace *mface; + TFace *tface; + int i; + + float ellipse[2]; // we need to deal with ellipses, as + // non square textures require for circle + // selection. this ellipse is normalized; r = 1.0 + + me = get_mesh(editobj); + + getSpaceImageDimension(curarea->spacedata.first, ellipse); + ellipse[0] /= rad; + ellipse[1] /= rad; + + areamouseco_to_ipoco(G.v2d, mval, &offset[0], &offset[1]); + + mface= me->mface; + tface= me->tface; + + if (selecting) { + for(i = 0; i < me->totface; i++) { + sel_uvco_inside_radius(selecting, tface, 0, offset, ellipse, TF_SEL1); + sel_uvco_inside_radius(selecting, tface, 1, offset, ellipse, TF_SEL2); + sel_uvco_inside_radius(selecting, tface, 2, offset, ellipse, TF_SEL3); + if (mface->v4) + sel_uvco_inside_radius(selecting, tface, 3, offset, ellipse, TF_SEL4); + + tface++; mface++; + + } + // force_draw() is no good here... + glDrawBuffer(GL_FRONT); + draw_tfaces(); + glDrawBuffer(GL_BACK); + } +} + + +void mouseco_to_curtile(void) +{ + float fx, fy; + short mval[2]; + + if( is_uv_tface_editing_allowed()==0) return; + + if(G.sima->image && G.sima->image->tpageflag & IMA_TILES) { + + G.sima->flag |= SI_EDITTILE; + + while(get_mbut()&L_MOUSE) { + + calc_image_view(G.sima, 'f'); + + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &fx, &fy); + + if(fx>=0.0 && fy>=0.0 && fx<1.0 && fy<1.0) { + + fx= (fx)*G.sima->image->xrep; + fy= (fy)*G.sima->image->yrep; + + mval[0]= fx; + mval[1]= fy; + + G.sima->curtile= mval[1]*G.sima->image->xrep + mval[0]; + } + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + + } + + G.sima->flag &= ~SI_EDITTILE; + + image_changed(G.sima, 1); + + allqueue(REDRAWVIEW3D, 0); + scrarea_queue_winredraw(curarea); + } +} diff --git a/source/blender/src/editsound.c b/source/blender/src/editsound.c new file mode 100644 index 00000000000..53a3628aa48 --- /dev/null +++ b/source/blender/src/editsound.c @@ -0,0 +1,1017 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdio.h> +#include <math.h> +#include <string.h> +#include <fcntl.h> +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#endif +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_sound_types.h" +#include "DNA_packedFile_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_sound.h" +#include "BKE_library.h" +#include "BKE_packedFile.h" + +#include "BIF_space.h" +#include "BIF_screen.h" +#include "BIF_interface.h" +#include "BIF_editsound.h" +#include "BIF_mywindow.h" + +#include "BSE_drawipo.h" +#include "BSE_headerbuttons.h" + +#include "blendef.h" + +#include "interface.h" +#include "mydevice.h" + +#include "SND_C-api.h" +#include "SND_DependKludge.h" + +#include "SYS_System.h" + +#include "license_key.h" + +extern int LICENSE_KEY_VALID; + +/* this might move to the external header */ +void* sound_get_libraryinterface(void); + +static SND_SceneHandle ghSoundScene; +static SND_AudioDeviceInterfaceHandle ghAudioDeviceInterface; + +/* que? why only here? because of the type define? */ +bSound *sound_find_sound(char *id_name); +void sound_read_wav_data(bSound * sound, PackedFile * pf); +void sound_stop_sound(void *object, bSound *sound); +void winqreadsoundspace(unsigned short event, short val, char ascii); +/* void sound_stop_all_sounds(void); already in BIF_editsound.h */ + + + +/* Right. Now for some implementation: */ +void winqreadsoundspace(unsigned short event, short val, char ascii) +{ + float dx, dy; + int doredraw= 0, cfra, first = 0; + short mval[2]; + + if(curarea->win==0) return; + + if(val) { + + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) + { + case LEFTMOUSE: + if( view2dmove()==0 ) + { + do + { + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &dx, &dy); + + cfra = (int)dx; + if(cfra< 1) cfra= 1; + + if( cfra!=CFRA || first ) + { + first= 0; + CFRA= cfra; + update_for_newframe(); + force_draw_plus(SPACE_VIEW3D); + } + + } while(get_mbut()&L_MOUSE); + + } + break; + case MIDDLEMOUSE: + view2dmove(); /* in drawipo.c */ + break; + case RIGHTMOUSE: + /* mouse_select_seq(); */ + break; + case PADPLUSKEY: + dx= (float)(0.1154*(G.v2d->cur.xmax-G.v2d->cur.xmin)); + G.v2d->cur.xmin+= dx; + G.v2d->cur.xmax-= dx; + test_view2d(G.v2d, curarea->winx, curarea->winy); + + doredraw= 1; + break; + case PADMINUS: + dx= (float)(0.15*(G.v2d->cur.xmax-G.v2d->cur.xmin)); + G.v2d->cur.xmin-= dx; + G.v2d->cur.xmax+= dx; + test_view2d(G.v2d, curarea->winx, curarea->winy); + + doredraw= 1; + break; + case HOMEKEY: + do_sound_buttons(B_SOUNDHOME); + break; + } + } + + if(doredraw) + scrarea_queue_winredraw(curarea); +} + + + +void sound_initialize_sounds(void) +{ + bSound* sound; + + /* clear the soundscene */ + SND_RemoveAllSounds(ghSoundScene); + SND_RemoveAllSamples(ghSoundScene); + + /* initialize sounds */ + sound = G.main->sound.first; + while (sound) + { + sound_sample_is_null(sound); + sound = (bSound *) sound->id.next; + } +} + + + +bSound* sound_make_copy(bSound* originalsound) +{ + bSound* sound = NULL; + char name[160]; + int len; + + /* only copy sounds that are sounds */ + if (originalsound) + { + /* do some name magic */ + strcpy(name, originalsound->name); + len = strlen(name); + while ((len > 0) && (name[len - 1] != '/') && (name[len - 1] != '\\')) + len--; + + /* allocate the needed memory */ + sound = alloc_libblock(&G.main->sound, ID_SO, name + len); + + /* create a soundobject */ + sound->snd_sound = SND_CreateSound(); + + /* set the samplename */ + strcpy(sound->name, name); + SND_SetSampleName(sound->snd_sound, sound->name); + + /* add the new object to the soundscene */ + SND_AddSound(ghSoundScene, sound->snd_sound); + + /* and copy the data from the original */ + sound->attenuation = originalsound->attenuation; + sound->distance = originalsound->distance; + sound->max_gain = originalsound->max_gain; + sound->min_gain = originalsound->min_gain; + sound->newpackedfile = originalsound->newpackedfile; + sound->panning = originalsound->panning; + sound->pitch = originalsound->pitch; + sound->sample = originalsound->sample; + sound->volume = originalsound->volume; + + if (originalsound->flags & SOUND_FLAGS_3D) + sound->flags |= SOUND_FLAGS_3D; + else + sound->flags &= ~SOUND_FLAGS_3D; + } + + return sound; +} + + + +void sound_initialize_sample(bSound* sound) +{ + if (sound && sound->sample == NULL) + sound_sample_is_null(sound); +} + + + +void sound_read_wav_data(bSound* sound, PackedFile* pf) +{ + int i, temp; + short shortbuf, *temps; + int longbuf; + char buffer[25]; + char *data = NULL; + char *tempc; + bSample *sample = NULL; + int channels, rate, bits, len; + + /* prepare for the worst... */ + sound->sample->type = SAMPLE_INVALID; + + rewindPackedFile(pf); + + /* check to see if it is a file in "RIFF WAVE fmt" format */ + if (readPackedFile(pf, buffer, 16) != 16) + { + if (G.f & G_DEBUG) printf("File too short\n"); + return; + } + + if(!(memcmp(buffer, "RIFF", 4) && memcmp(&(buffer[8]), "WAVEfmt ", 8))) + { + readPackedFile(pf, &i, 4);// start of data + if(G.order==B_ENDIAN) + SWITCH_INT(i); + + /* read the sampleformat */ + readPackedFile(pf, &shortbuf, 2); + if(G.order==B_ENDIAN) + { + /* was SWITCH_SHORT before */ + char s_i, *p_i; + p_i= (char *)&(shortbuf); + s_i= p_i[0]; + p_i[0]= p_i[1]; + p_i[1]= s_i; + } + + /* read the number of channels */ + readPackedFile(pf, &shortbuf, 2); + if(G.order==B_ENDIAN) + { + /* was SWITCH_SHORT before */ + char s_i, *p_i; + p_i= (char *)&(shortbuf); + s_i= p_i[0]; + p_i[0]= p_i[1]; + p_i[1]= s_i; + } + + /* check the number of channels */ + if(shortbuf != 1 && shortbuf != 2) + { + if (G.f & G_DEBUG) printf("Unsupported number of channels\n"); + return; + } + channels = shortbuf; + + /* read the samplerate */ + readPackedFile(pf, &longbuf, 4); + if(G.order==B_ENDIAN) + SWITCH_INT(longbuf); + rate = longbuf; + + /* read the bitrate */ + // Ton's way + readPackedFile(pf, &temp, 4); + if(G.order==B_ENDIAN) + SWITCH_INT(temp); + + if(channels && rate) + bits= 8*temp/(rate * channels); + + // Frank's way + readPackedFile(pf, &shortbuf, 2); + readPackedFile(pf, &shortbuf, 2); + if(G.order==B_ENDIAN) + { + /* was SWITCH_SHORT before */ + char s_i, *p_i; + p_i= (char *)&(shortbuf); + s_i= p_i[0]; + p_i[0]= p_i[1]; + p_i[1]= s_i; + } + bits = shortbuf; + + seekPackedFile(pf, i-16, SEEK_CUR); + readPackedFile(pf, buffer, 4); + + /* check if we have a 'data' chunk */ + while(memcmp(buffer, "data", 4)!=0) + { + if (readPackedFile(pf, &i, 4) != 4) + break; + + if(G.order==B_ENDIAN) + SWITCH_INT(i); + + seekPackedFile(pf, i, SEEK_CUR); + + if (readPackedFile(pf, buffer, 4) != 4) + break; + } + + /* guess not */ + if (memcmp(buffer, "data", 4) !=0) + { + if (G.f & G_DEBUG) printf("No data found\n"); + } + /* or maybe we do! */ + else + { + readPackedFile(pf, &longbuf, 4); + if(G.order==B_ENDIAN) SWITCH_INT(longbuf); + + /* handle 8 and 16 bit samples differently */ + if (bits == 8) + data = (char *)MEM_mallocN(2 * longbuf, "sample data"); + else if (bits == 16) + data = (char *)MEM_mallocN(longbuf, "sample data"); + + len = longbuf; + + if(data) + { + readPackedFile(pf, data, len); + + /* data is only used to draw! */ + if (bits == 8) + { + temps = (short *) data; + tempc = (char *) data; + for (i = len - 1; i >= 0; i--) + temps[i] = tempc[i] << 8; + } + else + { + if(G.order==B_ENDIAN) + { + temps= (short *)data; + for(i=0; i< len / 2; i++, temps++) + { + /* was SWITCH_SHORT before */ + char s_i, *p_i; + p_i= (char *)&(temps); + s_i= p_i[0]; + p_i[0]= p_i[1]; + p_i[1]= s_i; + } + } + } + + /* fill the sound with the found data */ + sample = sound->sample; + sample->channels = channels; + sample->rate = rate; + sample->bits = bits; + sample->len = len; + sample->data = data; + sample->type = SAMPLE_WAV; + } + } + } + else + { + sound->sample->type = SAMPLE_INVALID; + if (G.f & G_DEBUG) printf("Unsupported sound format: %s\n", sound->name); + } +} + + + +/* ugly, but it works (for now) */ +int sound_get_filetype_from_header(bSound* sound, PackedFile* pf) +{ + int i, filetype = SAMPLE_INVALID; + char buffer[25]; + short shortbuf; + + rewindPackedFile(pf); + + if (readPackedFile(pf, buffer, 16) != 16) + { + if (G.f & G_DEBUG) printf("File too short\n"); + return filetype; + } + + if(!(memcmp(buffer, "RIFF", 4) && memcmp(&(buffer[8]), "WAVEfmt ", 8))) + { + readPackedFile(pf, &i, 4); + if(G.order==B_ENDIAN) + SWITCH_INT(i); + + /* read the sampleformat */ + readPackedFile(pf, &shortbuf, 2); + if(G.order==B_ENDIAN) + { + char s_i, *p_i; + p_i= (char *)&(shortbuf); + s_i= p_i[0]; + p_i[0]= p_i[1]; + p_i[1]= s_i; + } + + if (shortbuf == SND_WAVE_FORMAT_PCM) + { + filetype = SAMPLE_WAV; + } + else + /* only fmod supports compressed wav */ +#ifdef USE_FMOD + { + /* and only valid publishers may use compressed wav */ + if (LICENSE_KEY_VALID) + { + switch (shortbuf) + { + case SND_WAVE_FORMAT_ADPCM: + case SND_WAVE_FORMAT_ALAW: + case SND_WAVE_FORMAT_MULAW: + case SND_WAVE_FORMAT_DIALOGIC_OKI_ADPCM: + case SND_WAVE_FORMAT_CONTROL_RES_VQLPC: + case SND_WAVE_FORMAT_GSM_610: + case SND_WAVE_FORMAT_MPEG3: + filetype = SAMPLE_WAV; + break; + default: +#endif + { + filetype = SAMPLE_INVALID; + if (G.f & G_DEBUG) printf("Unsupported wav compression\n"); + } + } +#ifdef USE_FMOD + } + } + } + /* only valid publishers may use ogg vorbis */ + else if (!memcmp(buffer, "OggS", 4) && LICENSE_KEY_VALID) + { + filetype = SAMPLE_OGG_VORBIS; + } + /* only valid publishers may use mp3 */ + else if (((!memcmp(buffer, "ID3", 3)) || (!memcmp(buffer, "ÿû", 2))) && LICENSE_KEY_VALID) + { + filetype = SAMPLE_MP3; + } +#endif + else + { + filetype = SAMPLE_INVALID; + if (G.f & G_DEBUG) printf("Unsupported sound format: %s\n", sound->name); + } + + return filetype; +} + + + +int check_filetype(bSound* sound, PackedFile* pf) +{ +// char* pdest; + sound->sample->type = SAMPLE_INVALID; +/* + // parse the name for the extension to see what kind of sample it is + pdest = strrchr(sound->sample->name, '.'); + + // a simple check to see what kind of sample we're dealing with + if (stricmp(pdest, ".wav") == 0) + sound->sample->type = SAMPLE_WAV; + +#ifdef USE_FMOD + if (stricmp(pdest, ".mp2") == 0) + sound->sample->type = SAMPLE_MP2; + if (stricmp(pdest, ".mp3") == 0) + sound->sample->type = SAMPLE_MP3; + if (stricmp(pdest, ".ogg") == 0) + sound->sample->type = SAMPLE_OGG_VORBIS; + if (stricmp(pdest, ".raw") == 0) + sound->sample->type = SAMPLE_RAW; + if (stricmp(pdest, ".wma") == 0) + sound->sample->type = SAMPLE_WMA; + if (stricmp(pdest, ".asf") == 0) + sound->sample->type = SAMPLE_ASF; +#endif +*/ + sound->sample->type = sound_get_filetype_from_header(sound, pf); + + /* get some info from the sample */ + switch (sound->sample->type) + { + case SAMPLE_WAV: + { + sound_read_wav_data(sound, pf); + break; + } + case SAMPLE_OGG_VORBIS: + case SAMPLE_MP3: + case SAMPLE_MP2: + case SAMPLE_RAW: + case SAMPLE_WMA: + case SAMPLE_ASF: + break; + default: + { + if (G.f & G_DEBUG) printf("No valid sample: %s\n", sound->name); + break; + } + } + + return sound->sample->type; +} + + + +int sound_load_sample(bSound* sound) +{ + int result = FALSE; + PackedFile* pf; + int freePF = FALSE; + int buffer = -1; + + /* check the sample (valid?) */ + if (sound->sample->type == SAMPLE_UNKNOWN || sound->snd_sound == NULL) + { + /* find... */ + pf = sound_find_packedfile(sound); + + /* ...or create a (temp)packedfile */ + if (pf == NULL) + { + pf = newPackedFile(sound->name); + + /* if autopack is off, free the pf afterwards */ + if ((G.fileflags & G_AUTOPACK) == 0) + freePF = TRUE; + } + + /* if we have a valid pf... */ + if (pf) + { + /* check the content of the pf */ + check_filetype(sound, pf); + + /* check if the sampletype is supported */ + if (sound->sample->type != SAMPLE_INVALID && sound->sample->type != SAMPLE_UNKNOWN) + { + /* register the sample at the audiodevice */ + buffer = SND_AddSample(ghSoundScene, sound->sample->name, pf->data, pf->size); + + /* create a soundobject */ + sound->snd_sound = SND_CreateSound(); + SND_SetSampleName(sound->snd_sound, sound->sample->name); + + /* add the soundobject to the soundscene */ + if (SND_CheckBuffer(ghSoundScene, sound->snd_sound)) + SND_AddSound(ghSoundScene, sound->snd_sound); + else + if (G.f & G_DEBUG) printf("error: sample didn't load properly\n"); + + /* if it was places in buffer[0] or higher, it succeeded */ + if (buffer >= 0) + result = TRUE; + } + /* if not, free the pf */ + else + { + freePF = TRUE; + } + + /* if you want it freed, make it so */ + if (freePF) + { + freePackedFile(pf); + pf = NULL; + } + /* or else connect the pf to the sound and sample */ +// else +// { + sound->newpackedfile = pf; + sound->sample->packedfile = pf; +// } + } + else + { + if (G.f & G_DEBUG) printf("%s: File not found!\n", sound->name); + sound->sample->type = SAMPLE_INVALID; + } + } + /* if the sample ain't invalid, we're ready to go! */ + else if (sound->sample->type != SAMPLE_INVALID) + { + result = TRUE; + } + + return result; +} + + + +bSound* sound_new_sound(char* name) +{ + bSound *sound = NULL; + int len, file; + char str[FILE_MAXDIR+FILE_MAXFILE]; + + /* convert the name to absolute path */ + strcpy(str, name); + BLI_convertstringcode(str, G.sce, G.scene->r.cfra); + + /* check if the sample on disk can be opened */ + file = open(str, O_BINARY|O_RDONLY); + + if (file != -1) + { + close(file); + + /* do some name magic */ + len = strlen(name); + while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\') + len--; + + /* allocate some memory for the sound */ + sound = alloc_libblock(&G.main->sound, ID_SO, name + len); + strcpy(sound->name, name); + + /* intialize and check the sample */ + sound_initialize_sample(sound); + + /* load the sample & check if this blender supports the sound format */ +// sound_load_sample(sound); + + if (sound->sample->type == SAMPLE_INVALID) + { + free_libblock(&G.main->sound, sound); + sound = NULL; + } + else + { + sound->volume = 1.0; + sound->attenuation = 1.0; + sound->distance = 1.0; + sound->min_gain = 0.0; + sound->max_gain = 1.0; + } + } + + return (sound); +} + + + +int sound_set_sample(bSound *sound, bSample *sample) +{ + int result = TRUE; + + /* decrease the usernumber for this sample */ + if (sound->sample) + sound->sample->id.us--; + + /* delete the soundobject */ + if (sound->snd_sound) + { + SND_RemoveSound(ghSoundScene, sound->snd_sound); + sound->snd_sound = NULL; + } + + /* connect the sample to the sound */ + sound->sample = sample; + sound->newpackedfile = NULL; + + /* increase the usercount */ + if (sound->sample) + { + sound->sample->id.us++; + + /* and set the right pf */ + sound->newpackedfile = sample->packedfile; + + /* if the sampletype is unknown initialize it */ + if (sound->sample->type == SAMPLE_UNKNOWN) + { + sound_initialize_sample(sound); + + /* load the sample & check if this blender supports the sound format */ + if (!sound_load_sample(sound)) + { + result = FALSE; + } + } + } + return result; +} + + + +bSample *sound_new_sample(bSound * sound) +{ + bSample *sample = NULL; + int len; + char *name; + + if (sound != NULL) + { + name = sound->name; + len = strlen(name); + /* do some name magic */ + while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\') + len--; + + /* allocate the memory for the sample */ + sample = alloc_libblock(samples, ID_SAMPLE, name + len); + sample->data = &sample->fakedata[0]; + sample->type = SAMPLE_UNKNOWN; + + /* some default settings. We get divide by zero if these values are not set */ + sample->channels = 1; + sample->rate = 44100; + sample->bits = 16; + sample->alindex = SAMPLE_INVALID; + + /* convert sound->name to abolute filename */ + strcpy(sample->name, sound->name); + BLI_convertstringcode(sample->name, G.sce, G.scene->r.cfra); + + /* connect the pf to the sample */ + if (sound->newpackedfile) + sample->packedfile = sound->newpackedfile; + else + sample->packedfile = sound_find_packedfile(sound); + } + + return(sample); +} + + + +/* find a sample that might already be loaded */ +bSample* sound_find_sample(bSound* sound) +{ + bSample* sample; + char name[FILE_MAXDIR + FILE_MAXFILE]; + char samplename[FILE_MAXDIR + FILE_MAXFILE]; + + // convert sound->name to abolute filename + strcpy(name, sound->name); + BLI_convertstringcode(name, G.sce, G.scene->r.cfra); + + /* search through the list of loaded samples */ + sample = samples->first; + + while (sample) + { + strcpy(samplename, sample->name); + BLI_convertstringcode(samplename, G.sce, G.scene->r.cfra); + + if (strcmp(name, samplename) == 0) + { + break; + } + sample = sample->id.next; + } + + return (sample); +} + + + +int sound_sample_is_null(bSound* sound) +{ + int result = FALSE; + bSample* sample; + + /* find the right sample or else create one */ + if (sound->sample == NULL) + { + /* find... */ + sample = sound_find_sample(sound); + + /* or a new one? */ + if (sample == NULL) + sample = sound_new_sample(sound); + + if (sound_set_sample(sound, sample)) + result = TRUE; + } + + return result; +} + + + +void sound_stop_all_sounds(void) +{ + SND_StopAllSounds(ghSoundScene); + SND_Proceed(ghAudioDeviceInterface, ghSoundScene); +} + + + +void sound_end_all_sounds(void) +{ + sound_stop_all_sounds(); + SND_RemoveAllSounds(ghSoundScene); +} + + + +void sound_play_sound(bSound* sound) +{ + /* first check if we want sound or not */ + SND_IsPlaybackWanted(ghSoundScene); + + /* stop all previous sounds */ + SND_StopAllSounds(ghSoundScene); + + if (sound != NULL && sound->sample != NULL) + { + /* load the sample if needed */ + if (sound_load_sample(sound)) + { + /* set all kinds of parameters */ + SND_SetListenerGain(ghSoundScene, G.listener->gain); + SND_SetDopplerFactor(ghSoundScene, G.listener->dopplerfactor); + SND_SetDopplerVelocity(ghSoundScene, G.listener->dopplervelocity); + + SND_SetGain((SND_ObjectHandle)sound->snd_sound, (sound->volume)); + SND_SetPitch((SND_ObjectHandle)sound->snd_sound, (exp((sound->pitch / 12.0) * log(2.0)))); + + if (sound->flags & SOUND_FLAGS_LOOP) + { + SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_NORMAL); +#ifdef SOUND_UNDER_DEVELOPMENT +/* SND_SetLoopPoints((SND_ObjectHandle)sound->snd_sound, sound->loopstart, sound->loopend); +*/ +#endif + if (sound->flags & SOUND_FLAGS_BIDIRECTIONAL_LOOP) + SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_BIDIRECTIONAL); + else + SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_NORMAL); + + } + else + { + SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_OFF); + } + + if (sound->flags & SOUND_FLAGS_3D) + { + SND_SetRollOffFactor((SND_ObjectHandle)sound->snd_sound, sound->attenuation); + SND_SetReferenceDistance((SND_ObjectHandle)sound->snd_sound, sound->distance); + SND_SetMinimumGain((SND_ObjectHandle)sound->snd_sound, sound->min_gain); + SND_SetMaximumGain((SND_ObjectHandle)sound->snd_sound, sound->max_gain); + } + else + { + SND_SetRollOffFactor((SND_ObjectHandle)sound->snd_sound, 0); + SND_SetReferenceDistance((SND_ObjectHandle)sound->snd_sound, 1); + SND_SetMinimumGain((SND_ObjectHandle)sound->snd_sound, 1); + SND_SetMaximumGain((SND_ObjectHandle)sound->snd_sound, 1); + } + + if (G.f & G_DEBUG) printf("Set pitch to: %f\n", SND_GetPitch((SND_ObjectHandle)sound->snd_sound)); + if (G.f & G_DEBUG) printf("Set gain to: %f\n", SND_GetGain((SND_ObjectHandle)sound->snd_sound)); + if (G.f & G_DEBUG) printf("Set looping to: %d\n", SND_GetLoopMode((SND_ObjectHandle)sound->snd_sound)); + + /* play the sound */ + SND_StartSound(ghSoundScene, (SND_ObjectHandle)sound->snd_sound); + + /* update the device */ + SND_Proceed(ghAudioDeviceInterface, ghSoundScene); + } + } + else + { + if (G.f & G_DEBUG) + { + printf("uninitialized sound !\n"); + if (sound) + { + printf("sound: %p\n", sound); + if (sound->sample) + { + printf("sample: %p\n", sound->sample); + if (sound->snd_sound) + printf("hSoundObject: %p\n", sound->snd_sound); + } + } + else + { + printf("sound == NULL\n"); + } + } + } +} + + + +bSound *sound_find_sound(char *id_name) +{ + bSound *sound; + + // look for sound with same *id* name + sound = G.main->sound.first; + while (sound) + { + if (strcmp(sound->id.name + 2, id_name) == 0) + break; + + sound = sound->id.next; + } + + return sound; +} + + + +static void sound_init_listener(void) +{ + G.listener = MEM_callocN(sizeof(bSoundListener), "soundlistener"); + G.listener->gain = 1.0; + G.listener->dopplerfactor = 1.0; + G.listener->dopplervelocity = 1.0; +} + + + +void sound_init_audio(void) +{ + int noaudio; + SYS_SystemHandle hSystem = NULL; + ghAudioDeviceInterface = NULL; + + hSystem = SYS_GetSystem(); + noaudio = SYS_GetCommandLineInt(hSystem,"noaudio",0); + + if (noaudio) + SND_SetDeviceType(snd_e_dummydevice); + + ghAudioDeviceInterface = SND_GetAudioDevice(); + ghSoundScene = SND_CreateScene(ghAudioDeviceInterface); + + sound_init_listener(); +} + + + +int sound_get_mixrate(void) +{ + return MIXRATE; +} + + + +static void sound_exit_listener(void) +{ + MEM_freeN(G.listener); +} + + + +void sound_exit_audio(void) +{ + SND_DeleteScene(ghSoundScene); + SND_ReleaseDevice(); + sound_exit_listener(); +} diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c new file mode 100644 index 00000000000..1ca7672f4d9 --- /dev/null +++ b/source/blender/src/editview.c @@ -0,0 +1,1328 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * cursor/gestures/selecteren + */ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "IMB_imbuf.h" + +#include "DNA_armature_types.h" +#include "DNA_meta_types.h" +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_armature.h" +#include "BKE_lattice.h" + +#include "BIF_gl.h" +#include "BIF_mywindow.h" +#include "BIF_space.h" +#include "BIF_screen.h" +#include "BIF_buttons.h" +#include "BIF_editgroup.h" +#include "BIF_editmesh.h" +#include "BIF_editoops.h" +#include "BIF_editsima.h" +#include "BIF_editview.h" +#include "BIF_glutil.h" +#include "BIF_editarmature.h" + +#include "BDR_editobject.h" /* For headerprint */ +#include "BDR_vpaint.h" +#include "BDR_editface.h" +#include "BDR_drawobject.h" +#include "BDR_editcurve.h" + +#include "BSE_edit.h" +#include "BSE_view.h" /* give_cursor() */ +#include "BSE_editipo.h" +#include "BSE_drawview.h" +#include "BSE_editaction.h" + +#include "blendertimer.h" + +#include "blendef.h" +#include "mydevice.h" + +extern ListBase editNurb; /* originally from exports.h, memory from editcurve.c*/ +/* editmball.c */ +extern ListBase editelems; + + + +void arrows_move_cursor(unsigned short event) +{ + short mval[2]; + + getmouseco_sc(mval); + + if(event==UPARROWKEY) { + warp_pointer(mval[0], mval[1]+1); + } else if(event==DOWNARROWKEY) { + warp_pointer(mval[0], mval[1]-1); + } else if(event==LEFTARROWKEY) { + warp_pointer(mval[0]-1, mval[1]); + } else if(event==RIGHTARROWKEY) { + warp_pointer(mval[0]+1, mval[1]); + } +} + +#define MOVES 50 + + +static char interpret_move(short mcord[][2], int count) +{ + float x1, x2, y1, y2, d1, d2, inp, sq, mouse[MOVES][2]; + int i, j, dir = 0; + + if (count <= 10) return ('g'); + + /* van short naar float (tekenen is met shorts) */ + for(j=0; j<count; j++) { + mouse[j][0]= mcord[j][0]; + mouse[j][1]= mcord[j][1]; + } + + /* nieuwe opzet: + * + * vanuit eindpunten middelpunt met maximale afstand berekenen + * aan de hand van de hoek wordt s / g / r bepaald + */ + + + /* filteren */ + + for( j = 3 ; j > 0; j--){ + x1 = mouse[1][0]; + y1 = mouse[1][1]; + for (i = 2; i < count; i++){ + x2 = mouse[i-1][0]; + y2 = mouse[i-1][1]; + mouse[i-1][0] = ((x1 + mouse[i][0]) /4.0) + (x2 / 2.0); + mouse[i-1][1] = ((y1 + mouse[i][1]) /4.0) + (y2 / 2.0); + x1 = x2; + y1 = y2; + } + } + + /* maak directions overzicht */ + for (i = 0; i <= count - 2; i++){ + x1 = mouse[i][0] - mouse[i + 1][0]; + y1 = mouse[i][1] - mouse[i + 1][1]; + + if (x1 < -0.5){ + if (y1 < -0.5) dir |= 32; + else if (y1 > 0.5) dir |= 128; + else dir |= 64; + } else if (x1 > 0.5){ + if (y1 < -0.5) dir |= 8; + else if (y1 > 0.5) dir |= 2; + else dir |= 4; + } else{ + if (y1 < -0.5) dir |= 16; + else if (y1 > 0.5) dir |= 1; + else dir |= 0; + } + } + + /* alle kruisjes naar rechts halen */ + for (i = 7; i>=0 ; i--){ + if (dir & 128) dir = (dir << 1) + 1; + else break; + } + dir &= 255; + for (i = 7; i>=0 ; i--){ + if ((dir & 1) == 0) dir >>= 1; + else break; + } + + /* theorie zegt: 1 richting: rechte lijn + * meer aaneengesloten richtingen: cirkel + * onderbroken en minstens 1 bit gezet in hoogste 4 bits: size + */ + switch(dir){ + case 1: + return ('g'); + break; + case 3: + case 7: + x1 = mouse[0][0] - mouse[count >> 1][0]; + y1 = mouse[0][1] - mouse[count >> 1][1]; + x2 = mouse[count >> 1][0] - mouse[count - 1][0]; + y2 = mouse[count >> 1][1] - mouse[count - 1][1]; + d1 = (x1 * x1) + (y1 * y1); + d2 = (x2 * x2) + (y2 * y2); + sq = sqrt(d1); + x1 /= sq; + y1 /= sq; + sq = sqrt(d2); + x2 /= sq; + y2 /= sq; + inp = (x1 * x2) + (y1 * y2); + /*printf("%f\n", inp);*/ + if (inp > 0.9) return ('g'); + else return ('r'); + break; + case 15: + case 31: + case 63: + case 127: + case 255: + return ('r'); + break; + default: + /* bij size moeten minstens een van de hogere bits gezet zijn */ + if (dir < 16) return ('r'); + else return ('s'); + } + + return (0); +} + +int gesture(void) +{ + short mcords[MOVES][2]; + int i= 1, end= 0, a; + unsigned short event; + short mval[2], val; + + glDrawBuffer(GL_FRONT); + persp(0); /* heeft ortho op pixelnivo */ + + getmouseco_areawin(mval); + + mcords[0][0] = mval[0]; + mcords[0][1] = mval[1]; + + while(get_mbut()&L_MOUSE) { + + event= extern_qread(&val); + + switch (event) { + case MOUSEY: + getmouseco_areawin(mval); + if( abs(mval[0]-mcords[i-1][0])>3 || abs(mval[1]-mcords[i-1][1])>3 ) { + mcords[i][0] = mval[0]; + mcords[i][1] = mval[1]; + if(i) { + sdrawXORline(mcords[i-1][0], mcords[i-1][1], mcords[i][0], mcords[i][1]); + glFlush(); + } + i++; + } + break; + case MOUSEX: + break; + case LEFTMOUSE: + break; + default: + if(event) end= 1; /* blender returns 0 */ + break; + } + if (i == MOVES || end == 1) break; + } + + for(a=1; a<i; a++) { + sdrawXORline(mcords[a-1][0], mcords[a-1][1], mcords[a][0], mcords[a][1]); + } + + persp(1); + glDrawBuffer(GL_BACK); + + if (i > 2) { + i = interpret_move(mcords, i); + + if(i) { + if(curarea->spacetype==SPACE_IPO) transform_ipo(i); + else if(curarea->spacetype==SPACE_IMAGE) transform_tface_uv(i); + else if(curarea->spacetype==SPACE_OOPS) transform_oops('g'); + else transform(i); + } + + return 1; + } + return 0; +} + +void mouse_cursor(void) +{ + extern float zfac; /* view.c */ + float dx, dy, fz, *fp = NULL, dvec[3], oldcurs[3]; + short mval[2], mx, my, lr_click=0; + + if(gesture()) return; + + getmouseco_areawin(mval); + + if(mval[0]!=G.vd->mx || mval[1]!=G.vd->my) { + + mx= mval[0]; + my= mval[1]; + + fp= give_cursor(); + + if(G.obedit && ((G.qual & LR_CTRLKEY) || get_mbut()&R_MOUSE )) lr_click= 1; + VECCOPY(oldcurs, fp); + + project_short_noclip(fp, mval); + + initgrabz(fp[0], fp[1], fp[2]); + + if(mval[0]!=3200) { + + window_to_3d(dvec, mval[0]-mx, mval[1]-my); + VecSubf(fp, fp, dvec); + + } + else { + + dx= ((float)(mx-(curarea->winx/2)))*zfac/(curarea->winx/2); + dy= ((float)(my-(curarea->winy/2)))*zfac/(curarea->winy/2); + + fz= G.vd->persmat[0][3]*fp[0]+ G.vd->persmat[1][3]*fp[1]+ G.vd->persmat[2][3]*fp[2]+ G.vd->persmat[3][3]; + fz= fz/zfac; + + fp[0]= (G.vd->persinv[0][0]*dx + G.vd->persinv[1][0]*dy+ G.vd->persinv[2][0]*fz)-G.vd->ofs[0]; + fp[1]= (G.vd->persinv[0][1]*dx + G.vd->persinv[1][1]*dy+ G.vd->persinv[2][1]*fz)-G.vd->ofs[1]; + fp[2]= (G.vd->persinv[0][2]*dx + G.vd->persinv[1][2]*dy+ G.vd->persinv[2][2]*fz)-G.vd->ofs[2]; + } + + allqueue(REDRAWVIEW3D, 1); + } + + if(lr_click) { + if(G.obedit->type==OB_MESH) addvert_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) addvert_Nurb(0); + else if (G.obedit->type==OB_ARMATURE) addvert_armature(); + VECCOPY(fp, oldcurs); + } + +} + +void deselectall(void) /* is toggle */ +{ + Base *base; + int a=0; + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + a= 1; + break; + } + base= base->next; + } + + base= FIRSTBASE; + while(base) { + if(base->lay & G.vd->lay) { + if(a) base->flag &= ~SELECT; + else base->flag |= SELECT; + base->object->flag= base->flag; + } + base= base->next; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWDATASELECT, 0); + allqueue(REDRAWNLA, 0); + + countall(); + +} + +static void deselectall_ex(Base *b) /* ALLES deselect behalve b */ +{ + Base *base; + + base= FIRSTBASE; + while(base) { + if (base->flag & SELECT) { + if(b!=base) { + + base->flag &= ~SELECT; + base->object->flag= base->flag; + draw_object_ext(base); /* deze test op layer */ + } + } + base= base->next; + } + countall(); +} + +static unsigned int samplerect(unsigned int *buf, int size, unsigned int dontdo) +{ + Base *base; + unsigned int *bufmin,*bufmax; + int a,b,rc,tel,aantal,dirvec[4][2],maxob; + unsigned int retval=0; + + base= LASTBASE; + if(base==0) return 0; + maxob= base->selcol; + + aantal= (size-1)/2; + rc= 0; + + dirvec[0][0]= 1; + dirvec[0][1]= 0; + dirvec[1][0]= 0; + dirvec[1][1]= -size; + dirvec[2][0]= -1; + dirvec[2][1]= 0; + dirvec[3][0]= 0; + dirvec[3][1]= size; + + bufmin= buf; + bufmax= buf+ size*size; + buf+= aantal*size+ aantal; + + for(tel=1;tel<=size;tel++) { + + for(a=0;a<2;a++) { + for(b=0;b<tel;b++) { + + if(*buf && *buf<=maxob && *buf!=dontdo) return *buf; + if( *buf==dontdo ) retval= dontdo; /* als alleen kleur dontdo aanwezig is, wel dontdo teruggeven */ + + buf+= (dirvec[rc][0]+dirvec[rc][1]); + + if(buf<bufmin || buf>=bufmax) return retval; + } + rc++; + rc &= 3; + } + } + return retval; +} + +#define SELECTSIZE 51 + +void set_active_base(Base *base) +{ + + BASACT= base; + + /* signalen naar buttons */ + redraw_test_buttons(base); + + set_active_group(); + + /* signaal naar ipo */ + + if (base) { + allqueue(REDRAWIPO, base->object->ipowin); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + + +} + +void set_active_object(Object *ob) +{ + Base *base; + + base= FIRSTBASE; + while(base) { + if(base->object==ob) { + set_active_base(base); + return; + } + base= base->next; + } +} + +void mouse_select(void) +{ + Base *base, *startbase=0, *basact=0, *oldbasact; + GLuint buffer[MAXPICKBUF]; + int temp, a, dist=100; + short hits, mval[2]; + + /* iedere keer lijst starten vanuit basact */ + startbase= FIRSTBASE; + if(BASACT && BASACT->next) startbase= BASACT->next; + + getmouseco_areawin(mval); + + if(G.obedit==0 && (G.qual & LR_CTRLKEY)) { + + base= startbase; + while(base) { + + if(base->lay & G.vd->lay) { + + project_short(base->object->obmat[3], &base->sx); + + temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]); + if(base==BASACT) temp+=10; + if(temp<dist ) { + basact= base; + dist= temp; + } + } + base= base->next; + + if(base==0) base= FIRSTBASE; + if(base==startbase) break; + } + + /* volledige redraw als */ + if(G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) allqueue(REDRAWVIEW3D, 0); + + } + else { + hits= selectprojektie(buffer, mval[0]-7, mval[1]-7, mval[0]+7, mval[1]+7); + if(hits==0) hits= selectprojektie(buffer, mval[0]-21, mval[1]-21, mval[0]+21, mval[1]+21); + + if(hits>0) { + + base= startbase; + while(base) { + if(base->lay & G.vd->lay) { + for(a=0; a<hits; a++) { + /* index was converted */ + if(base->selcol==buffer[ (4 * a) + 3 ]) basact= base; + } + } + if(basact) break; + + base= base->next; + if(base==0) base= FIRSTBASE; + if(base==startbase) break; + } + } + } + + if(basact) { + if(G.obedit) { + /* alleen select doen */ + deselectall_ex(BASACT); + basact->flag |= SELECT; + draw_object_ext(basact); + } + else { + oldbasact= BASACT; + BASACT= basact; + + if((G.qual & LR_SHIFTKEY)==0) { + deselectall_ex(basact); + basact->flag |= SELECT; + } + else { + if(oldbasact) if(oldbasact != basact) draw_object_ext(oldbasact); + + if(basact->flag & SELECT) { + if(basact==oldbasact) + basact->flag &= ~SELECT; + } + else basact->flag |= SELECT; + } + + /* if((basact->flag & SELECT)==0) BASACT= 0; */ + basact->object->flag= basact->flag; + + draw_object_ext(basact); + + if(oldbasact != basact) { + + set_active_base(basact); + + } + + if(basact->object->type!=OB_MESH) { + if(G.f & G_WEIGHTPAINT) { + set_wpaint(); /* toggle */ + } + if(G.f & G_VERTEXPAINT) { + set_vpaint(); /* toggle */ + } + if(G.f & G_FACESELECT) { + set_faceselect(); /* toggle */ + } + } + + allqueue(REDRAWBUTSGAME, 0); + allqueue(REDRAWDATASELECT, 0); + allqueue(REDRAWBUTSCONSTRAINT, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWHEADERS, 0); /* To force display update for the posebutton */ + } + + } + + countall(); + + rightmouse_transform(); +} + +/* ------------------------------------------------------------------------- */ +/** + * Does the 'borderselect' command. (Select verts based on selecting with a + * border: key 'b'). All selecting seems to be done in the get_border part. + */ +void borderselect(void) +{ + rcti rect; + Base *base; + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + MetaElem *ml; + struct EditVert *eve; + /* was IGLuint */ + GLuint buffer[MAXPICKBUF]; + int a, index; + short hits, val, tel; + + if(G.obedit==0 && (G.f & G_FACESELECT)) { + face_borderselect(); + return; + } + + val= get_border(&rect, 3); + if(val) { + if (G.obpose){ + if(G.obpose->type==OB_ARMATURE) { + Bone *bone; + hits= selectprojektie(buffer, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + base= FIRSTBASE; + for (a=0; a<hits; a++){ + index = buffer[(4*a)+3]; + if (val==LEFTMOUSE){ + if (index != -1){ + bone = get_indexed_bone(G.obpose->data, index &~(BONESEL_TIP|BONESEL_ROOT)); + bone->flag |= BONE_SELECTED; + select_actionchannel_by_name(G.obpose->action, bone->name, 1); + } + } + else{ + if (index != -1){ + bone = get_indexed_bone(G.obpose->data, index &~(BONESEL_TIP|BONESEL_ROOT)); + bone->flag &= ~BONE_SELECTED; + select_actionchannel_by_name(G.obpose->action, bone->name, 0); + } + } + } + + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSCONSTRAINT, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWVIEW3D, 0); + } + } + else + if(G.obedit) { + /* used to be a bigger test, also included sector and life */ + if(G.obedit->type==OB_MESH) { + + calc_meshverts_ext(); /* drawobject.c */ + eve= G.edve.first; + while(eve) { + if(eve->h==0 && eve->xs>rect.xmin && eve->xs<rect.xmax) { + if(eve->ys>rect.ymin && eve->ys<rect.ymax) { + if(val==LEFTMOUSE) eve->f|= 1; + else eve->f&= 254; + } + } + eve= eve->next; + } + if(val!=LEFTMOUSE) tekenvertices_ext(0); + tekenvertices_ext(1); + + } + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + + calc_nurbverts_ext(); /* drawobject.c */ + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(bezt->hide==0) { + if(bezt->s[0][0]>rect.xmin && bezt->s[0][0]<rect.xmax) { + if(bezt->s[0][1]>rect.ymin && bezt->s[0][1]<rect.ymax) { + if(val==LEFTMOUSE) bezt->f1|= 1; + else bezt->f1 &= ~1; + } + } + if(bezt->s[1][0]>rect.xmin && bezt->s[1][0]<rect.xmax) { + if(bezt->s[1][1]>rect.ymin && bezt->s[1][1]<rect.ymax) { + if(val==LEFTMOUSE) { + bezt->f1|= 1; bezt->f2|= 1; bezt->f3|= 1; + } + else { + bezt->f1 &= ~1; bezt->f2 &= ~1; bezt->f3 &= ~1; + } + } + } + if(bezt->s[2][0]>rect.xmin && bezt->s[2][0]<rect.xmax) { + if(bezt->s[2][1]>rect.ymin && bezt->s[2][1]<rect.ymax) { + if(val==LEFTMOUSE) bezt->f3|= 1; + else bezt->f3 &= ~1; + } + } + } + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->hide==0) { + if(bp->s[0]>rect.xmin && bp->s[0]<rect.xmax) { + if(bp->s[1]>rect.ymin && bp->s[1]<rect.ymax) { + if(val==LEFTMOUSE) bp->f1|= 1; + else bp->f1 &= ~1; + } + } + } + bp++; + } + } + nu= nu->next; + } + allqueue(REDRAWVIEW3D, 0); + } + else if(G.obedit->type==OB_MBALL) { + hits= selectprojektie(buffer, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + + ml= editelems.first; + + while(ml) { + for(a=0; a<hits; a++) { + if(ml->selcol==buffer[ (4 * a) + 3 ]) { + if(val==LEFTMOUSE) ml->flag |= SELECT; + else ml->flag &= ~SELECT; + break; + } + } + ml= ml->next; + } + allqueue(REDRAWVIEW3D, 0); + } + else if(G.obedit->type==OB_ARMATURE) { + EditBone *ebone; + + hits= selectprojektie(buffer, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + + base= FIRSTBASE; + for (a=0; a<hits; a++){ + index = buffer[(4*a)+3]; + if (val==LEFTMOUSE){ + if (index!=-1){ + ebone = BLI_findlink(&G.edbo, index & ~(BONESEL_TIP|BONESEL_ROOT)); + if (index & BONESEL_TIP) + ebone->flag |= BONE_TIPSEL; + if (index & BONESEL_ROOT) + ebone->flag |= BONE_ROOTSEL; + } + } + else{ + if (index!=-1){ + ebone = BLI_findlink(&G.edbo, index & ~(BONESEL_TIP|BONESEL_ROOT)); + if (index & BONESEL_TIP) + ebone->flag &= ~BONE_TIPSEL; + if (index & BONESEL_ROOT) + ebone->flag &= ~BONE_ROOTSEL; + } + } + } + + /* XXX, are all these really needed? + * I just copied them from the G.obpose + * OB_ARMATURE section above. - zr + */ + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSCONSTRAINT, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWVIEW3D, 0); + } + else if(G.obedit->type==OB_LATTICE) { + + calc_lattverts_ext(); + + bp= editLatt->def; + + a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + while(a--) { + if(bp->hide==0) { + if(bp->s[0]>rect.xmin && bp->s[0]<rect.xmax) { + if(bp->s[1]>rect.ymin && bp->s[1]<rect.ymax) { + if(val==LEFTMOUSE) bp->f1|= 1; + else bp->f1 &= ~1; + } + } + } + bp++; + } + allqueue(REDRAWVIEW3D, 0); + } + + } + else { + + hits= selectprojektie(buffer, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + + base= FIRSTBASE; + while(base) { + if(base->lay & G.vd->lay) { + for(a=0; a<hits; a++) { + /* converted index */ + if(base->selcol==buffer[ (4 * a) + 3 ]) { + if(val==LEFTMOUSE) base->flag |= SELECT; + else base->flag &= ~SELECT; + base->object->flag= base->flag; + + draw_object_ext(base); + break; + } + } + } + + base= base->next; + } + allqueue(REDRAWDATASELECT, 0); + + /* i.v.m. backbufprojektie */ + tel= 1; + base= FIRSTBASE; + while(base) { + /* elke base ivm meerdere windows */ + base->selcol = ((tel & 0xF00)<<12) + + ((tel & 0xF0)<<8) + + ((tel & 0xF)<<4); + tel++; + base= base->next; + } + /* new */ + allqueue(REDRAWBUTSGAME, 0); + allqueue(REDRAWNLA, 0); + } + countall(); + + allqueue(REDRAWINFO, 0); + } +} /* end of borderselect() */ + +/* ------------------------------------------------------------------------- */ + +/** The following functions are quick & dirty callback functions called + * on the Circle select function (press B twice in Editmode) + * They were torn out of the circle_select to make the latter more reusable + * The callback version of circle_select (called circle_selectCB) was moved + * to edit.c because of it's (wanted) generality. + + XXX These callback functions are still dirty, because they call globals... + */ + +void mesh_selectionCB(int selecting, Object *editobj, short *mval, float rad) +{ + EditVert *eve; + float x, y, r; + + calc_meshverts_ext(); /* drawobject.c */ + eve= G.edve.first; + while(eve) { + if(eve->h==0) { + x= eve->xs-mval[0]; + y= eve->ys-mval[1]; + r= sqrt(x*x+y*y); + if(r<=rad) { + if(selecting==LEFTMOUSE) eve->f|= 1; + else eve->f&= 254; + } + } + eve= eve->next; + } + if(G.f & (G_FACESELECT+G_DRAWFACES)) { + draw_sel_circle(0, 0, 0, 0, 0); /* signal */ + force_draw(); + } + else { + if(selecting!=LEFTMOUSE) tekenvertices_ext(0); + /* altijd geselecteerde vertices tekenen */ + tekenvertices_ext(1); + } +} + + +void nurbscurve_selectionCB(int selecting, Object *editobj, short *mval, float rad) +{ + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + float x, y, r; + int a; + + calc_nurbverts_ext(); /* drawobject.c */ + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(bezt->hide==0) { + x= bezt->s[0][0]-mval[0]; + y= bezt->s[0][1]-mval[1]; + r= sqrt(x*x+y*y); + if(r<=rad) { + if(selecting==LEFTMOUSE) bezt->f1|= 1; + else bezt->f1 &= ~1; + } + x= bezt->s[1][0]-mval[0]; + y= bezt->s[1][1]-mval[1]; + r= sqrt(x*x+y*y); + if(r<=rad) { + if(selecting==LEFTMOUSE) bezt->f2|= 1; + else bezt->f2 &= ~1; + } + x= bezt->s[2][0]-mval[0]; + y= bezt->s[2][1]-mval[1]; + r= sqrt(x*x+y*y); + if(r<=rad) { + if(selecting==LEFTMOUSE) bezt->f3|= 1; + else bezt->f3 &= ~1; + } + + } + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->hide==0) { + x= bp->s[0]-mval[0]; + y= bp->s[1]-mval[1]; + r= sqrt(x*x+y*y); + if(r<=rad) { + if(selecting==LEFTMOUSE) bp->f1|= 1; + else bp->f1 &= ~1; + } + } + bp++; + } + } + nu= nu->next; + } + draw_sel_circle(0, 0, 0, 0, 0); /* signal */ + force_draw(); + + +} + +void lattice_selectionCB(int selecting, Object *editobj, short *mval, float rad) +{ + BPoint *bp; + float x, y, r; + int a; + + calc_lattverts_ext(); + + bp= editLatt->def; + + a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + while(a--) { + if(bp->hide==0) { + x= bp->s[0]-mval[0]; + y= bp->s[1]-mval[1]; + r= sqrt(x*x+y*y); + if(r<=rad) { + if(selecting==LEFTMOUSE) bp->f1|= 1; + else bp->f1 &= ~1; + } + } + bp++; + } + draw_sel_circle(0, 0, 0, 0, 0); /* signal */ + force_draw(); +} + +/** Callbacks for selection in Editmode */ + +void obedit_selectionCB(short selecting, Object *editobj, short *mval, float rad) +{ + switch(editobj->type) { + case OB_MESH: + mesh_selectionCB(selecting, editobj, mval, rad); + break; + case OB_CURVE: + case OB_SURF: + nurbscurve_selectionCB(selecting, editobj, mval, rad); + break; + case OB_LATTICE: + lattice_selectionCB(selecting, editobj, mval, rad); + break; + } +} + +/** The circle select function - should be replaced by the callback + * version circle_selectCB(). Why ? Because it's not nice as it is! + * + */ + +void circle_select(void) +{ + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + EditVert *eve; + static float rad= 40.0; + float rado, x, y, trad; + int a, firsttime=1; + unsigned short event; + short mvalo[2], mval[2], val; + short selecting=0; + + if(G.obedit==0) return; + + getmouseco_areawin(mvalo); + draw_sel_circle(mvalo, 0, rad, 0.0, selecting); + + rado= rad; + + while(TRUE) { + + /* als een renderwindow open is en de muis gaat erin */ + + mywinset(curarea->win); + + getmouseco_areawin(mval); + + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || rado!=rad || firsttime) { + firsttime= 0; + + draw_sel_circle(mval, mvalo, rad, rado, selecting); + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + rado= rad; + + if(selecting) { + + if(G.obedit->type==OB_MESH) { + + calc_meshverts_ext(); /* drawobject.c */ + eve= G.edve.first; + while(eve) { + if(eve->h==0) { + x= eve->xs-mval[0]; + y= eve->ys-mval[1]; + trad= sqrt(x*x+y*y); + if(trad<=rad) { + if(selecting==LEFTMOUSE) eve->f|= 1; + else eve->f&= 254; + } + } + eve= eve->next; + } + if(G.f & (G_FACESELECT+G_DRAWFACES)) { + draw_sel_circle(0, 0, 0, 0, 0); /* signal */ + force_draw(); + } + else { + if(selecting!=LEFTMOUSE) tekenvertices_ext(0); + /* altijd geselecteerde vertices tekenen */ + tekenvertices_ext(1); + } + } + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + + calc_nurbverts_ext(); /* drawobject.c */ + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(bezt->hide==0) { + x= bezt->s[0][0]-mval[0]; + y= bezt->s[0][1]-mval[1]; + trad= sqrt(x*x+y*y); + if(trad<=rad) { + if(selecting==LEFTMOUSE) bezt->f1|= 1; + else bezt->f1 &= ~1; + } + x= bezt->s[1][0]-mval[0]; + y= bezt->s[1][1]-mval[1]; + trad= sqrt(x*x+y*y); + if(trad<=rad) { + if(selecting==LEFTMOUSE) bezt->f2|= 1; + else bezt->f2 &= ~1; + } + x= bezt->s[2][0]-mval[0]; + y= bezt->s[2][1]-mval[1]; + trad= sqrt(x*x+y*y); + if(trad<=rad) { + if(selecting==LEFTMOUSE) bezt->f3|= 1; + else bezt->f3 &= ~1; + } + + } + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->hide==0) { + x= bp->s[0]-mval[0]; + y= bp->s[1]-mval[1]; + trad= sqrt(x*x+y*y); + if(trad<=rad) { + if(selecting==LEFTMOUSE) bp->f1|= 1; + else bp->f1 &= ~1; + } + } + bp++; + } + } + nu= nu->next; + } + draw_sel_circle(0, 0, 0, 0, 0); /* signal */ + force_draw(); + } + else if(G.obedit->type==OB_LATTICE) { + calc_lattverts_ext(); + + bp= editLatt->def; + + a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + while(a--) { + if(bp->hide==0) { + x= bp->s[0]-mval[0]; + y= bp->s[1]-mval[1]; + trad= sqrt(x*x+y*y); + if(trad<=rad) { + if(selecting==LEFTMOUSE) bp->f1|= 1; + else bp->f1 &= ~1; + } + } + bp++; + } + draw_sel_circle(0, 0, 0, 0, 0); /* signal */ + force_draw(); + } + } + } + + event= extern_qread(&val); + if (event) { + int afbreek= 0; + + switch(event) { + case LEFTMOUSE: + case MIDDLEMOUSE: + if(val) selecting= event; + else selecting= 0; + firsttime= 1; + + break; + case PADPLUSKEY: + if(val) if(rad<200.0) rad*= 1.2; + break; + case PADMINUS: + if(val) if(rad>5.0) rad/= 1.2; + break; + + case ESCKEY: case SPACEKEY: case RIGHTMOUSE: + case GKEY: case SKEY: case RKEY: case XKEY: case EKEY: case TABKEY: + afbreek= 1; + break; + + } + + if(afbreek) break; + } + } + + /* cirkel wissen */ + draw_sel_circle(0, mvalo, 0, rad, 1); + + countall(); + allqueue(REDRAWINFO, 0); +} + +void set_render_border(void) +{ + rcti rect; + short val; + + if(G.vd->persp!=2) return; + + val= get_border(&rect, 2); + if(val) { + rcti vb; + + calc_viewborder(G.vd, &vb); + + G.scene->r.border.xmin= (float) (rect.xmin-vb.xmin)/(vb.xmax-vb.xmin); + G.scene->r.border.ymin= (float) (rect.ymin-vb.ymin)/(vb.ymax-vb.ymin); + G.scene->r.border.xmax= (float) (rect.xmax-vb.xmin)/(vb.xmax-vb.xmin); + G.scene->r.border.ymax= (float) (rect.ymax-vb.ymin)/(vb.ymax-vb.ymin); + + CLAMP(G.scene->r.border.xmin, 0.0, 1.0); + CLAMP(G.scene->r.border.ymin, 0.0, 1.0); + CLAMP(G.scene->r.border.xmax, 0.0, 1.0); + CLAMP(G.scene->r.border.ymax, 0.0, 1.0); + + allqueue(REDRAWVIEWCAM, 1); + } +} + + + +void fly(void) +{ + float speed=0.0, speedo=1.0, zspeed=0.0, dvec[3], *quat, mat[3][3]; + float oldvec[3], oldrot[3]; + int loop=1; + unsigned short toets; + short val, cent[2]; + short mval[2]; + + if(curarea->spacetype!=SPACE_VIEW3D) return; + if(G.vd->camera == 0) return; + if(G.vd->persp<2) return; + + VECCOPY(oldvec, G.vd->camera->loc); + VECCOPY(oldrot, G.vd->camera->rot); + + cent[0]= curarea->winrct.xmin+(curarea->winx)/2; + cent[1]= curarea->winrct.ymin+(curarea->winy)/2; + + warp_pointer(cent[0], cent[1]); + + cent[0]= (curarea->winx)/2; + cent[1]= (curarea->winy)/2; + + headerprint("Fly"); + + while(loop) { + getmouseco_areawin(mval); + + while(qtest()) { + + toets= extern_qread(&val); + + if(val) { + if(toets==ESCKEY) { + VECCOPY(G.vd->camera->loc, oldvec); + VECCOPY(G.vd->camera->rot, oldrot); + loop= 0; + break; + } + else if(toets==SPACEKEY) { + loop= 0; + break; + } + else if(toets==LEFTMOUSE) { + speed+= G.vd->grid/75.0; + if(get_mbut()&M_MOUSE) speed= 0.0; + } + else if(toets==MIDDLEMOUSE) { + speed-= G.vd->grid/75.0; + if(get_mbut()&L_MOUSE) speed= 0.0; + } + } + } + if(loop==0) break; + + /* dvec bepalen */ + val= mval[0]-cent[0]; + if(val>20) val-= 20; else if(val< -20) val+= 20; else val= 0; + dvec[0]= 0.000001*val*val; + if(val>0) dvec[0]= -dvec[0]; + + val= mval[1]-cent[1]; + if(val>20) val-= 20; else if(val< -20) val+= 20; else val= 0; + dvec[1]= 0.000001*val*val; + if(val>0) dvec[1]= -dvec[1]; + + dvec[2]= 1.0; + + zspeed= 0.0; + if(get_qual()&LR_CTRLKEY) zspeed= -G.vd->grid/25.0; + if(get_qual()&LR_ALTKEY) zspeed= G.vd->grid/25.0; + + if(speedo!=0.0 || zspeed!=0.0 || dvec[0]!=0.0 || dvec[1]!=0.0) { + + Normalise(dvec); + + Mat3CpyMat4(mat, G.vd->viewinv); + Mat3MulVecfl(mat, dvec); + quat= vectoquat(dvec, 5, 1); /* track en upflag, niet die van de base: cameraview-berekening gebruikt ze niet */ + + QuatToEul(quat, G.vd->camera->rot); + + compatible_eul(G.vd->camera->rot, oldrot); + + VecMulf(dvec, speed); + G.vd->camera->loc[0]-= dvec[0]; + G.vd->camera->loc[1]-= dvec[1]; + G.vd->camera->loc[2]-= (dvec[2]-zspeed); + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } + speedo= speed; + } + + allqueue(REDRAWVIEW3D, 0); + scrarea_queue_headredraw(curarea); + +} + diff --git a/source/blender/src/eventdebug.c b/source/blender/src/eventdebug.c new file mode 100644 index 00000000000..6c9a5ee005b --- /dev/null +++ b/source/blender/src/eventdebug.c @@ -0,0 +1,203 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#include "mydevice.h" +#include "blendef.h" + +char *event_to_string(short evt) { +#define smap(evt) case evt: return #evt + switch (evt) { + default: return "<unknown>"; + smap(CHANGED); + smap(DRAWEDGES); + smap(BACKBUFDRAW); + smap(EXECUTE); + smap(LOAD_FILE); + smap(RESHAPE); + smap(UI_BUT_EVENT); + smap(REDRAWVIEW3D); + smap(REDRAWBUTSHEAD); + smap(REDRAWBUTSALL); + smap(REDRAWBUTSVIEW); + smap(REDRAWBUTSLAMP); + smap(REDRAWBUTSMAT); + smap(REDRAWBUTSTEX); + smap(REDRAWBUTSANIM); + smap(REDRAWBUTSWORLD); + smap(REDRAWBUTSRENDER); + smap(REDRAWBUTSEDIT); + smap(REDRAWVIEWCAM); + smap(REDRAWHEADERS); + smap(REDRAWBUTSGAME); + smap(REDRAWBUTSRADIO); + smap(REDRAWVIEW3D_Z); + smap(REDRAWALL); + smap(REDRAWINFO); + smap(RENDERPREVIEW); + smap(REDRAWIPO); + smap(REDRAWDATASELECT); + smap(REDRAWSEQ); + smap(REDRAWIMAGE); + smap(REDRAWOOPS); + smap(REDRAWIMASEL); + smap(AFTERIMASELIMA); + smap(AFTERIMASELGET); + smap(AFTERIMAWRITE); + smap(IMALEFTMOUSE); + smap(AFTERPIBREAD); + smap(REDRAWTEXT); + smap(REDRAWBUTSSCRIPT); + smap(REDRAWSOUND); + smap(REDRAWBUTSSOUND); + smap(REDRAWACTION); + smap(LEFTMOUSE); + smap(MIDDLEMOUSE); + smap(RIGHTMOUSE); + smap(MOUSEX); + smap(MOUSEY); + smap(TIMER0); + smap(TIMER1); + smap(TIMER2); + smap(TIMER3); + smap(KEYBD); + smap(RAWKEYBD); + smap(REDRAW); + smap(INPUTCHANGE); + smap(QFULL); + smap(WINFREEZE); + smap(WINTHAW); + smap(WINCLOSE); + smap(WINQUIT); + smap(Q_FIRSTTIME); + smap(AKEY); + smap(BKEY); + smap(CKEY); + smap(DKEY); + smap(EKEY); + smap(FKEY); + smap(GKEY); + smap(HKEY); + smap(IKEY); + smap(JKEY); + smap(KKEY); + smap(LKEY); + smap(MKEY); + smap(NKEY); + smap(OKEY); + smap(PKEY); + smap(QKEY); + smap(RKEY); + smap(SKEY); + smap(TKEY); + smap(UKEY); + smap(VKEY); + smap(WKEY); + smap(XKEY); + smap(YKEY); + smap(ZKEY); + smap(ZEROKEY); + smap(ONEKEY); + smap(TWOKEY); + smap(THREEKEY); + smap(FOURKEY); + smap(FIVEKEY); + smap(SIXKEY); + smap(SEVENKEY); + smap(EIGHTKEY); + smap(NINEKEY); + smap(CAPSLOCKKEY); + smap(LEFTCTRLKEY); + smap(LEFTALTKEY); + smap(RIGHTALTKEY); + smap(RIGHTCTRLKEY); + smap(RIGHTSHIFTKEY); + smap(LEFTSHIFTKEY); + smap(ESCKEY); + smap(TABKEY); + smap(RETKEY); + smap(SPACEKEY); + smap(LINEFEEDKEY); + smap(BACKSPACEKEY); + smap(DELKEY); + smap(SEMICOLONKEY); + smap(PERIODKEY); + smap(COMMAKEY); + smap(QUOTEKEY); + smap(ACCENTGRAVEKEY); + smap(MINUSKEY); + smap(SLASHKEY); + smap(BACKSLASHKEY); + smap(EQUALKEY); + smap(LEFTBRACKETKEY); + smap(RIGHTBRACKETKEY); + smap(LEFTARROWKEY); + smap(DOWNARROWKEY); + smap(RIGHTARROWKEY); + smap(UPARROWKEY); + smap(PAD0); + smap(PAD1); + smap(PAD2); + smap(PAD3); + smap(PAD4); + smap(PAD5); + smap(PAD6); + smap(PAD7); + smap(PAD8); + smap(PAD9); + smap(PADPERIOD); + smap(PADSLASHKEY); + smap(PADASTERKEY); + smap(PADMINUS); + smap(PADENTER); + smap(PADPLUSKEY); + smap(F1KEY); + smap(F2KEY); + smap(F3KEY); + smap(F4KEY); + smap(F5KEY); + smap(F6KEY); + smap(F7KEY); + smap(F8KEY); + smap(F9KEY); + smap(F10KEY); + smap(F11KEY); + smap(F12KEY); + smap(PAUSEKEY); + smap(INSERTKEY); + smap(HOMEKEY); + smap(PAGEUPKEY); + smap(PAGEDOWNKEY); + smap(ENDKEY); + smap(REDRAWBUTSCONSTRAINT); + smap(REDRAWNLA); + } + #undef smap +} diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c new file mode 100644 index 00000000000..7a63a7779a0 --- /dev/null +++ b/source/blender/src/filesel.c @@ -0,0 +1,2376 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#ifdef WIN32 +#include <io.h> +#include <direct.h> +#include "BLI_winstuff.h" +#else +#include <unistd.h> +#include <sys/times.h> +#endif + +#include <sys/stat.h> +#include <sys/types.h> +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_linklist.h" +#include "BLI_storage_types.h" +#include "BLI_dynstr.h" + +#include "IMB_imbuf.h" + +#include "DNA_curve_types.h" +#include "DNA_image_types.h" +#include "DNA_ipo_types.h" +#include "DNA_vfont_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_texture_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_displist.h" +#include "BKE_library.h" +#include "BKE_curve.h" +#include "BKE_font.h" +#include "BKE_material.h" + +#include "BIF_gl.h" +#include "BIF_interface.h" +#include "BIF_toolbox.h" +#include "BIF_mywindow.h" +#include "BIF_editview.h" +#include "BIF_space.h" +#include "BIF_screen.h" + +#include "BLO_readfile.h" + +#include "BDR_editcurve.h" +#include "BSE_filesel.h" +#include "BSE_view.h" + +#include "mydevice.h" +#include "blendef.h" +#include "render.h" +#include "interface.h" +#include "nla.h" + +#if defined WIN32 || defined __BeOS + int fnmatch(){return 0;} +#else + #include <fnmatch.h> +#endif + +#ifndef WIN32 +#include <sys/param.h> +#endif + +#define FILESELHEAD 60 +#define FILESEL_DY 16 + +#define NOTACTIVE 0 +#define ACTIVATE 1 +#define INACTIVATE 2 + +#define STARTSWITH(x, y) (strncmp(x, y, sizeof(x) - 1) == 0) + +static int is_a_library(SpaceFile *sfile, char *dir, char *group); +static void do_library_append(SpaceFile *sfile); +static void library_to_filelist(SpaceFile *sfile); +static void filesel_select_objects(struct SpaceFile *sfile); +static void active_file_object(struct SpaceFile *sfile); +static int groupname_to_code(char *group); + +/* local globals */ + +static rcti scrollrct, textrct, bar; +static int filebuty1, filebuty2, page_ofs, collumwidth, selecting=0; +static int filetoname= 0; +static float pixels_to_ofs; +static char otherdir[FILE_MAXDIR]; +static ScrArea *otherarea; + +/* FSMENU HANDLING */ + + /* FSMenuEntry's without paths indicate seperators */ +typedef struct _FSMenuEntry FSMenuEntry; +struct _FSMenuEntry { + FSMenuEntry *next; + + char *path; +}; + +static FSMenuEntry *fsmenu= 0, *lseperator= 0; + +int fsmenu_get_nentries(void) +{ + FSMenuEntry *fsme; + int count= 0; + + for (fsme= fsmenu; fsme; fsme= fsme->next) + count++; + + return count; +} +int fsmenu_is_entry_a_seperator(int idx) +{ + FSMenuEntry *fsme; + + for (fsme= fsmenu; fsme && idx; fsme= fsme->next) + idx--; + + return (fsme && !fsme->path)?1:0; +} +char *fsmenu_get_entry(int idx) +{ + FSMenuEntry *fsme; + + for (fsme= fsmenu; fsme && idx; fsme= fsme->next) + idx--; + + return fsme?fsme->path:NULL; +} +char *fsmenu_build_menu(void) +{ + DynStr *ds= BLI_dynstr_new(); + FSMenuEntry *fsme; + char *menustr; + + for (fsme= fsmenu; fsme; fsme= fsme->next) { + if (!fsme->path) { + /* ignore consecutive or trailing seperators */ + if (fsme->next && fsme->next->path) + BLI_dynstr_append(ds, "%l|"); + } else { + BLI_dynstr_append(ds, fsme->path); + if (fsme->next) BLI_dynstr_append(ds, "|"); + } + } + + menustr= BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + return menustr; +} +void fsmenu_insert_entry(char *path, int sorted) +{ + FSMenuEntry *fsme, *prev; + + if (lseperator) { + prev= lseperator; + fsme= lseperator->next; + } else { + prev= NULL; + fsme= fsmenu; + } + for (; fsme; prev= fsme, fsme= fsme->next) { + if (fsme->path) { + if (BLI_streq(path, fsme->path)) { + return; + } else if (sorted && strcmp(path, fsme->path)<0) { + break; + } + } + } + + fsme= MEM_mallocN(sizeof(*fsme), "fsme"); + fsme->path= BLI_strdup(path); + + if (prev) { + fsme->next= prev->next; + prev->next= fsme; + } else { + fsme->next= fsmenu; + fsmenu= fsme; + } +} +void fsmenu_append_seperator(void) +{ + if (fsmenu) { + FSMenuEntry *fsme= fsmenu; + + while (fsme->next) fsme= fsme->next; + + lseperator= MEM_mallocN(sizeof(*fsme), "fsme"); + lseperator->next= NULL; + lseperator->path= NULL; + + fsme->next= lseperator; + } +} +void fsmenu_remove_entry(int idx) +{ + FSMenuEntry *prev= NULL, *fsme= fsmenu; + + for (fsme= fsmenu; fsme && idx; prev= fsme, fsme= fsme->next) + if (fsme->path) + idx--; + + if (fsme) { + if (prev) { + prev->next= fsme->next; + } else { + fsmenu= fsme->next; + } + + MEM_freeN(fsme->path); + MEM_freeN(fsme); + } +} +void fsmenu_free(void) +{ + FSMenuEntry *fsme= fsmenu; + + while (fsme) { + FSMenuEntry *n= fsme->next; + + if (fsme->path) MEM_freeN(fsme->path); + MEM_freeN(fsme); + + fsme= n; + } +} + +/* ******************* SORT ******************* */ + +static int compare_name(const void *a1, const void *a2) +{ + const struct direntry *entry1=a1, *entry2=a2; + + /* type is gelijk aan stat.st_mode */ + + if (S_ISDIR(entry1->type)){ + if (S_ISDIR(entry2->type)==0) return (-1); + } else{ + if (S_ISDIR(entry2->type)) return (1); + } + if (S_ISREG(entry1->type)){ + if (S_ISREG(entry2->type)==0) return (-1); + } else{ + if (S_ISREG(entry2->type)) return (1); + } + if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); + if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); + return (strcasecmp(entry1->relname,entry2->relname)); +} + +static int compare_date(const void *a1, const void *a2) +{ + const struct direntry *entry1=a1, *entry2=a2; + + /* type is gelijk aan stat.st_mode */ + + if (S_ISDIR(entry1->type)){ + if (S_ISDIR(entry2->type)==0) return (-1); + } else{ + if (S_ISDIR(entry2->type)) return (1); + } + if (S_ISREG(entry1->type)){ + if (S_ISREG(entry2->type)==0) return (-1); + } else{ + if (S_ISREG(entry2->type)) return (1); + } + if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); + if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); + +/* + if ( entry1->s.st_ctime < entry2->s.st_ctime) return 1; + if ( entry1->s.st_ctime > entry2->s.st_ctime) return -1; +*/ + if ( entry1->s.st_mtime < entry2->s.st_mtime) return 1; + if ( entry1->s.st_mtime > entry2->s.st_mtime) return -1; + else return strcasecmp(entry1->relname,entry2->relname); +} + +static int compare_size(const void *a1, const void *a2) +{ + const struct direntry *entry1=a1, *entry2=a2; + + /* type is gelijk aan stat.st_mode */ + + if (S_ISDIR(entry1->type)){ + if (S_ISDIR(entry2->type)==0) return (-1); + } else{ + if (S_ISDIR(entry2->type)) return (1); + } + if (S_ISREG(entry1->type)){ + if (S_ISREG(entry2->type)==0) return (-1); + } else{ + if (S_ISREG(entry2->type)) return (1); + } + if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); + if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); + + if ( entry1->s.st_size < entry2->s.st_size) return 1; + if ( entry1->s.st_size > entry2->s.st_size) return -1; + else return strcasecmp(entry1->relname,entry2->relname); +} + + +/* **************************************** */ + +void clear_global_filesel_vars() +{ + selecting= 0; +} + + +void filesel_statistics(SpaceFile *sfile, int *totfile, int *selfile, float *totlen, float *sellen) +{ + int a, len; + + *totfile= *selfile= 0; + *totlen= *sellen= 0; + + if(sfile->filelist==0) return; + + for(a=0; a<sfile->totfile; a++) { + if( (sfile->filelist[a].type & S_IFDIR)==0 ) { + (*totfile) ++; + + len = sfile->filelist[a].s.st_size; + (*totlen) += (len/1048576.0); + + if(sfile->filelist[a].flags & ACTIVE) { + (*selfile) ++; + (*sellen) += (len/1048576.0); + } + } + } +} + +/* *************** HULPFUNKTIES ******************* */ + +/* This is a really ugly function... its purpose is to + * take the space file name and clean it up, replacing + * excess file entry stuff (like /tmp/../tmp/../) + */ + +void checkdir(char *dir) +{ + short a; + char *start, *eind; + char tmp[FILE_MAXDIR+FILE_MAXFILE]; + + BLI_make_file_string(G.sce, tmp, dir, ""); + strcpy(dir, tmp); + +#ifdef WIN32 + if(dir[0]=='.') { /* komt voor, o.a. bij FILE_MAIN */ + dir[0]= '\\'; + dir[1]= 0; + return; + } + + while (start = strstr(dir, "\\..\\")) { + eind = start + strlen("\\..\\") - 1; + a = start-dir-1; + while (a>0) { + if (dir[a] == '\\') break; + a--; + } + strcpy(dir+a,eind); + } + + while (start = strstr(dir,"\\.\\")){ + eind = start + strlen("\\.\\") - 1; + strcpy(start,eind); + } + + while (start = strstr(dir,"\\\\" )){ + eind = start + strlen("\\\\") - 1; + strcpy(start,eind); + } + + if(a = strlen(dir)){ /* eerst alle '\\' weghalen aan het eind */ + while(a>0 && dir[a-1] == '\\'){ + a--; + dir[a] = 0; + } + } + + strcat(dir, "\\"); +#else + if(dir[0]=='.') { /* komt voor, o.a. bij FILE_MAIN */ + dir[0]= '/'; + dir[1]= 0; + return; + } + + while ( (start = strstr(dir, "/../")) ) { + eind = start + strlen("/../") - 1; + a = start-dir-1; + while (a>0) { + if (dir[a] == '/') break; + a--; + } + strcpy(dir+a,eind); + } + + while ( (start = strstr(dir,"/./")) ){ + eind = start + strlen("/./") - 1; + strcpy(start,eind); + } + + while ( (start = strstr(dir,"//" )) ){ + eind = start + strlen("//") - 1; + strcpy(start,eind); + } + + if( (a = strlen(dir)) ){ /* eerst alle '/' weghalen aan het eind */ + while(dir[a-1] == '/'){ + a--; + dir[a] = 0; + if (a<=0) break; + } + } + + strcat(dir, "/"); +#endif +} + +void test_flags_file(SpaceFile *sfile) +{ + struct direntry *file; + int num; + + file= sfile->filelist; + + for(num=0; num<sfile->totfile; num++, file++) { + file->flags= 0; + file->type= file->s.st_mode; /* restore het geknoei van hieronder */ + + /* Don't check extensions for directories */ + if (file->type&S_IFDIR) + continue; + + if(sfile->type==FILE_BLENDER || sfile->type==FILE_LOADLIB) { + if(BLO_has_bfile_extension(file->relname)) { + file->flags |= BLENDERFILE; + if(sfile->type==FILE_LOADLIB) { + file->type &= ~S_IFMT; + file->type |= S_IFDIR; + } + } + else if(BLI_testextensie(file->relname, ".psx")) { + file->flags |= PSXFILE; + } + } else if (sfile->type==FILE_SPECIAL){ + if(BLI_testextensie(file->relname, ".jpg") || + BLI_testextensie(file->relname, ".tga") || + BLI_testextensie(file->relname, ".rgb") || + BLI_testextensie(file->relname, ".png") || + BLI_testextensie(file->relname, ".sgi")) { + file->flags |= IMAGEFILE; + } + else if(BLI_testextensie(file->relname, ".avi") || + BLI_testextensie(file->relname, ".mv")) { + file->flags |= MOVIEFILE; + } + } + } +} + + +void sort_filelist(SpaceFile *sfile) +{ + struct direntry *file; + int num;/* , act= 0; */ + + switch(sfile->sort) { + case FILE_SORTALPHA: + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name); + break; + case FILE_SORTDATE: + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_date); + break; + case FILE_SORTSIZE: + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_size); + break; + case FILE_SORTEXTENS: + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name); + break; + } + + sfile->act= -1; + + file= sfile->filelist; + for(num=0; num<sfile->totfile; num++, file++) { + file->flags &= ~HILITE; + } + +} + +void read_dir(SpaceFile *sfile) +{ + int num, len; + char wdir[FILE_MAXDIR]; + + /* sfile->act wordt gebruikt o.a. bij databrowse: dubbele namen van library objecten */ + sfile->act= -1; + + if(sfile->type==FILE_MAIN) { + main_to_filelist(sfile); + return; + } + else if(sfile->type==FILE_LOADLIB) { + library_to_filelist(sfile); + if(sfile->libfiledata) return; + } + + BLI_hide_dot_files(sfile->flag & FILE_HIDE_DOT); + + BLI_getwdN(wdir); + sfile->totfile= BLI_getdir(sfile->dir, &(sfile->filelist)); + chdir(wdir); + + if(sfile->sort!=FILE_SORTALPHA) sort_filelist(sfile); + + sfile->maxnamelen= 0; + + for (num=0; num<sfile->totfile; num++) { + + len = BMF_GetStringWidth(G.font, sfile->filelist[num].relname); + if (len > sfile->maxnamelen) sfile->maxnamelen = len; + + if(filetoname) { + if(strcmp(sfile->file, sfile->filelist[num].relname)==0) { + + sfile->ofs= num-( sfile->collums*(curarea->winy-FILESELHEAD-20)/(2*FILESEL_DY)); + filetoname= 0; + } + } + } + test_flags_file(sfile); + + filetoname= 0; +} + +void freefilelist(SpaceFile *sfile) +{ + int num; + + num= sfile->totfile-1; + + if (sfile->filelist==0) return; + + for(; num>=0; num--){ + free(sfile->filelist[num].relname); + + if (sfile->filelist[num].string) free(sfile->filelist[num].string); + } + free(sfile->filelist); + sfile->filelist= 0; +} + +static void split_sfile(SpaceFile *sfile, char *s1) +{ + char string[FILE_MAXDIR+FILE_MAXFILE], dir[FILE_MAXDIR], file[FILE_MAXFILE]; + + strcpy(string, s1); + + BLI_split_dirfile(string, dir, file); + + if(sfile->filelist) { + if(strcmp(dir, sfile->dir)!=0) { + freefilelist(sfile); + } + else test_flags_file(sfile); + } + strcpy(sfile->file, file); + BLI_make_file_string(G.sce, sfile->dir, dir, ""); +} + + +void parent(SpaceFile *sfile) +{ + short a; + char *dir; + + /* als databrowse: geen parent */ + if(sfile->type==FILE_MAIN && sfile->returnfunc) return; + + dir= sfile->dir; + +#ifdef WIN32 + if(a = strlen(dir)) { /* eerst alle '/' weghalen aan het eind */ + while(dir[a-1] == '\\') { + a--; + dir[a] = 0; + if (a<=0) break; + } + } + if(a = strlen(dir)) { /* daarna alles weghalen tot aan '/' */ + while(dir[a-1] != '\\') { + a--; + dir[a] = 0; + if (a<=0) break; + } + } + if (a = strlen(dir)) { + if (dir[a-1] != '\\') strcat(dir,"\\"); + } + else if(sfile->type!=FILE_MAIN) strcpy(dir,"\\"); +#else + if( (a = strlen(dir)) ) { /* eerst alle '/' weghalen aan het eind */ + while(dir[a-1] == '/') { + a--; + dir[a] = 0; + if (a<=0) break; + } + } + if( (a = strlen(dir)) ) { /* daarna alles weghalen tot aan '/' */ + while(dir[a-1] != '/') { + a--; + dir[a] = 0; + if (a<=0) break; + } + } + if ( (a = strlen(dir)) ) { + if (dir[a-1] != '/') strcat(dir,"/"); + } + else if(sfile->type!=FILE_MAIN) strcpy(dir,"/"); +#endif + + /* to be sure */ + BLI_make_exist(sfile->dir); + + freefilelist(sfile); + sfile->ofs= 0; + scrarea_queue_winredraw(curarea); +} + +void swapselect_file(SpaceFile *sfile) +{ + struct direntry *file; + int num, act= 0; + + file= sfile->filelist; + for(num=0; num<sfile->totfile; num++, file++) { + if(file->flags & ACTIVE) { + act= 1; + break; + } + } + file= sfile->filelist+2; + for(num=2; num<sfile->totfile; num++, file++) { + if(act) file->flags &= ~ACTIVE; + else file->flags |= ACTIVE; + } +} + +static int find_active_file(SpaceFile *sfile, short x, short y) +{ + int ofs; + + if(y > textrct.ymax) y= textrct.ymax; + if(y <= textrct.ymin) y= textrct.ymin+1; + + ofs= (x-textrct.xmin)/collumwidth; + if(ofs<0) ofs= 0; + ofs*= (textrct.ymax-textrct.ymin); + + return sfile->ofs+ (ofs+textrct.ymax-y)/FILESEL_DY; + +} + + +/* ********************** DRAW ******************************* */ + +static void calc_file_rcts(SpaceFile *sfile) +{ + int tot, h, len; + float fac, start, totfile; + + scrollrct.xmin= 15; + scrollrct.xmax= 35; + scrollrct.ymin= 10; + scrollrct.ymax= curarea->winy-10-FILESELHEAD; + + textrct.xmin= scrollrct.xmax+10; + textrct.xmax= curarea->winx-10; + textrct.ymin= scrollrct.ymin; + textrct.ymax= scrollrct.ymax; + + if(textrct.xmax-textrct.xmin <60) textrct.xmax= textrct.xmin+60; + + len= (textrct.ymax-textrct.ymin) % FILESEL_DY; + textrct.ymin+= len; + scrollrct.ymin+= len; + + filebuty1= curarea->winy-FILESELHEAD; + filebuty2= filebuty1+FILESELHEAD/2 -6; + + + /* aantal kolommen */ + len= sfile->maxnamelen+25; + + if(sfile->type==FILE_MAIN) len+= 100; + else if(sfile->flag & FILE_SHOWSHORT) len+= 100; + else len+= 380; + + sfile->collums= (textrct.xmax-textrct.xmin)/len; + + if(sfile->collums<1) sfile->collums= 1; + else if(sfile->collums>8) sfile->collums= 8; + + if((U.flag & FSCOLLUM)==0) if(sfile->type!=FILE_MAIN) sfile->collums= 1; + + collumwidth= (textrct.xmax-textrct.xmin)/sfile->collums; + + + totfile= sfile->totfile + 0.5; + + tot= FILESEL_DY*totfile; + if(tot) fac= ((float)sfile->collums*(scrollrct.ymax-scrollrct.ymin))/( (float)tot); + else fac= 1.0; + + if(sfile->ofs<0) sfile->ofs= 0; + + if(tot) start= ( (float)sfile->ofs)/(totfile); + else start= 0.0; + if(fac>1.0) fac= 1.0; + + if(start+fac>1.0) { + sfile->ofs= ceil((1.0-fac)*totfile); + start= ( (float)sfile->ofs)/(totfile); + fac= 1.0-start; + } + + bar.xmin= scrollrct.xmin+2; + bar.xmax= scrollrct.xmax-2; + h= (scrollrct.ymax-scrollrct.ymin)-4; + bar.ymax= scrollrct.ymax-2- start*h; + bar.ymin= bar.ymax- fac*h; + + pixels_to_ofs= (totfile)/(float)(h+3); + page_ofs= fac*totfile; +} + +int filescrollselect= 0; + +static void draw_filescroll(SpaceFile *sfile) +{ + + if(scrollrct.ymin+10 >= scrollrct.ymax) return; + + cpack(0x707070); + glRecti(scrollrct.xmin, scrollrct.ymin, scrollrct.xmax, scrollrct.ymax); + + uiEmboss(scrollrct.xmin, scrollrct.ymin, scrollrct.xmax, scrollrct.ymax, 1); + + cpack(0x909090); + glRecti(bar.xmin+2, bar.ymin+2, bar.xmax-2, bar.ymax-2); + + uiEmboss(bar.xmin+2, bar.ymin+2, bar.xmax-2, bar.ymax-2, filescrollselect); + +} + +static void regelrect(unsigned int col, int x, int y) +{ + cpack(col); + glRects(x-17, y-3, x+collumwidth-21, y+11); + +} + +static void printregel(SpaceFile *sfile, struct direntry *files, int x, int y) +{ + unsigned int boxcol=0; + char *s; + + switch(files->flags & (HILITE + ACTIVE)) { + case HILITE+ACTIVE: + boxcol= (0xC09090); + break; + case HILITE: + boxcol= (0x909090); + break; + case ACTIVE: + boxcol= (0xB08080); + break; + } + + if(boxcol) { + regelrect(boxcol, x, y); + } + + if(files->flags & BLENDERFILE) { + cpack(0xA0A0); + glRects(x-14, y, x-8, y+7); + } + else if(files->flags & PSXFILE) { + cpack(0xA060B0); + glRects(x-14, y, x-8, y+7); + } + else if(files->flags & IMAGEFILE) { + cpack(0xF08040); + glRects(x-14, y, x-8, y+7); + } + else if(files->flags & MOVIEFILE) { + cpack(0x70A070); + glRects(x-14, y, x-8, y+7); + } + + if(S_ISDIR(files->type)) cpack(0xFFFFFF); + else cpack(0x0); + + s = files->string; + if(s) { + glRasterPos2i(x, y); + BMF_DrawString(G.font, files->relname); + + x += sfile->maxnamelen + 100; + + glRasterPos2i(x - BMF_GetStringWidth(G.font, files->size), y); + BMF_DrawString(G.font, files->size); + + if(sfile->flag & FILE_SHOWSHORT) return; + +#ifndef WIN32 + /* rwx rwx rwx */ + x += 20; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->mode1); + + x += 30; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->mode2); + + x += 30; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->mode3); + + /* owner time date */ + x += 30; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->owner); +#endif + + x += 60; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->time); + + x += 50; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->date); + } + else { + glRasterPos2i(x, y); + BMF_DrawString(G.font, files->relname); + + if(files->nr) { /* extra info */ + x+= sfile->maxnamelen+20; + glRasterPos2i(x, y); + BMF_DrawString(G.font, files->extra); + } + } +} + + +static int calc_filesel_regel(SpaceFile *sfile, int nr, int *valx, int *valy) +{ + /* sco van de de regel */ + int val, coll; + + nr-= sfile->ofs; + + /* aantal regels in de hoogte */ + val= (textrct.ymax-textrct.ymin)/FILESEL_DY; + coll= nr/val; + nr -= coll*val; + + *valy= textrct.ymax-FILESEL_DY+3 - nr*FILESEL_DY; + *valx= coll*collumwidth + textrct.xmin+20; + + if(nr<0 || coll > sfile->collums) return 0; + return 1; +} + +static void set_active_file(SpaceFile *sfile, int act) +{ + struct direntry *file; + int num, redraw= 0, newflag; + int old=0, newi=0; + + file= sfile->filelist; + if(file==0) return; + + for(num=0; num<sfile->totfile; num++, file++) { + if(num==act) { + + if(selecting && num>1) { + newflag= HILITE | (file->flags & ~ACTIVE); + if(selecting==ACTIVATE) newflag |= ACTIVE; + + if(file->flags != newflag) redraw|= 1; + file->flags= newflag; + } + else { + if(file->flags & HILITE); + else { + file->flags |= HILITE; + redraw|= 2; + newi= num; + } + } + } + else { + if(file->flags & HILITE) { + file->flags &= ~HILITE; + redraw|= 2; + old= num; + } + } + + } + + if(redraw==2) { + int x, y; + + glDrawBuffer(GL_FRONT); + + glScissor(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx-12, curarea->winy); + + if( calc_filesel_regel(sfile, old, &x, &y) ) { + regelrect(0x717171, x, y); + printregel(sfile, sfile->filelist+old, x, y); + } + if( calc_filesel_regel(sfile, newi, &x, &y) ) { + printregel(sfile, sfile->filelist+newi, x, y); + } + + glScissor(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx, curarea->winy); + + glFinish(); /* for geforce, to show it in the frontbuffer */ + glDrawBuffer(GL_BACK); + } + else if(redraw) { + scrarea_queue_winredraw(curarea); + } +} + + +static void draw_filetext(SpaceFile *sfile) +{ + struct direntry *files; + int a, x, y; + short mval[2]; + + if(textrct.ymin+10 >= textrct.ymax) return; + + + /* kader */ + cpack(0x717171); + glRecti(textrct.xmin, textrct.ymin, textrct.xmax, textrct.ymax); + + /* kolommen */ + x= textrct.xmin+collumwidth; + for(a=1; a<sfile->collums; a++, x+= collumwidth) { + cpack(0x303030); + sdrawline(x, textrct.ymin, x, textrct.ymax); + cpack(0xB0B0B0); + sdrawline(x+1, textrct.ymin, x+1, textrct.ymax); + } + + if(sfile->filelist==0) return; + + /* test: als muis niet in area staat: de HILITE wissen */ + getmouseco_areawin(mval); + + if(mval[0]<0 || mval[0]>curarea->winx) { + files= sfile->filelist+sfile->ofs; + for(a= sfile->ofs; a<sfile->totfile; a++, files++) files->flags &= ~HILITE; + } + + files= sfile->filelist+sfile->ofs; + for(a= sfile->ofs; a<sfile->totfile; a++, files++) { + + if( calc_filesel_regel(sfile, a, &x, &y)==0 ) break; + + printregel(sfile, files, x, y); + } + + /* wissen tekenfoutjes, tekst teveel aan de rechterkant: */ + uiEmboss(textrct.xmin, textrct.ymin, textrct.xmax, textrct.ymax, 1); + + glColor3f(.5625, .5625, .5625); + glRecti(textrct.xmax+2, textrct.ymin, textrct.xmax+10, textrct.ymax); +} + +void drawfilespace() +{ + SpaceFile *sfile; + uiBlock *block; + int act, loadbutton; + short mval[2]; + char name[20]; + char *menu; + + myortho2(-0.5, curarea->winrct.xmax-curarea->winrct.xmin-0.5, -0.5, curarea->winrct.ymax-curarea->winrct.ymin-0.5); + + glClearColor(.56, .56, .56, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + sfile= curarea->spacedata.first; + if(sfile->filelist==0) { + read_dir(sfile); + + calc_file_rcts(sfile); + + /* act berekenen */ + getmouseco_areawin(mval); + act= find_active_file(sfile, mval[0], mval[1]); + if(act>=0 && act<sfile->totfile) + sfile->filelist[act].flags |= HILITE; + } + else calc_file_rcts(sfile); + + /* HEADER */ + sprintf(name, "win %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, name, UI_EMBOSSF, UI_HELV, curarea->win); + + uiSetButLock( sfile->type==FILE_MAIN && sfile->returnfunc, NULL); + + /* space available for load/save buttons? */ + loadbutton= MAX2(80, 20+BMF_GetStringWidth(G.font, sfile->title)); + if(textrct.xmax-textrct.xmin > loadbutton+20) { + if(sfile->title[0]==0) loadbutton= 0; + } + else loadbutton= 0; + + uiDefBut(block, TEX, 1,"", textrct.xmin, filebuty1, textrct.xmax-textrct.xmin-loadbutton, 21, sfile->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + uiDefBut(block, TEX, 2,"", textrct.xmin, filebuty2, textrct.xmax-textrct.xmin-loadbutton, 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + if(loadbutton) { + uiSetCurFont(block, UI_HELV); + uiDefBut(block, BUT, 5, sfile->title, textrct.xmax-loadbutton, filebuty2, loadbutton, 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + uiDefBut(block, BUT, 6, "Cancel", textrct.xmax-loadbutton, filebuty1, loadbutton, 21, sfile->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + } + + menu= fsmenu_build_menu(); + uiDefButS(block, MENU, 3, menu, scrollrct.xmin, filebuty1, scrollrct.xmax-scrollrct.xmin, 21, &sfile->menu, 0, 0, 0, 0, ""); + MEM_freeN(menu); + + uiDefBut(block, BUT, 4, "P", scrollrct.xmin, filebuty2, scrollrct.xmax-scrollrct.xmin, 21, 0, 0, 0, 0, 0, "Move to the parent directory (PKEY)"); + + draw_filescroll(sfile); + draw_filetext(sfile); + + /* andere diskfree etc ? */ + scrarea_queue_headredraw(curarea); + + uiDrawBlock(block); + + curarea->win_swap= WIN_BACK_OK; +} + +static void do_filescroll(SpaceFile *sfile) +{ + short mval[2], oldy, yo; + + calc_file_rcts(sfile); + + filescrollselect= 1; + /* voor mooiigheid */ + + glDrawBuffer(GL_FRONT); + draw_filescroll(sfile); + glDrawBuffer(GL_BACK); + + getmouseco_areawin(mval); + oldy= yo= mval[1]; + + while(get_mbut()&L_MOUSE) { + getmouseco_areawin(mval); + + if(yo!=mval[1]) { + int dy= floor(0.5+((float)(oldy-mval[1]))*pixels_to_ofs); + + if(dy) { + sfile->ofs+= dy; + if(sfile->ofs<0) { + sfile->ofs= 0; + oldy= mval[1]; + } + else oldy= floor(0.5+ (float)oldy - (float)dy/pixels_to_ofs); + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + + } + + yo= mval[1]; + } + else BIF_wait_for_statechange(); + } + filescrollselect= 0; + + /* voor mooiigheid */ + glDrawBuffer(GL_FRONT); + draw_filescroll(sfile); + glDrawBuffer(GL_BACK); + +} + +void activate_fileselect(int type, char *title, char *file, void (*func)(char *)) +{ + SpaceFile *sfile; + char group[24], name[FILE_MAXDIR], temp[FILE_MAXDIR]; + + if(curarea==0) return; + if(curarea->win==0) return; + + newspace(curarea, SPACE_FILE); + scrarea_queue_winredraw(curarea); + + /* is misschien dubbelop, voor geval area al SPACE_FILE is met andere filename */ + addqueue(curarea->headwin, CHANGED, 1); + + + name[2]= 0; + strcpy(name, file); + + sfile= curarea->spacedata.first; + /* sfile wants a (*)(short), but get (*)(char*) */ + sfile->returnfunc= func; + sfile->type= type; + sfile->ofs= 0; + /* sfile->act wordt gebruikt bij databrowse: dubbele namen van library objecten */ + sfile->act= -1; + + if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) sfile->flag |= FILE_STRINGCODE; + else sfile->flag &= ~FILE_STRINGCODE; + + if(type==FILE_MAIN) { + char *groupname; + + strcpy(sfile->file, name+2); + + groupname = BLO_idcode_to_name( GS(name) ); + if (groupname) { + strcpy(sfile->dir, groupname); + strcat(sfile->dir, "/"); + } + + /* alles vrijgeven */ + if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata); + sfile->libfiledata= 0; + + freefilelist(sfile); + } + else if(type==FILE_LOADLIB) { + strcpy(sfile->dir, name); + if( is_a_library(sfile, temp, group) ) { + /* dit geval is om een reload van library-filelist te veroorzaken */ + if(sfile->libfiledata==0) { + freefilelist(sfile); + } + } + else { + split_sfile(sfile, name); + if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata); + sfile->libfiledata= 0; + } + } + else { /* FILE_BLENDER */ + split_sfile(sfile, name); /* test ook de filelist */ + + /* vrijgeven: filelist en libfiledata kloppen niet meer */ + if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata); + sfile->libfiledata= 0; + } + BLI_strncpy(sfile->title, title, sizeof(sfile->title)); + filetoname= 1; +} + +void activate_imageselect(int type, char *title, char *file, void (*func)(char *)) +{ + SpaceImaSel *simasel; + char dir[FILE_MAXDIR], name[FILE_MAXFILE]; + + if(curarea==0) return; + if(curarea->win==0) return; + + newspace(curarea, SPACE_IMASEL); + + /* is misschien dubbelop, voor geval area al SPACE_FILE is met andere filename */ + addqueue(curarea->headwin, CHANGED, 1); + addqueue(curarea->win, CHANGED, 1); + + name[2]= 0; + strcpy(name, file); + + simasel= curarea->spacedata.first; + simasel->returnfunc= func; + + if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) simasel->mode |= IMS_STRINGCODE; + else simasel->mode &= ~IMS_STRINGCODE; + + BLI_split_dirfile(name, dir, simasel->file); + if(strcmp(dir, simasel->dir)!=0) simasel->fase= 0; + strcpy(simasel->dir, dir); + + BLI_strncpy(simasel->title, title, sizeof(simasel->title)); + + + + /* filetoname= 1; */ +} + + +void activate_databrowse(ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short)) +{ + ListBase *lb; + SpaceFile *sfile; + char str[32]; + + if(id==0) { + lb= wich_libbase(G.main, idcode); + id= lb->first; + } + + if(id) strcpy(str, id->name); + else return; + + activate_fileselect(FILE_MAIN, "SELECT DATABLOCK", str, (void (*) (char*))func); + + sfile= curarea->spacedata.first; + sfile->retval= retval; + sfile->ipotype= fromcode; + sfile->menup= menup; +} + +void filesel_prevspace() +{ + SpaceFile *sfile; + + sfile= curarea->spacedata.first; + if(sfile->next) { + + BLI_remlink(&curarea->spacedata, sfile); + BLI_addtail(&curarea->spacedata, sfile); + + sfile= curarea->spacedata.first; + newspace(curarea, sfile->spacetype); + } + else newspace(curarea, SPACE_INFO); +} + +static int countselect(SpaceFile *sfile) +{ + int a, count=0; + + for(a=0; a<sfile->totfile; a++) { + if(sfile->filelist[a].flags & ACTIVE) { + count++; + } + } + return count; +} + +static int getotherdir(void) +{ + ScrArea *sa; + SpaceFile *sfile=0; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa!=curarea) { + if(sa->spacetype==SPACE_FILE) { + + /* al een gevonden */ + if(sfile) return 0; + + sfile= sa->spacedata.first; + + if(sfile->type & FILE_UNIX) { + otherarea= sa; + BLI_make_file_string(G.sce, otherdir, sfile->dir, ""); + } + else sfile= 0; + } + } + sa= sa->next; + } + if(sfile) return 1; + return 0; +} + +static void reread_other_fs(void) +{ + SpaceFile *sfile; + + /* oppassen: alleen aanroepen als getotherdir goed is afgelopen */ + + sfile= otherarea->spacedata.first; + freefilelist(sfile); + scrarea_queue_winredraw(otherarea); +} + + +void free_filesel_spec(char *dir) +{ + /* alle filesels met 'dir' worden vrijgegeven */ + bScreen *sc; + + sc= G.main->screen.first; + while(sc) { + ScrArea *sa= sc->areabase.first; + while(sa) { + SpaceLink *sl= sa->spacedata.first; + while(sl) { + if(sl->spacetype==SPACE_FILE) { + SpaceFile *sfile= (SpaceFile*) sl; + if (BLI_streq(sfile->dir, dir)) { + freefilelist(sfile); + } + } + sl= sl->next; + } + sa= sa->next; + } + sc= sc->id.next; + } +} + + +static void filesel_execute(SpaceFile *sfile) +{ + struct direntry *files; + char name[FILE_MAXDIR]; + int a; + + filesel_prevspace(); + + if(sfile->type==FILE_LOADLIB) { + do_library_append(sfile); + + allqueue(REDRAWALL, 1); + } + else if(sfile->returnfunc) { + fsmenu_insert_entry(sfile->dir, 1); + + if(sfile->type==FILE_MAIN) { + if (sfile->menup) { + if(sfile->act>=0) { + if(sfile->filelist) { + files= sfile->filelist+sfile->act; + *sfile->menup= files->nr; + } + else *sfile->menup= sfile->act+1; + } + else { + *sfile->menup= -1; + for(a=0; a<sfile->totfile; a++) { + if( strcmp(sfile->filelist[a].relname, sfile->file)==0) { + *sfile->menup= a+1; + break; + } + } + } + } + sfile->returnfunc((char*) sfile->retval); + } + else { + if(strncmp(sfile->title, "SAVE", 4)==0) free_filesel_spec(sfile->dir); + + strcpy(name, sfile->dir); + strcat(name, sfile->file); + + if(sfile->flag & FILE_STRINGCODE) BLI_makestringcode(G.sce, name); + + sfile->returnfunc(name); + } + } +} + +static void do_filesel_buttons(short event, SpaceFile *sfile) +{ + char butname[FILE_MAXDIR]; + + if (event == 1) { + if (strchr(sfile->file, '*') || strchr(sfile->file, '?') || strchr(sfile->file, '[')) { + int i, match = FALSE; + + for (i = 2; i < sfile->totfile; i++) { + if (fnmatch(sfile->file, sfile->filelist[i].relname, 0) == 0) { + sfile->filelist[i].flags |= ACTIVE; + match = TRUE; + } + } + if (match) strcpy(sfile->file, ""); + if(sfile->type==FILE_MAIN) filesel_select_objects(sfile); + scrarea_queue_winredraw(curarea); + } + } + else if(event== 2) { + /* reuse the butname variable */ + checkdir(sfile->dir); + + BLI_make_file_string(G.sce, butname, sfile->dir, ""); + /* strip the trailing slash if its a real dir */ + if (strlen(butname)!=1) + butname[strlen(butname)-1]=0; + + if(sfile->type & FILE_UNIX) { + if (!BLI_exists(butname)) { + if (okee("Makedir")) { + BLI_recurdir_fileops(butname); + if (!BLI_exists(butname)) parent(sfile); + } else parent(sfile); + } + } + freefilelist(sfile); + sfile->ofs= 0; + scrarea_queue_winredraw(curarea); + } + else if(event== 3) { + char *selected= fsmenu_get_entry(sfile->menu-1); + + /* welke string */ + if (selected) { + strcpy(sfile->dir, selected); + BLI_make_exist(sfile->dir); + checkdir(sfile->dir); + freefilelist(sfile); + sfile->ofs= 0; + scrarea_queue_winredraw(curarea); + } + + sfile->act= -1; + + } + else if(event== 4) parent(sfile); + else if(event== 5) { + if(sfile->type) filesel_execute(sfile); + } + else if(event== 6) filesel_prevspace(); + +} + +/****/ + +typedef void (*ReplaceFP)(ID *oldblock, ID *newblock); + +static void change_id_link(void *linkpv, void *newlinkv) { + ID **linkp= (ID**) linkpv; + ID *newlink= newlinkv; + + if (*linkp) { + (*linkp)->us--; + } + (*linkp)= newlink; + if (newlink) { + id_us_plus(newlink); + } +} + +static void replace_image(ID *oldblock, ID *newblock) { + Image *oldima= (Image*) oldblock; + Image *newima= (Image*) newblock; + bScreen *sc; + Scene *sce; + Tex *tex; + Mesh *me; + + for (tex= G.main->tex.first; tex; tex= tex->id.next) { + if (tex->env && tex->env->type == ENV_LOAD && tex->env->ima == oldima) + change_id_link(&tex->env->ima, newima); + if (tex->ima == oldima) + change_id_link(&tex->ima, newima); + } + + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if (sce->ima == oldima) + change_id_link(&sce->ima, newima); + } + + for (sc= G.main->screen.first; sc; sc= sc->id.next) { + ScrArea *sa; + + for (sa= sc->areabase.first; sa; sa= sa->next) { + SpaceLink *sl; + + for (sl= sa->spacedata.first; sl; sl= sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d= (View3D*) sl; + BGpic *bgp= v3d->bgpic; + + if (bgp && bgp->ima == oldima) + change_id_link(&bgp->ima, newima); + } else if (sl->spacetype == SPACE_IMAGE) { + SpaceImage *sima= (SpaceImage*) sl; + + if (sima->image == oldima) + change_id_link(&sima->image, newima); + } + } + } + } + + for (me= G.main->mesh.first; me; me= me->id.next) { + TFace *tfaces= me->tface; + + if (tfaces) { + int i; + + for (i=0; i<me->totface; i++) { + TFace *tf= &tfaces[i]; + + if (tf->tpage == oldima) { + /* not change_id_link, tpage's aren't owners :( + * see hack below. + */ + tf->tpage= newima; + } + } + } + } + + /* Nasty hack, necessary because tpages don't act + * as a user, so there lots of image user count + * munging occurs... this will ensure the image + * really dies. + */ + oldima->id.us= 0; +} + +static void replace_material(ID *oldblock, ID *newblock) +{ + Material *old= (Material*) oldblock; + Material *new= (Material*) newblock; + Material ***matarar; + ID *id; + Object *ob; + int a; + + ob= G.main->object.first; + while(ob) { + if(ob->totcol && ob->id.lib==0) { + matarar= give_matarar(ob); + for(a=1; a<=ob->totcol; a++) { + if(ob->mat[a-1] == old) { + if(old) old->id.us--; + id_us_plus((ID *)new); + ob->mat[a-1]= new; + } + id= ob->data; + if( (*matarar)[a-1] == old && id->lib==0) { + if(old) old->id.us--; + id_us_plus((ID *)new); + (*matarar)[a-1]= new; + } + } + } + ob= ob->id.next; + } +} + +static ReplaceFP get_id_replace_function(int idcode) { + switch (idcode) { + case ID_MA: + return &replace_material; + case ID_IM: + return &replace_image; + default: + return NULL; + } +} + +static void databrowse_replace(SpaceFile *sfile, int idcode) +{ + ReplaceFP replace_func= get_id_replace_function(idcode); + + if (!replace_func) { + error("Replacing %s blocks is unsupported", BLO_idcode_to_name(idcode)); + } else if (sfile->act==-1) { + error("Select target with leftmouse"); + } else { + ID *target= (ID*) sfile->filelist[sfile->act].poin; + + if (target) { + char buf[128]; + + sprintf(buf, "Replace with %s: %s", BLO_idcode_to_name(idcode), target->name+2); + + if (okee(buf)) { + int i; + + for (i = 0; i <sfile->totfile; i++) + if ((sfile->filelist[i].flags&ACTIVE) && sfile->filelist[i].poin!=target) + replace_func(sfile->filelist[i].poin, target); + } + } + } + + freefilelist(sfile); + scrarea_queue_winredraw(curarea); +} + +static void fs_fake_users(SpaceFile *sfile) +{ + ID *id; + int a; + + /* alleen bij F4 DATABROWSE */ + if(sfile->returnfunc) return; + + for(a=0; a<sfile->totfile; a++) { + if(sfile->filelist[a].flags & ACTIVE) { + id= (ID *)sfile->filelist[a].poin; + if(id) { + if( id->flag & LIB_FAKEUSER) { + id->flag -= LIB_FAKEUSER; + id->us--; + } + else { + id->flag |= LIB_FAKEUSER; + id->us++; + } + } + } + } + freefilelist(sfile); + scrarea_queue_winredraw(curarea); +} + +void winqreadfilespace(unsigned short event, short val, char ascii) +{ + static int acto=0; + SpaceFile *sfile; + int act, do_draw= 0, i, test, ret = 0; + short qual, mval[2]; + char str[FILE_MAXDIR+FILE_MAXFILE+12]; + + sfile= curarea->spacedata.first; + if(sfile==0) return; + if(sfile->filelist==0) { + /* wel buttons doen */ + if(val && event==LEFTMOUSE) { + /* FrontbufferButs(TRUE); */ + /* event= DoButtons(); */ + /* FrontbufferButs(FALSE); */ + /* NIET de headerbuttons! */ + /* if(event) do_filesel_buttons(event, sfile); */ + } + return; + } + + if(curarea->win==0) return; + calc_file_rcts(sfile); + getmouseco_areawin(mval); + + /* om hangen te voorkomen */ + if(selecting && !(get_mbut() & R_MOUSE)) selecting= 0; + + if(val) { + + if( event!=RETKEY && event!=PADENTER) + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) { + + case UI_BUT_EVENT: + do_filesel_buttons(val, sfile); + break; + + case LEFTMOUSE: + case MIDDLEMOUSE: + if(mval[0]>scrollrct.xmin && mval[0]<scrollrct.xmax && mval[1]>scrollrct.ymin && mval[1]<scrollrct.ymax) { + do_filescroll(sfile); + } + else if(mval[0]>textrct.xmin && mval[0]<textrct.xmax && mval[1]>textrct.ymin && mval[1]<textrct.ymax) { + + /* sfile->act wordt gebruikt bij databrowse: dubbelenamen van library objecten */ + + sfile->act= act= find_active_file(sfile, mval[0], mval[1]); + + if(act>=0 && act<sfile->totfile) { + if(S_ISDIR(sfile->filelist[act].type)) { + strcat(sfile->dir, sfile->filelist[act].relname); + strcat(sfile->dir,"/"); + checkdir(sfile->dir); + freefilelist(sfile); + sfile->ofs= 0; + do_draw= 1; + } + else { + if( strcmp(sfile->file, sfile->filelist[act].relname)) { + do_draw= 1; + strcpy(sfile->file, sfile->filelist[act].relname); + } + if(event==MIDDLEMOUSE && sfile->type) filesel_execute(sfile); + } + } + } + else { + /* FrontbufferButs(TRUE); */ + /* event= DoButtons(); */ + /* FrontbufferButs(FALSE); */ + /* NIET de headerbuttons! */ + /* if(event) do_filesel_buttons(event, sfile); */ + } + break; + case RIGHTMOUSE: + act= find_active_file(sfile, mval[0], mval[1]); + acto= act; + if(act>=0 && act<sfile->totfile) { + + if (sfile->filelist[act].flags & ACTIVE) { + sfile->filelist[act].flags &= ~ACTIVE; + selecting = INACTIVATE; + } + else { + test= sfile->filelist[act].relname[0]; + if (act>=2 || test!='.') sfile->filelist[act].flags |= ACTIVE; + + selecting = ACTIVATE; + } + do_draw= 1; + } + break; + case MOUSEY: + act= find_active_file(sfile, mval[0], mval[1]); + if (act!=acto) { + set_active_file(sfile, act); + } + if(selecting && act!=acto) { + + while(1) { + if (acto >= 2 && acto < sfile->totfile) { + if (selecting == ACTIVATE) sfile->filelist[acto].flags |= ACTIVE; + else if (selecting == INACTIVATE) sfile->filelist[acto].flags &= ~ACTIVE; + } + if (acto < act) acto++; + else if (acto > act) acto--; + else break; + + } + + } + acto= act; + break; + + case PAGEUPKEY: + sfile->ofs-= page_ofs; + do_draw= 1; + break; + case PAGEDOWNKEY: + sfile->ofs+= page_ofs; + do_draw= 1; + break; + case HOMEKEY: + sfile->ofs= 0; + do_draw= 1; + break; + case ENDKEY: + sfile->ofs= sfile->totfile; + do_draw= 1; + break; + + case AKEY: + swapselect_file(sfile); + if(sfile->type==FILE_MAIN) filesel_select_objects(sfile); + do_draw= 1; + break; + + case BKEY: + case CKEY: + case LKEY: + if(event==LKEY && sfile->type==FILE_MAIN && (G.qual & LR_CTRLKEY)) { + databrowse_replace(sfile, groupname_to_code(sfile->dir)); + break; + } + /* doorgeven */ + case MKEY: + if(sfile->type==FILE_MAIN) break; + + if(!countselect(sfile)) { + error("No files selected"); + break; + } + + if(!getotherdir()) { + error("No second fileselect"); + break; + } + + if (!strcmp(sfile->dir, otherdir)) { + error("Same directories"); + break; + } + + if(event==BKEY) sprintf(str, "Backup to %s", otherdir); + else if(event==CKEY) sprintf(str, "Copy to %s", otherdir); + else if(event==LKEY) sprintf(str, "Linked copy to %s", otherdir); + else if(event==MKEY) sprintf(str, "Move to %s", otherdir); + + if (!okee(str)) break; + + for (i = 0; i<sfile->totfile; i++){ + if (sfile->filelist[i].flags & ACTIVE) { + BLI_make_file_string(G.sce, str, sfile->dir, sfile->filelist[i].relname); + + if(event==BKEY) ret= BLI_backup(sfile->filelist[i].relname, sfile->dir, otherdir); + else if(event==CKEY) ret= BLI_copy_fileops(str, otherdir); + else if(event==LKEY) ret= BLI_link(str, otherdir); + else if(event==MKEY) ret= BLI_move(str, otherdir); + + if (ret) {error("Command failed, see console"); break;} + else sfile->filelist[i].flags &= ~ACTIVE; + } + } + do_draw= 1; + if(event==BKEY || event==MKEY) + freefilelist(sfile); + + reread_other_fs(); + + break; + case RKEY: + if(sfile->type==FILE_MAIN) { + databrowse_replace(sfile, groupname_to_code(sfile->dir)); + break; + } + /* doorgeven aan TKEY! */ + + case TKEY: + if(sfile->type==FILE_MAIN) break; + + if(!countselect(sfile)) { + error("No files selected"); + break; + } + + if(event==TKEY) sprintf(str, "Touch"); + else if(event==RKEY) sprintf(str, "Remove from %s", sfile->dir); + + qual= G.qual; /* want na okee() heb je de shift losgelaten */ + if (!okee(str)) break; + + for (i = 0; i <sfile->totfile; i++) { + if (sfile->filelist[i].flags & ACTIVE) { + BLI_make_file_string(G.sce, str, sfile->dir, sfile->filelist[i].relname); + + if(event==TKEY) ret= BLI_touch(str); + else if(event==RKEY) { + if(qual & LR_SHIFTKEY) ret= BLI_delete(str, 0, 1); + else if(S_ISDIR(sfile->filelist[i].type)) ret= BLI_delete(str, 1, 0); + else ret= BLI_delete(str, 0, 0); + } + + if (ret) {error("Command failed, see console"); break;} + else sfile->filelist[i].flags &= ~ACTIVE; + } + } + do_draw= 1; + freefilelist(sfile); + + break; + + case PKEY: + if(G.qual & LR_SHIFTKEY) { + extern char bprogname[]; /* usiblender.c */ + + sprintf(str, "%s -a \"%s%s\"", bprogname, sfile->dir, sfile->file); + system(str); + } + else + parent(sfile); + + break; + + case IKEY: + if(sfile->type==FILE_MAIN) break; + + sprintf(str, "$IMAGEEDITOR %s%s", sfile->dir, sfile->file); + system(str); + break; + + case EKEY: + if(sfile->type==FILE_MAIN) break; + + sprintf(str, "$WINEDITOR %s%s", sfile->dir, sfile->file); + system(str); + break; + + case FKEY: + if(sfile->type==FILE_MAIN) { + fs_fake_users(sfile); + } + break; + + case PADPLUSKEY: + case EQUALKEY: + if (G.qual & LR_CTRLKEY) BLI_newname(sfile->file, +100); + else if (G.qual & LR_SHIFTKEY) BLI_newname(sfile->file, +10); + else BLI_newname(sfile->file, +1); + + do_draw= 1; + break; + + case PADMINUS: + case MINUSKEY: + if (G.qual & LR_CTRLKEY) BLI_newname(sfile->file, -100); + else if (G.qual & LR_SHIFTKEY) BLI_newname(sfile->file, -10); + else BLI_newname(sfile->file, -1); + + do_draw= 1; + break; + + case BACKSLASHKEY: + case SLASHKEY: + if(sfile->type==FILE_MAIN) break; + +#ifdef WIN32 + strcpy(sfile->dir, "\\"); +#else + strcpy(sfile->dir, "/"); +#endif + freefilelist(sfile); + sfile->ofs= 0; + do_draw= 1; + break; + case PERIODKEY: + freefilelist(sfile); + do_draw= 1; + break; + case ESCKEY: + filesel_prevspace(); + break; + case PADENTER: + case RETKEY: + if(sfile->type) filesel_execute(sfile); + break; + } + } + else if(event==RIGHTMOUSE) { + selecting = NOTACTIVE; + if(sfile->type==FILE_MAIN) filesel_select_objects(sfile); + } + else if(event==LEFTMOUSE) { + if(sfile->type==FILE_MAIN) active_file_object(sfile); + } + + /* XXX, stupid patch, curarea can become undone + * because of file loading... fixme zr + */ + if(do_draw && curarea) scrarea_queue_winredraw(curarea); +} + + + + +/* ************* LIBRARY FILESEL ******************* */ + +static int groupname_to_code(char *group) +{ + char buf[32]; + char *lslash; + + strcpy(buf, group); + lslash= BLI_last_slash(buf); + if (lslash) + lslash[0]= '\0'; + + return BLO_idcode_from_name(buf); +} + +static int is_a_library(SpaceFile *sfile, char *dir, char *group) +{ + /* return ok als een blenderfile, in dir staat de filename, + * in group het type libdata + */ + int len; + char *fd; + + strcpy(dir, sfile->dir); + len= strlen(dir); + if(len<7) return 0; + if( dir[len-1] != '/' && dir[len-1] != '\\') return 0; + + group[0]= 0; + dir[len-1]= 0; + + /* Find the last slash */ + fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\'); + + if(fd==0) return 0; + *fd= 0; + if(BLO_has_bfile_extension(fd+1)) { + *fd= '/'; + } + else { + strcpy(group, fd+1); + + /* Find the last slash */ + fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\'); + if (!fd || !BLO_has_bfile_extension(fd+1)) return 0; + } + return 1; +} + +static void do_library_append(SpaceFile *sfile) +{ + char dir[FILE_MAXDIR], group[32]; + + if ( is_a_library(sfile, dir, group)==0 ) { + error("Not a library"); + } else if (!sfile->libfiledata) { + error("Library not loaded"); + } else if (group[0]==0) { + error("Nothing indicated"); + } else if (BLI_streq(G.main->name, dir)) { + error("Cannot use current file as library"); + } else { + Object *ob; + int idcode = groupname_to_code(group); + + BLO_library_append(sfile, dir, idcode); + + /* DISPLISTEN */ + ob= G.main->object.first; + set_displist_onlyzero(1); + while(ob) { + if(ob->id.lib) { + if(ob->type==OB_FONT) { + Curve *cu= ob->data; + if(cu->nurb.first==0) text_to_curve(ob, 0); + } + makeDispList(ob); + } + else if(ob->type==OB_MESH && ob->parent && ob->parent->type==OB_LATTICE ) { + makeDispList(ob); + } + + ob= ob->id.next; + } + set_displist_onlyzero(0); + + /* in sfile->dir staat de HELE libnaam */ + strcpy(G.lib, sfile->dir); + + if((sfile->flag & FILE_LINK)==0) all_local(); + } +} + +static void library_to_filelist(SpaceFile *sfile) +{ + char dir[FILE_MAXDIR], group[24]; + int ok, i, nnames, idcode; + LinkNode *l, *names; + + /* name testen */ + ok= is_a_library(sfile, dir, group); + if (!ok) { + /* vrijgeven */ + if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata); + sfile->libfiledata= 0; + return; + } + + /* en daar gaat ie */ + /* voorlopig alleen filedata inlezen als libfiledata==0 */ + if (sfile->libfiledata==0) { + sfile->libfiledata= BLO_blendhandle_from_file(dir); + if(sfile->libfiledata==0) return; + } + + if (idcode= groupname_to_code(group)) { + names= BLO_blendhandle_get_datablock_names(sfile->libfiledata, idcode); + } else { + names= BLO_blendhandle_get_linkable_groups(sfile->libfiledata); + } + + nnames= BLI_linklist_length(names); + + sfile->totfile= nnames + 2; + sfile->filelist= malloc(sfile->totfile * sizeof(*sfile->filelist)); + memset(sfile->filelist, 0, sfile->totfile * sizeof(*sfile->filelist)); + + sfile->filelist[0].relname= strdup("."); + sfile->filelist[0].type |= S_IFDIR; + sfile->filelist[1].relname= strdup(".."); + sfile->filelist[1].type |= S_IFDIR; + + for (i=0, l= names; i<nnames; i++, l= l->next) { + char *blockname= l->link; + + sfile->filelist[i + 2].relname= blockname; + if (!idcode) + sfile->filelist[i + 2].type |= S_IFDIR; + } + + BLI_linklist_free(names, NULL); + + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name); + + sfile->maxnamelen= 0; + for(i=0; i<sfile->totfile; i++) { + int len = BMF_GetStringWidth(G.font, sfile->filelist[i].relname); + if (len > sfile->maxnamelen) + sfile->maxnamelen = len; + } +} + +/* ******************* DATA SELECT ********************* */ + +static void filesel_select_objects(SpaceFile *sfile) +{ + Object *ob; + Base *base; + Scene *sce; + int a; + + /* alleen bij F4 DATABROWSE */ + if(sfile->returnfunc) return; + + if( strcmp(sfile->dir, "Object/")==0 ) { + for(a=0; a<sfile->totfile; a++) { + + ob= (Object *)sfile->filelist[a].poin; + + if(ob) { + if(sfile->filelist[a].flags & ACTIVE) ob->flag |= SELECT; + else ob->flag &= ~SELECT; + } + + } + base= FIRSTBASE; + while(base) { + base->flag= base->object->flag; + base= base->next; + } + allqueue(REDRAWVIEW3D, 0); + } + else if( strcmp(sfile->dir, "Scene/")==0 ) { + + for(a=0; a<sfile->totfile; a++) { + + sce= (Scene *)sfile->filelist[a].poin; + if(sce) { + if(sfile->filelist[a].flags & ACTIVE) sce->r.scemode |= R_BG_RENDER; + else sce->r.scemode &= ~R_BG_RENDER; + } + + } + allqueue(REDRAWBUTSRENDER, 0); + } +} + +static void active_file_object(SpaceFile *sfile) +{ + Object *ob; + + /* alleen bij F4 DATABROWSE */ + if(sfile->returnfunc) return; + + if( strcmp(sfile->dir, "Object/")==0 ) { + if(sfile->act >= 0) { + + ob= (Object *)sfile->filelist[sfile->act].poin; + + if(ob) { + set_active_object(ob); + if(BASACT && BASACT->object==ob) { + BASACT->flag |= SELECT; + sfile->filelist[sfile->act].flags |= ACTIVE; + allqueue(REDRAWVIEW3D, 0); + scrarea_queue_winredraw(curarea); + } + } + } + } +} + + +void main_to_filelist(SpaceFile *sfile) +{ + ID *id; + struct direntry *files, *firstlib = NULL; + ListBase *lb; + int a, fake, idcode, len, ok, totlib, totbl; + + if(sfile->dir[0]=='/') sfile->dir[0]= 0; + + if(sfile->dir[0]) { + idcode= groupname_to_code(sfile->dir); + if(idcode==0) sfile->dir[0]= 0; + } + + if( sfile->dir[0]==0) { + + /* directories maken */ + sfile->totfile= 22; + sfile->filelist= (struct direntry *)malloc(sfile->totfile * sizeof(struct direntry)); + + for(a=0; a<sfile->totfile; a++) { + memset( &(sfile->filelist[a]), 0 , sizeof(struct direntry)); + sfile->filelist[a].type |= S_IFDIR; + } + + sfile->filelist[0].relname= strdup(".."); + sfile->filelist[1].relname= strdup("."); + sfile->filelist[2].relname= strdup("Scene"); + sfile->filelist[3].relname= strdup("Object"); + sfile->filelist[4].relname= strdup("Mesh"); + sfile->filelist[5].relname= strdup("Curve"); + sfile->filelist[6].relname= strdup("Metaball"); + sfile->filelist[7].relname= strdup("Material"); + sfile->filelist[8].relname= strdup("Texture"); + sfile->filelist[9].relname= strdup("Image"); + sfile->filelist[10].relname= strdup("Ika"); + sfile->filelist[11].relname= strdup("Wave"); + sfile->filelist[12].relname= strdup("Lattice"); + sfile->filelist[13].relname= strdup("Lamp"); + sfile->filelist[14].relname= strdup("Camera"); + sfile->filelist[15].relname= strdup("Ipo"); + sfile->filelist[16].relname= strdup("World"); + sfile->filelist[17].relname= strdup("Screen"); + sfile->filelist[18].relname= strdup("VFont"); + sfile->filelist[19].relname= strdup("Text"); + sfile->filelist[20].relname= strdup("Armature"); + sfile->filelist[21].relname= strdup("Action"); + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name); + } + else { + + /* files maken */ + idcode= groupname_to_code(sfile->dir); + + lb= wich_libbase(G.main, idcode ); + if(lb==0) return; + + id= lb->first; + sfile->totfile= 0; + while(id) { + + if(sfile->returnfunc && idcode==ID_IP) { + if(sfile->ipotype== ((Ipo *)id)->blocktype) sfile->totfile++; + } + else sfile->totfile++; + + id= id->next; + } + + if(sfile->returnfunc==0) sfile->totfile+= 2; + sfile->filelist= (struct direntry *)malloc(sfile->totfile * sizeof(struct direntry)); + + files= sfile->filelist; + + if(sfile->returnfunc==0) { + memset( &(sfile->filelist[0]), 0 , sizeof(struct direntry)); + sfile->filelist[0].relname= strdup("."); + sfile->filelist[0].type |= S_IFDIR; + memset( &(sfile->filelist[1]), 0 , sizeof(struct direntry)); + sfile->filelist[1].relname= strdup(".."); + sfile->filelist[1].type |= S_IFDIR; + + files+= 2; + } + + id= lb->first; + totlib= totbl= 0; + + while(id) { + + ok= 0; + if(sfile->returnfunc && idcode==ID_IP) { + if(sfile->ipotype== ((Ipo *)id)->blocktype) ok= 1; + } + else ok= 1; + + if(ok) { + + memset( files, 0 , sizeof(struct direntry)); + files->relname= strdup(id->name+2); + + if(sfile->returnfunc==0) { /* F4 DATA BROWSE */ + if(idcode==ID_OB) { + if( ((Object *)id)->flag & SELECT) files->flags |= ACTIVE; + } + else if(idcode==ID_SCE) { + if( ((Scene *)id)->r.scemode & R_BG_RENDER) files->flags |= ACTIVE; + } + } + files->nr= totbl+1; + files->poin= id; + fake= id->flag & LIB_FAKEUSER; + + if(id->lib && fake) sprintf(files->extra, "LF %d", id->us); + else if(id->lib) sprintf(files->extra, "L %d", id->us); + else if(fake) sprintf(files->extra, "F %d", id->us); + else sprintf(files->extra, " %d", id->us); + + if(id->lib) { + if(totlib==0) firstlib= files; + totlib++; + } + + files++; + totbl++; + } + + id= id->next; + } + + /* alleen qsort van libraryblokken */ + if(totlib>1) { + qsort(firstlib, totlib, sizeof(struct direntry), compare_name); + } + } + + sfile->maxnamelen= 0; + for(a=0; a<sfile->totfile; a++) { + len = BMF_GetStringWidth(G.font, sfile->filelist[a].relname); + if (len > sfile->maxnamelen) sfile->maxnamelen = len; + + if(filetoname) { + if( strcmp(sfile->file, sfile->filelist[a].relname)==0) { + sfile->ofs= a-( sfile->collums*(curarea->winy-FILESELHEAD-10)/(2*FILESEL_DY)); + filetoname= 0; + if(sfile->returnfunc) sfile->filelist[a].flags |= ACTIVE; + } + } + } +} + + + diff --git a/source/blender/src/ghostwinlay.c b/source/blender/src/ghostwinlay.c new file mode 100644 index 00000000000..1280278edf6 --- /dev/null +++ b/source/blender/src/ghostwinlay.c @@ -0,0 +1,572 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#include <stdlib.h> +#include <stdio.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" + +#include "GHOST_C-api.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" + +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_usiblender.h" + +#include "mydevice.h" +#include "blendef.h" + +#include "winlay.h" + +static GHOST_SystemHandle g_system= 0; + + /* Some simple ghost <-> blender conversions */ + +static GHOST_TStandardCursor convert_cursor(int curs) { + switch(curs) { + default: + case CURSOR_STD: return GHOST_kStandardCursorDefault; + case CURSOR_VPAINT: return GHOST_kStandardCursorLeftArrow; + case CURSOR_FACESEL: return GHOST_kStandardCursorRightArrow; + case CURSOR_WAIT: return GHOST_kStandardCursorWait; + case CURSOR_EDIT: return GHOST_kStandardCursorCrosshair; + case CURSOR_HELP: return GHOST_kStandardCursorHelp; + case CURSOR_X_MOVE: return GHOST_kStandardCursorLeftRight; + case CURSOR_Y_MOVE: return GHOST_kStandardCursorUpDown; + } +} + +static int convert_mbut(GHOST_TButtonMask but) { + if (but == GHOST_kButtonMaskLeft) { + return LEFTMOUSE; + } else if (but == GHOST_kButtonMaskRight) { + return RIGHTMOUSE; + } else { + return MIDDLEMOUSE; + } +} + +static int convert_key(GHOST_TKey key) { + if (key>=GHOST_kKeyA && key<=GHOST_kKeyZ) { + return (AKEY + ((int) key - GHOST_kKeyA)); + } else if (key>=GHOST_kKey0 && key<=GHOST_kKey9) { + return (ZEROKEY + ((int) key - GHOST_kKey0)); + } else if (key>=GHOST_kKeyNumpad0 && key<=GHOST_kKeyNumpad9) { + return (PAD0 + ((int) key - GHOST_kKeyNumpad0)); + } else if (key>=GHOST_kKeyF1 && key<=GHOST_kKeyF12) { + return (F1KEY + ((int) key - GHOST_kKeyF1)); + } else { + switch (key) { + case GHOST_kKeyBackSpace: return BACKSPACEKEY; + case GHOST_kKeyTab: return TABKEY; + case GHOST_kKeyLinefeed: return LINEFEEDKEY; + case GHOST_kKeyClear: return 0; + case GHOST_kKeyEnter: return RETKEY; + + case GHOST_kKeyEsc: return ESCKEY; + case GHOST_kKeySpace: return SPACEKEY; + case GHOST_kKeyQuote: return QUOTEKEY; + case GHOST_kKeyComma: return COMMAKEY; + case GHOST_kKeyMinus: return MINUSKEY; + case GHOST_kKeyPeriod: return PERIODKEY; + case GHOST_kKeySlash: return SLASHKEY; + + case GHOST_kKeySemicolon: return SEMICOLONKEY; + case GHOST_kKeyEqual: return EQUALKEY; + + case GHOST_kKeyLeftBracket: return LEFTBRACKETKEY; + case GHOST_kKeyRightBracket: return RIGHTBRACKETKEY; + case GHOST_kKeyBackslash: return BACKSLASHKEY; + case GHOST_kKeyAccentGrave: return ACCENTGRAVEKEY; + + case GHOST_kKeyLeftShift: return LEFTSHIFTKEY; + case GHOST_kKeyRightShift: return RIGHTSHIFTKEY; + case GHOST_kKeyLeftControl: return LEFTCTRLKEY; + case GHOST_kKeyRightControl: return RIGHTCTRLKEY; + case GHOST_kKeyLeftAlt: return LEFTALTKEY; + case GHOST_kKeyRightAlt: return RIGHTALTKEY; + + case GHOST_kKeyCapsLock: return CAPSLOCKKEY; + case GHOST_kKeyNumLock: return 0; + case GHOST_kKeyScrollLock: return 0; + + case GHOST_kKeyLeftArrow: return LEFTARROWKEY; + case GHOST_kKeyRightArrow: return RIGHTARROWKEY; + case GHOST_kKeyUpArrow: return UPARROWKEY; + case GHOST_kKeyDownArrow: return DOWNARROWKEY; + + case GHOST_kKeyPrintScreen: return 0; + case GHOST_kKeyPause: return PAUSEKEY; + + case GHOST_kKeyInsert: return INSERTKEY; + case GHOST_kKeyDelete: return DELKEY; + case GHOST_kKeyHome: return HOMEKEY; + case GHOST_kKeyEnd: return ENDKEY; + case GHOST_kKeyUpPage: return PAGEUPKEY; + case GHOST_kKeyDownPage: return PAGEDOWNKEY; + + case GHOST_kKeyNumpadPeriod: return PADPERIOD; + case GHOST_kKeyNumpadEnter: return PADENTER; + case GHOST_kKeyNumpadPlus: return PADPLUSKEY; + case GHOST_kKeyNumpadMinus: return PADMINUS; + case GHOST_kKeyNumpadAsterisk: return PADASTERKEY; + case GHOST_kKeyNumpadSlash: return PADSLASHKEY; + case GHOST_kKeyUnknown: return UNKNOWNKEY; + + default: + return 0; + } + } +} + + /***/ + +struct _Window { + GHOST_WindowHandle ghostwin; + + /* Handler and private data for handler */ + WindowHandlerFP handler; + void *user_data; + + /* Window state */ + int size[2], position[2]; + int active, visible; + + /* Last known mouse/button/qualifier state */ + int lmouse[2]; + int lqual; /* (LR_SHFTKEY, LR_CTRLKEY, LR_ALTKEY) */ + int lmbut; /* (L_MOUSE, M_MOUSE, R_MOUSE) */ + int commandqual; + + /* Tracks the faked mouse button, if non-zero it is + * the event number of the last faked button. + */ + int faked_mbut; + + GHOST_TimerTaskHandle timer; + int timer_event; +}; + +static Window *window_new(GHOST_WindowHandle ghostwin) +{ + Window *win= MEM_callocN(sizeof(*win), "Window"); + win->ghostwin= ghostwin; + + return win; +} + +static void window_handle(Window *win, short event, short val) +{ + if (win->handler) { + win->handler(win, win->user_data, event, val, 0); + } +} +static void window_handle_ext(Window *win, short event, short val, short extra) +{ + if (win->handler) { + win->handler(win, win->user_data, event, val, extra); + } +} + +static void window_free(Window *win) +{ + MEM_freeN(win); +} + + /***/ + +static Window *active_gl_window= NULL; + +Window *window_open(char *title, int posx, int posy, int sizex, int sizey, int start_maximized) +{ + GHOST_WindowHandle ghostwin; + GHOST_TWindowState inital_state; + int scr_w, scr_h; + + winlay_get_screensize(&scr_w, &scr_h); + posy= (scr_h-posy-sizey); + + inital_state= start_maximized?GHOST_kWindowStateMaximized:GHOST_kWindowStateNormal; + ghostwin= GHOST_CreateWindow(g_system, + title, + posx, posy, sizex, sizey, + inital_state, + GHOST_kDrawingContextTypeOpenGL, + 0 /* no stereo */); + + if (ghostwin) { + Window *win= window_new(ghostwin); + + if (win) { + GHOST_SetWindowUserData(ghostwin, win); + + win->position[0]= posx; + win->position[1]= posy; + win->size[0]= sizex; + win->size[1]= sizey; + + win->lmouse[0]= win->size[0]/2; + win->lmouse[1]= win->size[1]/2; + } else { + GHOST_DisposeWindow(g_system, ghostwin); + } + + return win; + } else { + return NULL; + } +} + +void window_set_handler(Window *win, WindowHandlerFP handler, void *user_data) +{ + win->handler= handler; + win->user_data= user_data; +} + +static void window_timer_proc(GHOST_TimerTaskHandle timer, GHOST_TUns64 time) +{ + Window *win= GHOST_GetTimerTaskUserData(timer); + + win->handler(win, win->user_data, win->timer_event, 0, 0); +} + +void window_set_timer(Window *win, int delay_ms, int event) +{ + if (win->timer) GHOST_RemoveTimer(g_system, win->timer); + + win->timer_event= event; + win->timer= GHOST_InstallTimer(g_system, delay_ms, delay_ms, window_timer_proc, win); +} + +void window_destroy(Window *win) { + if (active_gl_window==win) { + active_gl_window= NULL; + } + + if (win->timer) { + GHOST_RemoveTimer(g_system, win->timer); + win->timer= NULL; + } + + GHOST_DisposeWindow(g_system, win->ghostwin); + window_free(win); +} + +void window_set_cursor(Window *win, int curs) { + if (curs==CURSOR_NONE) { + GHOST_SetCursorVisibility(win->ghostwin, 0); + } else { + GHOST_SetCursorVisibility(win->ghostwin, 1); + GHOST_SetCursorShape(win->ghostwin, convert_cursor(curs)); + } +} + +void window_set_custom_cursor(Window *win, unsigned char mask[16][2], unsigned char bitmap[16][2]) { + GHOST_SetCustomCursorShape(win->ghostwin, bitmap, mask, 7, 7); +} + +void window_make_active(Window *win) { + if (win != active_gl_window) { + active_gl_window= win; + GHOST_ActivateWindowDrawingContext(win->ghostwin); + } +} +void window_swap_buffers(Window *win) { + GHOST_SwapWindowBuffers(win->ghostwin); +} + +static int query_qual(char qual) { + GHOST_TModifierKeyMask left, right; + int val= 0; + + if (qual=='s') { + left= GHOST_kModifierKeyLeftShift; + right= GHOST_kModifierKeyRightShift; + } else if (qual=='c') { + left= GHOST_kModifierKeyLeftControl; + right= GHOST_kModifierKeyRightControl; + } else if (qual=='C') { + left= right= GHOST_kModifierKeyCommand; + } else { + left= GHOST_kModifierKeyLeftAlt; + right= GHOST_kModifierKeyRightAlt; + } + + GHOST_GetModifierKeyState(g_system, left, &val); + if (!val) + GHOST_GetModifierKeyState(g_system, right, &val); + + return val; +} +static int change_bit(int val, int bit, int to_on) { + return to_on?(val|bit):(val&~bit); +} +static int event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) { + GHOST_TEventType type= GHOST_GetEventType(evt); + + if (type == GHOST_kEventQuit) { + exit_usiblender(); + } else { + GHOST_WindowHandle ghostwin= GHOST_GetEventWindow(evt); + GHOST_TEventDataPtr data= GHOST_GetEventData(evt); + Window *win; + + if (!ghostwin) { + printf("GHOST event error - no window - type: %d\n", type); + return 1; + } else if (!GHOST_ValidWindow(g_system, ghostwin)) { + printf("GHOST event error - invalid window - win: %p\n", ghostwin); + return 1; + } else { + win= GHOST_GetWindowUserData(ghostwin); + } + + switch (type) { + case GHOST_kEventCursorMove: { + GHOST_TEventCursorData *cd= data; + int cx, cy; + + GHOST_ScreenToClient(win->ghostwin, cd->x, cd->y, &cx, &cy); + win->lmouse[0]= cx; + win->lmouse[1]= (win->size[1]-1) - cy; + + window_handle(win, MOUSEX, win->lmouse[0]); + window_handle(win, MOUSEY, win->lmouse[1]); + + break; + } + case GHOST_kEventButtonDown: + case GHOST_kEventButtonUp: { + GHOST_TEventButtonData *bd= data; + int val= (type==GHOST_kEventButtonDown); + int bbut= convert_mbut(bd->button); + + if (bbut==LEFTMOUSE) { + if (val) { + if (win->commandqual) { + bbut= win->faked_mbut= RIGHTMOUSE; + } else if (win->lqual & LR_ALTKEY) { + bbut= win->faked_mbut= MIDDLEMOUSE; + } + } else { + if (win->faked_mbut) { + bbut= win->faked_mbut; + win->faked_mbut= 0; + } + } + } + + if (bbut==LEFTMOUSE) { + win->lmbut= change_bit(win->lmbut, L_MOUSE, val); + } else if (bbut==MIDDLEMOUSE) { + win->lmbut= change_bit(win->lmbut, M_MOUSE, val); + } else { + win->lmbut= change_bit(win->lmbut, R_MOUSE, val); + } + window_handle(win, bbut, val); + + break; + } + + case GHOST_kEventKeyDown: + case GHOST_kEventKeyUp: { + GHOST_TEventKeyData *kd= data; + int val= (type==GHOST_kEventKeyDown); + int bkey= convert_key(kd->key); + + if (kd->key == GHOST_kKeyCommand) { + win->commandqual= val; + } + + if (bkey) { + if (bkey==LEFTSHIFTKEY || bkey==RIGHTSHIFTKEY) { + win->lqual= change_bit(win->lqual, LR_SHIFTKEY, val); + } else if (bkey==LEFTCTRLKEY || bkey==RIGHTCTRLKEY) { + win->lqual= change_bit(win->lqual, LR_CTRLKEY, val); + } else if (bkey==LEFTALTKEY || bkey==RIGHTALTKEY) { + win->lqual= change_bit(win->lqual, LR_ALTKEY, val); + } + + window_handle_ext(win, bkey, val, kd->ascii); + } + + break; + } + + case GHOST_kEventWindowDeactivate: + case GHOST_kEventWindowActivate: { + win->active= (type==GHOST_kEventWindowActivate); + window_handle(win, INPUTCHANGE, win->active); + + if (win->active) { + if ((win->lqual & LR_SHIFTKEY) && !query_qual('s')) { + win->lqual= change_bit(win->lqual, LR_SHIFTKEY, 0); + window_handle(win, LEFTSHIFTKEY, 0); + } + if ((win->lqual & LR_CTRLKEY) && !query_qual('c')) { + win->lqual= change_bit(win->lqual, LR_CTRLKEY, 0); + window_handle(win, LEFTCTRLKEY, 0); + } + if ((win->lqual & LR_ALTKEY) && !query_qual('a')) { + win->lqual= change_bit(win->lqual, LR_ALTKEY, 0); + window_handle(win, LEFTALTKEY, 0); + } + win->commandqual= query_qual('C'); + + /* + * XXX quick hack so OSX version works better + * when the window is clicked on (focused). + */ + window_handle(win, MOUSEX, win->lmouse[0]); + window_handle(win, MOUSEY, win->lmouse[1]); + } + + break; + } + case GHOST_kEventWindowClose: { + window_handle(win, WINCLOSE, 1); + break; + } + case GHOST_kEventWindowUpdate: { + window_handle(win, REDRAW, 1); + break; + } + case GHOST_kEventWindowSize: { + GHOST_RectangleHandle client_rect; + int l, t, r, b, scr_w, scr_h; + + client_rect= GHOST_GetClientBounds(win->ghostwin); + GHOST_GetRectangle(client_rect, &l, &t, &r, &b); + + GHOST_DisposeRectangle(client_rect); + + winlay_get_screensize(&scr_w, &scr_h); + win->position[0]= l; + win->position[1]= scr_h - b - 1; + win->size[0]= r-l; + win->size[1]= b-t; + + window_handle(win, RESHAPE, 1); + break; + } + } + } + + return 1; +} + +char *window_get_title(Window *win) { + char *title= GHOST_GetTitle(win->ghostwin); + char *mem_title= BLI_strdup(title); + free(title); + + return mem_title; +} +void window_set_title(Window *win, char *title) { + GHOST_SetTitle(win->ghostwin, title); +} + +short window_get_qual(Window *win) { + return win->lqual; +} +short window_get_mbut(Window *win) { + return win->lmbut; +} +void window_get_mouse(Window *win, short *mval) { + mval[0]= win->lmouse[0]; + mval[1]= win->lmouse[1]; +} +void window_get_position(Window *win, int *posx_r, int *posy_r) { + *posx_r= win->position[0]; + *posy_r= win->position[1]; +} +void window_get_size(Window *win, int *width_r, int *height_r) { + *width_r= win->size[0]; + *height_r= win->size[1]; +} + +void window_set_size(Window *win, int width, int height) { + GHOST_SetClientSize(win->ghostwin, width, height); +} + +void window_lower(Window *win) { + GHOST_SetWindowOrder(win->ghostwin, GHOST_kWindowOrderBottom); +} +void window_raise(Window *win) { + GHOST_SetWindowOrder(win->ghostwin, GHOST_kWindowOrderTop); +} + +void window_warp_pointer(Window *win, int x, int y) { + y= win->size[1] - y - 1; + GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y); + GHOST_SetCursorPosition(g_system, x, y); +} + +void window_queue_redraw(Window *win) { + GHOST_InvalidateWindow(win->ghostwin); +} + +/***/ + +void winlay_process_events(int wait_for_event) { + GHOST_ProcessEvents(g_system, wait_for_event); + GHOST_DispatchEvents(g_system); +} + +void winlay_get_screensize(int *width_r, int *height_r) { + unsigned int uiwidth; + unsigned int uiheight; + + if (!g_system) { + GHOST_EventConsumerHandle consumer= GHOST_CreateEventConsumer(event_proc, NULL); + + g_system= GHOST_CreateSystem(); + GHOST_AddEventConsumer(g_system, consumer); + } + + GHOST_GetMainDisplayDimensions(g_system, &uiwidth, &uiheight); + *width_r= uiwidth; + *height_r= uiheight; +} + +Window *winlay_get_active_window(void) { + return active_gl_window; +} diff --git a/source/blender/src/glutil.c b/source/blender/src/glutil.c new file mode 100644 index 00000000000..c6144e36ae6 --- /dev/null +++ b/source/blender/src/glutil.c @@ -0,0 +1,411 @@ + + +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "DNA_vec_types.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + + /* Invert line handling */ + +#define glToggle(mode, onoff) (((onoff)?glEnable:glDisable)(mode)) + +static void set_inverted_drawing(int enable) +{ + glLogicOp(enable?GL_INVERT:GL_COPY); + + /* Use GL_BLEND_EQUATION_EXT on sgi (if we have it), + * apparently GL_COLOR_LOGIC_OP doesn't work on O2? + * Is this an sgi bug or our bug? + */ +#if defined(__sgi) && defined(GL_BLEND_EQUATION_EXT) + glBlendEquationEXT(enable?GL_LOGIC_OP:GL_FUNC_ADD_EXT); + glToggle(GL_BLEND, enable); +#else + glToggle(GL_COLOR_LOGIC_OP, enable); +#endif + + glToggle(GL_DITHER, !enable); +} + +void sdrawXORline(int x0, int y0, int x1, int y1) +{ + if(x0==x1 && y0==y1) return; + + set_inverted_drawing(1); + + glBegin(GL_LINES); + glVertex2i(x0, y0); + glVertex2i(x1, y1); + glEnd(); + + set_inverted_drawing(0); +} + +void glutil_draw_front_xor_line(int x0, int y0, int x1, int y1) +{ + glDrawBuffer(GL_FRONT); + sdrawXORline(x0, y0, x1, y1); + glFinish(); + glDrawBuffer(GL_BACK); +} + +void sdrawXORline4(int nr, int x0, int y0, int x1, int y1) +{ + static short old[4][2][2]; + static char flags[4]= {0, 0, 0, 0}; + + /* automatische onthoud, max 4 lijnen */ + + set_inverted_drawing(1); + + glBegin(GL_LINES); + if(nr== -1) { /* flush */ + for (nr=0; nr<4; nr++) { + if (flags[nr]) { + glVertex2sv(old[nr][0]); + glVertex2sv(old[nr][1]); + flags[nr]= 0; + } + } + } else { + if(nr>=0 && nr<4) { + if(flags[nr]) { + glVertex2sv(old[nr][0]); + glVertex2sv(old[nr][1]); + } + + old[nr][0][0]= x0; + old[nr][0][1]= y0; + old[nr][1][0]= x1; + old[nr][1][1]= y1; + + flags[nr]= 1; + } + + glVertex2i(x0, y0); + glVertex2i(x1, y1); + } + glEnd(); + + set_inverted_drawing(0); +} + +void sdrawXORcirc(short xofs, short yofs, float rad) +{ + set_inverted_drawing(1); + + glPushMatrix(); + glTranslatef(xofs, yofs, 0.0); + glutil_draw_lined_arc(0.0, M_PI*2, rad, 20); + glPopMatrix(); + + set_inverted_drawing(0); +} + +void glutil_draw_filled_arc(float start, float angle, float radius, int nsegments) { + int i; + + glBegin(GL_TRIANGLE_FAN); + glVertex2f(0.0, 0.0); + for (i=0; i<nsegments; i++) { + float t= (float) i/(nsegments-1); + float cur= start + t*angle; + + glVertex2f(cos(cur)*radius, sin(cur)*radius); + } + glEnd(); +} + +void glutil_draw_lined_arc(float start, float angle, float radius, int nsegments) { + int i; + + glBegin(GL_LINE_STRIP); + for (i=0; i<nsegments; i++) { + float t= (float) i/(nsegments-1); + float cur= start + t*angle; + + glVertex2f(cos(cur)*radius, sin(cur)*radius); + } + glEnd(); +} + +int glaGetOneInteger(int param) +{ + int i; + glGetIntegerv(param, &i); + return i; +} + +float glaGetOneFloat(int param) +{ + float v; + glGetFloatv(param, &v); + return v; +} + +void glaRasterPosSafe2f(float x, float y, float known_good_x, float known_good_y) +{ + GLubyte dummy= 0; + + /* As long as known good coordinates are correct + * this is guarenteed to generate an ok raster + * position (ignoring potential (real) overflow + * issues). + */ + glRasterPos2f(known_good_x, known_good_y); + + /* Now shift the raster position to where we wanted + * it in the first place using the glBitmap trick. + */ + glBitmap(1, 1, 0, 0, x - known_good_x, y - known_good_y, &dummy); +} + +static int get_cached_work_texture(int *w_r, int *h_r) +{ + static int texid= -1; + static int tex_w= 256; + static int tex_h= 256; + + if (texid==-1) { + GLint ltexid= glaGetOneInteger(GL_TEXTURE_2D); + unsigned char *tbuf; + + glGenTextures(1, &texid); + + glBindTexture(GL_TEXTURE_2D, texid); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + tbuf= MEM_callocN(tex_w*tex_h*4, "tbuf"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tbuf); + MEM_freeN(tbuf); + + glBindTexture(GL_TEXTURE_2D, ltexid); + } + + *w_r= tex_w; + *h_r= tex_h; + return texid; +} + +void glaDrawPixelsTex(float x, float y, int img_w, int img_h, void *rect) +{ + unsigned char *uc_rect= (unsigned char*) rect; + float xzoom= glaGetOneFloat(GL_ZOOM_X), yzoom= glaGetOneFloat(GL_ZOOM_Y); + int ltexid= glaGetOneInteger(GL_TEXTURE_2D); + int lrowlength= glaGetOneInteger(GL_UNPACK_ROW_LENGTH); + int subpart_x, subpart_y, tex_w, tex_h; + int texid= get_cached_work_texture(&tex_w, &tex_h); + int nsubparts_x= (img_w+(tex_w-1))/tex_w; + int nsubparts_y= (img_h+(tex_h-1))/tex_h; + + glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w); + glBindTexture(GL_TEXTURE_2D, texid); + + for (subpart_y=0; subpart_y<nsubparts_y; subpart_y++) { + for (subpart_x=0; subpart_x<nsubparts_x; subpart_x++) { + int subpart_w= (subpart_x==nsubparts_x-1)?(img_w-subpart_x*tex_w):tex_w; + int subpart_h= (subpart_y==nsubparts_y-1)?(img_h-subpart_y*tex_h):tex_h; + float rast_x= x+subpart_x*tex_w*xzoom; + float rast_y= y+subpart_y*tex_h*yzoom; + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, GL_RGBA, GL_UNSIGNED_BYTE, &uc_rect[(subpart_y*tex_w)*img_w*4 + (subpart_x*tex_w)*4]); + + glColor3ub(255, 255, 255); + glEnable(GL_TEXTURE_2D); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(rast_x, rast_y); + + glTexCoord2f((float) subpart_w/tex_w, 0); + glVertex2f(rast_x+subpart_w*xzoom, rast_y); + + glTexCoord2f((float) subpart_w/tex_w, (float) subpart_h/tex_h); + glVertex2f(rast_x+subpart_w*xzoom, rast_y+subpart_h*yzoom); + + glTexCoord2f(0, (float) subpart_h/tex_h); + glVertex2f(rast_x, rast_y+subpart_h*yzoom); + glEnd(); + glDisable(GL_TEXTURE_2D); + } + } + + glBindTexture(GL_TEXTURE_2D, ltexid); + glPixelStorei(GL_UNPACK_ROW_LENGTH, lrowlength); +} + +void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, void *rect) +{ + unsigned char *uc_rect= (unsigned char*) rect; + float origin_x= 0.375; + float origin_y= 0.375; + + /* Trivial case */ + if (x>=origin_x && y>=origin_y) { + glRasterPos2f(x, y); + glDrawPixels(img_w, img_h, GL_RGBA, GL_UNSIGNED_BYTE, uc_rect); + } else { + int old_row_length= glaGetOneInteger(GL_UNPACK_ROW_LENGTH); + float xzoom= glaGetOneFloat(GL_ZOOM_X); + float yzoom= glaGetOneFloat(GL_ZOOM_Y); + + /* The pixel space coordinate of the intersection of + * the [zoomed] image with the origin. + */ + float ix= (origin_x-x)/xzoom; + float iy= (origin_y-y)/yzoom; + + /* The maximum pixel amounts the image can cropped + * without exceeding the origin. + */ + int off_x= floor((ix>origin_x)?ix:origin_x); + int off_y= floor((iy>origin_y)?iy:origin_y); + + /* The zoomed space coordinate of the raster + * position. + */ + float rast_x= x + off_x*xzoom; + float rast_y= y + off_y*yzoom; + + if (off_x<img_w && off_y<img_h) { + glaRasterPosSafe2f(rast_x, rast_y, origin_x, origin_y); + glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w); + glDrawPixels(img_w-off_x, img_h-off_y, GL_RGBA, GL_UNSIGNED_BYTE, uc_rect+off_y*img_w*4+off_x*4); + glPixelStorei(GL_UNPACK_ROW_LENGTH, old_row_length); + } + } +} + +/* 2D Drawing Assistance */ + +void glaDefine2DArea(rcti *screen_rect) +{ + int sc_w= screen_rect->xmax - screen_rect->xmin; + int sc_h= screen_rect->ymax - screen_rect->ymin; + + glViewport(screen_rect->xmin, screen_rect->ymin, sc_w, sc_h); + glScissor(screen_rect->xmin, screen_rect->ymin, sc_w, sc_h); + + /* The 0.375 magic number is to shift the matrix so that + * both raster and vertex integer coordinates fall at pixel + * centers properly. For a longer discussion see the OpenGL + * Programming Guide, Appendix H, Correctness Tips. + */ + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.0, sc_w, 0.0, sc_h, -1, 1); + glTranslatef(0.375, 0.375, 0.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +struct gla2DDrawInfo { + int orig_vp[4], orig_sc[4]; + float orig_projmat[16], orig_viewmat[16]; + + rcti screen_rect; + rctf world_rect; + + float wo_to_sc[2]; +}; + +gla2DDrawInfo *glaBegin2DDraw(rcti *screen_rect, rctf *world_rect) +{ + gla2DDrawInfo *di= MEM_mallocN(sizeof(*di), "gla2DDrawInfo"); + int sc_w, sc_h; + float wo_w, wo_h; + + glGetIntegerv(GL_VIEWPORT, di->orig_vp); + glGetIntegerv(GL_SCISSOR_BOX, di->orig_sc); + glGetFloatv(GL_PROJECTION_MATRIX, di->orig_projmat); + glGetFloatv(GL_MODELVIEW_MATRIX, di->orig_viewmat); + + di->screen_rect= *screen_rect; + if (world_rect) { + di->world_rect= *world_rect; + } else { + di->world_rect.xmin= di->screen_rect.xmin; + di->world_rect.ymin= di->screen_rect.ymin; + di->world_rect.xmax= di->screen_rect.xmax; + di->world_rect.ymax= di->screen_rect.ymax; + } + + sc_w= (di->screen_rect.xmax-di->screen_rect.xmin); + sc_h= (di->screen_rect.ymax-di->screen_rect.ymin); + wo_w= (di->world_rect.xmax-di->world_rect.xmin); + wo_h= (di->world_rect.ymax-di->world_rect.ymin); + + di->wo_to_sc[0]= sc_w/wo_w; + di->wo_to_sc[1]= sc_h/wo_h; + + glaDefine2DArea(&di->screen_rect); + + return di; +} + +void gla2DDrawTranslatePt(gla2DDrawInfo *di, float wo_x, float wo_y, int *sc_x_r, int *sc_y_r) +{ + *sc_x_r= (wo_x - di->world_rect.xmin)*di->wo_to_sc[0]; + *sc_y_r= (wo_y - di->world_rect.ymin)*di->wo_to_sc[1]; +} +void gla2DDrawTranslatePtv(gla2DDrawInfo *di, float world[2], int screen_r[2]) +{ + screen_r[0]= (world[0] - di->world_rect.xmin)*di->wo_to_sc[0]; + screen_r[1]= (world[1] - di->world_rect.ymin)*di->wo_to_sc[1]; +} + +void glaEnd2DDraw(gla2DDrawInfo *di) +{ + glViewport(di->orig_vp[0], di->orig_vp[1], di->orig_vp[2], di->orig_vp[3]); + glScissor(di->orig_vp[0], di->orig_vp[1], di->orig_vp[2], di->orig_vp[3]); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(di->orig_projmat); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(di->orig_viewmat); + + MEM_freeN(di); +} diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c new file mode 100644 index 00000000000..71cbac51dea --- /dev/null +++ b/source/blender/src/headerbuttons.c @@ -0,0 +1,5577 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <string.h> +#include <math.h> + +#include <sys/types.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_storage_types.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "DNA_ID.h" +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_camera_types.h" +#include "DNA_curve_types.h" +#include "DNA_group_types.h" +#include "DNA_image_types.h" +#include "DNA_ipo_types.h" +#include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_lattice_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_object_types.h" +#include "DNA_oops_types.h" +#include "DNA_packedFile_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_sequence_types.h" +#include "DNA_sound_types.h" +#include "DNA_space_types.h" +#include "DNA_texture_types.h" +#include "DNA_text_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view2d_types.h" +#include "DNA_view3d_types.h" +#include "DNA_world_types.h" +#include "DNA_constraint_types.h" + +#include "BKE_utildefines.h" + +#include "BKE_constraint.h" +#include "BKE_action.h" +#include "BKE_armature.h" +#include "BKE_blender.h" +#include "BKE_curve.h" +#include "BKE_displist.h" +#include "BKE_exotic.h" +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_ika.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_lattice.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_mball.h" +#include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_packedFile.h" +#include "BKE_sca.h" +#include "BKE_scene.h" +#include "BKE_texture.h" +#include "BKE_text.h" +#include "BKE_world.h" + +#include "BLO_readfile.h" +#include "BLO_writefile.h" + +#include "BIF_drawimage.h" +#include "BIF_drawoops.h" +#include "BIF_drawscene.h" +#include "BIF_drawtext.h" +#include "BIF_editarmature.h" +#include "BIF_editfont.h" +#include "BIF_editlattice.h" +#include "BIF_editconstraint.h" +#include "BIF_editmesh.h" +#include "BIF_editmesh.h" +#include "BIF_editsima.h" +#include "BIF_editsound.h" +#include "BIF_editsound.h" +#include "BIF_gl.h" +#include "BIF_imasel.h" +#include "BIF_interface.h" +#include "BIF_mainqueue.h" +#include "BIF_mywindow.h" +#include "BIF_poseobject.h" +#include "BIF_renderwin.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_toets.h" +#include "BIF_toets.h" +#include "BIF_toolbox.h" +#include "BIF_usiblender.h" +#include "BIF_previewrender.h" +#include "BIF_writeimage.h" + +#include "BSE_edit.h" +#include "BSE_filesel.h" +#include "BSE_headerbuttons.h" +#include "BSE_view.h" +#include "BSE_sequence.h" +#include "BSE_editaction.h" +#include "BSE_editaction_types.h" +#include "BSE_editipo.h" +#include "BSE_drawipo.h" + +#include "BDR_drawmesh.h" +#include "BDR_vpaint.h" +#include "BDR_editface.h" +#include "BDR_editobject.h" +#include "BDR_editcurve.h" +#include "BDR_editmball.h" + +#include "BPY_extern.h" // Blender Python library + +#include "interface.h" +#include "mydevice.h" +#include "blendef.h" +#include "render.h" +#include "ipo.h" +#include "nla.h" /* __NLA : To be removed later */ + +#include "TPT_DependKludge.h" + +/* these are needed to hide functions behind function tables, + which are initialized by the python key code */ +#include "keyed_functions.h" +#include "license_key.h" + +/* local (?) functions */ +void do_file_buttons(short event); +void do_text_buttons(unsigned short event); +void load_space_sound(char *str); +void load_sound_buttons(char *str); +void load_space_image(char *str); +void image_replace(Image *old, Image *new); +void replace_space_image(char *str); +void do_image_buttons(unsigned short event); +void do_imasel_buttons(short event); +static void check_packAll(void); +static void unique_bone_name(Bone *bone, bArmature *arm); +static void validate_bonebutton(void *data1, void *data2); +static int bonename_exists(Bone *orig, char *name, ListBase *list); + +static void test_idbutton_cb(void *namev, void *arg2_unused) +{ + char *name= namev; + test_idbutton(name+2); +} + +#define SPACEICONMAX 13 /* See release/datafiles/blenderbuttons */ + +#include "BIF_poseobject.h" + +#include "SYS_System.h" + +#include "license_key.h" +static int std_libbuttons(uiBlock *block, + int xco, int pin, short *pinpoin, + int browse, ID *id, ID *parid, + short *menupoin, int users, + int lib, int del, int autobut); + + +extern char versionstr[]; /* from blender.c */ +/* extern void add_text_fs(char *file); *//* from text.c, BIF_text.h*/ + + /* LET OP: alle headerbuttons voor zelfde window steeds zelfde naam + * event B_REDR is standaard redraw + * + */ + + +/* + * The next define turns the newest menu structure on. + * There are some loose ends here at the moment so leave this undefined for now. + */ +/* #define EXPERIMENTAL_MENUS */ + + +#define XIC 20 +#define YIC 20 + +static int viewmovetemp=0; + +/* extern void info_buttons(); in BSE_headerbuttons.c */ + +extern char videosc_dir[]; /* exotic.c */ + +/* *********************************************************************** */ + +void write_videoscape_fs() +{ + if(G.obedit) { + error("Can't save Videoscape. Press TAB to leave EditMode"); + } + else { + if(videosc_dir[0]==0) strcpy(videosc_dir, G.sce); + activate_fileselect(FILE_SPECIAL, "SAVE VIDEOSCAPE", videosc_dir, write_videoscape); + } +} + +void write_vrml_fs() +{ + if(G.obedit) { + error("Can't save VRML. Press TAB to leave EditMode"); + } + else { + if(videosc_dir[0]==0) strcpy(videosc_dir, G.sce); + + activate_fileselect(FILE_SPECIAL, "SAVE VRML1", videosc_dir, write_vrml); + } + +} + +void write_dxf_fs() +{ + if(G.obedit) { + error("Can't save DXF. Press TAB to leave EditMode"); + } + else { + + if(videosc_dir[0]==0) strcpy(videosc_dir, G.sce); + + activate_fileselect(FILE_SPECIAL, "SAVE DXF", videosc_dir, write_dxf); + } +} + +/* ********************** GLOBAL ****************************** */ + +static int std_libbuttons(uiBlock *block, int xco, int pin, short *pinpoin, int browse, ID *id, ID *parid, short *menupoin, int users, int lib, int del, int autobut) +{ + ListBase *lb; + Object *ob; + Ipo *ipo; + uiBut *but; + int len, idwasnul=0, idtype, oldcol; + char *str=NULL, str1[10]; + + oldcol= uiBlockGetCol(block); + + if(id && pin) { + uiDefIconButS(block, ICONTOG, pin, ICON_PIN_DEHLT, (short)xco,0,XIC,YIC, pinpoin, 0, 0, 0, 0, "Pin this data block; no update according Object selection"); + xco+= XIC; + } + if(browse) { + if(id==0) { + idwasnul= 1; + /* alleen de browse button */ + ob= OBACT; + if(curarea->spacetype==SPACE_IMAGE) { + id= G.main->image.first; + } + else if(curarea->spacetype==SPACE_SOUND) { + id= G.main->sound.first; + } + else if(curarea->spacetype==SPACE_ACTION) { + id= G.main->action.first; + } + else if(curarea->spacetype==SPACE_NLA) { + id=NULL; + } + else if(curarea->spacetype==SPACE_IPO) { + id= G.main->ipo.first; + /* testen op ipotype */ + while(id) { + ipo= (Ipo *)id; + if(G.sipo->blocktype==ipo->blocktype) break; + id= id->next; + } + } + else if(curarea->spacetype==SPACE_BUTS) { + if(browse==B_WORLDBROWSE) { + id= G.main->world.first; + } + else if(ob && ob->type && (ob->type<OB_LAMP)) { + if(G.buts->mainb==BUTS_MAT) id= G.main->mat.first; + else if(G.buts->mainb==BUTS_TEX) id= G.main->tex.first; + } + } + else if(curarea->spacetype==SPACE_TEXT) { + id= G.main->text.first; + } + } + if(id) { + char *extrastr= NULL; + + idtype= GS(id->name); + lb= wich_libbase(G.main, GS(id->name)); + + if(idwasnul) id= NULL; + else if(id->us>1) uiBlockSetCol(block, BUTDBLUE); + + if (pin && *pinpoin) { + uiBlockSetCol(block, BUTDPINK); + } + + if ELEM7( idtype, ID_SCE, ID_SCR, ID_MA, ID_TE, ID_WO, ID_IP, ID_AC) extrastr= "ADD NEW %x 32767"; + else if (idtype==ID_TXT) extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767"; + else if (idtype==ID_SO) extrastr= "OPEN NEW %x 32766"; + + uiSetButLock(G.scene->id.lib!=0, "Can't edit library data"); + if( idtype==ID_SCE || idtype==ID_SCR ) uiClearButLock(); + + if(curarea->spacetype==SPACE_BUTS) + uiSetButLock(idtype!=ID_SCR && G.obedit!=0 && G.buts->mainb==BUTS_EDIT, NULL); + + if(parid) uiSetButLock(parid->lib!=0, "Can't edit library data"); + + if (lb) { + if( idtype==ID_IP) + IPOnames_to_pupstring(&str, NULL, extrastr, lb, id, menupoin, G.sipo->blocktype); + else + IDnames_to_pupstring(&str, NULL, extrastr, lb, id, menupoin); + } + + uiDefButS(block, MENU, browse, str, (short)xco,0,XIC,YIC, menupoin, 0, 0, 0, 0, "Browse Datablock or Add NEW"); + + uiClearButLock(); + + MEM_freeN(str); + xco+= XIC; + } + else if(curarea->spacetype==SPACE_BUTS) { + if ELEM3(G.buts->mainb, BUTS_MAT, BUTS_TEX, BUTS_WORLD) { + uiSetButLock(G.scene->id.lib!=0, "Can't edit library data"); + if(parid) uiSetButLock(parid->lib!=0, "Can't edit library data"); + uiDefButS(block, MENU, browse, "ADD NEW %x 32767",(short) xco,0,XIC,YIC, menupoin, 0, 0, 0, 0, "Browse Datablock"); + uiClearButLock(); + } else if (G.buts->mainb == BUTS_SOUND) { + uiDefButS(block, MENU, browse, "OPEN NEW %x 32766",(short) xco,0,XIC,YIC, menupoin, 0, 0, 0, 0, "Browse Datablock"); + } + } + else if(curarea->spacetype==SPACE_TEXT) { + uiDefButS(block, MENU, browse, "OPEN NEW %x 32766 | ADD NEW %x 32767", (short)xco,0,XIC,YIC, menupoin, 0, 0, 0, 0, "Browse Datablock"); + } + else if(curarea->spacetype==SPACE_SOUND) { + uiDefButS(block, MENU, browse, "OPEN NEW %x 32766",(short)xco,0,XIC,YIC, menupoin, 0, 0, 0, 0, "Browse Datablock"); + } + else if(curarea->spacetype==SPACE_NLA) { + } + else if(curarea->spacetype==SPACE_ACTION) { + uiSetButLock(G.scene->id.lib!=0, "Can't edit library data"); + if(parid) uiSetButLock(parid->lib!=0, "Can't edit library data"); + + uiDefButS(block, MENU, browse, "ADD NEW %x 32767", xco,0,XIC,YIC, menupoin, 0, 0, 0, 0, "Browse Datablock"); + uiClearButLock(); + } + else if(curarea->spacetype==SPACE_IPO) { + uiSetButLock(G.scene->id.lib!=0, "Can't edit library data"); + if(parid) uiSetButLock(parid->lib!=0, "Can't edit library data"); + + uiDefButS(block, MENU, browse, "ADD NEW %x 32767", (short)xco,0,XIC,YIC, menupoin, 0, 0, 0, 0, "Browse Datablock"); + uiClearButLock(); + } + } + + + uiBlockSetCol(block, oldcol); + + if(id) { + + /* name */ + if(id->us>1) uiBlockSetCol(block, BUTDBLUE); + /* Pinned data ? */ + if (pin && *pinpoin) { + uiBlockSetCol(block, BUTDPINK); + } + /* Redalert overrides pin color */ + if(id->us<=0) uiBlockSetCol(block, REDALERT); + + uiSetButLock(id->lib!=0, "Can't edit library data"); + + str1[0]= id->name[0]; + str1[1]= id->name[1]; + str1[2]= ':'; + str1[3]= 0; + if(strcmp(str1, "SC:")==0) strcpy(str1, "SCE:"); + else if(strcmp(str1, "SR:")==0) strcpy(str1, "SCR:"); + + if( GS(id->name)==ID_IP) len= 110; + else len= 120; + + but= uiDefBut(block, TEX, B_IDNAME, str1,(short)xco, 0, (short)len, YIC, id->name+2, 0.0, 19.0, 0, 0, "Datablock name"); + uiButSetFunc(but, test_idbutton_cb, id->name, NULL); + + uiClearButLock(); + + xco+= len; + + if(id->lib) { + + if(parid && parid->lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB,(short)xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Indirect Library Datablock"); + else uiDefIconBut(block, BUT, lib, ICON_PARLIB, (short)xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Library DataBlock, press to make local"); + + xco+= XIC; + } + + + if(users && id->us>1) { + uiSetButLock (pin && *pinpoin, "Can't make pinned data single-user"); + + sprintf(str1, "%d", id->us); + if(id->us<100) { + + uiDefBut(block, BUT, users, str1, (short)xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Number of users, press to make single-user"); + xco+= XIC; + } + else { + uiDefBut(block, BUT, users, str1, (short)xco, 0, XIC+10, YIC, 0, 0, 0, 0, 0, "Number of users, press to make single-user"); + xco+= XIC+10; + } + + uiClearButLock(); + + } + + if(del) { + + uiSetButLock (pin && *pinpoin, "Can't unlink pinned data"); + if(parid && parid->lib); + else { + uiDefIconBut(block, BUT, del, ICON_X, (short)xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Delete link to this Datablock"); + xco+= XIC; + } + + uiClearButLock(); + } + + if(autobut) { + if(parid && parid->lib); + else { + uiDefIconBut(block, BUT, autobut, ICON_AUTO,(short)xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Automatic name"); + xco+= XIC; + } + + + } + } + else xco+=XIC; + + uiBlockSetCol(block, oldcol); + + return xco; +} + +void update_for_newframe(void) +{ + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION,0); + allqueue(REDRAWNLA,0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWINFO, 1); + allqueue(REDRAWSEQ, 1); + allqueue(REDRAWSOUND, 1); + allqueue(REDRAWBUTSHEAD, 1); + allqueue(REDRAWBUTSMAT, 1); + allqueue(REDRAWBUTSLAMP, 1); + + /* layers/materials, object ipos are calculted in where_is_object (too) */ + do_all_ipos(); + BPY_do_all_scripts(SCRIPT_FRAMECHANGED); + do_all_keys(); + do_all_actions(); + do_all_ikas(); + + test_all_displists(); +} + +static void show_splash(void) +{ + extern char datatoc_splash_jpg[]; + extern int datatoc_splash_jpg_size; + char *string = NULL; + +#ifdef NAN_BUILDINFO + char buffer[1024]; + extern char * build_date; + extern char * build_time; + extern char * build_platform; + extern char * build_type; + + string = &buffer[0]; + sprintf(string,"Built on %s %s Version %s %s", build_date, build_time, build_platform, build_type); +#endif + + splash((void *)datatoc_splash_jpg, datatoc_splash_jpg_size, string); +} + +void do_global_buttons(unsigned short event) +{ + ListBase *lb; + Object *ob; + Material *ma; + MTex *mtex; + Ipo *ipo; + Lamp *la; + World *wrld; + Sequence *seq; + bAction *act; + ID *id, *idtest, *from; + int nr= 1; + + ob= OBACT; + + id= 0; /* id op nul voor texbrowse */ + + switch(event) { + + case B_NEWFRAME: + scrarea_queue_winredraw(curarea); + scrarea_queue_headredraw(curarea); + + update_for_newframe(); + break; + case B_REDR: + scrarea_queue_winredraw(curarea); + scrarea_queue_headredraw(curarea); + break; + case B_EDITBROWSE: + if(ob==0) return; + if(ob->id.lib) return; + id= ob->data; + if(id==0) return; + + if(G.buts->menunr== -2) { + activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_EDITBROWSE, &G.buts->menunr, do_global_buttons); + return; + } + if(G.buts->menunr < 0) return; + + lb= wich_libbase(G.main, GS(id->name)); + idtest= lb->first; + while(idtest) { + if(nr==G.buts->menunr) { + if(idtest!=id) { + id->us--; + id_us_plus(idtest); + + ob->data= idtest; + + test_object_materials(idtest); + + if( GS(idtest->name)==ID_CU ) { + test_curve_type(ob); + allqueue(REDRAWBUTSEDIT, 0); + makeDispList(ob); + } + else if( ob->type==OB_MESH ) { + makeDispList(ob); + } + + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION,0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWNLA,0); + } + break; + } + nr++; + idtest= idtest->next; + } + + break; + case B_MESHBROWSE: + if(ob==0) return; + if(ob->id.lib) return; + + id= ob->data; + if(id==0) id= G.main->mesh.first; + if(id==0) return; + + if(G.buts->menunr== -2) { + activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_MESHBROWSE, &G.buts->menunr, do_global_buttons); + return; + } + if(G.buts->menunr < 0) return; + + + idtest= G.main->mesh.first; + while(idtest) { + if(nr==G.buts->menunr) { + + set_mesh(ob, (Mesh *)idtest); + + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION,0); + allqueue(REDRAWIPO, 0); + + break; + } + nr++; + idtest= idtest->next; + } + + break; + case B_MATBROWSE: + if(G.buts->menunr== -2) { + activate_databrowse((ID *)G.buts->lockpoin, ID_MA, 0, B_MATBROWSE, &G.buts->menunr, do_global_buttons); + return; + } + + if(G.buts->menunr < 0) return; + + if(G.buts->pin) { + + } + else { + + ma= give_current_material(ob, ob->actcol); + nr= 1; + + id= (ID *)ma; + + idtest= G.main->mat.first; + while(idtest) { + if(nr==G.buts->menunr) { + break; + } + nr++; + idtest= idtest->next; + } + if(idtest==0) { /* new mat */ + if(id) idtest= (ID *)copy_material((Material *)id); + else { + idtest= (ID *)add_material("Material"); + } + idtest->us--; + } + if(idtest!=id) { + assign_material(ob, (Material *)idtest, ob->actcol); + + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSMAT, 0); + allqueue(REDRAWIPO, 0); + BIF_preview_changed(G.buts); + } + + } + break; + case B_MATDELETE: + if(G.buts->pin) { + + } + else { + ma= give_current_material(ob, ob->actcol); + if(ma) { + assign_material(ob, 0, ob->actcol); + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSMAT, 0); + allqueue(REDRAWIPO, 0); + BIF_preview_changed(G.buts); + } + } + break; + case B_TEXDELETE: + if(G.buts->pin) { + + } + else { + if(G.buts->texfrom==0) { /* from mat */ + ma= give_current_material(ob, ob->actcol); + if(ma) { + mtex= ma->mtex[ ma->texact ]; + if(mtex) { + if(mtex->tex) mtex->tex->id.us--; + MEM_freeN(mtex); + ma->mtex[ ma->texact ]= 0; + allqueue(REDRAWBUTSTEX, 0); + allqueue(REDRAWIPO, 0); + BIF_preview_changed(G.buts); + } + } + } + else if(G.buts->texfrom==1) { /* from world */ + wrld= G.scene->world; + if(wrld) { + mtex= wrld->mtex[ wrld->texact ]; + if(mtex) { + if(mtex->tex) mtex->tex->id.us--; + MEM_freeN(mtex); + wrld->mtex[ wrld->texact ]= 0; + allqueue(REDRAWBUTSTEX, 0); + allqueue(REDRAWIPO, 0); + BIF_preview_changed(G.buts); + } + } + } + else { /* from lamp */ + la= ob->data; + if(la && ob->type==OB_LAMP) { /* voor zekerheid */ + mtex= la->mtex[ la->texact ]; + if(mtex) { + if(mtex->tex) mtex->tex->id.us--; + MEM_freeN(mtex); + la->mtex[ la->texact ]= 0; + allqueue(REDRAWBUTSTEX, 0); + allqueue(REDRAWIPO, 0); + BIF_preview_changed(G.buts); + } + } + } + } + break; + case B_EXTEXBROWSE: + case B_TEXBROWSE: + + if(G.buts->texnr== -2) { + + id= G.buts->lockpoin; + if(event==B_EXTEXBROWSE) { + id= 0; + ma= give_current_material(ob, ob->actcol); + if(ma) { + mtex= ma->mtex[ ma->texact ]; + if(mtex) id= (ID *)mtex->tex; + } + } + + activate_databrowse(id, ID_TE, 0, B_TEXBROWSE, &G.buts->texnr, do_global_buttons); + return; + } + if(G.buts->texnr < 0) break; + + if(G.buts->pin) { + + } + else { + id= 0; + + ma= give_current_material(ob, ob->actcol); + if(ma) { + mtex= ma->mtex[ ma->texact ]; + if(mtex) id= (ID *)mtex->tex; + } + + idtest= G.main->tex.first; + while(idtest) { + if(nr==G.buts->texnr) { + break; + } + nr++; + idtest= idtest->next; + } + if(idtest==0) { /* new tex */ + if(id) idtest= (ID *)copy_texture((Tex *)id); + else idtest= (ID *)add_texture("Tex"); + idtest->us--; + } + if(idtest!=id && ma) { + + if( ma->mtex[ma->texact]==0) ma->mtex[ma->texact]= add_mtex(); + + ma->mtex[ ma->texact ]->tex= (Tex *)idtest; + id_us_plus(idtest); + if(id) id->us--; + + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSTEX, 0); + allqueue(REDRAWBUTSMAT, 0); + allqueue(REDRAWIPO, 0); + BIF_preview_changed(G.buts); + } + } + break; + case B_ACTIONDELETE: + act=ob->action; + + if (act) + act->id.us--; + ob->action=NULL; + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWIPO, 0); + break; + case B_ACTIONBROWSE: + if (!ob) + break; + act=ob->action; + id= (ID *)act; + + if (G.saction->actnr== -2){ + activate_databrowse((ID *)G.saction->action, ID_AC, 0, B_ACTIONBROWSE, &G.saction->actnr, do_global_buttons); + return; + } + + if(G.saction->actnr < 0) break; + + /* See if we have selected a valid action */ + for (idtest= G.main->action.first; idtest; idtest= idtest->next) { + if(nr==G.saction->actnr) { + break; + } + nr++; + + } + + if(G.saction->pin) { + G.saction->action= (bAction *)idtest; + allqueue(REDRAWACTION, 0); + } + else { + + /* Store current action */ + if (!idtest){ + if (act) + idtest= (ID *)copy_action(act); + else + idtest=(ID *)add_empty_action(); + idtest->us--; + } + + + if(idtest!=id && ob) { + act= (bAction *)idtest; + + ob->action= act; + ob->activecon=NULL; + id_us_plus(idtest); + + if(id) id->us--; + + // Update everything + do_global_buttons (B_NEWFRAME); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWHEADERS, 0); + } + } + + break; + case B_IPOBROWSE: + + ipo= get_ipo_to_edit(&from); + id= (ID *)ipo; + if(from==0) return; + + if(G.sipo->menunr== -2) { + activate_databrowse((ID *)G.sipo->ipo, ID_IP, GS(from->name), B_IPOBROWSE, &G.sipo->menunr, do_global_buttons); + return; + } + + if(G.sipo->menunr < 0) break; + + idtest= G.main->ipo.first; + while(idtest) { + if( ((Ipo *)idtest)->blocktype == G.sipo->blocktype) { + if(nr==G.sipo->menunr) { + break; + } + nr++; + } + idtest= idtest->next; + } + + if(G.sipo->pin) { + if(idtest) { + G.sipo->ipo= (Ipo *)idtest; + allspace(REMAKEIPO, 0); // in fact it should only do this one, but there is no function for it + } + } + else { + // assign the ipo to ... + + if(idtest==0) { + if(ipo) idtest= (ID *)copy_ipo(ipo); + else { + nr= GS(from->name); + if(nr==ID_OB){ + if (G.sipo->blocktype==IPO_CO) + idtest= (ID *)add_ipo("CoIpo", IPO_CO); /* BLEARGH! */ + else + idtest= (ID *)add_ipo("ObIpo", nr); + } + else if(nr==ID_MA) idtest= (ID *)add_ipo("MatIpo", nr); + else if(nr==ID_SEQ) idtest= (ID *)add_ipo("MatSeq", nr); + else if(nr==ID_CU) idtest= (ID *)add_ipo("CuIpo", nr); + else if(nr==ID_KE) idtest= (ID *)add_ipo("KeyIpo", nr); + else if(nr==ID_WO) idtest= (ID *)add_ipo("WoIpo", nr); + else if(nr==ID_LA) idtest= (ID *)add_ipo("LaIpo", nr); + else if(nr==ID_CA) idtest= (ID *)add_ipo("CaIpo", nr); + else if(nr==ID_SO) idtest= (ID *)add_ipo("SndIpo", nr); + else if(nr==ID_AC) idtest= (ID *)add_ipo("ActIpo", nr); + else error("Warn bugs@blender.nl!"); + } + idtest->us--; + } + if(idtest!=id && from) { + ipo= (Ipo *)idtest; + + if (ipo->blocktype==IPO_CO){ + ((Object*)from)->activecon->ipo = ipo; + id_us_plus(idtest); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + else if(ipo->blocktype==ID_OB) { + ( (Object *)from)->ipo= ipo; + id_us_plus(idtest); + allqueue(REDRAWVIEW3D, 0); + } + else if(ipo->blocktype==ID_AC) { + bActionChannel *chan; + chan = get_hilighted_action_channel ((bAction*)from); + if (!chan){ + error ("Create an action channel first"); + return; + } + chan->ipo=ipo; + id_us_plus(idtest); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + } + else if(ipo->blocktype==ID_MA) { + ( (Material *)from)->ipo= ipo; + id_us_plus(idtest); + allqueue(REDRAWBUTSMAT, 0); + } + else if(ipo->blocktype==ID_SEQ) { + seq= (Sequence *)from; + if(seq->type & SEQ_EFFECT) { + id_us_plus(idtest); + seq->ipo= ipo; + } + } + else if(ipo->blocktype==ID_CU) { + ( (Curve *)from)->ipo= ipo; + id_us_plus(idtest); + allqueue(REDRAWVIEW3D, 0); + } + else if(ipo->blocktype==ID_KE) { + ( (Key *)from)->ipo= ipo; + + id_us_plus(idtest); + allqueue(REDRAWVIEW3D, 0); + + } + else if(ipo->blocktype==ID_WO) { + ( (World *)from)->ipo= ipo; + id_us_plus(idtest); + allqueue(REDRAWBUTSWORLD, 0); + } + else if(ipo->blocktype==ID_LA) { + ( (Lamp *)from)->ipo= ipo; + id_us_plus(idtest); + allqueue(REDRAWBUTSLAMP, 0); + } + else if(ipo->blocktype==ID_CA) { + ( (Camera *)from)->ipo= ipo; + id_us_plus(idtest); + allqueue(REDRAWBUTSEDIT, 0); + } + else if(ipo->blocktype==ID_SO) { + ( (bSound *)from)->ipo= ipo; + id_us_plus(idtest); + allqueue(REDRAWBUTSEDIT, 0); + } + else + printf("error in browse ipo \n"); + + if(id) id->us--; + + scrarea_queue_winredraw(curarea); + scrarea_queue_headredraw(curarea); + allqueue(REDRAWIPO, 0); + } + } + break; + case B_IPODELETE: + ipo= get_ipo_to_edit(&from); + if(from==0) return; + + ipo->id.us--; + + if(ipo->blocktype==ID_OB) ( (Object *)from)->ipo= 0; + else if(ipo->blocktype==ID_MA) ( (Material *)from)->ipo= 0; + else if(ipo->blocktype==ID_SEQ) ( (Sequence *)from)->ipo= 0; + else if(ipo->blocktype==ID_CU) ( (Curve *)from)->ipo= 0; + else if(ipo->blocktype==ID_KE) ( (Key *)from)->ipo= 0; + else if(ipo->blocktype==ID_WO) ( (World *)from)->ipo= 0; + else if(ipo->blocktype==ID_LA) ( (Lamp *)from)->ipo= 0; + else if(ipo->blocktype==ID_WO) ( (World *)from)->ipo= 0; + else if(ipo->blocktype==ID_CA) ( (Camera *)from)->ipo= 0; + else if(ipo->blocktype==ID_SO) ( (bSound *)from)->ipo= 0; + else if(ipo->blocktype==ID_AC) get_hilighted_action_channel((bAction*)from)->ipo= 0; + else if(ipo->blocktype==IPO_CO) ((Object *)from)->activecon->ipo= 0; + + else error("Warn bugs@blender.nl!"); + + editipo_changed(G.sipo, 1); /* doredraw */ + allqueue(REDRAWIPO, 0); + allqueue(REDRAWNLA, 0); + allqueue (REDRAWACTION, 0); + + break; + case B_WORLDBROWSE: + + if(G.buts->menunr==-2) { + activate_databrowse((ID *)G.scene->world, ID_WO, 0, B_WORLDBROWSE, &G.buts->menunr, do_global_buttons); + break; + } + + if(G.buts->menunr < 0) break; + /* geen lock */ + + wrld= G.scene->world; + nr= 1; + + id= (ID *)wrld; + + idtest= G.main->world.first; + while(idtest) { + if(nr==G.buts->menunr) { + break; + } + nr++; + idtest= idtest->next; + } + if(idtest==0) { /* new world */ + if(id) idtest= (ID *)copy_world((World *)id); + else idtest= (ID *)add_world("World"); + idtest->us--; + } + if(idtest!=id) { + G.scene->world= (World *)idtest; + id_us_plus(idtest); + if(id) id->us--; + + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSWORLD, 0); + allqueue(REDRAWIPO, 0); + BIF_preview_changed(G.buts); + } + break; + case B_WORLDDELETE: + if(G.scene->world) { + G.scene->world->id.us--; + G.scene->world= 0; + allqueue(REDRAWBUTSWORLD, 0); + allqueue(REDRAWIPO, 0); + } + + break; + case B_WTEXBROWSE: + + if(G.buts->texnr== -2) { + id= 0; + wrld= G.scene->world; + if(wrld) { + mtex= wrld->mtex[ wrld->texact ]; + if(mtex) id= (ID *)mtex->tex; + } + + activate_databrowse((ID *)id, ID_TE, 0, B_WTEXBROWSE, &G.buts->texnr, do_global_buttons); + return; + } + if(G.buts->texnr < 0) break; + + if(G.buts->pin) { + + } + else { + id= 0; + + wrld= G.scene->world; + if(wrld) { + mtex= wrld->mtex[ wrld->texact ]; + if(mtex) id= (ID *)mtex->tex; + } + + idtest= G.main->tex.first; + while(idtest) { + if(nr==G.buts->texnr) { + break; + } + nr++; + idtest= idtest->next; + } + if(idtest==0) { /* new tex */ + if(id) idtest= (ID *)copy_texture((Tex *)id); + else idtest= (ID *)add_texture("Tex"); + idtest->us--; + } + if(idtest!=id && wrld) { + + if( wrld->mtex[wrld->texact]==0) { + wrld->mtex[wrld->texact]= add_mtex(); + wrld->mtex[wrld->texact]->texco= TEXCO_VIEW; + } + wrld->mtex[ wrld->texact ]->tex= (Tex *)idtest; + id_us_plus(idtest); + if(id) id->us--; + + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSTEX, 0); + allqueue(REDRAWBUTSWORLD, 0); + allqueue(REDRAWIPO, 0); + BIF_preview_changed(G.buts); + } + } + break; + case B_LAMPBROWSE: + /* geen lock */ + if(ob==0) return; + if(ob->type!=OB_LAMP) return; + + if(G.buts->menunr== -2) { + activate_databrowse((ID *)G.buts->lockpoin, ID_LA, 0, B_LAMPBROWSE, &G.buts->menunr, do_global_buttons); + return; + } + if(G.buts->menunr < 0) break; + + la= ob->data; + nr= 1; + id= (ID *)la; + + idtest= G.main->lamp.first; + while(idtest) { + if(nr==G.buts->menunr) { + break; + } + nr++; + idtest= idtest->next; + } + if(idtest==0) { /* geen new lamp */ + return; + } + if(idtest!=id) { + ob->data= (Lamp *)idtest; + id_us_plus(idtest); + if(id) id->us--; + + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSLAMP, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIPO, 0); + BIF_preview_changed(G.buts); + } + break; + + case B_LTEXBROWSE: + + if(ob==0) return; + if(ob->type!=OB_LAMP) return; + + if(G.buts->texnr== -2) { + id= 0; + la= ob->data; + mtex= la->mtex[ la->texact ]; + if(mtex) id= (ID *)mtex->tex; + + activate_databrowse(id, ID_TE, 0, B_LTEXBROWSE, &G.buts->texnr, do_global_buttons); + return; + } + if(G.buts->texnr < 0) break; + + if(G.buts->pin) { + + } + else { + id= 0; + + la= ob->data; + mtex= la->mtex[ la->texact ]; + if(mtex) id= (ID *)mtex->tex; + + idtest= G.main->tex.first; + while(idtest) { + if(nr==G.buts->texnr) { + break; + } + nr++; + idtest= idtest->next; + } + if(idtest==0) { /* new tex */ + if(id) idtest= (ID *)copy_texture((Tex *)id); + else idtest= (ID *)add_texture("Tex"); + idtest->us--; + } + if(idtest!=id && la) { + + if( la->mtex[la->texact]==0) { + la->mtex[la->texact]= add_mtex(); + la->mtex[la->texact]->texco= TEXCO_GLOB; + } + la->mtex[ la->texact ]->tex= (Tex *)idtest; + id_us_plus(idtest); + if(id) id->us--; + + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSTEX, 0); + allqueue(REDRAWBUTSLAMP, 0); + allqueue(REDRAWIPO, 0); + BIF_preview_changed(G.buts); + } + } + break; + + case B_IMAGEDELETE: + G.sima->image= 0; + image_changed(G.sima, 0); + allqueue(REDRAWIMAGE, 0); + break; + + case B_AUTOMATNAME: + automatname(G.buts->lockpoin); + allqueue(REDRAWBUTSHEAD, 0); + break; + case B_AUTOTEXNAME: + if(G.buts->mainb==BUTS_TEX) { + autotexname(G.buts->lockpoin); + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSTEX, 0); + } + else if(G.buts->mainb==BUTS_MAT) { + ma= G.buts->lockpoin; + if(ma->mtex[ ma->texact]) autotexname(ma->mtex[ma->texact]->tex); + allqueue(REDRAWBUTSMAT, 0); + } + else if(G.buts->mainb==BUTS_WORLD) { + wrld= G.buts->lockpoin; + if(wrld->mtex[ wrld->texact]) autotexname(wrld->mtex[wrld->texact]->tex); + allqueue(REDRAWBUTSWORLD, 0); + } + else if(G.buts->mainb==BUTS_LAMP) { + la= G.buts->lockpoin; + if(la->mtex[ la->texact]) autotexname(la->mtex[la->texact]->tex); + allqueue(REDRAWBUTSLAMP, 0); + } + break; + + case B_RESETAUTOSAVE: + reset_autosave(); + break; + case B_SOUNDTOGGLE: + SYS_WriteCommandLineInt(SYS_GetSystem(), "noaudio", (U.gameflags & USERDEF_DISABLE_SOUND)); + break; + case B_SHOWSPLASH: + if ((LICENSE_KEY_VALID) && ((G.qual & LR_SHIFTKEY) == 0)) { + SHOW_LICENSE_KEY(); + } else { + show_splash(); + } + break; + case B_MIPMAPCHANGED: + set_mipmap(!(U.gameflags & USERDEF_DISABLE_SOUND)); + allqueue(REDRAWVIEW3D, 0); + break; + case B_NEWSPACE: + newspace(curarea, curarea->butspacetype); + break; + case B_LOADTEMP: /* is button uit space.c */ + BIF_read_autosavefile(); + break; + case B_FULL: + if(curarea->spacetype!=SPACE_INFO) { + area_fullscreen(); + } + break; + + case B_IDNAME: + /* changing a metaballs name, sadly enough, + * can require it to be updated because its + * basis might have changed... -zr + */ + if (OBACT && OBACT->type==OB_MBALL) + makeDispList(OBACT); + + /* redraw omdat naam veranderd is: nieuwe pup */ + scrarea_queue_headredraw(curarea); + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWINFO, 1); + allqueue(REDRAWOOPS, 1); + /* naam scene ook in set PUPmenu */ + if ELEM(curarea->spacetype, SPACE_BUTS, SPACE_INFO) allqueue(REDRAWBUTSALL, 0); + + allqueue(REDRAWHEADERS, 0); + + break; + } +} + + +void do_global_buttons2(short event) +{ + Base *base; + Object *ob; + Material *ma; + MTex *mtex; + Mesh *me; + Curve *cu; + MetaBall *mb; + Ipo *ipo; + Lamp *la; + Lattice *lt; + World *wrld; + ID *idfrom; + bAction *act; + + /* algemeen: Single User mag als from==LOCAL + * Make Local mag als (from==LOCAL && id==LIB) + */ + + ob= OBACT; + + switch(event) { + + case B_LAMPALONE: + if(ob && ob->id.lib==0) { + la= ob->data; + if(la->id.us>1) { + if(okee("Single user")) { + ob->data= copy_lamp(la); + la->id.us--; + } + } + } + break; + case B_LAMPLOCAL: + if(ob && ob->id.lib==0) { + la= ob->data; + if(la->id.lib) { + if(okee("Make local")) { + make_local_lamp(la); + } + } + } + break; + + case B_ARMLOCAL: + if (ob&&ob->id.lib==0){ + bArmature *arm=ob->data; + if (arm->id.lib){ + if(okee("Make local")) { + make_local_armature(arm); + } + } + } + break; + case B_ARMALONE: + if(ob && ob->id.lib==0) { + bArmature *arm=ob->data; + if(arm->id.us>1) { + if(okee("Single user")) { + ob->data= copy_armature(arm); + arm->id.us--; + } + } + } + break; + case B_ACTLOCAL: + if(ob && ob->id.lib==0) { + act= ob->action; + if(act->id.lib) { + if(okee("Make local")) { + make_local_action(act); + allqueue(REDRAWACTION,0); + } + } + } + break; + case B_ACTALONE: + if (ob) + act= ob->action; + + if(ob && ob->id.lib==0) { + if(act->id.us>1) { + if(okee("Single user")) { + ob->action=copy_action(act); + ob->activecon=NULL; + act->id.us--; + allqueue(REDRAWACTION, 0); + } + } + } + break; + + case B_CAMERAALONE: + if(ob && ob->id.lib==0) { + Camera *ca= ob->data; + if(ca->id.us>1) { + if(okee("Single user")) { + ob->data= copy_camera(ca); + ca->id.us--; + } + } + } + break; + case B_CAMERALOCAL: + if(ob && ob->id.lib==0) { + Camera *ca= ob->data; + if(ca->id.lib) { + if(okee("Make local")) { + make_local_camera(ca); + } + } + } + break; + case B_WORLDALONE: + wrld= G.scene->world; + if(wrld->id.us>1) { + if(okee("Single user")) { + G.scene->world= copy_world(wrld); + wrld->id.us--; + } + } + break; + case B_WORLDLOCAL: + wrld= G.scene->world; + if(wrld && wrld->id.lib) { + if(okee("Make local")) { + make_local_world(wrld); + } + } + break; + + case B_LATTALONE: + if(ob && ob->id.lib==0) { + lt= ob->data; + if(lt->id.us>1) { + if(okee("Single user")) { + ob->data= copy_lattice(lt); + lt->id.us--; + } + } + } + break; + case B_LATTLOCAL: + if(ob && ob->id.lib==0) { + lt= ob->data; + if(lt->id.lib) { + if(okee("Make local")) { + make_local_lattice(lt); + } + } + } + break; + + case B_MATALONE: + if(ob==0) return; + ma= give_current_material(ob, ob->actcol); + idfrom= material_from(ob, ob->actcol); + if(idfrom && idfrom->lib==0) { + if(ma->id.us>1) { + if(okee("Single user")) { + ma= copy_material(ma); + ma->id.us= 0; + assign_material(ob, ma, ob->actcol); + } + } + } + break; + case B_MATLOCAL: + if(ob==0) return; + idfrom= material_from(ob, ob->actcol); + if(idfrom->lib==0) { + ma= give_current_material(ob, ob->actcol); + if(ma && ma->id.lib) { + if(okee("Make local")) { + make_local_material(ma); + } + } + } + break; + + case B_MESHLOCAL: + if(ob && ob->id.lib==0) { + me= ob->data; + if(me && me->id.lib) { + if(okee("Make local")) { + make_local_mesh(me); + make_local_key( me->key ); + } + } + } + break; + + case B_MBALLALONE: + if(ob && ob->id.lib==0) { + mb= ob->data; + if(mb->id.us>1) { + if(okee("Single user")) { + ob->data= copy_mball(mb); + mb->id.us--; + if(ob==G.obedit) allqueue(REDRAWVIEW3D, 0); + } + } + } + break; + case B_MBALLLOCAL: + if(ob && ob->id.lib==0) { + mb= ob->data; + if(mb->id.lib) { + if(okee("Make local")) { + make_local_mball(mb); + } + } + } + break; + + case B_CURVEALONE: + if(ob && ob->id.lib==0) { + cu= ob->data; + if(cu->id.us>1) { + if(okee("Single user")) { + ob->data= copy_curve(cu); + cu->id.us--; + makeDispList(ob); + if(ob==G.obedit) allqueue(REDRAWVIEW3D, 0); + } + } + } + break; + case B_CURVELOCAL: + if(ob && ob->id.lib==0) { + cu= ob->data; + if(cu->id.lib) { + if(okee("Make local")) { + make_local_curve(cu); + make_local_key( cu->key ); + makeDispList(ob); + } + } + } + break; + + case B_TEXALONE: + if(G.buts->texfrom==0) { /* from mat */ + if(ob==0) return; + ma= give_current_material(ob, ob->actcol); + if(ma && ma->id.lib==0) { + mtex= ma->mtex[ ma->texact ]; + if(mtex->tex && mtex->tex->id.us>1) { + if(okee("Single user")) { + mtex->tex->id.us--; + mtex->tex= copy_texture(mtex->tex); + } + } + } + } + else if(G.buts->texfrom==1) { /* from world */ + wrld= G.scene->world; + if(wrld->id.lib==0) { + mtex= wrld->mtex[ wrld->texact ]; + if(mtex->tex && mtex->tex->id.us>1) { + if(okee("Single user")) { + mtex->tex->id.us--; + mtex->tex= copy_texture(mtex->tex); + } + } + } + } + else if(G.buts->texfrom==2) { /* from lamp */ + if(ob==0 || ob->type!=OB_LAMP) return; + la= ob->data; + if(la->id.lib==0) { + mtex= la->mtex[ la->texact ]; + if(mtex->tex && mtex->tex->id.us>1) { + if(okee("Single user")) { + mtex->tex->id.us--; + mtex->tex= copy_texture(mtex->tex); + } + } + } + } + break; + case B_TEXLOCAL: + if(G.buts->texfrom==0) { /* from mat */ + if(ob==0) return; + ma= give_current_material(ob, ob->actcol); + if(ma && ma->id.lib==0) { + mtex= ma->mtex[ ma->texact ]; + if(mtex->tex && mtex->tex->id.lib) { + if(okee("Make local")) { + make_local_texture(mtex->tex); + } + } + } + } + else if(G.buts->texfrom==1) { /* from world */ + wrld= G.scene->world; + if(wrld->id.lib==0) { + mtex= wrld->mtex[ wrld->texact ]; + if(mtex->tex && mtex->tex->id.lib) { + if(okee("Make local")) { + make_local_texture(mtex->tex); + } + } + } + } + else if(G.buts->texfrom==2) { /* from lamp */ + if(ob==0 || ob->type!=OB_LAMP) return; + la= ob->data; + if(la->id.lib==0) { + mtex= la->mtex[ la->texact ]; + if(mtex->tex && mtex->tex->id.lib) { + if(okee("Make local")) { + make_local_texture(mtex->tex); + } + } + } + } + break; + + case B_IPOALONE: + ipo= get_ipo_to_edit(&idfrom); + + if(idfrom && idfrom->lib==0) { + if(ipo->id.us>1) { + if(okee("Single user")) { + if(ipo->blocktype==ID_OB) ((Object *)idfrom)->ipo= copy_ipo(ipo); + else if(ipo->blocktype==ID_MA) ((Material *)idfrom)->ipo= copy_ipo(ipo); + else if(ipo->blocktype==ID_SEQ) ((Sequence *)idfrom)->ipo= copy_ipo(ipo); + else if(ipo->blocktype==ID_CU) ((Curve *)idfrom)->ipo= copy_ipo(ipo); + else if(ipo->blocktype==ID_KE) ((Key *)idfrom)->ipo= copy_ipo(ipo); + else if(ipo->blocktype==ID_LA) ((Lamp *)idfrom)->ipo= copy_ipo(ipo); + else if(ipo->blocktype==ID_WO) ((World *)idfrom)->ipo= copy_ipo(ipo); + else if(ipo->blocktype==ID_CA) ((Camera *)idfrom)->ipo= copy_ipo(ipo); + else if(ipo->blocktype==ID_SO) ((bSound *)idfrom)->ipo= copy_ipo(ipo); + else if(ipo->blocktype==ID_AC) get_hilighted_action_channel((bAction *)idfrom)->ipo= copy_ipo(ipo); + else if(ipo->blocktype==IPO_CO) ((Object *)idfrom)->activecon->ipo= copy_ipo(ipo); + else error("Warn ton!"); + + ipo->id.us--; + allqueue(REDRAWIPO, 0); + } + } + } + break; + case B_IPOLOCAL: + ipo= get_ipo_to_edit(&idfrom); + + if(idfrom && idfrom->lib==0) { + if(ipo->id.lib) { + if(okee("Make local")) { + make_local_ipo(ipo); + allqueue(REDRAWIPO, 0); + } + } + } + break; + + case B_OBALONE: + if(G.scene->id.lib==0) { + if(ob->id.us>1) { + if(okee("Single user")) { + base= FIRSTBASE; + while(base) { + if(base->object==ob) { + base->object= copy_object(ob); + ob->id.us--; + allqueue(REDRAWVIEW3D, 0); + break; + } + base= base->next; + } + } + } + } + break; + case B_OBLOCAL: + if(G.scene->id.lib==0) { + if(ob->id.lib) { + if(okee("Make local")) { + make_local_object(ob); + allqueue(REDRAWVIEW3D, 0); + } + } + } + break; + case B_MESHALONE: + if(ob && ob->id.lib==0) { + + me= ob->data; + + if(me && me->id.us>1) { + if(okee("Single user")) { + Mesh *men= copy_mesh(me); + men->id.us= 0; + + set_mesh(ob, men); + + if(ob==G.obedit) allqueue(REDRAWVIEW3D, 0); + } + } + } + break; + } + + allqueue(REDRAWBUTSALL, 0); + allqueue(REDRAWOOPS, 0); +} + +/* ********************** EMPTY ****************************** */ +/* ********************** INFO ****************************** */ + +int buttons_do_unpack() +{ + int how; + char menu[2048]; + char line[128]; + int ret_value = RET_OK, count = 0; + + count = countPackedFiles(); + + if (count) { + if (count == 1) { + sprintf(menu, "Unpack 1 file%%t"); + } else { + sprintf(menu, "Unpack %d files%%t", count); + } + + sprintf(line, "|Use files in current directory (create when necessary)%%x%d", PF_USE_LOCAL); + strcat(menu, line); + + sprintf(line, "|Write files to current directory (overwrite existing files)%%x%d", PF_WRITE_LOCAL); + strcat(menu, line); + + sprintf(line, "|%%l|Use files in original location (create when necessary)%%x%d", PF_USE_ORIGINAL); + strcat(menu, line); + + sprintf(line, "|Write files to original location (overwrite existing files)%%x%d", PF_WRITE_ORIGINAL); + strcat(menu, line); + + sprintf(line, "|%%l|Disable AutoPack, keep all packed files %%x%d", PF_KEEP); + strcat(menu, line); + + sprintf(line, "|Ask for each file %%x%d", PF_ASK); + strcat(menu, line); + + how = pupmenu(menu); + + if(how != -1) { + if (how != PF_KEEP) { + unpackAll(how); + } + G.fileflags &= ~G_AUTOPACK; + } else { + ret_value = RET_CANCEL; + } + } else { + pupmenu("No packed files. Autopack disabled"); + } + + return (ret_value); +} + +/* here, because of all creator stuff */ + +Scene *copy_scene(Scene *sce, int level) +{ + /* level 0: alle objects shared + * level 1: alle objectdata shared + * level 2: volledige kopie + */ + Scene *scen; + Base *base, *obase; + + + /* level 0 */ + scen= copy_libblock(sce); + duplicatelist(&(scen->base), &(sce->base)); + + clear_id_newpoins(); + + id_us_plus((ID *)scen->world); + id_us_plus((ID *)scen->set); + + scen->ed= 0; + scen->radio= 0; + + obase= sce->base.first; + base= scen->base.first; + while(base) { + base->object->id.us++; + if(obase==sce->basact) scen->basact= base; + + obase= obase->next; + base= base->next; + } + + if(level==0) return scen; + + /* level 1 */ + G.scene= scen; + single_object_users(0); + + /* camera */ + ID_NEW(G.scene->camera); + + /* level 2 */ + if(level>=2) { + if(scen->world) { + scen->world->id.us--; + scen->world= copy_world(scen->world); + } + single_obdata_users(0); + single_mat_users_expand(); + single_tex_users_expand(); + } + + clear_id_newpoins(); + + BPY_copy_scriptlink(&sce->scriptlink); + + + + // make a private copy of the avicodecdata + + if (sce->r.avicodecdata) { + + scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata); + + scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat); + + scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms); + + } + + return scen; +} + +void do_info_buttons(unsigned short event) +{ + bScreen *sc, *oldscreen; + Scene *sce, *sce1; + ScrArea *sa; + int nr; + + switch(event) { + + case B_INFOSCR: /* menu select screen */ + + if( G.curscreen->screennr== -2) { + if(curarea->winy <50) { + sa= closest_bigger_area(); + areawinset(sa->win); + } + activate_databrowse((ID *)G.curscreen, ID_SCR, 0, B_INFOSCR, &G.curscreen->screennr, do_info_buttons); + return; + } + if( G.curscreen->screennr < 0) return; + + sc= G.main->screen.first; + nr= 1; + while(sc) { + if(nr==G.curscreen->screennr) { + if(is_allowed_to_change_screen(sc)) setscreen(sc); + else error("Unable to perform function in EditMode"); + break; + } + nr++; + sc= sc->id.next; + } + /* laatste item: NEW SCREEN */ + if(sc==0) { + duplicate_screen(); + } + break; + case B_INFODELSCR: + /* dit event alleen met buttons doen, zodoende nooit vanuit full aanroepbaar */ + + if(G.curscreen->id.prev) sc= G.curscreen->id.prev; + else if(G.curscreen->id.next) sc= G.curscreen->id.next; + else return; + if(okee("Delete current screen")) { + /* vind nieuwe G.curscreen */ + + oldscreen= G.curscreen; + setscreen(sc); /* deze test of sc een full heeft */ + unlink_screen(oldscreen); + free_libblock(&G.main->screen, oldscreen); + } + scrarea_queue_headredraw(curarea); + + break; + case B_INFOSCE: /* menu select scene */ + + if( G.obedit) { + error("Unable to perform function in EditMode"); + return; + } + if( G.curscreen->scenenr== -2) { + if(curarea->winy <50) { + sa= closest_bigger_area(); + areawinset(sa->win); + } + activate_databrowse((ID *)G.scene, ID_SCE, 0, B_INFOSCE, &G.curscreen->scenenr, do_info_buttons); + return; + } + if( G.curscreen->scenenr < 0) return; + + sce= G.main->scene.first; + nr= 1; + while(sce) { + if(nr==G.curscreen->scenenr) { + if(sce!=G.scene) set_scene(sce); + break; + } + nr++; + sce= sce->id.next; + } + /* laatste item: NEW SCENE */ + if(sce==0) { + nr= pupmenu("Add scene%t|Empty|Link Objects|Link ObData|Full Copy"); + if(nr<= 0) return; + if(nr==1) { + sce= add_scene(G.scene->id.name+2); + sce->r= G.scene->r; + } + else sce= copy_scene(G.scene, nr-2); + + set_scene(sce); + } + + break; + case B_INFODELSCE: + + if(G.scene->id.prev) sce= G.scene->id.prev; + else if(G.scene->id.next) sce= G.scene->id.next; + else return; + if(okee("Delete current scene")) { + + /* alle sets aflopen */ + sce1= G.main->scene.first; + while(sce1) { + if(sce1->set == G.scene) sce1->set= 0; + sce1= sce1->id.next; + } + + /* alle sequences aflopen */ + clear_scene_in_allseqs(G.scene); + + /* alle schermen */ + sc= G.main->screen.first; + while(sc) { + if(sc->scene == G.scene) sc->scene= sce; + sc= sc->id.next; + } + free_libblock(&G.main->scene, G.scene); + set_scene(sce); + } + + break; + case B_FILEMENU: + tbox_setmain(9); + toolbox(); + break; + } +} + +/* strubi shamelessly abused the status line as a progress bar... + feel free to kill him after release */ + +static int g_progress_bar = 0; +static char *g_progress_info = 0; +static float g_done; + +int start_progress_bar(void) +{ + g_progress_bar = 1; + return 1; // we never fail (yet) +} + +void end_progress_bar(void) +{ + g_progress_bar = 0; +} + +static void update_progress_bar(float done, char *info) +{ + g_done = done; + g_progress_info = info; +} + +/** Progress bar + 'done': a value between 0.0 and 1.0, showing progress + 'info': a info text what is currently being done + + Make sure that the progress bar is always called with: + done = 0.0 first + and + done = 1.0 last -- or alternatively use: + + start_progressbar(); + do_stuff_and_callback_progress_bar(); + end_progressbar(); +*/ +int progress_bar(float done, char *busy_info) +{ + ScrArea *sa; + short val; + + /* User break (ESC) */ + while (qtest()) { + if (extern_qread(&val) == ESCKEY) + return 0; + } + if (done == 0.0) { + start_progress_bar(); + } else if (done > 0.99) { + end_progress_bar(); + } + + sa= G.curscreen->areabase.first; + while(sa) { + if (sa->spacetype == SPACE_INFO) { + update_progress_bar(done, busy_info); + + curarea = sa; + + scrarea_do_headdraw(curarea); + areawinset(curarea->win); + sa->head_swap= WIN_BACK_OK; + screen_swapbuffers(); + } + sa = sa->next; + } + return 1; +} + + +static void check_packAll() +{ + // first check for dirty images + Image *ima; + + ima = G.main->image.first; + while (ima) { + if (ima->ibuf && (ima->ibuf->userflags &= IB_BITMAPDIRTY)) { + break; + } + ima= ima->id.next; + } + + if (ima == 0 || okee("Some images are painted on. These changes will be lost. Continue ?")) { + packAll(); + G.fileflags |= G_AUTOPACK; + } +} + + +/* KEYED FUNCTIONS + --------------- */ + +/* this function name is meaningless and only called that way for some + obscurity + It is called by a function table from the license_key; + see include/keyed_functions.h +*/ + +struct twostrings +{ + char *outname; + char *exename; +}; + +/** This function is called for writing runtimes. + * It's locked behind the key and called through a function table + * which is initialized properly by the Python key code (if valid) + */ +int make_beautiful_animation(void *vp) +{ + char *freestr= NULL; + struct twostrings *twostrings = (struct twostrings *) vp; + char *str = twostrings->outname; + char *ext = 0; + +#ifdef _WIN32 + ext = ".exe"; +#endif + +#ifdef __APPLE__ + ext = ".app"; +#endif + if (ext && (!BLI_testextensie(str, ext))) { + freestr= MEM_mallocN(strlen(str) + strlen(ext) + 1, "write_runtime_check"); + strcpy(freestr, str); + strcat(freestr, ext); + str= freestr; + } + + if (!BLI_exists(str) || saveover(str)) + BLO_write_runtime(str, twostrings->exename); + + if (freestr) + MEM_freeN(freestr); + + return 0; +} + +int make_nice_software(void) +{ + Fptr f = KEY_RETURN_TRUE; + if (f) return f(0); + else return 0; +} + +static void write_runtime_check_dynamic(char *str) +{ + Fptr f = KEY_WRITE_RUNTIME; + struct twostrings twostrings; + + twostrings.outname = str; + twostrings.exename = "blenderdynplayer.exe"; + + if (f) f((void *) &twostrings); +} + +static void write_runtime_check(char *str) +{ + Fptr f = KEY_WRITE_RUNTIME; + struct twostrings twostrings; + char player[128]; + + twostrings.outname = str; + twostrings.exename = player; + + strcpy(player, "blenderplayer"); + +#ifdef _WIN32 + strcat(player, ".exe"); +#endif + +#ifdef __APPLE__ + strcat(player, ".app"); +#endif + + if (f) f((void *) &twostrings); +} +/* end keyed functions */ + + +static void do_info_filemenu(void *arg, int event) +{ + ScrArea *sa; + char dir[FILE_MAXDIR]; + + if(curarea->spacetype==SPACE_INFO) { + sa= closest_bigger_area(); + areawinset(sa->win); + } + + /* these are no defines, easier this way, the codes are in the function below */ + switch(event) { + case 0: + if (okee("ERASE ALL")) { + if (!BIF_read_homefile()) + error("No file ~/.B.blend"); + } + break; + case 1: + activate_fileselect(FILE_BLENDER, "LOAD FILE", G.sce, BIF_read_file); + break; + case 2: + { + char *s= MEM_mallocN(strlen(G.sce) + 11 + 1, "okee_reload"); + strcpy(s, "Open file: "); + strcat(s, G.sce); + if (okee(s)) + BIF_read_file(G.sce); + MEM_freeN(s); + } + break; + case 3: + activate_fileselect(FILE_LOADLIB, "LOAD LIBRARY", G.lib, 0); + break; + case 4: + strcpy(dir, G.sce); + untitled(dir); + activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file); + break; + case 5: + strcpy(dir, G.sce); + if (untitled(dir)) { + activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file); + } else { + BIF_write_file(dir); + free_filesel_spec(dir); + } + break; + case 6: + mainqenter(F3KEY, 1); + break; + case 7: + write_vrml_fs(); + break; + case 8: + write_dxf_fs(); + break; + case 9: + write_videoscape_fs(); + break; + case 20: + strcpy(dir, G.sce); + activate_fileselect(FILE_SPECIAL, "INSTALL LICENSE KEY", dir, loadKeyboard); + break; + case 21: + SHOW_LICENSE_KEY(); + break; + case 22: + activate_fileselect(FILE_SPECIAL, "WRITE RUNTIME", "", write_runtime_check); + break; + case 23: + activate_fileselect(FILE_SPECIAL, "WRITE DYNAMIC RUNTIME", "", write_runtime_check_dynamic); + break; + case 30: + // import menu, no handling + break; + +#ifdef EXPERIMENTAL_MENUS + case 10: + check_packAll(); + break; + case 11: + unpackAll(PF_WRITE_LOCAL); + G.fileflags &= ~G_AUTOPACK; + break; + case 12: + if (buttons_do_unpack() != RET_CANCEL) { + /* Clear autopack bit only if user selected one of the unpack options */ + G.fileflags &= ~G_AUTOPACK; + } + break; + case 13: +#else /* EXPERIMENTAL_MENUS */ + case 10: +#endif /* EXPERIMENTAL_MENUS */ + exit_usiblender(); + break; + } + allqueue(REDRAWINFO, 0); +} + +void do_info_file_optionsmenu(void *arg, int event) +{ + G.fileflags ^= (1 << event); + + // allqueue(REDRAWINFO, 0); +} + + +static uiBlock *info_file_optionsmenu(void *arg_unused) +{ + uiBlock *block; + short yco= 0, xco = 20; + + block= uiNewBlock(&curarea->uiblocks, "runtime_options", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetButmFunc(block, do_info_file_optionsmenu, NULL); + uiBlockSetXOfs(block,-40); // offset to parent button + + /* flags are case-values */ + uiDefBut(block, BUTM, 1, "Compress File", xco, yco-=20, 100, 19, NULL, 0.0, 0.0, 0, G_FILE_COMPRESS_BIT, "Use file compression"); + uiDefBut(block, BUTM, 1, "Sign File", xco, yco-=20, 100, 19, NULL, 0.0, 0.0, 0, G_FILE_SIGN_BIT, "Add signature to file"); + uiDefBut(block, BUTM, 1, "Lock File", xco, yco-=20, 100, 19, NULL, 0.0, 0.0, 0, G_FILE_LOCK_BIT, "Protect the file from editing by others"); + + /* Toggle buttons */ + + yco= 0; + xco -= 20; + uiBlockSetEmboss(block, UI_EMBOSSW); + uiBlockSetButmFunc(block, NULL, NULL); + /* flags are defines */ + uiDefIconButI(block, ICONTOG|BIT|G_FILE_COMPRESS_BIT, 0, ICON_CHECKBOX_DEHLT, xco, yco-=20, 19, 19, &G.fileflags, 0.0, 0.0, 0, 0, ""); + uiDefIconButI(block, ICONTOG|BIT|G_FILE_SIGN_BIT, 0, ICON_CHECKBOX_DEHLT, xco, yco-=20, 19, 19, &G.fileflags, 0.0, 0.0, 0, 0, ""); + uiDefIconButI(block, ICONTOG|BIT|G_FILE_LOCK_BIT, 0, ICON_CHECKBOX_DEHLT, xco, yco-=20, 19, 19, &G.fileflags, 0.0, 0.0, 0, 0, ""); + + uiBlockSetDirection(block, UI_RIGHT); + + return block; +} + +static uiBlock *info_runtime_optionsmenu(void *arg_unused) +{ + uiBlock *block; + short yco= 0, xco = 20; + + block= uiNewBlock(&curarea->uiblocks, "add_surfacemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetXOfs(block, -40); // offset to parent button + + uiBlockSetEmboss(block, UI_EMBOSSW); + + uiDefBut(block, LABEL, 0, "Size options:", xco, yco-=20, 114, 19, 0, 0.0, 0.0, 0, 0, ""); + uiDefButS(block, NUM, 0, "X:", xco+19, yco-=20, 95, 19, &G.scene->r.xplay, 10.0, 2000.0, 0, 0, "X screen/window resolution"); + uiDefButS(block, NUM, 0, "Y:", xco+19, yco-=20, 95, 19, &G.scene->r.yplay, 10.0, 2000.0, 0, 0, "Y screen/window resolution"); + + uiDefBut(block, SEPR, 0, "", xco, yco-=4, 114, 4, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefBut(block, LABEL, 0, "Fullscreen options:", xco, yco-=20, 114, 19, 0, 0.0, 0.0, 0, 0, ""); + uiDefButS(block, TOG, 0, "Fullscreen", xco + 19, yco-=20, 95, 19, &G.scene->r.fullscreen, 0.0, 0.0, 0, 0, "Starts player in a new fullscreen display"); + uiDefButS(block, NUM, 0, "Freq:", xco+19, yco-=20, 95, 19, &G.scene->r.freqplay, 10.0, 120.0, 0, 0, "Clock frequency of fullscreen display"); + uiDefButS(block, NUM, 0, "Bits:", xco+19, yco-=20, 95, 19, &G.scene->r.depth, 1.0, 32.0, 0, 0, "Bit depth of full screen disply"); + + uiDefBut(block, SEPR, 0, "", xco, yco-=4, 114, 4, NULL, 0.0, 0.0, 0, 0, ""); + + /* stereo settings */ + /* can't use any definition from the game engine here so hardcode it. Change it here when it changes there! + * RAS_IRasterizer has definitions: + * RAS_STEREO_NOSTEREO 1 + * RAS_STEREO_QUADBUFFERED 2 + * RAS_STEREO_ABOVEBELOW 3 + * RAS_STEREO_INTERLACED 4 future + */ + uiDefBut(block, LABEL, 0, "Stereo options", xco, yco-=20, 114, 19, 0, 0.0, 0.0, 0, 0, ""); + uiDefButS(block, ROW, 0, "no stereo", xco+19, yco-=20, 95, 19, &(G.scene->r.stereomode), 6.0, 1.0, 0, 0, "Disables stereo"); + uiDefButS(block, ROW, 0, "h/w pageflip", xco+19, yco-=20, 95, 19, &(G.scene->r.stereomode), 6.0, 2.0, 0, 0, "Enables h/w pageflip stereo method"); + uiDefButS(block, ROW, 0, "syncdoubling", xco+19, yco-=20, 95, 19, &(G.scene->r.stereomode), 6.0, 3.0, 0, 0, "Enables syncdoubling stereo method"); +#if 0 + // future + uiDefButS(block, ROW, 0, "syncdoubling", xco+19, yco, 95, 19, &(G.scene->r.stereomode), 5.0, 4.0, 0, 0, "Enables interlaced stereo method"); +#endif + + uiBlockSetDirection(block, UI_RIGHT); + + return block; +} + +static uiBlock *info_file_importmenu(void *arg_unused) +{ + uiBlock *block; + short yco= 0, xco = 20; + + block= uiNewBlock(&curarea->uiblocks, "importmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetXOfs(block, -40); // offset to parent button + + uiBlockSetEmboss(block, UI_EMBOSSW); + + /* flags are defines */ + uiDefBut(block, LABEL, 0, "VRML 2.0 options", xco, yco, 125, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefButS(block, TOG|BIT|0, 0, "SepLayers", xco, yco-=20, 75, 19, &U.vrmlflag, 0.0, 0.0, 0, 0, "Separate Empties, Lamps, etc. into Layers"); + uiDefButS(block, TOG|BIT|1, 0, "Scale 1/100", xco, yco-=20, 75, 19, &U.vrmlflag, 0.0, 0.0, 0, 0, "Scale scene by 1/100 (3DS VRML)"); + uiDefButS(block, TOG|BIT|2, 0, "Two Sided", xco, yco-=20, 75, 19, &U.vrmlflag, 0.0, 0.0, 0, 0, "Import two sided faces"); + + uiBlockSetDirection(block, UI_RIGHT); + + return block; +} + +static uiBlock *info_filemenu(void *arg_unused) +{ + uiBlock *block; + short xco=0; + + block= uiNewBlock(&curarea->uiblocks, "filemenu", UI_EMBOSSP, UI_HELV, curarea->headwin); + uiBlockSetButmFunc(block, do_info_filemenu, NULL); + + uiDefBut(block, BUTM, 1, "New|Ctrl X", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "Start a new project (and delete the current)"); + uiDefBut(block, BUTM, 1, "Open|F1", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "Open a new file"); + uiDefBut(block, BUTM, 1, "Reopen Last|Ctrl O", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "Revert to the last version saved to file"); + uiDefBut(block, BUTM, 1, "Append|Shift F1", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "Append contents of a file to the current project"); + uiDefBlockBut(block, info_file_importmenu, NULL, "Import Settings|>>", 0, xco-=20, 160, 19, ""); + + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Save As|F2", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, "Save to a new file"); + uiDefBut(block, BUTM, 1, "Save|Ctrl W", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 5, "Save to the current file"); + + if (LICENSE_KEY_VALID && make_nice_software()) { + uiDefBlockBut(block, info_file_optionsmenu, NULL, "File options|>>", 0, xco-=20, 160, 19, "Click to open the File Options menu"); + + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefBut(block, BUTM, 1, "Save Runtime", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 22, "Create a runtime executable with the current project"); +#ifdef _WIN32 + uiDefBut(block, BUTM, 1, "Save dynamic Runtime", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 23, "Create a dynamic runtime executable with the current project (requieres extenal python20.dll)"); +#endif + uiDefBlockBut(block, info_runtime_optionsmenu, NULL, "Runtime options|>>", 0, xco-=20, 160, 19, "Click to open the File Options menu"); + } + + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Save Image|F3", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 6, "Save the image in the render buffer to a file"); + uiDefBut(block, BUTM, 1, "Save VRML 1.0|Ctrl F2", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 7, "Save the current scene to a file in VRML 1.0 format"); + uiDefBut(block, BUTM, 1, "Save DXF|Shift F2", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 8, "Save the current scene to a file in DXF format"); + uiDefBut(block, BUTM, 1, "Save VideoScape|Alt W", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 9, "Save the current scene to a file in VideoScape format"); + + + if (LICENSE_KEY_VALID) { + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 160, 6, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, 1, "Show License Key", 0, xco-=20, 140, 19, NULL, 0.0, 0.0, 1, 21, "Show the personal information stored in your Blender License Key"); + uiDefIconBut(block, BUTM, 1, ICON_PUBLISHER, 141,xco, 19, 19, NULL, 0.0, 0.0, 1, 21, "Show the personal information stored in your Blender License Key"); + } else if (I_AM_PUBLISHER) { + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 160, 6, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, 1, "Install License Key", 0, xco-=20, 140, 19, NULL, 0.0, 0.0, 1, 20, "Install your Blender License Key"); + uiDefIconBut(block, BUTM, 1, ICON_PUBLISHER, 141,xco, 19, 19, NULL, 0.0, 0.0, 1, 20, "Install your Blender License Key"); + } + + + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 160, 6, NULL, 0.0, 0.0, 1, 0, ""); + +#ifdef EXPERIMENTAL_MENUS + uiDefBut(block, BUTM, 1, "Pack Data", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, ""); + uiDefBut(block, BUTM, 1, "Unpack Data to current dir", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, ""); + uiDefBut(block, BUTM, 1, "Advanced Unpack", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, ""); + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 160, 6, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, 1, "Quit | Q", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 13, "Quit Blender immediately"); +#else /* EXPERIMENTAL_MENUS */ + uiDefBut(block, BUTM, 1, "Quit | Q", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, "Quit Blender immediately"); +#endif /* EXPERIMENTAL_MENUS */ + uiBlockSetDirection(block, UI_DOWN); + + + return block; +} + +static void do_info_editmenu(void *arg, int event) +{ + int oldqual; + + switch(event) { + + case 0: + /* (De)Select All */ + if(select_area(SPACE_VIEW3D)) mainqenter(AKEY, 1); + break; + /* Border Select */ + case 1: + if(select_area(SPACE_VIEW3D)) mainqenter(BKEY, 1); + break; + case 2: + /* Circle Select */ + /*if(select_area(SPACE_VIEW3D)) { + winqread3d(BKEY, 1, 0); + winqread3d(BKEY, 1, 0); + }*/ + break; + case 3: + /* Duplicate */ + if(select_area(SPACE_VIEW3D)) { + oldqual = G.qual; + G.qual = LR_SHIFTKEY; + winqread3d(DKEY, 1, 0); + G.qual = oldqual; + } + break; + case 4: + /* Delete */ + if(select_area(SPACE_VIEW3D)) { + winqread3d(XKEY, 1, 0); + } + break; + case 5: + /* Edit Mode */ + if(select_area(SPACE_VIEW3D)) { + blenderqread(TABKEY, 1); + } + break; + case 6: + /* Grabber */ + if(select_area(SPACE_VIEW3D)) { + transform('g'); + } + break; + case 7: + /* Rotate */ + if(select_area(SPACE_VIEW3D)) { + transform('r'); + } + break; + case 8: + /* Scale */ + if(select_area(SPACE_VIEW3D)) { + transform('s'); + } + break; + case 9: + /* Shear */ + if (!G.obedit) { + enter_editmode(); + /* ### put these into a deselectall_gen() */ + if(G.obedit->type==OB_MESH) deselectall_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) deselectall_nurb(); + else if(G.obedit->type==OB_MBALL) deselectall_mball(); + else if(G.obedit->type==OB_LATTICE) deselectall_Latt(); + /* ### */ + } + if(select_area(SPACE_VIEW3D)) { + transform('S'); + } + break; + case 10: + /* Warp/Bend */ + if (!G.obedit) { + enter_editmode(); + /* ### put these into a deselectall_gen() */ + if(G.obedit->type==OB_MESH) deselectall_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) deselectall_nurb(); + else if(G.obedit->type==OB_MBALL) deselectall_mball(); + else if(G.obedit->type==OB_LATTICE) deselectall_Latt(); + /* ### */ + } + if(select_area(SPACE_VIEW3D)) { + oldqual = G.qual; + G.qual = LR_SHIFTKEY; + winqread3d(WKEY, 1, 0); + G.qual = oldqual; + } + break; + case 11: + /* Snap */ + if(select_area(SPACE_VIEW3D)) { + oldqual = G.qual; + G.qual = LR_SHIFTKEY; + winqread3d(SKEY, 1, 0); + G.qual = oldqual; + } + break; + } + allqueue(REDRAWINFO, 0); +} + + +static uiBlock *info_editmenu(void *arg_unused) +{ +/* static short tog=0; */ + uiBlock *block; + short xco= 0; + + block= uiNewBlock(&curarea->uiblocks, "editmenu", UI_EMBOSSP, UI_HELV, curarea->headwin); + uiBlockSetButmFunc(block, do_info_editmenu, NULL); + + uiDefBut(block, BUTM, 1, "(De)Select All|A", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 0, "Select all objects in the scene or empty the selection"); + uiDefBut(block, BUTM, 1, "Border Select|B", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 1, "Select objects in a rectangular area (press B again to activate circle select in edit mode)"); + + /* uiDefBut(block, BUTM, 1, "Circle Select", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 2, "Select objects in a circular area"); */ + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Duplicate|Shift D", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 3, "Duplicate the selected object(s)"); + uiDefBut(block, BUTM, 1, "Delete|X", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 4, "Delete the selected object(s)"); + uiDefBut(block, BUTM, 1, "Edit Mode|Tab", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 5, "Toggle between object and edit mode"); + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Grabber|G", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 6, "Move the selected object(s)"); + uiDefBut(block, BUTM, 1, "Rotate|R", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 7, "Rotate the selected object(s)"); + uiDefBut(block, BUTM, 1, "Scale|S", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 8, "Scale the selected object(s)"); + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Shear|Ctrl S", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 9, "Shear the selected object(s)"); + uiDefBut(block, BUTM, 1, "Warp/Bend|Shift W", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 10, "Warp or bend the selected objects"); + uiDefBut(block, BUTM, 1, "Snap Menu|Shift S", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 11, "Activate the snap menu"); + + uiBlockSetDirection(block, UI_DOWN); + + return block; +} + +static void do_info_add_meshmenu(void *arg, int event) +{ + + switch(event) { +#ifdef EXPERIMENTAL_MENUS + /* Maarten's proposal for a new Add Mesh menu */ + case 0: + /* Line */ + //add_primitiveMesh(4); + break; + case 1: + /* Circle */ + if(select_area(SPACE_VIEW3D)) { + add_primitiveMesh(4); + } + break; + case 2: + /* Plane */ + add_primitiveMesh(0); + break; + case 3: + /* Cube */ + add_primitiveMesh(1); + break; + case 4: + /* UVsphere */ + add_primitiveMesh(11); + break; + case 5: + /* IcoSphere */ + add_primitiveMesh(12); + break; + case 6: + /* Cylinder */ + add_primitiveMesh(5); + break; + case 7: + /* Tube */ + add_primitiveMesh(6); + break; + case 8: + /* Cone */ + add_primitiveMesh(7); + break; + case 9: + /* Grid */ + add_primitiveMesh(10); + break; +#else /* EXPERIMENTAL_MENUS*/ + case 0: + /* Plane */ + add_primitiveMesh(0); + break; + case 1: + /* Cube */ + add_primitiveMesh(1); + break; + case 2: + /* Circle */ + add_primitiveMesh(4); + break; + case 3: + /* UVsphere */ + add_primitiveMesh(11); + break; + case 4: + /* IcoSphere */ + add_primitiveMesh(12); + break; + case 5: + /* Cylinder */ + add_primitiveMesh(5); + break; + case 6: + /* Tube */ + add_primitiveMesh(6); + break; + case 7: + /* Cone */ + add_primitiveMesh(7); + break; + case 8: + /* Grid */ + add_primitiveMesh(10); + break; +#endif /* EXPERIMENTAL_MENUS */ + default: + break; + } + allqueue(REDRAWINFO, 0); +} + +static uiBlock *info_add_meshmenu(void *arg_unused) +{ +/* static short tog=0; */ + uiBlock *block; + short xco= 0; + + block= uiNewBlock(&curarea->uiblocks, "add_meshmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetButmFunc(block, do_info_add_meshmenu, NULL); + +#ifdef EXPERIMENTAL_MENUS + /* Maarten's proposal for a new Add Mesh menu */ + uiDefBut(block, BUTM, 1, "Line|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "Add a Mesh Line"); + uiDefBut(block, BUTM, 1, "Circle|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "Add a Mesh Circle"); + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Plane|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "Add a Mesh Plane"); + uiDefBut(block, BUTM, 1, "Cube|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "Add a Mesh Cube"); + uiDefBut(block, BUTM, 1, "UVsphere", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, "Add a Mesh Sphere"); + uiDefBut(block, BUTM, 1, "IcoSphere|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 5, "Add a Mesh Isocohedron Sphere"); + uiDefBut(block, BUTM, 1, "Cylinder With Caps|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 6, "Add a Mesh Cylinder with caps"); + uiDefBut(block, BUTM, 1, "Cylinder Without Caps|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 7, "Add a Mesh Cylinder without caps"); + uiDefBut(block, BUTM, 1, "Cone|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 8, "Add a Mesh Cone"); + uiDefBut(block, BUTM, 1, "Grid|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 9, "Add a Mesh Grid"); +#else /* EXPERIMENTAL_MENUS */ + uiDefBut(block, BUTM, 1, "Plane|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "Add a Mesh Plane"); + uiDefBut(block, BUTM, 1, "Cube|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "Add a Mesh Cube"); + uiDefBut(block, BUTM, 1, "Circle|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "Add a Mesh Circle"); + uiDefBut(block, BUTM, 1, "UVsphere", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "Add a Mesh Sphere"); + uiDefBut(block, BUTM, 1, "IcoSphere|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, "Add a Mesh Isocohedron Sphere"); + uiDefBut(block, BUTM, 1, "Cylinder|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 5, "Add a Mesh Cylinder"); + uiDefBut(block, BUTM, 1, "Tube|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 6, "Add a Mesh Tube"); + uiDefBut(block, BUTM, 1, "Cone|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 7, "Add a Mesh Cone"); + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Grid|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 8, "Add a Mesh Grid"); +#endif /* EXPERIMENTAL_MENUS */ + + uiBlockSetDirection(block, UI_RIGHT); + + return block; +} + +static void do_info_add_curvemenu(void *arg, int event) +{ + + switch(event) { + case 0: + /* Bezier Curve */ + add_primitiveCurve(10); + break; + case 1: + /* Bezier Circle */ + add_primitiveCurve(11); + break; + case 2: + /* NURB Curve */ + add_primitiveCurve(40); + break; + case 3: + /* NURB Circle */ + add_primitiveCurve(41); + break; + case 4: + /* Path */ + add_primitiveCurve(46); + break; + default: + break; + } + allqueue(REDRAWINFO, 0); +} + +static uiBlock *info_add_curvemenu(void *arg_unused) +{ +/* static short tog=0; */ + uiBlock *block; + short xco= 0; + + block= uiNewBlock(&curarea->uiblocks, "add_curvemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetButmFunc(block, do_info_add_curvemenu, NULL); + + uiDefBut(block, BUTM, 1, "Bezier Curve|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "Add a Bezier curve"); + uiDefBut(block, BUTM, 1, "Bezier Circle|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "Add a Bezier circle"); + uiDefBut(block, BUTM, 1, "NURBS Curve|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "Add a NURB curve"); + uiDefBut(block, BUTM, 1, "NURBS Circle", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "Add a NURB circle"); + uiDefBut(block, BUTM, 1, "Path|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, "Add a path"); + + uiBlockSetDirection(block, UI_RIGHT); + + return block; +} + + +static void do_info_add_surfacemenu(void *arg, int event) +{ + + switch(event) { + case 0: + /* Curve */ + add_primitiveNurb(0); + break; + case 1: + /* Circle */ + add_primitiveNurb(1); + break; + case 2: + /* Surface */ + add_primitiveNurb(2); + break; + case 3: + /* Tube */ + add_primitiveNurb(3); + break; + case 4: + /* Sphere */ + add_primitiveNurb(4); + break; + case 5: + /* Donut */ + add_primitiveNurb(5); + break; + default: + break; + } + allqueue(REDRAWINFO, 0); +} + +static uiBlock *info_add_surfacemenu(void *arg_unused) +{ +/* static short tog=0; */ + uiBlock *block; + short xco= 0; + + block= uiNewBlock(&curarea->uiblocks, "add_surfacemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetButmFunc(block, do_info_add_surfacemenu, NULL); + + uiDefBut(block, BUTM, 1, "NURBS Curve|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "Add a curve"); + uiDefBut(block, BUTM, 1, "NURBS Circle|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "Add a circle"); + uiDefBut(block, BUTM, 1, "NURBS Surface|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "Add a surface"); + uiDefBut(block, BUTM, 1, "NURBS Tube", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "Add a tube"); + uiDefBut(block, BUTM, 1, "NURBS Sphere|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, "Add a sphere"); + uiDefBut(block, BUTM, 1, "NURBS Donut|", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 5, "Add a donut"); + + uiBlockSetDirection(block, UI_RIGHT); + + return block; +} + +static void do_info_addmenu(void *arg, int event) +{ + + switch(event) { + case 0: + /* Mesh */ + break; + case 1: + /* Curve */ + break; + case 2: + /* Surface */ + break; + case 3: + /* Text (argument is discarded) */ + add_primitiveFont(event); + break; + case 4: + /* Metaball (argument is discarded) */ + add_primitiveMball(event); + break; + case 5: + /* Empty */ + add_object_draw(OB_EMPTY); + break; + case 6: + /* Camera */ + add_object_draw(OB_CAMERA); + break; + case 7: + /* Lamp */ + add_object_draw(OB_LAMP); + break; + case 8: + /* Armature */ + add_primitiveArmature(OB_ARMATURE); + break; + case 9: + /* Lattice */ + add_object_draw(OB_LATTICE); + break; + default: + break; + } + allqueue(REDRAWINFO, 0); +} + + +static uiBlock *info_addmenu(void *arg_unused) +{ +/* static short tog=0; */ + uiBlock *block; + short xco= 0; + + block= uiNewBlock(&curarea->uiblocks, "addmenu", UI_EMBOSSP, UI_HELV, curarea->headwin); + uiBlockSetButmFunc(block, do_info_addmenu, NULL); + + uiDefBlockBut(block, info_add_meshmenu, NULL, "Mesh|>>", 0, xco-=20, 120, 19, "Click to open the Add Mesh menu"); + uiDefBlockBut(block, info_add_curvemenu, NULL, "Curve|>>", 0, xco-=20, 120, 19, "Click to open the Add Curve menu"); + uiDefBlockBut(block, info_add_surfacemenu, NULL, "Surface|>>", 0, xco-=20, 120, 19, "Click to open the Add Surface menu"); + + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Text|", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 3, ""); + uiDefBut(block, BUTM, 1, "Metaball|", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 4, ""); + uiDefBut(block, BUTM, 1, "Empty|", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 5, ""); + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Camera|", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 6, ""); + uiDefBut(block, BUTM, 1, "Lamp|", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 7, ""); +// uiDefBut(block, BUTM, 1, "Armature|", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 8, ""); + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Lattice|", 0, xco-=20, 120, 19, NULL, 0.0, 0.0, 1, 9, ""); + + uiBlockSetDirection(block, UI_DOWN); + + return block; +} + +static void do_info_viewmenu(void *arg, int event) +{ + switch(event) { + case 0: + if(select_area(SPACE_VIEW3D)) mainqenter(PAD1, 1); + break; + case 1: + if(select_area(SPACE_VIEW3D)) mainqenter(PAD3, 1); + break; + case 2: + if(select_area(SPACE_VIEW3D)) mainqenter(PAD7, 1); + break; + case 3: + if(select_area(SPACE_VIEW3D)) mainqenter(PAD0, 1); + break; + case 4: + if(select_area(SPACE_VIEW3D)) mainqenter(PADPLUSKEY, 1); + break; + case 5: + if(select_area(SPACE_VIEW3D)) mainqenter(PADMINUS, 1); + break; + case 6: + if(select_area(SPACE_VIEW3D)) mainqenter(CKEY, 1); + break; + case 7: + if(select_area(SPACE_VIEW3D)) mainqenter(HOMEKEY, 1); + break; + } + allqueue(REDRAWINFO, 0); +} + +static uiBlock *info_viewmenu(void *arg_unused) +{ +/* static short tog=0; */ + uiBlock *block; + short xco= 0; + + block= uiNewBlock(&curarea->uiblocks, "filemenu", UI_EMBOSSP, UI_HELV, curarea->headwin); + uiBlockSetButmFunc(block, do_info_viewmenu, NULL); + + // uiBlockSetCol(block, BUTBLUE); + + uiDefBut(block, BUTM, 1, "Front|NumPad 1", 0, xco-=20, 140, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Right|NumPad 3", 0, xco-=20, 140, 19, NULL, 0.0, 0.0, 0, 1, ""); + uiDefBut(block, BUTM, 1, "Top|NumPad 7", 0, xco-=20, 140, 19, NULL, 0.0, 0.0, 0, 2, ""); + uiDefBut(block, BUTM, 1, "Camera|NumPad 0", 0, xco-=20, 140, 19, NULL, 0.0, 0.0, 0, 3, ""); + + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 140, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Zoom In|NumPad +", 0, xco-=20, 140, 19, NULL, 0.0, 0.0, 0, 4, ""); + uiDefBut(block, BUTM, 1, "Zoom Out|NumPad -", 0, xco-=20, 140, 19, NULL, 0.0, 0.0, 0, 5, ""); + + uiDefBut(block, SEPR, 0, "", 0, xco-=6, 140, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Center|C", 0, xco-=20, 140, 19, NULL, 0.0, 0.0, 0, 6, ""); + uiDefBut(block, BUTM, 1, "View All|Home", 0, xco-=20, 140, 19, NULL, 0.0, 0.0, 0, 7, ""); + + uiBlockSetDirection(block, UI_DOWN); + + return block; +} + +static void do_game_menu(void *arg, int event) +{ + switch (event) { + case G_FILE_ENABLE_ALL_FRAMES_BIT: + case G_FILE_SHOW_FRAMERATE_BIT: + case G_FILE_SHOW_DEBUG_PROPS_BIT: + case G_FILE_AUTOPLAY_BIT: + G.fileflags ^= (1 << event); + break; + default: + ; /* ignore the rest */ + } +} + + +static uiBlock *info_gamemenu(void *arg_unused) +{ + uiBlock *block; + short yco= 0; + + block= uiNewBlock(&curarea->uiblocks, "gamemenu", UI_EMBOSSP, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTBLUE); + uiBlockSetDirection(block, UI_DOWN); + + uiDefBut(block, BUTM, B_STARTGAME, "Start Game|P", + 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 0, 0, + "Start the game (press the Escape key to stop)"); + uiDefBut(block, SEPR, 0, "", + -20, yco-=6, 180, 6, NULL, 0.0, 0.0, 1, 0, ""); + + /* flags are case-values */ + uiBlockSetButmFunc(block, do_game_menu, NULL); + uiDefBut(block, BUTM, 1, "Enable All Frames", + 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, G_FILE_ENABLE_ALL_FRAMES_BIT, + "Toggle between draw all frames on (no frames dropped) and off (full speed)"); + uiDefBut(block, BUTM, 1, "Show framerate and profile", + 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, G_FILE_SHOW_FRAMERATE_BIT, + "Toggle between showing and not showing the framerate and profile"); + uiDefBut(block, BUTM, 1, "Show debug properties", + 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, G_FILE_SHOW_DEBUG_PROPS_BIT, + "Toggle between showing and not showing debug properties"); + uiDefBut(block, SEPR, 0, "", -20, yco-=6, 180, 6, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, 1, "Autostart", + 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, G_FILE_AUTOPLAY_BIT, + "Toggle between automatic game start on and off"); + + /* Toggle buttons */ + yco= -26; + uiBlockSetEmboss(block, UI_EMBOSSW); + /* flags are defines */ + + uiBlockSetButmFunc(block, NULL, NULL); // to prevent it from calling the menu function + uiDefIconButI(block, ICONTOG|BIT|G_FILE_ENABLE_ALL_FRAMES_BIT, + 0, ICON_CHECKBOX_DEHLT, -20, yco-=20, 19, 19, + &G.fileflags, 0.0, 0.0, 0, 0, ""); + uiDefIconButI(block, ICONTOG|BIT|G_FILE_SHOW_FRAMERATE_BIT, + 0, ICON_CHECKBOX_DEHLT, -20, yco-=20, 19, 19, + &G.fileflags, 0.0, 0.0, 0, 0, ""); + uiDefIconButI(block, ICONTOG|BIT|G_FILE_SHOW_DEBUG_PROPS_BIT, + 0, ICON_CHECKBOX_DEHLT, -20, yco-=20, 19, 19, + &G.fileflags, 0.0, 0.0, 0, 0, ""); + yco-=6; + uiDefIconButI(block, ICONTOG|BIT|G_FILE_AUTOPLAY_BIT, + 0, ICON_CHECKBOX_DEHLT, -20, yco-=20, 19, 19, + &G.fileflags, 0.0, 0.0, 0, 0, ""); + + return block; +} + +#ifndef EXPERIMENTAL_MENUS +/* In the Maarten's new menu structure proposal, the tools menu moved to the file menu */ +static void do_info_toolsmenu(void *arg, int event) +{ + + switch(event) { + case 0: + check_packAll(); + break; + case 1: + unpackAll(PF_WRITE_LOCAL); + G.fileflags &= ~G_AUTOPACK; + break; + case 2: + if (buttons_do_unpack() != RET_CANCEL) { + // clear autopack bit only if + // user selected one of the unpack options + G.fileflags &= ~G_AUTOPACK; + } + break; + } + allqueue(REDRAWINFO, 0); +} + +static uiBlock *info_toolsmenu(void *arg_unused) +{ +/* static short tog=0; */ + uiBlock *block; + short xco= 0; + + block= uiNewBlock(&curarea->uiblocks, "toolsmenu", UI_EMBOSSP, UI_HELV, curarea->headwin); + uiBlockSetButmFunc(block, do_info_toolsmenu, NULL); + // uiBlockSetCol(block, BUTBLUE); + + uiDefBut(block, BUTM, 1, "Pack Data", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, 1, "Unpack Data to current dir", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefBut(block, BUTM, 1, "Advanced Unpack", 0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, ""); + uiBlockSetDirection(block, UI_DOWN); + + return block; +} +#endif /* EXPERIMENTAL_MENUS */ + + +static void info_text(int x, int y) +{ + Object *ob; + extern float hashvectf[]; + extern int mem_in_use; + unsigned int swatch_color; + float fac1, fac2, fac3; + char infostr[300]; + char *headerstr; + int hsize; + + + if(G.obedit) { + sprintf(infostr,"Ve:%d-%d Fa:%d-%d Mem:%.2fM ", + G.totvertsel, G.totvert, G.totfacesel, G.totface, + (mem_in_use>>10)/1024.0); + } + else { + sprintf(infostr,"Ve:%d Fa:%d Ob:%d-%d La:%d Mem:%.2fM ", + G.totvert, G.totface, G.totobj, G.totobjsel, G.totlamp, (mem_in_use>>10)/1024.0); + } + ob= OBACT; + if(ob) { + strcat(infostr, ob->id.name+2); + } + + if (g_progress_bar) { + hsize = 4 + (120.0 * g_done); + fac1 = 0.5 * g_done; // do some rainbow colours on progress + fac2 = 1.0; + fac3 = 0.9; + } else { + hsize = 124; + /* promise! Never change these lines again! */ + fac1= fabs(hashvectf[ 2*G.version+4]); + fac2= 0.5+0.1*hashvectf[ G.version+3]; + fac3= 0.7; + } + + if (g_progress_bar && g_progress_info) { + headerstr= g_progress_info; + } else { + headerstr= versionstr; + } + + swatch_color= hsv_to_cpack(fac1, fac2, fac3); + + cpack( swatch_color ); + glRecti(x-24, y-4, x-24+hsize, y+13); + + glColor3ub(0, 0, 0); + + glRasterPos2i(x, y); + BMF_DrawString(G.fonts, headerstr); + + glRasterPos2i(x+120, y); + BMF_DrawString(G.fonts, infostr); +} + +void info_buttons(void) +{ + uiBlock *block; + short xco= 32; + char naam[20]; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSM, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTGREY); + + uiDefBlockBut(block, info_filemenu, NULL, "File", xco, 3, 40, 15, ""); + xco+= 40; + uiDefBlockBut(block, info_editmenu, NULL, "Edit", xco, 3, 40, 15, ""); + xco+= 40; + + uiDefBlockBut(block, info_addmenu, NULL, "Add", xco, 3, 40, 15, ""); + xco+= 40; + + uiDefBlockBut(block, info_viewmenu, NULL, "View", xco, 3, 40, 15, ""); + xco+= 40; + uiDefBlockBut(block, info_gamemenu, NULL, "Game", xco, 3, 40, 15, ""); + xco+= 40; + +#ifndef EXPERIMENTAL_MENUS + /* In the Maarten's new menu structure proposal, the tools menu moved to the file menu */ + uiDefBlockBut(block, info_toolsmenu, NULL, "Tools", xco, 3, 40, 15, ""); + xco+= 40; +#endif /* EXPERIMENTAL_MENUS */ + + /* pack icon indicates a packed file */ + + if (G.fileflags & G_AUTOPACK) { + uiBlockSetEmboss(block, UI_EMBOSSN); + uiDefIconBut(block, LABEL, 0, ICON_PACKAGE, xco, 0, XIC, YIC, &G.fileflags, 0.0, 0.0, 0, 0, "This is a Packed file. See File menu."); + xco += 24; + uiBlockSetEmboss(block, UI_EMBOSSX); + } + + uiBlockSetEmboss(block, UI_EMBOSSX); + + if (curarea->full == 0) { + curarea->butspacetype= SPACE_INFO; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type "); + + /* STD SCREEN BUTTONS */ + xco+= XIC; + xco= std_libbuttons(block, xco, 0, NULL, B_INFOSCR, (ID *)G.curscreen, 0, &G.curscreen->screennr, 1, 1, B_INFODELSCR, 0); + + /* STD SCENE BUTTONS */ + xco+= 5; + xco= std_libbuttons(block, xco, 0, NULL, B_INFOSCE, (ID *)G.scene, 0, &G.curscreen->scenenr, 1, 1, B_INFODELSCE, 0); + } + else xco= 430; + + info_text(xco+24, 6); + + uiBlockSetEmboss(block, UI_EMBOSSN); + uiDefIconBut(block, BUT, B_SHOWSPLASH, ICON_BLENDER, xco+1, 0,XIC,YIC, 0, 0, 0, 0, 0, ""); + uiBlockSetEmboss(block, UI_EMBOSSX); + + if (LICENSE_KEY_VALID) { + uiBlockSetEmboss(block, UI_EMBOSSN); + uiDefIconBut(block, LABEL, 0, ICON_PUBLISHER, xco+125, 0,XIC,YIC, 0, 0, 0, 0, 0, ""); + uiBlockSetEmboss(block, UI_EMBOSSX); + } + + /* altijd als laatste doen */ + curarea->headbutlen= xco+2*XIC; + + if(curarea->headbutlen + 4*XIC < curarea->winx) { + uiDefIconBut(block, BUT, B_FILEMENU, ICON_HELP, (short)(curarea->winx-XIC-2), 0,XIC,YIC, 0, 0, 0, 0, 0, "Toolbox menu, hotkey: SPACE"); + } + + uiDrawBlock(block); +} + +/* ********************** END INFO ****************************** */ +/* ********************** SEQUENCE ****************************** */ + +void do_seq_buttons(short event) +{ + Editing *ed; + + ed= G.scene->ed; + if(ed==0) return; + + switch(event) { + case B_SEQHOME: + G.v2d->cur= G.v2d->tot; + test_view2d(G.v2d, curarea->winx, curarea->winy); + scrarea_queue_winredraw(curarea); + break; + case B_SEQCLEAR: + free_imbuf_seq(); + allqueue(REDRAWSEQ, 1); + break; + } + +} + +void seq_buttons() +{ + SpaceSeq *sseq; + short xco; + char naam[20]; + uiBlock *block; + + sseq= curarea->spacedata.first; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTPURPLE); + + curarea->butspacetype= SPACE_SEQ; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type "); + + /* FULL WINDOW */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Restore smaller windows (CTRL+Up arrow)"); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Make fullscreen window (CTRL+Down arrow)"); + + /* HOME */ + uiDefIconBut(block, BUT, B_SEQHOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Home (HOMEKEY)"); + xco+= XIC; + + /* IMAGE */ + uiDefIconButS(block, TOG, B_REDR, ICON_IMAGE_COL, xco+=XIC,0,XIC,YIC, &sseq->mainb, 0, 0, 0, 0, "Toggles image display"); + + /* ZOOM en BORDER */ + xco+= XIC; + uiDefIconButI(block, TOG, B_VIEW2DZOOM, ICON_VIEWZOOM, xco+=XIC,0,XIC,YIC, &viewmovetemp, 0, 0, 0, 0, "Zoom view (CTRL+MiddleMouse)"); + uiDefIconBut(block, BUT, B_IPOBORDER, ICON_BORDERMOVE, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Translate view (MiddleMouse)"); + + /* CLEAR MEM */ + xco+= XIC; + uiDefBut(block, BUT, B_SEQCLEAR, "Clear", xco+=XIC,0,2*XIC,YIC, 0, 0, 0, 0, 0, "Forces a clear of all buffered images in memory"); + + uiDrawBlock(block); +} + +/* ********************** END SEQ ****************************** */ +/* ********************** VIEW3D ****************************** */ + +void do_view3d_buttons(short event) +{ + int bit; + + /* pas op: als curarea->win niet bestaat, afvangen als direkt tekenroutines worden aangeroepen */ + + switch(event) { + case B_HOME: + view3d_home(0); + break; + case B_SCENELOCK: + if(G.vd->scenelock) { + G.vd->lay= G.scene->lay; + /* layact zoeken */ + bit= 0; + while(bit<32) { + if(G.vd->lay & (1<<bit)) { + G.vd->layact= 1<<bit; + break; + } + bit++; + } + G.vd->camera= G.scene->camera; + scrarea_queue_winredraw(curarea); + scrarea_queue_headredraw(curarea); + } + break; + case B_LOCALVIEW: + if(G.vd->localview) initlocalview(); + else endlocalview(curarea); + scrarea_queue_headredraw(curarea); + break; + case B_EDITMODE: + if (G.f & G_VERTEXPAINT) { + /* Switch off vertex paint */ + G.f &= ~G_VERTEXPAINT; + } + if (G.f & G_WEIGHTPAINT){ + /* Switch off weight paint */ + G.f &= ~G_WEIGHTPAINT; + } +#ifdef NAN_TPT + if (G.f & G_TEXTUREPAINT) { + /* Switch off texture paint */ + G.f &= ~G_TEXTUREPAINT; + } +#endif /* NAN_VPT */ + if(G.obedit==0) enter_editmode(); + else exit_editmode(1); + scrarea_queue_headredraw(curarea); + break; + case B_POSEMODE: + /* if (G.obedit){ + error("Unable to perform function in EditMode"); + G.vd->flag &= ~V3D_POSEMODE; + scrarea_queue_headredraw(curarea); + } + else{ + */ + if (G.obpose==NULL) enter_posemode(); + else exit_posemode(1); + + allqueue(REDRAWHEADERS, 0); + + break; + case B_WPAINT: + if (G.f & G_VERTEXPAINT) { + /* Switch off vertex paint */ + G.f &= ~G_VERTEXPAINT; + } +#ifdef NAN_TPT + if ((!(G.f & G_WEIGHTPAINT)) && (G.f & G_TEXTUREPAINT)) { + /* Switch off texture paint */ + G.f &= ~G_TEXTUREPAINT; + } +#endif /* NAN_VPT */ + if(G.obedit) { + error("Unable to perform function in EditMode"); + G.vd->flag &= ~V3D_WEIGHTPAINT; + scrarea_queue_headredraw(curarea); + } + else if(G.obpose) { + error("Unable to perform function in PoseMode"); + G.vd->flag &= ~V3D_WEIGHTPAINT; + scrarea_queue_headredraw(curarea); + } + else set_wpaint(); + break; + case B_VPAINT: + if ((!(G.f & G_VERTEXPAINT)) && (G.f & G_WEIGHTPAINT)) { + G.f &= ~G_WEIGHTPAINT; + } +#ifdef NAN_TPT + if ((!(G.f & G_VERTEXPAINT)) && (G.f & G_TEXTUREPAINT)) { + /* Switch off texture paint */ + G.f &= ~G_TEXTUREPAINT; + } +#endif /* NAN_VPT */ + if(G.obedit) { + error("Unable to perform function in EditMode"); + G.vd->flag &= ~V3D_VERTEXPAINT; + scrarea_queue_headredraw(curarea); + } + else if(G.obpose) { + error("Unable to perform function in PoseMode"); + G.vd->flag &= ~V3D_VERTEXPAINT; + scrarea_queue_headredraw(curarea); + } + else set_vpaint(); + break; + +#ifdef NAN_TPT + case B_TEXTUREPAINT: + if (G.f & G_TEXTUREPAINT) { + G.f &= ~G_TEXTUREPAINT; + } + else { + if (G.obedit) { + error("Unable to perform function in EditMode"); + G.vd->flag &= ~V3D_TEXTUREPAINT; + } + else { + if (G.f & G_WEIGHTPAINT){ + /* Switch off weight paint */ + G.f &= ~G_WEIGHTPAINT; + } + if (G.f & G_VERTEXPAINT) { + /* Switch off vertex paint */ + G.f &= ~G_VERTEXPAINT; + } + if (G.f & G_FACESELECT) { + /* Switch off face select */ + G.f &= ~G_FACESELECT; + } + G.f |= G_TEXTUREPAINT; + scrarea_queue_headredraw(curarea); + } + } + break; +#endif /* NAN_TPT */ + + case B_FACESEL: + if(G.obedit) { + error("Unable to perform function in EditMode"); + G.vd->flag &= ~V3D_FACESELECT; + scrarea_queue_headredraw(curarea); + } + else if(G.obpose) { + error("Unable to perform function in PoseMode"); + G.vd->flag &= ~V3D_FACESELECT; + scrarea_queue_headredraw(curarea); + } + else set_faceselect(); + break; + + case B_VIEWBUT: + + if(G.vd->viewbut==1) persptoetsen(PAD7); + else if(G.vd->viewbut==2) persptoetsen(PAD1); + else if(G.vd->viewbut==3) persptoetsen(PAD3); + break; + + case B_PERSP: + + if(G.vd->persp==2) persptoetsen(PAD0); + else { + G.vd->persp= 1-G.vd->persp; + persptoetsen(PAD5); + } + + break; + case B_PROPTOOL: + allqueue(REDRAWHEADERS, 0); + break; + case B_VIEWRENDER: + if (curarea->spacetype==SPACE_VIEW3D) { + BIF_do_ogl_render(curarea->spacedata.first, G.qual!=0 ); + } + break; + case B_STARTGAME: + if (select_area(SPACE_VIEW3D)) { + start_game(); + } + break; + case B_VIEWZOOM: + viewmovetemp= 0; + viewmove(2); + scrarea_queue_headredraw(curarea); + break; + case B_VIEWTRANS: + viewmovetemp= 0; + viewmove(1); + scrarea_queue_headredraw(curarea); + break; + + default: + + if(event>=B_LAY && event<B_LAY+31) { + if(G.vd->lay!=0 && (G.qual & LR_SHIFTKEY)) { + + /* wel actieve layer zoeken */ + + bit= event-B_LAY; + if( G.vd->lay & (1<<bit)) G.vd->layact= 1<<bit; + else { + if( (G.vd->lay & G.vd->layact) == 0) { + bit= 0; + while(bit<32) { + if(G.vd->lay & (1<<bit)) { + G.vd->layact= 1<<bit; + break; + } + bit++; + } + } + } + } + else { + bit= event-B_LAY; + G.vd->lay= 1<<bit; + G.vd->layact= G.vd->lay; + scrarea_queue_headredraw(curarea); + } + scrarea_queue_winredraw(curarea); + countall(); + + if(G.vd->scenelock) handle_view3d_lock(); + allqueue(REDRAWOOPS, 0); + } + break; + } +} + +void do_layer_buttons(short event) +{ + static int oldlay= 1; + + if(G.vd==0) return; + if(G.vd->localview) return; + + if(event==-1 && (G.qual & LR_CTRLKEY)) { + G.vd->scenelock= !G.vd->scenelock; + do_view3d_buttons(B_SCENELOCK); + } else if (event==-1) { + if(G.vd->lay== (2<<20)-1) { + if(G.qual & LR_SHIFTKEY) G.vd->lay= oldlay; + } + else { + oldlay= G.vd->lay; + G.vd->lay= (2<<20)-1; + } + + if(G.vd->scenelock) handle_view3d_lock(); + scrarea_queue_winredraw(curarea); + } + else { + if(G.qual & LR_ALTKEY) { + if(event<11) event+= 10; + } + if(G.qual & LR_SHIFTKEY) { + if(G.vd->lay & (1<<event)) G.vd->lay -= (1<<event); + else G.vd->lay += (1<<event); + } + do_view3d_buttons(event+B_LAY); + } + /* redraw lijkt dubbelop: wordt in queue netjes afgehandeld */ + scrarea_queue_headredraw(curarea); + + if(curarea->spacetype==SPACE_OOPS) allqueue(REDRAWVIEW3D, 1); /* 1==ook headwin */ + +} + +void do_nla_buttons(unsigned short event) +{ + View2D *v2d; + + switch(event){ + case B_NLAHOME: + // Find X extents + v2d= &(G.snla->v2d); + + v2d->cur.xmin = G.scene->r.sfra; + v2d->cur.ymin=-SCROLLB; + +// if (!G.saction->action){ + v2d->cur.xmax=G.scene->r.efra; +// } +// else +// { +// v2d->cur.xmax=calc_action_length(G.saction->action)+1; +// } + + test_view2d(G.v2d, curarea->winx, curarea->winy); + addqueue (curarea->win, REDRAW, 1); + break; + } +} + +void nla_buttons(void) +{ + SpaceNla *snla; + short xco; + char naam[20]; + uiBlock *block; + + snla= curarea->spacedata.first; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTCHOKE); + + curarea->butspacetype= SPACE_NLA; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type "); + + /* FULL WINDOW */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Restore smaller windows (CTRL+Up arrow)"); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Make fullscreen window (CTRL+Down arrow)"); + + /* HOME */ + uiDefIconBut(block, BUT, B_NLAHOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Home (HOMEKEY)"); + xco+= XIC; + + /* IMAGE */ +// uiDefIconButS(block, TOG, B_REDR, ICON_IMAGE_COL, xco+=XIC,0,XIC,YIC, &sseq->mainb, 0, 0, 0, 0, "Toggles image display"); + + /* ZOOM en BORDER */ +// xco+= XIC; +// uiDefIconButI(block, TOG, B_VIEW2DZOOM, ICON_VIEWZOOM, xco+=XIC,0,XIC,YIC, &viewmovetemp, 0, 0, 0, 0, "Zoom view (CTRL+MiddleMouse)"); +// uiDefIconBut(block, BUT, B_NLABORDER, ICON_BORDERMOVE, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Translate view (MiddleMouse)"); + + /* draw LOCK */ + xco+= XIC/2; + uiDefIconButI(block, ICONTOG, 1, ICON_UNLOCKED, xco+=XIC,0,XIC,YIC, &(G.snla->lock), 0, 0, 0, 0, "Lock redraw of other windows while editing"); + + uiDrawBlock(block);} + +void action_buttons(void) +{ + uiBlock *block; + short xco; + char naam[256]; + Object *ob; + ID *from; + + if (!G.saction) + return; + + // copy from drawactionspace.... + if (!G.saction->pin) { + if (OBACT) + G.saction->action = OBACT->action; + else + G.saction->action=NULL; + } + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTPINK); + + curarea->butspacetype= SPACE_ACTION; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type"); + + /* FULL WINDOW */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Restore smaller windows (CTRL+Up arrow)"); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Make fullscreen window (CTRL+Down arrow)"); + uiDefIconBut(block, BUT, B_ACTHOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Home (HOMEKEY)"); + + + /* NAME ETC */ + ob=OBACT; + from = (ID*) ob; + + xco= std_libbuttons(block, xco+1.5*XIC, B_ACTPIN, &G.saction->pin, B_ACTIONBROWSE, (ID*)G.saction->action, from, &(G.saction->actnr), B_ACTALONE, B_ACTLOCAL, B_ACTIONDELETE, 0); + +#ifdef __NLA_BAKE + /* Draw action baker */ + uiDefBut(block, BUT, B_ACTBAKE, "Bake", xco+=XIC, 0, 64, YIC, 0, 0, 0, 0, 0, "Generate an action with the constraint effects converted into ipo keys"); + xco+=64; +#endif + uiClearButLock(); + + /* draw LOCK */ + xco+= XIC/2; + uiDefIconButS(block, ICONTOG, 1, ICON_UNLOCKED, xco+=XIC,0,XIC,YIC, &(G.saction->lock), 0, 0, 0, 0, "Lock redraw of other windows while editing"); + + + /* always as last */ + curarea->headbutlen= xco+2*XIC; + + uiDrawBlock(block); +} + +void view3d_buttons(void) +{ + uiBlock *block; + int a; + short xco; + char naam[20]; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTBLUE); + + curarea->butspacetype= SPACE_VIEW3D; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type "); + + + /* FULL WINDOW */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Restore smaller windows (CTRL+Up arrow)"); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Make fullscreen window (CTRL+Down arrow)"); + + /* HOME */ + uiDefIconBut(block, BUT, B_HOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Home (HOMEKEY)"); + + xco+= XIC+8; + if(G.vd->localview==0) { + /* LAYERS */ + for(a=0; a<10; a++) { + uiDefButI(block, TOG|BIT|(a+10), B_LAY+10+a, "",(short)(xco+a*(XIC/2)), 0, XIC/2, (YIC)/2, &(G.vd->lay), 0, 0, 0, 0, "Layers"); + uiDefButI(block, TOG|BIT|a, B_LAY+a, "", (short)(xco+a*(XIC/2)), (short)(YIC/2),(short)(XIC/2),(short)(YIC/2), &(G.vd->lay), 0, 0, 0, 0, "Layers"); + if(a==4) xco+= 5; + } + xco+= (a-2)*(XIC/2)+5; + + /* LOCK */ + uiDefIconButS(block, ICONTOG, B_SCENELOCK, ICON_UNLOCKED, xco+=XIC,0,XIC,YIC, &(G.vd->scenelock), 0, 0, 0, 0, "Lock layers and used Camera to Scene"); + xco+= XIC; + + } + else xco+= (10+2)*(XIC/2)+10; + + /* LOCALVIEW */ + uiDefIconButS(block, ICONROW, B_LOCALVIEW, ICON_LOCALVIEW, xco+=XIC,0,XIC,YIC, &(G.vd->localview), 0.0, 2.0, 0, 0, "Local View (NumPad /)"); + + /* PERSP */ + xco+= XIC/2; + uiDefIconButS(block, ICONROW, B_PERSP, ICON_ORTHO, xco+=XIC,0,XIC,YIC, &(G.vd->persp), 0.0, 2.0, 0, 0, "Perspective mode (NumPad 5, Numpad 0)"); + + xco+= XIC/2; + /* AANZICHT */ + + if(G.vd->view==7) G.vd->viewbut= 1; + else if(G.vd->view==1) G.vd->viewbut= 2; + else if(G.vd->view==3) G.vd->viewbut= 3; + else G.vd->viewbut= 0; + + uiDefIconButS(block, ICONROW, B_VIEWBUT, ICON_VIEW_AXIS_NONE, xco+=XIC,0,XIC,YIC, &G.vd->viewbut, 0.0, 3.0, 0, 0, "Top/Front or Side views (Numpad 7, 1, 3)"); + + /* DRAWTYPE */ + xco+= XIC/2; + uiDefIconButS(block, ICONROW, B_REDR, ICON_BBOX, xco+=XIC,0,XIC,YIC, &(G.vd->drawtype), 1.0, 5.0, 0, 0, "Drawtype: boundbox/wire/solid/shaded (ZKEY, SHIFT+Z)"); + + /* VIEWMOVE */ + xco+= XIC/2; + uiDefIconButI(block, TOG, B_VIEWTRANS, ICON_VIEWMOVE, xco+=XIC,0,XIC,YIC, &viewmovetemp, 0, 0, 0, 0, "Translate view (SHIFT+MiddleMouse)"); + uiDefIconButI(block, TOG, B_VIEWZOOM, ICON_VIEWZOOM, xco+=XIC,0,XIC,YIC, &viewmovetemp, 0, 0, 0, 0, "Zoom view (CTRL+MiddleMouse)"); + + /* around */ + xco+= XIC/2; + uiDefIconButS(block, ROW, 1, ICON_ROTATE, xco+=XIC,0,XIC,YIC, &G.vd->around, 3.0, 0.0, 0, 0, "Rotation/Scaling around boundbox center (COMMAKEY)"); + uiDefIconButS(block, ROW, 1, ICON_ROTATECENTER, xco+=XIC,0,XIC,YIC, &G.vd->around, 3.0, 3.0, 0, 0, "Rotation/Scaling around median point"); + uiDefIconButS(block, ROW, 1, ICON_CURSOR, xco+=XIC,0,XIC,YIC, &G.vd->around, 3.0, 1.0, 0, 0, "Rotation/Scaling around cursor (DOTKEY)"); + uiDefIconButS(block, ROW, 1, ICON_ROTATECOLLECTION, xco+=XIC,0,XIC,YIC, &G.vd->around, 3.0, 2.0, 0, 0, "Rotation/Scaling around individual centers"); + + /* mode */ + G.vd->flag &= ~V3D_MODE; + if(G.obedit) G.vd->flag |= V3D_EDITMODE; + if(G.f & G_VERTEXPAINT) G.vd->flag |= V3D_VERTEXPAINT; + if(G.f & G_WEIGHTPAINT) G.vd->flag |= V3D_WEIGHTPAINT; +#ifdef NAN_TPT + if (G.f & G_TEXTUREPAINT) G.vd->flag |= V3D_TEXTUREPAINT; +#endif /* NAN_TPT */ + if(G.f & G_FACESELECT) G.vd->flag |= V3D_FACESELECT; + if(G.obpose){ + G.vd->flag |= V3D_POSEMODE; + } + + xco+= XIC/2; + /* If there is a posable object hilighted & selected, display this button */ + if (OBACT){ + if (OBACT->type==OB_ARMATURE){ + uiDefIconButS(block, ICONTOG|BIT|7, B_POSEMODE, ICON_POSE_DEHLT, xco+=XIC,0,XIC,YIC, &G.vd->flag, 0, 0, 0, 0, "PoseMode (CTRL+TAB)"); + } + } + uiDefIconButS(block, ICONTOG|BIT|4, B_EDITMODE, ICON_EDITMODE_DEHLT, xco+=XIC,0,XIC,YIC, &G.vd->flag, 0, 0, 0, 0, "EditMode (TAB)"); + if (!G.obpose && !G.obedit) + { + xco+= XIC/2; + /* Only if mesh is selected */ + if (OBACT && OBACT->type == OB_MESH){ + uiDefIconButS(block, ICONTOG|BIT|5, B_VPAINT, ICON_VPAINT_DEHLT, xco+=XIC,0,XIC,YIC, &G.vd->flag, 0, 0, 0, 0, "VertexPaint Mode (VKEY)"); + /* Only if deformable mesh is selected */ + if ((((Mesh*)(OBACT->data))->dvert)) + uiDefIconButS(block, ICONTOG|BIT|9, B_WPAINT, ICON_WPAINT_DEHLT, xco+=XIC,0,XIC,YIC, &G.vd->flag, 0, 0, 0, 0, "WeightPaint Mode"); +#ifdef NAN_TPT + uiDefIconButS(block, ICONTOG|BIT|8, B_TEXTUREPAINT, ICON_TPAINT_DEHLT, xco+=XIC,0,XIC,YIC, &G.vd->flag, 0, 0, 0, 0, "TexturePaint Mode"); +#endif /* NAN_TPT */ + uiDefIconButS(block, ICONTOG|BIT|6, B_FACESEL, ICON_FACESEL_DEHLT, xco+=XIC,0,XIC,YIC, &G.vd->flag, 0, 0, 0, 0, "FaceSelect Mode (FKEY)"); + } + } + if (G.obpose){ + /* Copy paste - WAS in action window */ + xco+= XIC/2; + // xco-= XIC/2; // Used in action window + if(curarea->headertype==HEADERTOP) { + uiDefIconBut(block, BUT, B_ACTCOPY, ICON_COPYUP, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the current pose to the buffer"); + uiSetButLock(G.obpose->id.lib!=0, "Can't edit library data"); + uiDefIconBut(block, BUT, B_ACTPASTE, ICON_PASTEUP, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the pose from the buffer"); + uiDefIconBut(block, BUT, B_ACTPASTEFLIP, ICON_PASTEFLIPUP, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the flipped pose from the buffer"); + } + else { + uiDefIconBut(block, BUT, B_ACTCOPY, ICON_COPYDOWN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the current pose to the buffer"); + uiSetButLock(G.obpose->id.lib!=0, "Can't edit library data"); + uiDefIconBut(block, BUT, B_ACTPASTE, ICON_PASTEDOWN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the pose from the buffer"); + uiDefIconBut(block, BUT, B_ACTPASTEFLIP, ICON_PASTEFLIPDOWN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the flipped pose from the buffer"); + } +// xco+=XIC/2; // Used in action window + } + if(G.vd->bgpic) { + xco+= XIC/2; + uiDefIconButS(block, TOG|BIT|1, B_REDR, ICON_IMAGE_COL, xco+=XIC,0,XIC,YIC, &G.vd->flag, 0, 0, 0, 0, "Display Background picture"); + } + if(G.obedit) { + extern int prop_mode; + xco+= XIC/2; + uiDefIconButI(block, ICONTOG|BIT|14, B_PROPTOOL, ICON_GRID, xco+=XIC,0,XIC,YIC, &G.f, 0, 0, 0, 0, "Proportional vertex editing (OKEY)"); + if(G.f & G_PROPORTIONAL) { + uiDefIconButI(block, ROW, 0, ICON_SHARPCURVE, xco+=XIC,0,XIC,YIC, &prop_mode, 4.0, 0.0, 0, 0, "Sharp falloff (SHIFT+OKEY)"); + uiDefIconButI(block, ROW, 0, ICON_SMOOTHCURVE, xco+=XIC,0,XIC,YIC, &prop_mode, 4.0, 1.0, 0, 0, "Smooth falloff (SHIFT+OKEY)"); + } + } + + xco+=XIC; + uiDefIconBut(block, BUT, B_VIEWRENDER, ICON_SCENE, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Render this view. (Hold SHIFT for Anim render)"); + xco+=XIC; + uiDefIconBut(block, BUT, B_STARTGAME, ICON_GAME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Start game (PKEY)"); + + + /* Always do this last */ + curarea->headbutlen= xco+2*XIC; + + uiDrawBlock(block); +} + +/* ********************** VIEW3D ****************************** */ +/* ********************** IPO ****************************** */ + +void do_ipo_buttons(short event) +{ + EditIpo *ei; + View2D *v2d; + rcti rect; + float xmin, ymin, dx, dy; + int a, val, first; + short mval[2]; + + if(curarea->win==0) return; + + switch(event) { + case B_IPOHOME: + + /* boundbox */ + + v2d= &(G.sipo->v2d); + first= 1; + + ei= G.sipo->editipo; + if(ei==0) return; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + + boundbox_ipocurve(ei->icu); + + if(first) { + v2d->tot= ei->icu->totrct; + first= 0; + } + else BLI_union_rctf(&(v2d->tot), &(ei->icu->totrct)); + } + } + + /* speciale home */ + if(G.qual & LR_SHIFTKEY) { + v2d->tot.xmin= SFRA; + v2d->tot.xmax= EFRA; + } + + /* beetje uitzoomen */ + dx= 0.10*(v2d->tot.xmax-v2d->tot.xmin); + dy= 0.10*(v2d->tot.ymax-v2d->tot.ymin); + + if(dx<v2d->min[0]) dx= v2d->min[0]; + if(dy<v2d->min[1]) dy= v2d->min[1]; + + v2d->cur.xmin= v2d->tot.xmin- dx; + v2d->cur.xmax= v2d->tot.xmax+ dx; + v2d->cur.ymin= v2d->tot.ymin- dy; + v2d->cur.ymax= v2d->tot.ymax+ dy; + + test_view2d(G.v2d, curarea->winx, curarea->winy); + scrarea_queue_winredraw(curarea); + break; + case B_IPOBORDER: + val= get_border(&rect, 2); + if(val) { + mval[0]= rect.xmin; + mval[1]= rect.ymin; + areamouseco_to_ipoco(G.v2d, mval, &xmin, &ymin); + mval[0]= rect.xmax; + mval[1]= rect.ymax; + areamouseco_to_ipoco(G.v2d, mval, &(G.v2d->cur.xmax), &(G.v2d->cur.ymax)); + G.v2d->cur.xmin= xmin; + G.v2d->cur.ymin= ymin; + + test_view2d(G.v2d, curarea->winx, curarea->winy); + scrarea_queue_winredraw(curarea); + } + break; + + case B_IPOPIN: + allqueue (REDRAWIPO, 0); + break; + + case B_IPOCOPY: + copy_editipo(); + break; + case B_IPOPASTE: + paste_editipo(); + break; + case B_IPOCONT: + set_exprap_ipo(IPO_HORIZ); + break; + case B_IPOEXTRAP: + set_exprap_ipo(IPO_DIR); + break; + case B_IPOCYCLIC: + set_exprap_ipo(IPO_CYCL); + break; + case B_IPOCYCLICX: + set_exprap_ipo(IPO_CYCLX); + break; + case B_IPOMAIN: + make_editipo(); + scrarea_queue_winredraw(curarea); + scrarea_queue_headredraw(curarea); + + break; + case B_IPOSHOWKEY: + /* waarde omkeren vanwege winqread */ + G.sipo->showkey= 1-G.sipo->showkey; + winqreadipo(KKEY, 1, 0); + break; + case B_VIEW2DZOOM: + viewmovetemp= 0; + view2dzoom(); + scrarea_queue_headredraw(curarea); + break; + + } +} + +void ipo_buttons(void) +{ + Object *ob; + ID *id, *from; + uiBlock *block; + short xco; + char naam[20]; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTSALMON); + + curarea->butspacetype= SPACE_IPO; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type "); + + test_editipo(); /* test of huidige editipo klopt, make_editipo zet de v2d->cur */ + + /* FULL WINDOW en HOME */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Restore smaller windows (CTRL+Up arrow)"); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Make fullscreen window (CTRL+Down arrow)"); + uiDefIconBut(block, BUT, B_IPOHOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Home (HOMEKEY)"); + uiDefIconButS(block, ICONTOG, B_IPOSHOWKEY, ICON_KEY_DEHLT, xco+=XIC,0,XIC,YIC, &G.sipo->showkey, 0, 0, 0, 0, "Toggles curve/key display (KKEY)"); + + /* mainmenu, only when data is there and no pin */ + uiSetButLock(G.sipo->pin, "Can't change because of pinned data"); + + ob= OBACT; + xco+= XIC/2; + uiDefIconButS(block, ROW, B_IPOMAIN, ICON_OBJECT, xco+=XIC,0,XIC,YIC, &G.sipo->blocktype, 1.0, (float)ID_OB, 0, 0, "Display Object Ipos "); + + if(ob && give_current_material(ob, ob->actcol)) { + uiDefIconButS(block, ROW, B_IPOMAIN, ICON_MATERIAL, xco+=XIC,0,XIC,YIC, &G.sipo->blocktype, 1.0, (float)ID_MA, 0, 0, "Display Material Ipos "); + if(G.sipo->blocktype==ID_MA) { + uiDefButS(block, NUM, B_IPOMAIN, "", xco+=XIC,0,XIC-4,YIC, &G.sipo->channel, 0.0, 7.0, 0, 0, "Channel Number of the active Material texture"); + xco-= 4; + } + } + if(G.scene->world) { + uiDefIconButS(block, ROW, B_IPOMAIN, ICON_WORLD, xco+=XIC,0,XIC,YIC, &G.sipo->blocktype, 1.0, (float)ID_WO, 0, 0, "Display World Ipos"); + if(G.sipo->blocktype==ID_WO) { + uiDefButS(block, NUM, B_IPOMAIN, "", xco+=XIC,0,XIC-4,YIC, &G.sipo->channel, 0.0, 7.0, 0, 0, "Channel Number of the active World texture"); + xco-= 4; + } + } + + if(ob && ob->type==OB_CURVE) + uiDefIconButS(block, ROW, B_IPOMAIN, ICON_ANIM, xco+=XIC,0,XIC,YIC, &G.sipo->blocktype, 1.0, (float)ID_CU, 0, 0, "Display Curve Ipos"); + + if(ob && ob->type==OB_CAMERA) + uiDefIconButS(block, ROW, B_IPOMAIN, ICON_CAMERA, xco+=XIC,0,XIC,YIC, &G.sipo->blocktype, 1.0, (float)ID_CA, 0, 0, "Display Camera Ipos"); + + if(ob && ob->type==OB_LAMP) { + uiDefIconButS(block, ROW, B_IPOMAIN, ICON_LAMP, xco+=XIC,0,XIC,YIC, &G.sipo->blocktype, 1.0, (float)ID_LA, 0, 0, "Display Lamp Ipos"); + if(G.sipo->blocktype==ID_LA) { + uiDefButS(block, NUM, B_IPOMAIN, "", xco+=XIC,0,XIC-4,YIC, &G.sipo->channel, 0.0, 7.0, 0, 0, "Channel Number of the active Lamp texture"); + xco-= 4; + } + } + + if(ob) { + if ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_LATTICE) + uiDefIconButS(block, ROW, B_IPOMAIN, ICON_EDIT, xco+=XIC,0,XIC,YIC, &G.sipo->blocktype, 1.0, (float)ID_KE, 0, 0, "Display VertexKeys Ipos"); + if (ob->action) + uiDefIconButS(block, ROW, B_IPOMAIN, ICON_ACTION, xco+=XIC,0,XIC,YIC, &G.sipo->blocktype, 1.0, (float)ID_AC, 0, 0, "Display Action Ipos"); +#ifdef __CON_IPO + uiDefIconButS(block, ROW, B_IPOMAIN, ICON_CONSTRAINT, xco+=XIC,0,XIC,YIC, &G.sipo->blocktype, 1.0, (float)IPO_CO, 0, 0, "Display Constraint Ipos"); +#endif + } + uiDefIconButS(block, ROW, B_IPOMAIN, ICON_SEQUENCE, xco+=XIC,0,XIC,YIC, &G.sipo->blocktype, 1.0, (float)ID_SEQ, 0, 0, "Display Sequence Ipos"); + + if(G.buts && G.buts->mainb == BUTS_SOUND && G.buts->lockpoin) + uiDefIconButS(block, ROW, B_IPOMAIN, ICON_SOUND, xco+=XIC,0,XIC,YIC, &G.sipo->blocktype, 1.0, (float)ID_SO, 0, 0, "Display Sound Ipos"); + + + uiClearButLock(); + + /* NAME ETC */ + id= (ID *)get_ipo_to_edit(&from); + + xco= std_libbuttons(block, (short)(xco+1.5*XIC), B_IPOPIN, &G.sipo->pin, B_IPOBROWSE, (ID*)G.sipo->ipo, from, &(G.sipo->menunr), B_IPOALONE, B_IPOLOCAL, B_IPODELETE, 0); + + uiSetButLock(id && id->lib, "Can't edit library data"); + + /* COPY PASTE */ + xco-= XIC/2; + if(curarea->headertype==HEADERTOP) { + uiDefIconBut(block, BUT, B_IPOCOPY, ICON_COPYUP, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the selected curves to the buffer"); + uiSetButLock(id && id->lib, "Can't edit library data"); + uiDefIconBut(block, BUT, B_IPOPASTE, ICON_PASTEUP, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the curves from the buffer"); + } + else { + uiDefIconBut(block, BUT, B_IPOCOPY, ICON_COPYDOWN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the selected curves to the buffer"); + uiSetButLock(id && id->lib, "Can't edit library data"); + uiDefIconBut(block, BUT, B_IPOPASTE, ICON_PASTEDOWN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the curves from the buffer"); + } + xco+=XIC/2; + + /* EXTRAP */ + uiDefIconBut(block, BUT, B_IPOCONT, ICON_CONSTANT, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Sets the extend mode to constant"); + uiDefIconBut(block, BUT, B_IPOEXTRAP, ICON_LINEAR, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Sets the extend mode to extrapolation"); + uiDefIconBut(block, BUT, B_IPOCYCLIC, ICON_CYCLICLINEAR, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Sets the extend mode to cyclic"); + uiDefIconBut(block, BUT, B_IPOCYCLICX, ICON_CYCLIC, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Sets the extend mode to cyclic extrapolation"); + xco+= XIC/2; + + uiClearButLock(); + /* ZOOM en BORDER */ + uiDefIconButI(block, TOG, B_VIEW2DZOOM, ICON_VIEWZOOM, xco+=XIC,0,XIC,YIC, &viewmovetemp, 0, 0, 0, 0, "Zoom view (CTRL+MiddleMouse)"); + uiDefIconBut(block, BUT, B_IPOBORDER, ICON_BORDERMOVE, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Translate view (MiddleMouse)"); + + /* draw LOCK */ + uiDefIconButS(block, ICONTOG, 1, ICON_UNLOCKED, xco+=XIC,0,XIC,YIC, &(G.sipo->lock), 0, 0, 0, 0, "Lock redraw of other windows while editing"); + + /* altijd als laatste doen */ + curarea->headbutlen= xco+2*XIC; + + uiDrawBlock(block); +} + +/* ********************** IPO ****************************** */ +/* ********************** BUTS ****************************** */ + +Material matcopybuf; + +void clear_matcopybuf(void) +{ + memset(&matcopybuf, 0, sizeof(Material)); +} + +void free_matcopybuf(void) +{ + extern MTex mtexcopybuf; /* buttons.c */ + int a; + + for(a=0; a<8; a++) { + if(matcopybuf.mtex[a]) { + MEM_freeN(matcopybuf.mtex[a]); + matcopybuf.mtex[a]= 0; + } + } + + default_mtex(&mtexcopybuf); +} + +void do_buts_buttons(short event) +{ + static short matcopied=0; + MTex *mtex; + Material *ma; + ID id; + int a; + + if(curarea->win==0) return; + + switch(event) { + case B_BUTSHOME: + G.v2d->cur= G.v2d->tot; + test_view2d(G.v2d, curarea->winx, curarea->winy); + scrarea_queue_winredraw(curarea); + break; + case B_BUTSPREVIEW: + BIF_preview_changed(G.buts); + scrarea_queue_headredraw(curarea); + scrarea_queue_winredraw(curarea); + break; + case B_MATCOPY: + if(G.buts->lockpoin) { + + if(matcopied) free_matcopybuf(); + + memcpy(&matcopybuf, G.buts->lockpoin, sizeof(Material)); + for(a=0; a<8; a++) { + mtex= matcopybuf.mtex[a]; + if(mtex) { + matcopybuf.mtex[a]= MEM_dupallocN(mtex); + } + } + matcopied= 1; + } + break; + case B_MATPASTE: + if(matcopied && G.buts->lockpoin) { + ma= G.buts->lockpoin; + /* vrijgeven huidige mat */ + for(a=0; a<8; a++) { + mtex= ma->mtex[a]; + if(mtex && mtex->tex) mtex->tex->id.us--; + if(mtex) MEM_freeN(mtex); + } + + id= (ma->id); + memcpy(G.buts->lockpoin, &matcopybuf, sizeof(Material)); + (ma->id)= id; + + for(a=0; a<8; a++) { + mtex= ma->mtex[a]; + if(mtex) { + ma->mtex[a]= MEM_dupallocN(mtex); + if(mtex->tex) id_us_plus((ID *)mtex->tex); + } + } + BIF_preview_changed(G.buts); + scrarea_queue_winredraw(curarea); + } + break; + case B_MESHTYPE: + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); + break; + } +} + +void buttons_active_id(ID **id, ID **idfrom) +{ + Object *ob= OBACT; + Material *ma; + ID * search; + + *id= NULL; + *idfrom= (ID *)ob; + + if(G.buts->mainb==BUTS_LAMP) { + if(ob && ob->type==OB_LAMP) { + *id= ob->data; + } + } + else if(G.buts->mainb==BUTS_MAT) { + if(ob && (ob->type<OB_LAMP) && ob->type) { + *id= (ID *)give_current_material(ob, ob->actcol); + *idfrom= material_from(ob, ob->actcol); + } + } + else if(G.buts->mainb==BUTS_TEX) { + MTex *mtex; + + if(G.buts->mainbo != G.buts->mainb) { + if(G.buts->mainbo==BUTS_LAMP) G.buts->texfrom= 2; + else if(G.buts->mainbo==BUTS_WORLD) G.buts->texfrom= 1; + else if(G.buts->mainbo==BUTS_MAT) G.buts->texfrom= 0; + } + + if(G.buts->texfrom==0) { + if(ob && ob->type<OB_LAMP && ob->type) { + ma= give_current_material(ob, ob->actcol); + *idfrom= (ID *)ma; + if(ma) { + mtex= ma->mtex[ ma->texact ]; + if(mtex) *id= (ID *)mtex->tex; + } + } + } + else if(G.buts->texfrom==1) { + World *wrld= G.scene->world; + *idfrom= (ID *)wrld; + if(wrld) { + mtex= wrld->mtex[ wrld->texact]; + if(mtex) *id= (ID *)mtex->tex; + } + } + else if(G.buts->texfrom==2) { + Lamp *la; + if(ob && ob->type==OB_LAMP) { + la= ob->data; + *idfrom= (ID *)la; + mtex= la->mtex[ la->texact]; + if(mtex) *id= (ID *)mtex->tex; + } + } + } + else if ELEM3(G.buts->mainb, BUTS_ANIM, BUTS_GAME, BUTS_CONSTRAINT) { + if(ob) { + *idfrom= (ID *)G.scene; + *id= (ID *)ob; + } + } + else if(G.buts->mainb==BUTS_WORLD) { + *id= (ID *)G.scene->world; + *idfrom= (ID *)G.scene; + } + else if(G.buts->mainb==BUTS_RENDER) { + *id= (ID *)G.scene; + + } + else if(G.buts->mainb==BUTS_EDIT) { + if(ob && ob->data) { + *id= ob->data; + } + } + else if (G.buts->mainb == BUTS_SOUND) { + // printf("lockp: %d\n", G.buts->lockpoin); + + if (G.buts->lockpoin) { + search = G.main->sound.first; + while (search) { + if (search == G.buts->lockpoin) { + break; + } + search = search->next; + } + if (search == NULL) { + *id = G.main->sound.first; + } else { + *id = search; + } + } else { + *id = G.main->sound.first; + } + // printf("id: %d\n\n", *id); + } +} + +static void validate_bonebutton(void *bonev, void *data2_unused){ + Bone *bone= bonev; + bArmature *arm; + + arm = get_armature(G.obpose); + unique_bone_name(bone, arm); +} + + +static int bonename_exists(Bone *orig, char *name, ListBase *list) +{ + Bone *curbone; + + for (curbone=list->first; curbone; curbone=curbone->next){ + /* Check this bone */ + if (orig!=curbone){ + if (!strcmp(curbone->name, name)) + return 1; + } + + /* Check Children */ + if (bonename_exists(orig, name, &curbone->childbase)) + return 1; + } + + return 0; + +} + +static void unique_bone_name (Bone *bone, bArmature *arm) +{ + char tempname[64]; + char oldname[64]; + int number; + char *dot; + + if (!arm) + return; + + strcpy(oldname, bone->name); + + /* See if we even need to do this */ + if (!bonename_exists(bone, bone->name, &arm->bonebase)) + return; + + /* Strip off the suffix */ + dot=strchr(bone->name, '.'); + if (dot) + *dot=0; + + for (number = 1; number <=999; number++){ + sprintf (tempname, "%s.%03d", bone->name, number); + + if (!bonename_exists(bone, tempname, &arm->bonebase)){ + strcpy (bone->name, tempname); + return; + } + } +} + +void buts_buttons(void) +{ + ID *id, *idfrom; + Object *ob; + uiBlock *block; + uiBut *but; + short xco; + int alone, local, browse; + char naam[20]; + short type; + void *data=NULL; + char str[256]; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTGREY); + + curarea->butspacetype= SPACE_BUTS; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type "); + + /* FULL WINDOW */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Restore smaller windows (CTRL+Up arrow)"); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Make fullscreen window (CTRL+Down arrow)"); + + /* HOME */ + uiDefIconBut(block, BUT, B_BUTSHOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Home (HOMEKEY)"); + + /* keuzemenu */ + xco+= 2*XIC; + uiDefIconButS(block, ROW, B_REDR, ICON_EYE, xco+=XIC, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_VIEW, 0, 0, "View buttons"); + uiDefIconButS(block, ROW, B_BUTSPREVIEW, ICON_LAMP, xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_LAMP, 0, 0, "Lamp buttons (F4)"); + uiDefIconButS(block, ROW, B_BUTSPREVIEW, ICON_MATERIAL, xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_MAT, 0, 0, "Material buttons (F5)"); + uiDefIconButS(block, ROW, B_BUTSPREVIEW, ICON_TEXTURE, xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_TEX, 0, 0, "Texture buttons (F6)"); + uiDefIconButS(block, ROW, B_REDR, ICON_ANIM, xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_ANIM, 0, 0, "Animation buttons (F7)"); + uiDefIconButS(block, ROW, B_REDR, ICON_GAME, xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_GAME, 0, 0, "Realtime buttons (F8)"); + uiDefIconButS(block, ROW, B_REDR, ICON_EDIT, xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_EDIT, 0, 0, "Edit buttons (F9)"); + uiDefIconButS(block, ROW, B_REDR, ICON_CONSTRAINT,xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_CONSTRAINT, 0, 0, "Constraint buttons"); + uiDefIconButS(block, ROW, B_REDR, ICON_SPEAKER,xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_SOUND, 0, 0, "Sound buttons"); + uiDefIconButS(block, ROW, B_BUTSPREVIEW, ICON_WORLD, xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_WORLD, 0, 0, "World buttons"); + uiDefIconButS(block, ROW, B_REDR, ICON_PAINT,xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_FPAINT, 0, 0, "Paint buttons"); + uiDefIconButS(block, ROW, B_REDR, ICON_RADIO,xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_RADIO, 0, 0, "Radiosity buttons"); + uiDefIconButS(block, ROW, B_REDR, ICON_SCRIPT,xco+=30, 0, 30, YIC, &(G.buts->mainb), 1.0, (float)BUTS_SCRIPT, 0, 0, "Script buttons"); + uiDefIconButS(block, ROW, B_REDR, ICON_SCENE, xco+=30, 0, 50, YIC, &(G.buts->mainb), 1.0, (float)BUTS_RENDER, 0, 0, "Display buttons (F10)"); + xco+= 80; + + ob= OBACT; + + buttons_active_id(&id, &idfrom); + + G.buts->lockpoin= id; + + if(G.buts->mainb==BUTS_LAMP) { + if(id) { + xco= std_libbuttons(block, xco, 0, NULL, B_LAMPBROWSE, id, (ID *)ob, &(G.buts->menunr), B_LAMPALONE, B_LAMPLOCAL, 0, 0); + } + } + else if(G.buts->mainb==BUTS_MAT) { + if(ob && (ob->type<OB_LAMP) && ob->type) { + xco= std_libbuttons(block, xco, 0, NULL, B_MATBROWSE, id, idfrom, &(G.buts->menunr), B_MATALONE, B_MATLOCAL, B_MATDELETE, B_AUTOMATNAME); + } + + /* COPY PASTE */ + if(curarea->headertype==HEADERTOP) { + uiDefIconBut(block, BUT, B_MATCOPY, ICON_COPYUP, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Copy Material to the buffer"); + uiSetButLock(id && id->lib, "Can't edit library data"); + uiDefIconBut(block, BUT, B_MATPASTE, ICON_PASTEUP, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Paste Material from the buffer"); + } + else { + uiDefIconBut(block, BUT, B_MATCOPY, ICON_COPYDOWN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Copy Material to the buffer"); + uiSetButLock(id && id->lib, "Can't edit library data"); + uiDefIconBut(block, BUT, B_MATPASTE, ICON_PASTEDOWN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Paste Material from the buffer"); + } + xco+=XIC; + + } + else if(G.buts->mainb==BUTS_TEX) { + if(G.buts->texfrom==0) { + if(idfrom) { + xco= std_libbuttons(block, xco, 0, NULL, B_TEXBROWSE, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME); + } + } + else if(G.buts->texfrom==1) { + if(idfrom) { + xco= std_libbuttons(block, xco, 0, NULL, B_WTEXBROWSE, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME); + } + } + else if(G.buts->texfrom==2) { + if(idfrom) { + xco= std_libbuttons(block, xco, 0, NULL, B_LTEXBROWSE, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME); + } + } + } + else if(G.buts->mainb==BUTS_ANIM) { + if(id) { + xco= std_libbuttons(block, xco, 0, NULL, 0, id, idfrom, &(G.buts->menunr), B_OBALONE, B_OBLOCAL, 0, 0); + + if(G.scene->group) { + Group *group= G.scene->group; + but= uiDefBut(block, TEX, B_IDNAME, "GR:", xco, 0, 135, YIC, group->id.name+2, 0.0, 19.0, 0, 0, "Active Group name"); + uiButSetFunc(but, test_idbutton_cb, group->id.name, NULL); + xco+= 135; + } + } + } + else if(G.buts->mainb==BUTS_GAME) { + if(id) { + xco= std_libbuttons(block, xco, 0, NULL, 0, id, idfrom, &(G.buts->menunr), B_OBALONE, B_OBLOCAL, 0, 0); + } + } + else if(G.buts->mainb==BUTS_WORLD) { + xco= std_libbuttons(block, xco, 0, NULL, B_WORLDBROWSE, id, idfrom, &(G.buts->menunr), B_WORLDALONE, B_WORLDLOCAL, B_WORLDDELETE, 0); + } + else if (G.buts->mainb==BUTS_SOUND) { + xco= std_libbuttons(block, xco, 0, NULL, B_SOUNDBROWSE2, id, idfrom, &(G.buts->texnr), 1, 0, 0, 0); + } + + else if(G.buts->mainb==BUTS_RENDER) { + xco= std_libbuttons(block, xco, 0, NULL, B_INFOSCE, (ID *)G.scene, 0, &(G.curscreen->scenenr), 1, 1, B_INFODELSCE, 0); + } + else if(G.buts->mainb==BUTS_EDIT) { + if(id) { + + alone= 0; + local= 0; + browse= B_EDITBROWSE; + xco+= 10; + + if(ob->type==OB_MESH) { + browse= B_MESHBROWSE; + alone= B_MESHALONE; + local= B_MESHLOCAL; + uiSetButLock(G.obedit!=0, "Unable to perform function in EditMode"); + } + else if(ob->type==OB_MBALL) { + alone= B_MBALLALONE; + local= B_MBALLLOCAL; + } + else if ELEM3(ob->type, OB_CURVE, OB_FONT, OB_SURF) { + alone= B_CURVEALONE; + local= B_CURVELOCAL; + } + else if(ob->type==OB_CAMERA) { + alone= B_CAMERAALONE; + local= B_CAMERALOCAL; + } + else if(ob->type==OB_LAMP) { + alone= B_LAMPALONE; + local= B_LAMPLOCAL; + } + else if (ob->type==OB_ARMATURE){ + alone = B_ARMALONE; + local = B_ARMLOCAL; + } + else if(ob->type==OB_LATTICE) { + alone= B_LATTALONE; + local= B_LATTLOCAL; + } + + xco= std_libbuttons(block, xco, 0, NULL, browse, id, idfrom, &(G.buts->menunr), alone, local, 0, 0); + + xco+= XIC; + } + if(ob) { + but= uiDefBut(block, TEX, B_IDNAME, "OB:", xco, 0, 135, YIC, ob->id.name+2, 0.0, 19.0, 0, 0, "Active Object name"); + uiButSetFunc(but, test_idbutton_cb, ob->id.name, NULL); + xco+= 135; + } + } + else if(G.buts->mainb==BUTS_CONSTRAINT){ + if(id) { + + + xco= std_libbuttons(block, xco, 0, NULL, 0, id, idfrom, &(G.buts->menunr), B_OBALONE, B_OBLOCAL, 0, 0); + + get_constraint_client(NULL, &type, &data); + if (data && type==TARGET_BONE){ + sprintf(str, "BO:%s", ((Bone*)data)->name); +#if 0 + /* XXXXX, not idname... but check redrawing */ + but= uiDefBut(block, TEX, 1, "BO:", xco, 0, 135, YIC, ((Bone*)data)->name, 0.0, 19.0, 0, 0, "Active Bone name"); + uiButSetFunc(but, validate_bonebutton, data, NULL); +#else + but= uiDefBut(block, LABEL, 1, str, xco, 0, 135, YIC, ((Bone*)data)->name, 0.0, 19.0, 0, 0, "Active Bone name"); +#endif + xco+= 135; + } + } + } + else if(G.buts->mainb==BUTS_SCRIPT) { + if(ob) + uiDefIconButS(block, ROW, B_REDR, ICON_OBJECT, xco,0,XIC,YIC, &G.buts->scriptblock, 2.0, (float)ID_OB, 0, 0, "Display Object script links"); + + if(ob && give_current_material(ob, ob->actcol)) + uiDefIconButS(block, ROW, B_REDR, ICON_MATERIAL, xco+=XIC,0,XIC,YIC, &G.buts->scriptblock, 2.0, (float)ID_MA, 0, 0, "Display Material script links "); + + if(G.scene->world) + uiDefIconButS(block, ROW, B_REDR, ICON_WORLD, xco+=XIC,0,XIC,YIC, &G.buts->scriptblock, 2.0, (float)ID_WO, 0, 0, "Display World script links"); + + if(ob && ob->type==OB_CAMERA) + uiDefIconButS(block, ROW, B_REDR, ICON_CAMERA, xco+=XIC,0,XIC,YIC, &G.buts->scriptblock, 2.0, (float)ID_CA, 0, 0, "Display Camera script links"); + + if(ob && ob->type==OB_LAMP) + uiDefIconButS(block, ROW, B_REDR, ICON_LAMP, xco+=XIC,0,XIC,YIC, &G.buts->scriptblock, 2.0, (float)ID_LA, 0, 0, "Display Lamp script links"); + + xco+= 20; + } + + uiDefButS(block, NUM, B_NEWFRAME, "", (short)(xco+20),0,60,YIC, &(G.scene->r.cfra), 1.0, 18000.0, 0, 0, "Current Frame"); + xco+= 80; + + G.buts->mainbo= G.buts->mainb; + + /* altijd als laatste doen */ + uiDrawBlock(block); + curarea->headbutlen= xco; +} + +/* ********************** BUTS ****************************** */ +/* ******************** FILE ********************** */ + +void do_file_buttons(short event) +{ + SpaceFile *sfile; + + if(curarea->win==0) return; + sfile= curarea->spacedata.first; + + switch(event) { + case B_SORTFILELIST: + sort_filelist(sfile); + scrarea_queue_winredraw(curarea); + break; + case B_RELOADDIR: + freefilelist(sfile); + scrarea_queue_winredraw(curarea); + break; + } + +} + +void file_buttons(void) +{ + SpaceFile *sfile; + uiBlock *block; + float df, totlen, sellen; + short xco; + int totfile, selfile; + char naam[256]; + + sfile= curarea->spacedata.first; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTGREY); + + curarea->butspacetype= SPACE_FILE; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type"); + + /* FULL WINDOW */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Restore smaller windows (CTRL+Up arrow)"); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Make fullscreen window (CTRL+Down arrow)"); + + /* SORT TYPE */ + xco+=XIC; + uiDefIconButS(block, ROW, B_SORTFILELIST, ICON_SORTALPHA, xco+=XIC,0,XIC,YIC, &sfile->sort, 1.0, 0.0, 0, 0, "Sort files alphabetically"); + uiDefIconButS(block, ROW, B_SORTFILELIST, ICON_SORTTIME, xco+=XIC,0,XIC,YIC, &sfile->sort, 1.0, 1.0, 0, 0, "Sort files by time"); + uiDefIconButS(block, ROW, B_SORTFILELIST, ICON_SORTSIZE, xco+=XIC,0,XIC,YIC, &sfile->sort, 1.0, 2.0, 0, 0, "Sort files by size"); + + cpack(0x0); + glRasterPos2i(xco+=XIC+10, 5); + BMF_DrawString(uiBlockGetCurFont(block), sfile->title); + + xco+= BMF_GetStringWidth(G.font, sfile->title); + + uiDefIconButS(block, ICONTOG|BIT|0, B_SORTFILELIST, ICON_LONGDISPLAY,xco+=XIC,0,XIC,YIC, &sfile->flag, 0, 0, 0, 0, "Toggle long info"); + uiDefIconButS(block, TOG|BIT|3, B_RELOADDIR, ICON_GHOST,xco+=XIC,0,XIC,YIC, &sfile->flag, 0, 0, 0, 0, "Hide dot files"); + + xco+=XIC+10; + + if(sfile->type==FILE_LOADLIB) { + uiDefButS(block, TOGN|BIT|2, B_REDR, "Append", xco+=XIC,0,100,YIC, &sfile->flag, 0, 0, 0, 0, "Causes selected data to be copied into current file"); + uiDefButS(block, TOG|BIT|2, B_REDR, "Link", xco+=100,0,100,YIC, &sfile->flag, 0, 0, 0, 0, "Causes selected data to be linked by current file"); + } + + if(sfile->type==FILE_UNIX) { + df= BLI_diskfree(sfile->dir)/(1048576.0); + + filesel_statistics(sfile, &totfile, &selfile, &totlen, &sellen); + + sprintf(naam, "Free: %.3f Mb Files: (%d) %d (%.3f) %.3f Mb", + df, selfile,totfile, sellen, totlen); + + cpack(0x0); + glRasterPos2i(xco, 5); + BMF_DrawString(uiBlockGetCurFont(block), naam); + } + /* altijd als laatste doen */ + curarea->headbutlen= xco+2*XIC; + + uiDrawBlock(block); +} + + +/* ********************** FILE ****************************** */ +/* ******************** OOPS ********************** */ + +void do_oops_buttons(short event) +{ + float dx, dy; + + if(curarea->win==0) return; + + switch(event) { + case B_OOPSHOME: + boundbox_oops(); + G.v2d->cur= G.v2d->tot; + dx= 0.15*(G.v2d->cur.xmax-G.v2d->cur.xmin); + dy= 0.15*(G.v2d->cur.ymax-G.v2d->cur.ymin); + G.v2d->cur.xmin-= dx; + G.v2d->cur.xmax+= dx; + G.v2d->cur.ymin-= dy; + G.v2d->cur.ymax+= dy; + test_view2d(G.v2d, curarea->winx, curarea->winy); + scrarea_queue_winredraw(curarea); + break; + + case B_NEWOOPS: + scrarea_queue_winredraw(curarea); + scrarea_queue_headredraw(curarea); + G.soops->lockpoin= 0; + break; + } + +} + +void oops_buttons(void) +{ + SpaceOops *soops; + Oops *oops; + uiBlock *block; + short xco; + char naam[256]; + + soops= curarea->spacedata.first; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTGREEN); + + curarea->butspacetype= SPACE_OOPS; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type"); + + /* FULL WINDOW */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Restore smaller windows (CTRL+Up arrow)"); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, (short)(xco+=XIC),0,XIC,YIC, 0, 0, 0, 0, 0, "Make fullscreen window (CTRL+Down arrow)"); + + /* HOME */ + uiDefIconBut(block, BUT, B_OOPSHOME, ICON_HOME, (short)(xco+=XIC),0,XIC,YIC, 0, 0, 0, 0, 0, "Home (HOMEKEY)"); + xco+= XIC; + + /* ZOOM en BORDER */ + xco+= XIC; + uiDefIconButI(block, TOG, B_VIEW2DZOOM, ICON_VIEWZOOM, (short)(xco+=XIC),0,XIC,YIC, &viewmovetemp, 0, 0, 0, 0, "Zoom view (CTRL+MiddleMouse)"); + uiDefIconBut(block, BUT, B_OOPSBORDER, ICON_BORDERMOVE, (short)(xco+=XIC),0,XIC,YIC, 0, 0, 0, 0, 0, "Translate view (MiddleMouse)"); + + /* VISIBLE */ + xco+= XIC; + uiDefButS(block, TOG|BIT|10,B_NEWOOPS, "lay", (short)(xco+=XIC),0,XIC+10,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Objects based on layer"); + uiDefIconButS(block, TOG|BIT|0, B_NEWOOPS, ICON_SCENE_HLT, (short)(xco+=XIC+10),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Scene data"); + uiDefIconButS(block, TOG|BIT|1, B_NEWOOPS, ICON_OBJECT_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Object data"); + uiDefIconButS(block, TOG|BIT|2, B_NEWOOPS, ICON_MESH_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Mesh data"); + uiDefIconButS(block, TOG|BIT|3, B_NEWOOPS, ICON_CURVE_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Curve/Surface/Font data"); + uiDefIconButS(block, TOG|BIT|4, B_NEWOOPS, ICON_MBALL_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Metaball data"); + uiDefIconButS(block, TOG|BIT|5, B_NEWOOPS, ICON_LATTICE_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Lattice data"); + uiDefIconButS(block, TOG|BIT|6, B_NEWOOPS, ICON_LAMP_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Lamp data"); + uiDefIconButS(block, TOG|BIT|7, B_NEWOOPS, ICON_MATERIAL_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Material data"); + uiDefIconButS(block, TOG|BIT|8, B_NEWOOPS, ICON_TEXTURE_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Texture data"); + uiDefIconButS(block, TOG|BIT|9, B_NEWOOPS, ICON_IPO_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Ipo data"); + uiDefIconButS(block, TOG|BIT|12, B_NEWOOPS, ICON_IMAGE_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Image data"); + uiDefIconButS(block, TOG|BIT|11, B_NEWOOPS, ICON_LIBRARY_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Display Library data"); + + /* naam */ + if(G.soops->lockpoin) { + oops= G.soops->lockpoin; + if(oops->type==ID_LI) strcpy(naam, ((Library *)oops->id)->name); + else strcpy(naam, oops->id->name); + + cpack(0x0); + glRasterPos2i(xco+=XIC+10, 5); + BMF_DrawString(uiBlockGetCurFont(block), naam); + + } + + /* altijd als laatste doen */ + curarea->headbutlen= xco+2*XIC; + + uiDrawBlock(block); +} + + +/* ********************** OOPS ****************************** */ +/* ********************** TEXT ****************************** */ + +void do_text_buttons(unsigned short event) +{ + SpaceText *st= curarea->spacedata.first; + ID *id, *idtest; + int nr= 1; + Text *text; + + if (!st) return; + if (st->spacetype != SPACE_TEXT) return; + + switch (event) { + case B_TEXTBROWSE: + if (st->menunr==-2) { + activate_databrowse((ID *)st->text, ID_TXT, 0, B_TEXTBROWSE, &st->menunr, do_text_buttons); + break; + } + if(st->menunr < 0) break; + + text= st->text; + + nr= 1; + id= (ID *)text; + + if (st->menunr==32767) { + st->text= (Text *)add_empty_text(); + + st->top= 0; + + allqueue(REDRAWTEXT, 0); + allqueue(REDRAWHEADERS, 0); + } + else if (st->menunr==32766) { + activate_fileselect(FILE_SPECIAL, "LOAD TEXT FILE", G.sce, add_text_fs); + return; + } + else { + idtest= G.main->text.first; + while(idtest) { + if(nr==st->menunr) { + break; + } + nr++; + idtest= idtest->next; + } + if(idtest==0) { /* new text */ + activate_fileselect(FILE_SPECIAL, "LOAD TEXT FILE", G.sce, add_text_fs); + return; + } + if(idtest!=id) { + st->text= (Text *)idtest; + st->top= 0; + + pop_space_text(st); + + allqueue(REDRAWTEXT, 0); + allqueue(REDRAWHEADERS, 0); + } + } + break; + + case B_TEXTDELETE: + if(!okee("Really delete text?")) return; + + text= st->text; + if (!text) return; + + BPY_clear_bad_scriptlinks(text); + free_text_controllers(text); + + unlink_text(text); + free_libblock(&G.main->text, text); + + break; + +/* + case B_TEXTSTORE: + st->text->flags ^= TXT_ISEXT; + + allqueue(REDRAWHEADERS, 0); + break; +*/ + case B_TEXTFONT: + switch(st->font_id) { + case 0: + st->lheight= 12; break; + case 1: + st->lheight= 15; break; + } + + allqueue(REDRAWTEXT, 0); + allqueue(REDRAWHEADERS, 0); + + break; + } +} + +void text_buttons(void) +{ + uiBlock *block; + SpaceText *st= curarea->spacedata.first; + short xco; + char naam[256]; + + if (!st || st->spacetype != SPACE_TEXT) return; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTGREY); + + curarea->butspacetype= SPACE_TEXT; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type"); + + /* FULL WINDOW */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Restore smaller windows (CTRL+Up arrow)"); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Make fullscreen window (CTRL+Down arrow)"); + + + /* STD TEXT BUTTONS */ + if (!BPY_spacetext_is_pywin(st)) { + xco+= 2*XIC; + xco= std_libbuttons(block, xco, 0, NULL, B_TEXTBROWSE, (ID*)st->text, 0, &(st->menunr), 0, 0, B_TEXTDELETE, 0); + + /* + if (st->text) { + if (st->text->flags & TXT_ISDIRTY && (st->text->flags & TXT_ISEXT || !(st->text->flags & TXT_ISMEM))) + uiDefIconBut(block, BUT,0, ICON_ERROR, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "The text has been changed"); + if (st->text->flags & TXT_ISEXT) + uiDefBut(block, BUT,B_TEXTSTORE, ICON(), xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Store text in .blend file"); + else + uiDefBut(block, BUT,B_TEXTSTORE, ICON(), xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Don't store text in .blend file"); + xco+=10; + } + */ + + xco+=XIC; + if(st->font_id>1) st->font_id= 0; + uiDefButI(block, MENU, B_TEXTFONT, "Screen 12 %x0|Screen 15%x1", xco,0,100,YIC, &st->font_id, 0, 0, 0, 0, "Font display menu"); + xco+=100; + } + + /* always as last */ + curarea->headbutlen= xco+2*XIC; + + uiDrawBlock(block); +} + + + +/* ******************** TEXT ********************** */ +/* ******************** SOUND ********************** */ + +void load_space_sound(char *str) /* called from fileselect */ +{ + bSound *sound; + + sound= sound_new_sound(str); + if (sound) { + if (G.ssound) { + G.ssound->sound= sound; + } + } else { + error("Not a valid sample: %s", str); + } + + allqueue(REDRAWSOUND, 0); + allqueue(REDRAWBUTSGAME, 0); +} + + +void load_sound_buttons(char *str) /* called from fileselect */ +{ + bSound *sound; + + sound= sound_new_sound(str); + if (sound) { + if (curarea && curarea->spacetype==SPACE_BUTS) { + if (G.buts->mainb == BUTS_SOUND) { + G.buts->lockpoin = sound; + } + } + } else { + error("Not a valid sample: %s", str); + } + + allqueue(REDRAWBUTSSOUND, 0); +} + +void do_action_buttons(unsigned short event) +{ + View2D *v2d; + + switch(event){ +#ifdef __NLA_BAKE + case B_ACTBAKE: + bake_action_with_client (G.saction->action, OBACT, 0.01); + break; +#endif + case B_ACTCONT: + set_exprap_action(IPO_HORIZ); + break; +// case B_ACTEXTRAP: +// set_exprap_ipo(IPO_DIR); +// break; + case B_ACTCYCLIC: + set_exprap_action(IPO_CYCL); + break; +// case B_ACTCYCLICX: +// set_exprap_ipo(IPO_CYCLX); +// break; + case B_ACTHOME: + // Find X extents + v2d= &(G.saction->v2d); + +// v2d->cur.xmin = 0; + v2d->cur.ymin=-SCROLLB; + + if (!G.saction->action){ + v2d->cur.xmax=100; + } + else + { + v2d->cur.xmin=calc_action_start(G.saction->action)-1; + v2d->cur.xmax=calc_action_end(G.saction->action)+1; + } + + +// G.v2d->cur= G.v2d->tot; + test_view2d(G.v2d, curarea->winx, curarea->winy); + addqueue (curarea->win, REDRAW, 1); + break; + case B_ACTCOPY: + copy_posebuf(); + allqueue(REDRAWVIEW3D, 1); + break; + case B_ACTPASTE: + paste_posebuf(0); + allqueue(REDRAWVIEW3D, 1); + break; + case B_ACTPASTEFLIP: + paste_posebuf(1); + allqueue(REDRAWVIEW3D, 1); + break; + + case B_ACTPIN: /* __PINFAKE */ +/* if (G.saction->flag & SACTION_PIN){ + if (G.saction->action) + G.saction->action->id.us ++; + + } + else { + if (G.saction->action) + G.saction->action->id.us --; + } +*/ /* end PINFAKE */ + allqueue(REDRAWACTION, 1); + break; + + } +} + +void do_sound_buttons(unsigned short event) +{ + ID *id, *idtest; + int nr; + char name[256]; + + switch(event) { + + case B_SOUNDBROWSE: + if(G.ssound->sndnr== -2) { + activate_databrowse((ID *)G.ssound->sound, ID_SO, 0, B_SOUNDBROWSE, &G.ssound->sndnr, do_sound_buttons); + return; + } + if (G.ssound->sndnr < 0) break; + if (G.ssound->sndnr == 32766) { + if (G.ssound && G.ssound->sound) strcpy(name, G.ssound->sound->name); + else strcpy(name, U.sounddir); + activate_fileselect(FILE_SPECIAL, "SELECT WAV FILE", name, load_space_sound); + } else { + nr= 1; + id= (ID *)G.ssound->sound; + + idtest= G.main->sound.first; + while(idtest) { + if(nr==G.ssound->sndnr) { + break; + } + nr++; + idtest= idtest->next; + } + + if(idtest==0) { /* geen new */ + return; + } + + if(idtest!=id) { + G.ssound->sound= (bSound *)idtest; + if(idtest->us==0) idtest->us= 1; + allqueue(REDRAWSOUND, 0); + } + } + + break; + case B_SOUNDBROWSE2: + id = (ID *)G.buts->lockpoin; + if(G.buts->texnr == -2) { + activate_databrowse(id, ID_SO, 0, B_SOUNDBROWSE2, &G.buts->texnr, do_sound_buttons); + return; + } + if (G.buts->texnr < 0) break; + if (G.buts->texnr == 32766) { + if (id) strcpy(name, ((bSound *)id)->name); + else strcpy(name, U.sounddir); + activate_fileselect(FILE_SPECIAL, "SELECT WAV FILE", name, load_sound_buttons); + } else { + nr= 1; + + idtest= G.main->sound.first; + while (idtest) { + if(nr == G.buts->texnr) { + break; + } + nr++; + idtest = idtest->next; + } + + if (idtest == 0) { /* geen new */ + return; + } + + if (idtest != id) { + G.buts->lockpoin = (bSound *)idtest; + if(idtest->us==0) idtest->us= 1; + allqueue(REDRAWBUTSSOUND, 0); + BIF_preview_changed(G.buts); + } + } + + break; + case B_SOUNDHOME: + + G.v2d->cur= G.v2d->tot; + test_view2d(G.v2d, curarea->winx, curarea->winy); + scrarea_queue_winredraw(curarea); + break; + } +} + +void sound_buttons(void) +{ + uiBlock *block; + short xco; + char naam[256]; + char ch[20]; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTYELLOW); + + curarea->butspacetype= SPACE_SOUND; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type"); + + /* FULL WINDOW */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Restore smaller windows (CTRL+Up arrow)"); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Make fullscreen window (CTRL+Down arrow)"); + uiDefIconBut(block, BUT, B_SOUNDHOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Home (HOMEKEY)"); + + xco= std_libbuttons(block, xco+40, 0, NULL, B_SOUNDBROWSE, (ID *)G.ssound->sound, 0, &(G.ssound->sndnr), 1, 0, 0, 0); + + if(G.ssound->sound) { + bSound *sound= G.ssound->sound; + + if (sound->sample && sound->sample->len) + { + if (sound->sample->channels == 1) + strcpy(ch, "Mono"); + else if (sound->sample->channels == 2) + strcpy(ch, "Stereo"); + else + strcpy(ch, "Unknown"); + + sprintf(naam, "Sample: %s, %d bit, %d Hz, %d samples", ch, sound->sample->bits, sound->sample->rate, sound->sample->len); + cpack(0x0); + glRasterPos2i(xco+10, 5); + BMF_DrawString(uiBlockGetCurFont(block), naam); + } + else + { + sprintf(naam, "No sample info available."); + cpack(0x0); + glRasterPos2i(xco+10, 5); + BMF_DrawString(uiBlockGetCurFont(block), naam); + } + + } + + /* always as last */ + curarea->headbutlen= xco+2*XIC; + + uiDrawBlock(block); +} + + +/* ******************** SOUND ********************** */ +/* ******************** IMAGE ********************** */ + +void load_space_image(char *str) /* aangeroepen vanuit fileselect */ +{ + Image *ima=0; + + if(G.obedit) { + error("Can't perfom this in editmode"); + return; + } + + ima= add_image(str); + if(ima) { + + G.sima->image= ima; + + free_image_buffers(ima); /* forceer opnieuw inlezen */ + ima->ok= 1; + image_changed(G.sima, 0); + + } + + allqueue(REDRAWIMAGE, 0); +} + +void image_replace(Image *old, Image *new) +{ + TFace *tface; + Mesh *me; + int a, rep=0; + + new->tpageflag= old->tpageflag; + new->twsta= old->twsta; + new->twend= old->twend; + new->xrep= old->xrep; + new->yrep= old->yrep; + + me= G.main->mesh.first; + while(me) { + + if(me->tface) { + tface= me->tface; + a= me->totface; + while(a--) { + if(tface->tpage==old) { + tface->tpage= new; + rep++; + } + tface++; + } + } + me= me->id.next; + + } + if(rep) { + if(new->id.us==0) new->id.us= 1; + } + else error("Nothing replaced"); +} + +void replace_space_image(char *str) /* aangeroepen vanuit fileselect */ +{ + Image *ima=0; + + if(G.obedit) { + error("Can't perfom this in editmode"); + return; + } + + ima= add_image(str); + if(ima) { + + if(G.sima->image != ima) { + image_replace(G.sima->image, ima); + } + + G.sima->image= ima; + + free_image_buffers(ima); /* forceer opnieuw inlezen */ + ima->ok= 1; + /* replace kent ook toe: */ + image_changed(G.sima, 0); + + } + allqueue(REDRAWIMAGE, 0); +} + +void save_paint(char *name) +{ + char str[FILE_MAXDIR+FILE_MAXFILE]; + Image *ima = G.sima->image; + ImBuf *ibuf; + + if (ima && ima->ibuf) { + BLI_strncpy(str, name, sizeof(str)); + + BLI_convertstringcode(str, G.sce, G.scene->r.cfra); + + if (saveover(str)) { + ibuf = IMB_dupImBuf(ima->ibuf); + + if (ibuf) { + if (BIF_write_ibuf(ibuf, str)) { + BLI_strncpy(ima->name, name, sizeof(ima->name)); + ima->ibuf->userflags &= ~IB_BITMAPDIRTY; + allqueue(REDRAWHEADERS, 0); + allqueue(REDRAWBUTSTEX, 0); + } else { + error("Couldn't write image: %s", str); + } + + IMB_freeImBuf(ibuf); + } + } + } +} + + +void do_image_buttons(unsigned short event) +{ + Image *ima; + ID *id, *idtest; + int nr; + char name[256], str[256]; + + if(curarea->win==0) return; + + switch(event) { + case B_SIMAGEHOME: + image_home(); + break; + + case B_SIMABROWSE: + if(G.sima->imanr== -2) { + activate_databrowse((ID *)G.sima->image, ID_IM, 0, B_SIMABROWSE, &G.sima->imanr, do_image_buttons); + return; + } + if(G.sima->imanr < 0) break; + + nr= 1; + id= (ID *)G.sima->image; + + idtest= G.main->image.first; + while(idtest) { + if(nr==G.sima->imanr) { + break; + } + nr++; + idtest= idtest->next; + } + if(idtest==0) { /* geen new */ + return; + } + + if(idtest!=id) { + G.sima->image= (Image *)idtest; + if(idtest->us==0) idtest->us= 1; + allqueue(REDRAWIMAGE, 0); + } + image_changed(G.sima, 0); /* ook als image gelijk is: assign! 0==geen tileflag */ + + break; + case B_SIMAGELOAD: + case B_SIMAGELOAD1: + + if(G.sima->image) strcpy(name, G.sima->image->name); + else strcpy(name, U.textudir); + + if(event==B_SIMAGELOAD) + activate_imageselect(FILE_SPECIAL, "SELECT IMAGE", name, load_space_image); + else + activate_fileselect(FILE_SPECIAL, "SELECT IMAGE", name, load_space_image); + break; + case B_SIMAGEREPLACE: + case B_SIMAGEREPLACE1: + + if(G.sima->image) strcpy(name, G.sima->image->name); + else strcpy(name, U.textudir); + + if(event==B_SIMAGEREPLACE) + activate_imageselect(FILE_SPECIAL, "REPLACE IMAGE", name, replace_space_image); + else + activate_fileselect(FILE_SPECIAL, "REPLACE IMAGE", name, replace_space_image); + break; + case B_SIMAGEDRAW: + + if(G.f & G_FACESELECT) { + make_repbind(G.sima->image); + image_changed(G.sima, 1); + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + break; + + case B_SIMAGEDRAW1: + image_changed(G.sima, 2); /* 2: alleen tileflag */ + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + break; + + case B_TWINANIM: + ima = G.sima->image; + if (ima) { + if(ima->flag & IMA_TWINANIM) { + nr= ima->xrep*ima->yrep; + if(ima->twsta>=nr) ima->twsta= 1; + if(ima->twend>=nr) ima->twend= nr-1; + if(ima->twsta>ima->twend) ima->twsta= 1; + allqueue(REDRAWIMAGE, 0); + } + } + break; + + case B_CLIP_UV: + tface_do_clip(); + allqueue(REDRAWIMAGE, 0); + allqueue(REDRAWVIEW3D, 0); + break; + + case B_SIMAGEPAINTTOOL: + // check for packed file here + allqueue(REDRAWIMAGE, 0); + allqueue(REDRAWVIEW3D, 0); + break; + case B_SIMAPACKIMA: + ima = G.sima->image; + if (ima) { + if (ima->packedfile) { + if (G.fileflags & G_AUTOPACK) { + if (okee("Disable AutoPack ?")) { + G.fileflags &= ~G_AUTOPACK; + } + } + + if ((G.fileflags & G_AUTOPACK) == 0) { + unpackImage(ima, PF_ASK); + } + } else { + if (ima->ibuf && (ima->ibuf->userflags & IB_BITMAPDIRTY)) { + error("Can't pack painted image. Save image first."); + } else { + ima->packedfile = newPackedFile(ima->name); + } + } + allqueue(REDRAWBUTSTEX, 0); + allqueue(REDRAWHEADERS, 0); + } + break; + case B_SIMAGESAVE: + ima = G.sima->image; + if (ima) { + strcpy(name, ima->name); + if (ima->ibuf) { + save_image_filesel_str(str); + activate_fileselect(FILE_SPECIAL, str, name, save_paint); + } + } + break; + } +} + +/* This should not be a stack var! */ +static int headerbuttons_packdummy; +void image_buttons(void) +{ + uiBlock *block; + short xco; + char naam[256]; + headerbuttons_packdummy = 0; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTBLUE); + + what_image(G.sima); + + curarea->butspacetype= SPACE_IMAGE; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type "); + + /* FULL WINDOW */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Restore smaller windows (CTRL+Up arrow)"); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Make fullscreen window (CTRL+Down arrow)"); + + /* HOME*/ + uiDefIconBut(block, BUT, B_SIMAGEHOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Home (HOMEKEY)"); + uiDefIconButS(block, TOG|BIT|0, B_BE_SQUARE, ICON_KEEPRECT, xco+=XIC,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Keep UV polygons square while editing"); + uiDefIconButS(block, ICONTOG|BIT|2, B_CLIP_UV, ICON_CLIPUV_DEHLT,xco+=XIC,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Clip UV with image size"); + + xco= std_libbuttons(block, xco+40, 0, NULL, B_SIMABROWSE, (ID *)G.sima->image, 0, &(G.sima->imanr), 0, 0, B_IMAGEDELETE, 0); + + if (G.sima->image) { + if (G.sima->image->packedfile) { + headerbuttons_packdummy = 1; + } + uiDefIconButI(block, TOG|BIT|0, B_SIMAPACKIMA, ICON_PACKAGE, xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this Image"); + xco += XIC; + } + + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_SIMAGELOAD, "Load", xco+=XIC,0,2*XIC,YIC, 0, 0, 0, 0, 0, "Load image - thumbnail view"); + + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_SIMAGELOAD1, "", (short)(xco+=2*XIC+2),0,10,YIC, 0, 0, 0, 0, 0, "Load image - file select view"); + xco+=XIC/2; + + if (G.sima->image) { + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_SIMAGEREPLACE, "Replace",xco+=XIC,0,(short)(3*XIC),YIC, 0, 0, 0, 0, 0, "Replace current image - thumbnail view"); + + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, BUT, B_SIMAGEREPLACE1, "", (short)(xco+=3*XIC+2),0,10,YIC, 0, 0, 0, 0, 0, "Replace current image - file select view"); + xco+=XIC/2; + + uiDefIconButS(block, TOG|BIT|4, 0, ICON_ENVMAP, xco+=XIC,0,XIC,YIC, &G.sima->image->flag, 0, 0, 0, 0, "Use this image as a reflection map (UV coordinates are ignored)"); + xco+=XIC/2; + + uiDefIconButS(block, TOG|BIT|0, B_SIMAGEDRAW1, ICON_GRID, xco+=XIC,0,XIC,YIC, &G.sima->image->flag, 0, 0, 0, 0, ""); + uiDefButS(block, NUM, B_SIMAGEDRAW, "", xco+=XIC,0,XIC,YIC, &G.sima->image->xrep, 1.0, 16.0, 0, 0, ""); + uiDefButS(block, NUM, B_SIMAGEDRAW, "", xco+=XIC,0,XIC,YIC, &G.sima->image->yrep, 1.0, 16.0, 0, 0, ""); + + uiDefButS(block, TOG|BIT|1, B_TWINANIM, "Anim", xco+=XIC,0,(short)(2*XIC),YIC, &G.sima->image->tpageflag, 0, 0, 0, 0, ""); + uiDefButS(block, NUM, B_TWINANIM, "", (short)(xco+=2*XIC),0,XIC,YIC, &G.sima->image->twsta, 0.0, 128.0, 0, 0, ""); + uiDefButS(block, NUM, B_TWINANIM, "", xco+=XIC,0,XIC,YIC, &G.sima->image->twend, 0.0, 128.0, 0, 0, ""); +// uiDefButS(block, TOG|BIT|2, 0, "Cycle", xco+=XIC,0,2*XIC,YIC, &G.sima->image->tpageflag, 0, 0, 0, 0, ""); + uiDefButS(block, NUM, 0, "Speed", xco+=(2*XIC),0,4*XIC,YIC, &G.sima->image->animspeed, 1.0, 100.0, 0, 0, "Speed of the animation in frames per second"); + +#ifdef NAN_TPT + xco+= 4*XIC; + uiDefIconButS(block, ICONTOG|BIT|3, B_SIMAGEPAINTTOOL, ICON_TPAINT_DEHLT, xco+=XIC,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "TexturePaint Mode"); + if (G.sima->image && G.sima->image->ibuf && (G.sima->image->ibuf->userflags & IB_BITMAPDIRTY)) { + uiDefBut(block, BUT, B_SIMAGESAVE, "Save", xco+=XIC,0,2*XIC,YIC, 0, 0, 0, 0, 0, "Save image"); + xco += XIC; + } +#endif /* NAN_TPT */ + xco+= XIC; + } + + /* draw LOCK */ + xco+= XIC/2; + uiDefIconButS(block, ICONTOG, 0, ICON_UNLOCKED, (short)(xco+=XIC),0,XIC,YIC, &(G.sima->lock), 0, 0, 0, 0, "Lock redraw of other windows while editing"); + + + /* Always do this last */ + curarea->headbutlen= xco+2*XIC; + + uiDrawBlock(block); +} + + +/* ********************** IMAGE ****************************** */ +/* ******************** IMASEL ********************** */ + +void do_imasel_buttons(short event) +{ + SpaceImaSel *simasel; + char name[256]; + + simasel= curarea->spacedata.first; + + if(curarea->win==0) return; + + switch(event) { + case B_IMASELHOME: + break; + + case B_IMASELREMOVEBIP: + + if(bitset(simasel->fase, IMS_FOUND_BIP)){ + + strcpy(name, simasel->dir); + strcat(name, ".Bpib"); + + remove(name); + + simasel->fase &= ~ IMS_FOUND_BIP; + } + break; + } +} + +void imasel_buttons(void) +{ + SpaceImaSel *simasel; + uiBlock *block; + short xco; + char naam[256]; + + simasel= curarea->spacedata.first; + + sprintf(naam, "header %d", curarea->headwin); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->headwin); + uiBlockSetCol(block, BUTBLUE); + + curarea->butspacetype= SPACE_IMASEL; + uiDefIconButC(block, ICONROW,B_NEWSPACE, ICON_VIEW3D, 6,0,XIC,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current window type"); + + /* FULL WINDOW */ + xco= 25; + if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, ""); + else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, ""); + + xco+=XIC; + if (simasel->title){ + xco+=25; + glRasterPos2i(xco, 4); + BMF_DrawString(G.font, simasel->title); + xco+=BMF_GetStringWidth(G.fonts, simasel->title); + xco+=25; + } + uiDefIconBut(block, BUT, B_IMASELREMOVEBIP, ICON_BPIBFOLDER_X, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "");/* remove */ + + uiDefIconButS(block, TOG|BIT|0, B_REDR, ICON_BPIBFOLDERGREY, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "");/* dir */ + uiDefIconButS(block, TOG|BIT|1, B_REDR, ICON_INFO, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "");/* info */ + uiDefIconButS(block, TOG|BIT|2, B_REDR, ICON_IMAGE_COL, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "");/* image */ + uiDefIconButS(block, TOG|BIT|3, B_REDR, ICON_MAGNIFY, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "");/* loep */ + + /* altijd als laatste doen */ + curarea->headbutlen= xco+2*XIC; + + uiDrawBlock(block); +} + +/* ********************** IMASEL ****************************** */ + +/* ******************** ALGEMEEN ********************** */ + +void do_headerbuttons(short event) +{ + + if(event<=50) do_global_buttons2(event); + else if(event<=100) do_global_buttons(event); + else if(event<200) do_view3d_buttons(event); + else if(event<250) do_ipo_buttons(event); + else if(event<300) do_oops_buttons(event); + else if(event<350) do_info_buttons(event); + else if(event<400) do_image_buttons(event); + else if(event<450) do_buts_buttons(event); + else if(event<500) do_imasel_buttons(event); + else if(event<550) do_text_buttons(event); + else if(event<600) do_file_buttons(event); + else if(event<650) do_seq_buttons(event); + else if(event<700) do_sound_buttons(event); + else if(event<800) do_action_buttons(event); + else if(event<900) do_nla_buttons(event); +} + diff --git a/source/blender/src/imasel.c b/source/blender/src/imasel.c new file mode 100644 index 00000000000..e75fa8eba26 --- /dev/null +++ b/source/blender/src/imasel.c @@ -0,0 +1,900 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdio.h> +#include <stdlib.h> +#ifndef WIN32 +#include <unistd.h> +#else +#include "BLI_winstuff.h" +#include <io.h> +#include <direct.h> +#endif +#include <fcntl.h> +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "DNA_screen_types.h" +#include "DNA_space_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" + +#include "BIF_imasel.h" +#include "BIF_space.h" +#include "BIF_screen.h" + +#include "blendef.h" +#include "mydevice.h" + +#ifndef WIN32 +#include <dirent.h> +#endif + +#include <sys/stat.h> +#include "datatoc.h" + +/* locals */ +void longtochar(char *des, unsigned int *src, int size); +void chartolong(unsigned int *des, char *src, int size); +int dir_compare(const void *a1, const void *a2); +void issort( int te, ImaDir **firstentry); +int ima_compare(const void *a1, const void *a2); +void imsort(OneSelectableIma **firstentry); +void append_pib(SpaceImaSel *simasel, OneSelectableIma *ima); +void add_ima(int who, SpaceImaSel *simasel, ImaDir *direntry); + +/* implementation */ +int bitset(int l, int bit) +{ return (( l & bit) == bit); } + +void longtochar(char *des, unsigned int *src, int size) +{ int i;for (i = 0; i<size; i++){ des[i] = src[i] & 0xFF; }} + +void chartolong(unsigned int *des, char *src, int size) +{ int i;for (i = 0; i<size; i++){ des[i] = src[i]; }} + +int dir_compare(const void *a1, const void *a2) +{ + ImaDir **in1, **in2; + ImaDir *use1, *use2; + + in1= (ImaDir **)a1; + in2= (ImaDir **)a2; + + use1 = *in1; + use2 = *in2; + + return strcasecmp(use1->name, use2->name); +} + +void issort( int te, ImaDir **firstentry) +{ + ImaDir **sort; + ImaDir *use; + int i = 0; + + sort = MEM_mallocN(te * sizeof(void *), "dir Sorteer temp"); + use = *firstentry; + + while (use){ + sort[i++] = use; + use = use->next; + } + + qsort (sort, te, sizeof(void *), dir_compare); + + *firstentry = sort[0]; + use = *firstentry; + + + for (i=0; i<te; i++){ + if (i != 0) use->prev = sort[i-1]; else use->prev = 0; + if (i != te-1) use->next = sort[i+1]; else use->next = 0; + + use = use->next; + } + + MEM_freeN(sort); +} + + +int ima_compare(const void *a1, const void *a2) +{ + OneSelectableIma **in1, **in2; + OneSelectableIma *use1, *use2; + + in1= (OneSelectableIma **)a1; + in2= (OneSelectableIma **)a2; + + use1 = *in1; use2 = *in2; + return strcasecmp(use1->file_name, use2->file_name); +} + +void imsort(OneSelectableIma **firstentry) +{ + OneSelectableIma **sort; + OneSelectableIma *use; + int tot = 0, i = 0; + + use = *firstentry; + while (use){ + tot++; + use = use->next; + } + + if (tot){ + sort = MEM_mallocN(tot * sizeof(void *), "Sorteer imsort temp"); + use = *firstentry; + while (use){ + sort[i++] = use; + use = use->next; + } + + qsort (sort, tot, sizeof(void *), ima_compare); + + *firstentry = sort[0]; + use = *firstentry; + for (i=0; i<tot; i++){ + if (i != 0) use->prev = sort[i-1]; else use->prev = 0; + if (i != tot-1) use->next = sort[i+1]; else use->next = 0; + + use = use->next; + } + MEM_freeN(sort); + } +} + +static int write_msb_int(int fd, int i) { + unsigned int ui= (unsigned int) i; + unsigned char buf[4]; + buf[0]= (ui>>24)&0xFF; + buf[1]= (ui>>16)&0xFF; + buf[2]= (ui>>8)&0xFF; + buf[3]= (ui>>0)&0xFF; + return write(fd, buf, 4); +} +static int write_msb_short(int fd, short s) { + unsigned short us= (unsigned short) s; + unsigned char buf[2]; + buf[0]= (us>>8)&0xFF; + buf[1]= (us>>0)&0xFF; + return write(fd, buf, 2); +} + +static int read_msb_int(int fd, int *i_r) { + unsigned char buf[4]; + int rcount= read(fd, buf, 4); + + if (i_r) + *i_r= (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|(buf[3]<<0); + + return rcount; +} +static int read_msb_short(int fd, short *s_r) { + unsigned char buf[2]; + int rcount= read(fd, buf, 2); + + if (s_r) + *s_r= (buf[0]<<8)|(buf[1]<<0); + + return rcount; +} + +void append_pib(SpaceImaSel *simasel, OneSelectableIma *ima) +{ + int file; + char name[FILE_MAXDIR+FILE_MAXFILE]; + + if ( bitset (simasel->fase, IMS_WRITE_NO_BIP)) return; + + strcpy(name, simasel->dir); + strcat(name, ".Bpib"); + + file = open(name, O_BINARY|O_APPEND | O_RDWR | O_CREAT, 0666); + if (file == -1) { + /* printf("Could not write .Bpib file in dir %s\n", simasel->dir); */ + simasel->fase |= IMS_WRITE_NO_BIP; + return; + } + + lseek(file, 0, SEEK_END); + + write(file, "BIP2", 4); + write_msb_int(file, ima->ibuf_type); + write_msb_int(file, 0); + write_msb_int(file, 0); + write_msb_int(file, 0); + write_msb_short(file, ima->cmap); + write_msb_short(file, ima->image); + write_msb_short(file, ima->draw_me); + write_msb_short(file, ima->rt); + write_msb_short(file, ima->sx); + write_msb_short(file, ima->sy); + write_msb_short(file, ima->ex); + write_msb_short(file, ima->ey); + write_msb_short(file, ima->dw); + write_msb_short(file, ima->dh); + write_msb_short(file, ima->selectable); + write_msb_short(file, ima->selected); + write_msb_int(file, ima->mtime); + write_msb_int(file, ima->disksize); + write(file, ima->file_name, 64); + write_msb_short(file, ima->orgx); + write_msb_short(file, ima->orgy); + write_msb_short(file, ima->orgd); + write_msb_short(file, ima->anim); + write_msb_int(file, 0); /* pad to 128 boundary */ + write(file, ima->pict_rect, 3968); + + close(file); +} + +void write_new_pib(SpaceImaSel *simasel) +{ + OneSelectableIma *ima; + char name[FILE_MAXDIR+FILE_MAXFILE]; + + strcpy(name, simasel->dir); + strcat(name, ".Bpib"); + remove(name); + + ima = simasel->first_sel_ima; + while (ima) { + append_pib(simasel, ima); + ima = ima->next; + } +} + +void free_ima_dir(ImaDir *firstdir) +{ + ImaDir *n; + + while(firstdir){ + n = firstdir->next; + MEM_freeN(firstdir); + firstdir = n; + } +} + +void free_sel_ima(OneSelectableIma *firstima) +{ + OneSelectableIma *n; + + while(firstima){ + + if (firstima->pict) { + IMB_freeImBuf(firstima->pict); + } + n = firstima->next; + MEM_freeN(firstima); + firstima = n; + } +} + +void check_for_pib(SpaceImaSel *simasel) +{ + ImaDir *direntry; + + direntry = simasel->firstfile; + while(direntry){ + if ((strlen(direntry->name) > 4) && (0==strcmp(direntry->name, ".Bpib")) ){ + simasel->fase |= IMS_FOUND_BIP; + direntry = 0; + }else{ + direntry = direntry->next; + } + } +} + +void clear_ima_dir(SpaceImaSel *simasel) +{ + if(simasel->first_sel_ima) free_sel_ima(simasel->first_sel_ima); + if(simasel->firstdir) free_ima_dir(simasel->firstdir); + if(simasel->firstfile) free_ima_dir(simasel->firstfile); + + simasel->first_sel_ima = 0; + simasel->firstdir = 0; + simasel->firstfile = 0; + + simasel->totaldirs = 0; + simasel->totalfiles = 0; + simasel->totalima = 0; + simasel->topdir = -1; + simasel->topfile = -1; + simasel->topima = 0; + simasel->image_slider = 0.0; + simasel->slider_height = 0.0; + simasel->slider_space = 0.0; + simasel->hilite = -1; + simasel->curimax = 0; + simasel->curimay = 0; + + simasel->total_selected = 0; + simasel->fase = 0; + simasel->subfase = 0; + simasel->imafase = 0; + simasel->ima_redraw = 0; +} + +int get_ima_dir(char *dirname, int dtype, int *td, ImaDir **first) +{ + DIR *dirp; + struct dirent *dep; + struct ImaDir *temp; + struct ImaDir *dnext = NULL, *fnext; + struct stat status; + char olddir[FILE_MAXDIR+FILE_MAXFILE]; + char getdirname[FILE_MAXDIR+FILE_MAXFILE]; + int /* i=0, */ tot=0; + int isdir; + + if(!BLI_getwdN(olddir)) return -1; + + if (chdir(dirname) == -1) return(-1); + + strcpy(getdirname, "."); + + dirp = (DIR *) opendir(getdirname); + if (dirp == NULL) return (-1); + + waitcursor(1); + + while((dep = (struct dirent*) readdir(dirp)) != NULL){ + + strcpy(getdirname, dirname); + strcat(getdirname,dep->d_name); + + stat(getdirname, &status); + isdir = S_ISDIR(status.st_mode); + + if ( ((dtype == IMS_DIR) && isdir) || ((dtype == IMS_FILE) && !isdir)){ + /* yes, searching for this type */ + tot++; + if (tot == 1){ + dnext = MEM_callocN(sizeof(struct ImaDir), "get first"); + *first = dnext; + + dnext->prev = 0; + dnext->next = 0; + }else{ + fnext = MEM_callocN(sizeof(struct ImaDir), "get nextdir"); + dnext->next = fnext; + + temp = dnext; + dnext = fnext; + + dnext ->prev = temp; + dnext ->next = 0; + } + + dnext->type = dtype; + dnext->selected = 0; + dnext->hilite = 0; + + dnext->mtime = status.st_ctime; + dnext->size = (int)status.st_size; + strcpy(dnext->name, dep->d_name); + } + } + closedir(dirp); + + if (tot) issort(tot, first); + + waitcursor(0); + + *td = tot; + + chdir (olddir); + + return (tot); +} + +void imadir_parent(SpaceImaSel *simasel) +{ + +#ifdef WIN32 + if (strlen(simasel->dir) > 1){ + simasel->dir[strlen(simasel->dir)-1] = 0; + while(simasel->dir[strlen(simasel->dir)-1] != '\\'){ + if(strlen(simasel->dir)==0) break; + simasel->dir[strlen(simasel->dir)-1] = 0; + } + } +#else + if (strlen(simasel->dir) > 1){ + simasel->dir[strlen(simasel->dir)-1] = 0; + while(simasel->dir[strlen(simasel->dir)-1] != '/') { + if(strlen(simasel->dir)==0) break; + simasel->dir[strlen(simasel->dir)-1] = 0; + } + } +#endif +} + + +void get_next_image(SpaceImaSel *simasel) +{ + OneSelectableIma * ima; + ImBuf * ibuf; + struct anim * anim; + int i = 0, size; + char name[FILE_MAXDIR+FILE_MAXFILE]; + + ima = simasel->first_sel_ima; + if (ima == 0){ + simasel->imafase = 0; + simasel->fase |= IMS_KNOW_IMA; + simasel->fase &= ~IMS_DOTHE_IMA; + return; + } + if (simasel->imafase > simasel->totalima){ + simasel->imafase = 0; + simasel->fase &= ~IMS_DOTHE_IMA; + simasel->fase |= IMS_KNOW_IMA; + } + + ima = simasel->first_sel_ima; + i = 0; + while(i < simasel->imafase){ + if ((ima) && (ima->next)) ima = ima->next; + i++; + } + + if (ima->image == 0) { + if (ima->anim == 1) { + /* open movie, get len, get middle picture */ + + strcpy(name, simasel->dir); + strcat(name, ima->file_name); + + anim = IMB_open_anim(name, IB_rect); + + if (anim == 0) { + // ibuf= IMB_loadiffmem((int*)datatoc_cmovie_tga, IB_rect); + ibuf= IMB_ibImageFromMemory((int *)datatoc_cmovie_tga, datatoc_cmovie_tga_size, IB_rect); + } + else{ + int animlen; + + ibuf = IMB_anim_nextpic(anim); + IMB_freeImBuf(ibuf); + + animlen= IMB_anim_get_duration(anim); + ibuf = IMB_anim_absolute(anim, animlen / 2); + + IMB_free_anim(anim); + } + } + else { + + strcpy(name, simasel->dir); + strcat(name, ima->file_name); + + ibuf = IMB_loadiffname(name, IB_rect); + if(ibuf && ibuf->zbuf) IMB_freezbufImBuf(ibuf); + } + + if (ibuf){ + if (ima->dw < 4) ima->dw = 4; + if (ima->dh < 4) ima->dh = 4; + + IMB_scaleImBuf(ibuf, ima->dw, ima->dh); + /* the whole cmap system is wacko */ + + if (G.order==B_ENDIAN) + IMB_convert_rgba_to_abgr(ima->dw*ima->dh, ibuf->rect); + + ibuf->mincol = 0; + ibuf->maxcol = 256; + ibuf->cbits = 5; + ibuf->depth = 8; + + IMB_freecmapImBuf(ibuf); + ibuf->cmap = simasel->cmap->cmap; + + IMB_converttocmap(ibuf); + + /* copy ibuf->rect naar ima->pict_rect */ + size = ima->dw * ima->dh; if (size > 3968) size = 3968; + longtochar(ima->pict_rect, ibuf->rect, size); + + IMB_applycmap(ibuf); + IMB_convert_rgba_to_abgr(size, ibuf->rect); + + if (ima->pict) IMB_freeImBuf(ima->pict); + ima->pict = ibuf; + ibuf = 0; + ima->cmap = 1; + ima->image = 1; + + append_pib(simasel, ima); + } + } + simasel->ima_redraw++; + simasel->imafase ++; + if (simasel->imafase == simasel->totalima){ + simasel->imafase = 0; + simasel->fase &= ~IMS_DOTHE_IMA; + simasel->fase |= IMS_KNOW_IMA; + } +} + +void add_ima(int who, SpaceImaSel *simasel, ImaDir *direntry) +{ + OneSelectableIma *ima, *prev_ima; + ImBuf *ibuf; + char name[FILE_MAXDIR+FILE_MAXFILE]; + + strcpy(name , simasel->dir); + strcat(name , direntry->name); + + prev_ima = simasel->first_sel_ima; + while((prev_ima)&&(prev_ima->next)){ + prev_ima = prev_ima->next; + } + + ima = MEM_callocN(sizeof(OneSelectableIma), "OSIbip"); + if (direntry->type == IMS_IMA){ + /* Picture is an Image */ + ibuf = IMB_loadiffname(name, IB_test); + if (ibuf){ + ima->anim = 0; + ima->pict = ibuf; + ima->ibuf_type= ibuf->ftype; + ima->orgx = ibuf->x; + ima->orgy = ibuf->y; + ima->orgd = ibuf->depth; + + ima->dw = 64; + ima->dh = 51; + ima->cmap = 0; + ima->image = 0; + if (ima->orgx > ima->orgy){ + ima->dw = 64; + ima->dh = (short)(62 * ((float)ima->orgy / (float)ima->orgx)); + }else{ + ima->dw = (short)(64 * ((float)ima->orgx / (float)ima->orgy)); + ima->dh = 62; + } + }else{ + printf("%s image with no imbuf ???\n", name); + } + ibuf = 0; + }else{ + /* Picture is an Animation */ + + ima->pict = 0; + ima->anim = 1; + ima->ibuf_type= 0; + ima->orgx = 64; + ima->orgy = 51; + ima->orgd = 24; + + ima->dw = 64; + ima->dh = 51; + ima->cmap = 0; + ima->image = 0; + } + + strcpy(name, direntry->name); name[63] = 0; + strcpy(ima->file_name, name); + ima->disksize = (int)direntry->size; + ima->mtime = (int)direntry->mtime; + + ima->next = 0; + ima->prev = prev_ima; + + if (prev_ima) { + prev_ima->next = ima; + }else{ + simasel->first_sel_ima = ima; + } + + simasel->ima_redraw++; + simasel->totalima++; +} + + +void get_file_info(SpaceImaSel *simasel) +{ + OneSelectableIma *prev_ima; + ImaDir *direntry; + char name[FILE_MAXDIR+FILE_MAXFILE]; + int i = 0; + + if (!simasel->firstfile){ + simasel->subfase = 0; + simasel->fase |= IMS_KNOW_INF; + simasel->fase &= ~IMS_DOTHE_INF; + return; + } + if (simasel->subfase > simasel->totalfiles){ + simasel->subfase = 0; + simasel->fase |= IMS_KNOW_INF; + simasel->fase &= ~IMS_DOTHE_INF; + } + + direntry = simasel->firstfile; + while(i < simasel->subfase){ + direntry = direntry->next; + i++; + } + + prev_ima = simasel->first_sel_ima; + while((prev_ima)&&(prev_ima->next)){ + prev_ima = prev_ima->next; + } + + strcpy(name , simasel->dir); + strcat(name , direntry->name); + + if (IMB_ispic(name)) { + direntry->type = IMS_IMA; + }else{ + if (IMB_isanim(name)) { + direntry->type = IMS_ANIM; + }else{ + direntry->type = IMS_NOIMA; + } + } + + if (direntry->type != IMS_NOIMA){ + add_ima(1, simasel, direntry); + } + + simasel->subfase++; + + if (simasel->subfase == simasel->totalfiles){ + simasel->subfase = 0; + simasel->fase |= IMS_KNOW_INF; + simasel->fase &= ~IMS_DOTHE_INF; + } +} + +/* Note: the thumbnails are saved in ABGR format in the .Bpib +cache file */ + +void get_pib_file(SpaceImaSel *simasel) +{ + ImaDir *direntry, *prev_dir, *next_dir; + OneSelectableIma *ima, *prev_ima; + int flen; + int dl, file, first, trd=0, rd, size, found, ima_added = 0; + char name[FILE_MAXDIR+FILE_MAXFILE]; + + if (bitset(simasel->fase , IMS_KNOW_BIP)) return; + + waitcursor(1); + + strcpy(name, simasel->dir); + strcat(name, ".Bpib"); + + file = open(name, O_BINARY|O_RDONLY); + + flen = BLI_filesize(file); + + simasel->totalima = 0; + prev_ima = 0; + first = 1; + trd = 0; + + while(trd < flen){ + char header[5]; + + ima = MEM_callocN(sizeof(OneSelectableIma), "Ima"); + + rd= 0; + rd+= read(file, header, 4); + rd+= read_msb_int(file, &ima->ibuf_type); + rd+= read_msb_int(file, NULL); + rd+= read_msb_int(file, NULL); + rd+= read_msb_int(file, NULL); + rd+= read_msb_short(file, &ima->cmap); + rd+= read_msb_short(file, &ima->image); + rd+= read_msb_short(file, &ima->draw_me); + rd+= read_msb_short(file, &ima->rt); + rd+= read_msb_short(file, &ima->sx); + rd+= read_msb_short(file, &ima->sy); + rd+= read_msb_short(file, &ima->ex); + rd+= read_msb_short(file, &ima->ey); + rd+= read_msb_short(file, &ima->dw); + rd+= read_msb_short(file, &ima->dh); + rd+= read_msb_short(file, &ima->selectable); + rd+= read_msb_short(file, &ima->selected); + rd+= read_msb_int(file, &ima->mtime); + rd+= read_msb_int(file, &ima->disksize); + rd+= read(file, ima->file_name, 64); + rd+= read_msb_short(file, &ima->orgx); + rd+= read_msb_short(file, &ima->orgy); + rd+= read_msb_short(file, &ima->orgd); + rd+= read_msb_short(file, &ima->anim); + rd+= read_msb_int(file, NULL); + rd+= read(file, ima->pict_rect, 3968); + + found = 0; + + if (rd != sizeof(OneSelectableIma) || memcmp(header, "BIP2", 4)!=0) { + printf("Error in Bpib file\n"); + strcpy(name, simasel->dir); + strcat(name, ".Bpib"); + dl = remove(name); + if (dl == 0) printf("corrupt Bpib file removed\n"); + trd = flen; + } else { + /* find matching direntry (if possible) */ + for (direntry= simasel->firstfile; direntry; direntry= direntry->next) + if (BLI_streq(direntry->name, ima->file_name)) + break; + + if (direntry) { + if (direntry->mtime == ima->mtime) { + /* ima found and same, load pic */ + size = ima->dw * ima->dh; + if (size > 3968) size = 3968; + if (size) { + ima->pict = IMB_allocImBuf(ima->dw, ima->dh, 24, IB_rect | IB_cmap, 0); + chartolong(ima->pict->rect, ima->pict_rect, size); + ima->pict->cmap = simasel->cmap->cmap; + ima->pict->maxcol = 256; + IMB_applycmap(ima->pict); + IMB_convert_rgba_to_abgr(size, ima->pict->rect); + } + ima->selected = 0; + ima->selectable = 0; + + if(prev_ima) prev_ima->next = ima; + ima->next = 0; + ima->prev = prev_ima; + + prev_ima = ima; + + if (first){ first = 0;simasel->first_sel_ima = ima; } + simasel->totalima++; + found = 1; + } + + /* remove direntry */ + prev_dir = direntry->prev; + next_dir = direntry->next; + + if(prev_dir) prev_dir->next = next_dir; + if(next_dir) next_dir->prev = prev_dir; + + MEM_freeN(direntry); + } + } + if (!found) MEM_freeN(ima); + + trd+=rd; + } + close(file); + + direntry = simasel->firstfile; + + while(direntry){ + + strcpy(name , simasel->dir); + strcat(name , direntry->name); + + if (IMB_ispic(name)) { + direntry->type = IMS_IMA; + }else{ + if (IMB_isanim(name)) { + direntry->type = IMS_ANIM; + }else{ + direntry->type = IMS_NOIMA; + } + } + + if (direntry->type != IMS_NOIMA){ + prev_ima = simasel->first_sel_ima; + while((prev_ima)&&(prev_ima->next)){ + prev_ima = prev_ima->next; + } + add_ima(2, simasel, direntry); + ima_added = 1; + } + direntry = direntry->next; + } + + imsort(&simasel->first_sel_ima); + + simasel->fase |= IMS_KNOW_BIP; + simasel->fase |= IMS_KNOW_INF; + simasel->fase |= IMS_KNOW_IMA; + + if (ima_added){ + simasel->fase |= IMS_DOTHE_IMA; + simasel->fase &= ~IMS_KNOW_IMA; + addafterqueue(curarea->win, AFTERIMASELGET, 1); + }else{ + write_new_pib(simasel); + } + + waitcursor(0); +} + +void change_imadir(SpaceImaSel *simasel) +{ + ImaDir *direntry; + int i; + + direntry = simasel->firstdir; + for (i=0; i<simasel->hilite; i++){ + direntry = direntry->next; + } + + if(direntry==NULL); + else if (direntry->name[0] != '.'){ + strcat(simasel->dir, direntry->name); + strcat(simasel->dir, "/"); + } + else { + if (direntry->name[1] == '.'){ + imadir_parent(simasel); + } + } + + clear_ima_dir(simasel); +} + +void check_imasel_copy(SpaceImaSel *simasel) +{ + + /* LET OP: wordt ook gebruikt bij inlezen blender file */ + /* dingen op nul zetten, opnieuw malloccen etc */ + simasel->first_sel_ima = 0; + simasel->hilite_ima = 0; + simasel->firstdir = 0; + simasel->firstfile = 0; + simasel->cmap = 0; + clear_ima_dir(simasel); + + // simasel->cmap= IMB_loadiffmem((int*)datatoc_cmap_tga, IB_rect|IB_cmap); + simasel->cmap= IMB_ibImageFromMemory((int *)datatoc_cmap_tga, datatoc_cmap_tga_size, IB_rect|IB_cmap); +} + +void free_imasel(SpaceImaSel *simasel) +{ + /* NIET de imasel zelf vrijgeven */ + + clear_ima_dir(simasel); + IMB_freeImBuf(simasel->cmap); +} + diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c new file mode 100644 index 00000000000..454d4355bdf --- /dev/null +++ b/source/blender/src/interface.c @@ -0,0 +1,4105 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> +#include <stdlib.h> +#include <string.h> + +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "PIL_time.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" + +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_keyval.h" +#include "BIF_mainqueue.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_toolbox.h" +#include "BIF_mywindow.h" +#include "BIF_space.h" +#include "BIF_glutil.h" +#include "BIF_interface.h" + +#include "BSE_view.h" + +#include "blendertimer.h" + +#include "mydevice.h" +#include "interface.h" +#include "blendef.h" + +/* naming conventions: + * + * uiBlahBlah() external function + * ui_blah_blah() internal function + */ + +/***/ + +typedef struct { + short xim, yim; + unsigned int *rect; + short xofs, yofs; +} uiIconImage; + +typedef struct { + short mval[2]; + short qual, val; + int event; +} uiEvent; + +typedef struct { + void *xl, *large, *medium, *small; +} uiFont; + +typedef struct uiLinkLine uiLinkLine; +struct uiLinkLine { /* only for draw/edit */ + uiLinkLine *next, *prev; + + short flag, pad; + + uiBut *from, *to; +}; + +typedef struct { + void **poin; /* pointer to original pointer */ + void ***ppoin; /* pointer to original pointer-array */ + short *totlink; /* if pointer-array, here is the total */ + + short maxlink, pad; + short fromcode, tocode; + + ListBase lines; +} uiLink; + +struct uiBut { + uiBut *next, *prev; + short type, pointype, bit, bitnr, retval, flag, strwidth, ofs, pos; + + char *str; + char strdata[UI_MAX_NAME_STR]; + char drawstr[UI_MAX_DRAW_STR]; + + float x1, y1, x2, y2; + + char *poin; + float min, max; + float a1, a2, rt[4]; + float aspect; + + void (*func)(void *, void *); + void *func_arg1; + void *func_arg2; + + void (*embossfunc)(BIFColorID, float, float, float, float, float, int); + + uiLink *link; + + char *tip, *lockstr; + + BIFColorID col; + void *font; + + BIFIconID icon; + short lock, win; + short iconadd; + + /* IDPOIN data */ + uiIDPoinFuncFP idpoin_func; + ID **idpoin_idpp; + + /* BLOCK data */ + uiBlockFuncFP block_func; + + /* BUTM data */ + void (*butm_func)(void *arg, int event); + void *butm_func_arg; +}; + +struct uiBlock { + uiBlock *next, *prev; + + ListBase buttons; + + char name[UI_MAX_NAME_STR]; + + float winmat[4][4]; + + float minx, miny, maxx, maxy; + float aspect; + + void (*butm_func)(void *arg, int event); + void *butm_func_arg; + + void (*func)(void *arg1, void *arg2); + void *func_arg1; + void *func_arg2; + + BIFColorID col; + short font; /* indices */ + int afterval; + void *curfont; + + short autofill, flag, win, winq, direction, dt; + void *saveunder; + + float xofs, yofs; // offset to parent button +}; + +/* ************ GLOBALS ************* */ + +int UIfrontbuf= 0; + +static float UIwinmat[4][4]; +static int UIlock= 0, UIafterval; +static char *UIlockstr=NULL; +static void (*UIafterfunc)(void *arg, int event); +static void *UIafterfunc_arg; + +static uiFont UIfont[UI_ARRAY]= {0}; +static uiBut *UIbuttip; + +/* ****************************** */ + +static void ui_check_but(uiBut *but); +static void ui_set_but_val(uiBut *but, double value); +static double ui_get_but_val(uiBut *but); + +/* ****************************** */ + +static int uibut_contains_pt(uiBut *but, short *pt) +{ + return ((but->x1<pt[0] && but->x2>=pt[0]) && + (but->y1<pt[1] && but->y2>=pt[1])); +} + +static void uibut_do_func(uiBut *but) +{ + if (but->func) { + but->func(but->func_arg1, but->func_arg2); + } +} + +/* ************* SAVE UNDER ************ */ + +typedef struct { + short x, y, sx, sy, oldwin; + int oldcursor; + unsigned int *rect; +} uiSaveUnder; + + +static void ui_paste_under(uiSaveUnder *su) +{ + + if(su) { + glDisable(GL_DITHER); + glRasterPos2f( su->x-0.5, su->y-0.5 ); + glDrawPixels(su->sx, su->sy, GL_RGBA, GL_UNSIGNED_BYTE, su->rect); + glEnable(GL_DITHER); + + if(su->oldwin) { + mywinset(su->oldwin); + if (su->oldcursor) { + set_cursor(su->oldcursor); + } + } + + MEM_freeN(su->rect); + MEM_freeN(su); + } +} + + +static uiSaveUnder *ui_save_under(int x, int y, int sx, int sy) +{ + uiSaveUnder *su=NULL; + + if(sx>1 && sy>1) { + + su= MEM_callocN(sizeof(uiSaveUnder), "save under"); + + su->rect= MEM_mallocN(sx*sy*4, "temp_frontbuffer_image"); + su->x= x; + su->y= y; + su->sx= sx; + su->sy= sy; + glReadPixels(x, y, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, su->rect); + } + + return su; +} + + + + + +/* ************* DRAW ************** */ + + +static void ui_graphics_to_window(int win, float *x, float *y) /* voor rectwrite b.v. */ +{ + float gx, gy; + int sx, sy; + int getsizex, getsizey; + + bwin_getsize(win, &getsizex, &getsizey); + bwin_getsuborigin(win, &sx, &sy); + + gx= *x; + gy= *y; + *x= sx + getsizex*(0.5+ 0.5*(gx*UIwinmat[0][0]+ gy*UIwinmat[1][0]+ UIwinmat[3][0])); + *y= sy + getsizey*(0.5+ 0.5*(gx*UIwinmat[0][1]+ gy*UIwinmat[1][1]+ UIwinmat[3][1])); +} + + + +static void ui_window_to_graphics(int win, float *x, float *y) /* voor muiscursor b.v. */ +{ + float a, b, c, d, e, f, px, py; + int getsizex, getsizey; + + bwin_getsize(win, &getsizex, &getsizey); + + a= .5*getsizex*UIwinmat[0][0]; + b= .5*getsizex*UIwinmat[1][0]; + c= .5*getsizex*(1.0+UIwinmat[3][0]); + + d= .5*getsizey*UIwinmat[0][1]; + e= .5*getsizey*UIwinmat[1][1]; + f= .5*getsizey*(1.0+UIwinmat[3][1]); + + px= *x; + py= *y; + + *y= (a*(py-f) + d*(c-px))/(a*e-d*b); + *x= (px- b*(*y)- c)/a; + +} + +static uiSaveUnder *ui_bgnpupdraw(int startx, int starty, int endx, int endy, int cursor) +{ + uiSaveUnder *su; + short oldwin; + + #if defined(__sgi) || defined(__sun) + /* this is a dirty patch: gets sometimes the backbuffer */ + my_get_frontbuffer_image(0, 0, 1, 1); + my_put_frontbuffer_image(); + #endif + + oldwin= mywinget(); + + mywinset(G.curscreen->mainwin); + + /* pietsje groter, 1 pixel aan de rand */ + + glReadBuffer(GL_FRONT); + glDrawBuffer(GL_FRONT); + + /* for geforce and other cards */ + glFinish(); + + su= ui_save_under(startx-1, starty-1, endx-startx+2, endy-starty+6); + if(su) su->oldwin= oldwin; + + if(su && cursor) { + su->oldcursor= get_cursor(); + set_cursor(CURSOR_STD); + } + + return su; +} + +static void ui_endpupdraw(uiSaveUnder *su) +{ + + /* for geforce and other cards */ + + glReadBuffer(GL_FRONT); + glDrawBuffer(GL_FRONT); + + glFinish(); + + if(su) { + ui_paste_under(su); + } + glReadBuffer(GL_BACK); + glDrawBuffer(GL_BACK); +} + +static void ui_draw_icon(uiBut *but, BIFIconID icon) +{ + float xs= (but->x1+but->x2- BIF_get_icon_width(icon))/2.0; + float ys= (but->y1+but->y2- BIF_get_icon_height(icon))/2.0; + + glRasterPos2f(xs, ys); + + if(but->aspect>1.1) glPixelZoom(1.0/but->aspect, 1.0/but->aspect); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if(but->flag & UI_SELECT) { + if(but->flag & UI_ACTIVE) { + BIF_draw_icon_blended(icon, but->col, COLORSHADE_DARK); + } else { + BIF_draw_icon_blended(icon, but->col, COLORSHADE_GREY); + } + } + else { + if ((but->flag & UI_ACTIVE) && but->type==BUTM) { + BIF_draw_icon_blended(icon, BUTMACTIVE, COLORSHADE_MEDIUM); + } else if (but->flag & UI_ACTIVE) { + BIF_draw_icon_blended(icon, but->col, COLORSHADE_HILITE); + } else { + BIF_draw_icon_blended(icon, but->col, COLORSHADE_MEDIUM); + } + } + + glBlendFunc(GL_ONE, GL_ZERO); + glDisable(GL_BLEND); + + glPixelZoom(1.0, 1.0); +} + +static void ui_draw_outlineX(float x1, float y1, float x2, float y2, float asp1) +{ + float vec[2]; + + glBegin(GL_LINE_LOOP); + vec[0]= x1+asp1; vec[1]= y1-asp1; + glVertex2fv(vec); + vec[0]= x2-asp1; + glVertex2fv(vec); + vec[0]= x2+asp1; vec[1]= y1+asp1; + glVertex2fv(vec); + vec[1]= y2-asp1; + glVertex2fv(vec); + vec[0]= x2-asp1; vec[1]= y2+asp1; + glVertex2fv(vec); + vec[0]= x1+asp1; + glVertex2fv(vec); + vec[0]= x1-asp1; vec[1]= y2-asp1; + glVertex2fv(vec); + vec[1]= y1+asp1; + glVertex2fv(vec); + glEnd(); + +} + +static void ui_emboss_X(BIFColorID bc, float asp, float x1, float y1, float x2, float y2, int flag) +{ + /* paper */ + if(flag & UI_SELECT) { + if(flag & UI_ACTIVE) BIF_set_color(bc, COLORSHADE_DARK); + else BIF_set_color(bc, COLORSHADE_GREY); + } + else { + if(flag & UI_ACTIVE) BIF_set_color(bc, COLORSHADE_HILITE); + else BIF_set_color(bc, COLORSHADE_MEDIUM); + } + + glRectf(x1+1, y1+1, x2-1, y2-1); + + x1+= asp; + x2-= asp; + y1+= asp; + y2-= asp; + + /* below */ + if(flag & UI_SELECT) BIF_set_color(bc, COLORSHADE_MEDIUM); + else BIF_set_color(bc, COLORSHADE_DARK); + fdrawline(x1, y1, x2, y1); + + /* right */ + fdrawline(x2, y1, x2, y2); + + /* top */ + if(flag & UI_SELECT) BIF_set_color(bc, COLORSHADE_DARK); + else BIF_set_color(bc, COLORSHADE_WHITE); + fdrawline(x1, y2, x2, y2); + + /* left */ + fdrawline(x1, y1, x1, y2); + + /* outline */ + glColor3ub(0,0,0); + ui_draw_outlineX(x1, y1, x2, y2, asp); +} + +void uiEmboss(float x1, float y1, float x2, float y2, int sel) +{ + + /* below */ + if(sel) glColor3ub(255,255,255); + else glColor3ub(0,0,0); + fdrawline(x1, y1, x2, y1); + + /* right */ + fdrawline(x2, y1, x2, y2); + + /* top */ + if(sel) glColor3ub(0,0,0); + else glColor3ub(255,255,255); + fdrawline(x1, y2, x2, y2); + + /* left */ + fdrawline(x1, y1, x1, y2); + +} + +/* super minimal button as used in logic menu */ +static void ui_emboss_W(BIFColorID bc, float asp, float x1, float y1, float x2, float y2, int flag) +{ + + x1+= asp; + x2-= asp; + y1+= asp; + y2-= asp; + + /* paper */ + if(flag & UI_SELECT) { + if(flag & UI_ACTIVE) BIF_set_color(bc, COLORSHADE_DARK); + else BIF_set_color(bc, COLORSHADE_GREY); + } + else { + if(flag & UI_ACTIVE) BIF_set_color(bc, COLORSHADE_HILITE); + else BIF_set_color(bc, COLORSHADE_MEDIUM); + } + + glRectf(x1, y1, x2, y2); + + if(flag & UI_SELECT) { + BIF_set_color(bc, COLORSHADE_LIGHT); + + /* below */ + fdrawline(x1, y1, x2, y1); + + /* right */ + fdrawline(x2, y1, x2, y2); + } + else if(flag & UI_ACTIVE) { + BIF_set_color(bc, COLORSHADE_WHITE); + + /* top */ + fdrawline(x1, y2, x2, y2); + + /* left */ + fdrawline(x1, y1, x1, y2); + } +} + +/* minimal button with small black outline */ +static void ui_emboss_F(BIFColorID bc, float asp, float x1, float y1, float x2, float y2, int flag) +{ + float asp1; + + /* paper */ + if(flag & UI_SELECT) { + if(flag & UI_ACTIVE) BIF_set_color(bc, COLORSHADE_DARK); + else BIF_set_color(bc, COLORSHADE_GREY); + } + else { + if(flag & UI_ACTIVE) BIF_set_color(bc, COLORSHADE_HILITE); + else BIF_set_color(bc, COLORSHADE_MEDIUM); + } + + glRectf(x1+1, y1+1, x2-1, y2-1); + + asp1= asp; + + x1+= asp1; + x2-= asp1; + y1+= asp1; + y2-= asp1; + + /* below */ + if(flag & UI_SELECT) BIF_set_color(bc, COLORSHADE_WHITE); + else BIF_set_color(bc, COLORSHADE_DARK); + fdrawline(x1, y1, x2, y1); + + /* right */ + fdrawline(x2, y1, x2, y2); + + /* top */ + if(flag & UI_SELECT) BIF_set_color(bc, COLORSHADE_DARK); + else BIF_set_color(bc, COLORSHADE_WHITE); + fdrawline(x1, y2, x2, y2); + + /* left */ + fdrawline(x1, y1, x1, y2); + + glColor3ub(0,0,0); + fdrawbox(x1-asp1, y1-asp1, x2+asp1, y2+asp1); +} + +/* minimal for menu's */ +static void ui_emboss_M(BIFColorID bc, float asp, float x1, float y1, float x2, float y2, int flag) +{ + x1+= 1.0; + y1+= 1.0; + x2-= 1.0+asp; + y2-= 1.0+asp; + + + if(flag & UI_SELECT) { + BIF_set_color(bc, COLORSHADE_LIGHT); + + /* below */ + fdrawline(x1, y1, x2, y1); + + /* right */ + fdrawline(x2, y1, x2, y2); + } + else if(flag & UI_ACTIVE) { + BIF_set_color(bc, COLORSHADE_WHITE); + + /* top */ + fdrawline(x1, y2, x2, y2); + + /* left */ + fdrawline(x1, y1, x1, y2); + } + else { + BIF_set_color(bc, COLORSHADE_MEDIUM); + + fdrawbox(x1, y1, x2, y2); + } +} + + +/* nothing! */ +static void ui_emboss_N(BIFColorID bc, float asp, float x1, float y1, float x2, float y2, int sel) +{ +} + +/* pulldown menu */ +static void ui_emboss_P(BIFColorID bc, float asp, float x1, float y1, float x2, float y2, int flag) +{ + + BIF_set_color(bc, COLORSHADE_MEDIUM); + glRectf(x1, y1, x2, y2); + + if(flag & UI_ACTIVE) { + BIF_set_color(BUTMACTIVE, COLORSHADE_MEDIUM); + glRectf(x1, y1, x2, y2); + } + +} + +static void ui_emboss_slider(uiBut *but, float fac) +{ + float h; + + h= (but->y2-but->y1); + + BIF_set_color(but->col, COLORSHADE_DARK); + glRectf(but->x1, but->y1, but->x2, but->y2); + glColor3ub(0,0,0); + ui_draw_outlineX(but->x1+1, but->y1+1, but->x2-1, but->y2-1, but->aspect); + + /* het blokje */ + if(but->flag & UI_SELECT) BIF_set_color(but->col, COLORSHADE_LIGHT); + else BIF_set_color(but->col, COLORSHADE_GREY); + glRects(but->x1+fac, but->y1+1, but->x1+fac+h, but->y2-1); + + BIF_set_color(but->col, COLORSHADE_WHITE); + fdrawline(but->x1+fac, but->y2-1, but->x1+fac+h, but->y2-1); + fdrawline(but->x1+fac, but->y1+1, but->x1+fac, but->y2-1); + + glColor3ub(0,0,0); + fdrawline(but->x1+fac, but->y1+1, but->x1+fac+h, but->y1+1); + fdrawline(but->x1+fac+h, but->y1+1, but->x1+fac+h, but->y2-1); +} + +static void ui_draw_but_BUT(uiBut *but) +{ + float x; + + but->embossfunc(but->col, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag); + + if( but->flag & UI_HAS_ICON ) { + ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd)); + } + else if(but->drawstr[0]!=0) { + if(but->flag & UI_SELECT) glColor3ub(255,255,255); + else glColor3ub(0,0,0); + + if(but->flag & UI_TEXT_LEFT) x= but->x1+4.0; + else x= (but->x1+but->x2-but->strwidth+1)/2.0; + + glRasterPos2f( x, (but->y1+but->y2- 9.0)/2.0); + + BMF_DrawString(but->font, but->drawstr+but->ofs); + } +} + +static void ui_draw_but_TOG3(uiBut *but) +{ + float x; + + but->embossfunc(but->col, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag); + + if( but->flag & UI_HAS_ICON ) { + ui_draw_icon(but, but->icon); + } + else if(but->drawstr[0]!=0) { + if(but->flag & UI_SELECT) { + int ok= 0; + + if( but->pointype==CHA ) { + if( BTST( *(but->poin+2), but->bitnr )) ok= 1; + } + else if( but->pointype ==SHO ) { + short *sp= (short *)but->poin; + if( BTST( sp[1], but->bitnr )) ok= 1; + } + + if (ok) { + glColor3ub(255, 255, 0); + } else { + glColor3ub(255, 255, 255); + } + } else { + glColor3ub(0, 0, 0); + } + + if(but->flag & UI_TEXT_LEFT) x= but->x1+4.0; + else x= (but->x1+but->x2-but->strwidth+1)/2.0; + + glRasterPos2f( x, (but->y1+but->y2- 9.0)/2.0); + + BMF_DrawString(but->font, but->drawstr+but->ofs); + } +} + +static void ui_draw_but_TEX(uiBut *but) +{ + float x; + short pos, sel, t; + char ch; + + /* exception for text buttons using embossF */ + sel= but->flag; + if(but->embossfunc==ui_emboss_F) sel |= UI_SELECT; + + but->embossfunc(but->col, but->aspect, but->x1, but->y1, but->x2, but->y2, sel); + + sel= but->flag & UI_SELECT; + + /* draw cursor */ + if(but->pos != -1) { + + pos= but->pos+strlen(but->str); + if(pos >= but->ofs) { + ch= but->drawstr[pos]; + but->drawstr[pos]= 0; + t= but->aspect*BMF_GetStringWidth(but->font, but->drawstr+but->ofs) + 3; + + but->drawstr[pos]= ch; + glColor3ub(255,0,0); + + glRects(but->x1+t, but->y1+2, but->x1+t+3, but->y2-2); + } + } + if(but->drawstr[0]!=0) { + if(sel) glColor3ub(255,255,255); + else glColor3ub(0,0,0); + + if(but->flag & UI_TEXT_LEFT) x= but->x1+4.0; + else x= (but->x1+but->x2-but->strwidth+1)/2.0; + + glRasterPos2f( x, (but->y1+but->y2- 9.0)/2.0); + + BMF_DrawString(but->font, but->drawstr+but->ofs); + } +} + +static void ui_draw_but_BUTM(uiBut *but) +{ + float x; + short len; + char *cpoin; + + but->embossfunc(but->col, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag); + + if( but->flag & UI_HAS_ICON ) { + ui_draw_icon(but, but->icon); + } + else { + if(but->drawstr[0]!=0) { + cpoin= strchr(but->drawstr, '|'); + if(cpoin) *cpoin= 0; + + if(but->embossfunc==ui_emboss_P) { + if(but->flag & UI_ACTIVE) glColor3ub(255,255,255); + else glColor3ub(0,0,0); + } else { + glColor3ub(0,0,0); + } + + x= but->x1+4.0; + + glRasterPos2f( x, (but->y1+but->y2- 9.0)/2.0); + BMF_DrawString(but->font, but->drawstr); + + if(cpoin) { + len= BMF_GetStringWidth(but->font, cpoin+1); + glRasterPos2f( but->x2 - len*but->aspect-3, (but->y1+but->y2- 9.0)/2.0); + BMF_DrawString(but->font, cpoin+1); + *cpoin= '|'; + } + } + } +} + +static void ui_draw_but_LABEL(uiBut *but) +{ + float x; + int sel; + + sel= but->min!=0.0; + + if(sel) glColor3ub(255,255,255); + else glColor3ub(0,0,0); + + if( but->flag & UI_HAS_ICON ) { + ui_draw_icon(but, but->icon); + } + else if(but->drawstr[0]!=0) { + + if(but->flag & UI_TEXT_LEFT) x= but->x1+4.0; + else x= (but->x1+but->x2-but->strwidth+1)/2.0; + + glRasterPos2f( x, (but->y1+but->y2- 9.0)/2.0); + + BMF_DrawString(but->font, but->drawstr+but->ofs); + } +} + +static void ui_draw_but_SEPR(uiBut *but) +{ + float y= (but->y1+but->y2)/2.0; + + glColor3ub(0,0,0); + fdrawline(but->x1, y+but->aspect, but->x2, y+but->aspect); + glColor3ub(255,255,255); + fdrawline(but->x1, y, but->x2, y); +} + +static void ui_draw_but_LINK(uiBut *but) +{ + ui_draw_icon(but, but->icon); +} + + +static void ui_draw_but(uiBut *but) +{ + double value; + float fac, x1, y1, x2, y2, *fp; + short a; + char colr, colg, colb; + + if(but==0) return; + + if(UIfrontbuf) { + glDrawBuffer(GL_FRONT); + if(but->win==curarea->headwin) curarea->head_swap= WIN_FRONT_OK; + else curarea->win_swap= WIN_FRONT_OK; + } + + switch (but->type) { + + case BUT: + case ROW: + case TOG: + case TOGR: + case TOGN: + case ICONTOG: + case NUM: + case KEYEVT: + case IDPOIN: + ui_draw_but_BUT(but); + break; + + case TEX: + ui_draw_but_TEX(but); + break; + + case BUTM: + case BLOCK: + ui_draw_but_BUTM(but); + break; + + case ICONROW: + ui_draw_but_BUT(but); + + /* teken pijltjes, icon is standaard RGB */ + a= (but->y1+but->y2)/2; + + glColor3ub(0,0,0); + sdrawline((short)(but->x1-1), (short)(a-2), (short)(but->x1-1), (short)(a+2)); + sdrawline((short)(but->x1-2), (short)(a-1), (short)(but->x1-2), (short)(a+1)); + sdrawline((short)(but->x1-3), a, (short)(but->x1-3), a); + glColor3ub(255,255,255); + sdrawline((short)(but->x1-3), (short)(a-1), (short)(but->x1-1), (short)(a-3)); + + glColor3ub(0,0,0); + sdrawline((short)(but->x2+1), (short)(a-2), (short)(but->x2+1), (short)(a+2)); + sdrawline((short)(but->x2+2), (short)(a-1), (short)(but->x2+2), (short)(a+1)); + sdrawline((short)(but->x2+3), a, (short)(but->x2+3), a); + glColor3ub(255,255,255); + sdrawline((short)(but->x2+3), (short)(a-1), (short)(but->x2+1), (short)(a-3)); + + break; + + case MENU: + + ui_draw_but_BUT(but); + + /* als er ruimte is: teken symbooltje */ + if(but->strwidth+10 < but->x2-but->x1) { + int h; + + h= but->y2- but->y1; + x1= but->x2-0.66*h; x2= x1+.33*h; + y1= but->y1+.42*h; y2= y1+.16*h; + + glColor3ub(0,0,0); + glRecti(x1, y1, x2, y2); + glColor3ub(255,255,255); + glRecti(x1-1, y1+1, x2-1, y2+1); + } + break; + + case NUMSLI: + case HSVSLI: + + ui_draw_but_BUT(but); + + /* de slider */ + + x1= but->x1; x2= but->x2; + y1= but->y1; y2= but->y2; + + but->x1= (but->x1+but->x2)/2; + but->x2-= 9; + but->y1= -2+(but->y1+but->y2)/2; + but->y2= but->y1+6; + + value= ui_get_but_val(but); + fac= (value-but->min)*(but->x2-but->x1-but->y2+but->y1)/(but->max - but->min); + ui_emboss_slider(but, fac); + + but->x1= x1; but->x2= x2; + but->y1= y1; but->y2= y2; + + break; + + case TOG3: + ui_draw_but_TOG3(but); + break; + + case LABEL: + ui_draw_but_LABEL(but); + break; + + case SLI: + break; + + case SCROLL: + break; + + case SEPR: + ui_draw_but_SEPR(but); + break; + + case COL: + ui_draw_but_BUT(but); + + if( but->pointype==FLO ) { + fp= (float *)but->poin; + colr= floor(255.0*fp[0]+0.5); + colg= floor(255.0*fp[1]+0.5); + colb= floor(255.0*fp[2]+0.5); + } + else { + char *cp= (char *)but->poin; + colr= cp[0]; + colg= cp[1]; + colb= cp[2]; + } + glColor3ub(colr, colg, colb); + glRects((short)(but->x1+2), (short)(but->y1+2), (short)(but->x2-2), (short)(but->y2-2)); + break; + + case LINK: + ui_draw_but_LINK(but); + break; + + case INLINK: + ui_draw_but_LINK(but); + break; + } + + if(UIfrontbuf) { + glFinish(); + glDrawBuffer(GL_BACK); + } +} + +void uiDrawMenuBox(float minx, float miny, float maxx, float maxy) +{ + glRectf(minx, miny, maxx, maxy); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + glColor4ub(0, 0, 0, 100); + fdrawline(minx+4, miny-1, maxx+1, miny-1); + fdrawline(maxx+1, miny-1, maxx+1, maxy-4); + + glColor4ub(0, 0, 0, 75); + fdrawline(minx+4, miny-2, maxx+2, miny-2); + fdrawline(maxx+2, miny-2, maxx+2, maxy-4); + + glColor4ub(0, 0, 0, 50); + fdrawline(minx+4, miny-3, maxx+3, miny-3); + fdrawline(maxx+3, miny-3, maxx+3, maxy-4); + + glDisable(GL_BLEND); + + /* below */ + glColor3ub(0,0,0); + fdrawline(minx, miny, maxx, miny); + + /* right */ + fdrawline(maxx, miny, maxx, maxy); + + /* top */ + glColor3ub(255,255,255); + fdrawline(minx, maxy, maxx, maxy); + + /* left */ + fdrawline(minx, miny, minx, maxy); +} + +static void ui_draw_linkline(BIFColorID col, uiLinkLine *line) +{ + float vec1[2], vec2[2]; + + if(line->from==NULL || line->to==NULL) return; + + vec1[0]= (line->from->x1+line->from->x2)/2.0; + vec1[1]= (line->from->y1+line->from->y2)/2.0; + vec2[0]= (line->to->x1+line->to->x2)/2.0; + vec2[1]= (line->to->y1+line->to->y2)/2.0; + + if(line->flag & UI_SELECT) BIF_set_color(col, COLORSHADE_LIGHT); + else glColor3ub(0,0,0); + fdrawline(vec1[0], vec1[1], vec2[0], vec2[1]); +} + +static void ui_draw_links(uiBlock *block) +{ + uiBut *but; + uiLinkLine *line; + + but= block->buttons.first; + while(but) { + if(but->type==LINK && but->link) { + line= but->link->lines.first; + while(line) { + ui_draw_linkline(but->col, line); + line= line->next; + } + } + but= but->next; + } +} + + + +/* ******************* block calc ************************* */ + +void uiBoundsBlock(uiBlock *block, int addval) +{ + uiBut *bt; + + block->minx= block->miny= 10000; + block->maxx= block->maxy= -10000; + + bt= block->buttons.first; + while(bt) { + if(bt->x1 < block->minx) block->minx= bt->x1; + if(bt->y1 < block->miny) block->miny= bt->y1; + + if(bt->x2 > block->maxx) block->maxx= bt->x2; + if(bt->y2 > block->maxy) block->maxy= bt->y2; + + bt= bt->next; + } + + block->minx -= addval; + block->miny -= addval; + block->maxx += addval; + block->maxy += addval; +} + +static void ui_positionblock(uiBlock *block, uiBut *but) +{ + /* position block relative to but */ + uiBut *bt; + int xsize, ysize, xof=0, yof=0; + + block->minx= block->miny= 10000; + block->maxx= block->maxy= -10000; + + bt= block->buttons.first; + while(bt) { + if(bt->x1 < block->minx) block->minx= bt->x1; + if(bt->y1 < block->miny) block->miny= bt->y1; + + if(bt->x2 > block->maxx) block->maxx= bt->x2; + if(bt->y2 > block->maxy) block->maxy= bt->y2; + + bt= bt->next; + } + + block->minx-= 2.0; block->miny-= 2.0; + block->maxx+= 2.0; block->maxy+= 2.0; + + xsize= block->maxx - block->minx; + ysize= block->maxy - block->miny; + + if(but) { + rctf butrct; + short left=0, right=0, top=0, down=0; + short dir1, dir2 = 0; + + butrct.xmin= but->x1; butrct.xmax= but->x2; + butrct.ymin= but->y1; butrct.ymax= but->y2; + + /* added this for submenu's... */ + Mat4CpyMat4(UIwinmat, block->winmat); + + ui_graphics_to_window(block->win, &butrct.xmin, &butrct.ymin); + ui_graphics_to_window(block->win, &butrct.xmax, &butrct.ymax); + + if( butrct.xmin-xsize > 0.0) left= 1; + if( butrct.xmax+xsize < G.curscreen->sizex) right= 1; + if( butrct.ymin-ysize > 0.0) down= 1; + if( butrct.ymax+ysize < G.curscreen->sizey) top= 1; + + dir1= block->direction; + if(dir1==UI_LEFT || dir1==UI_RIGHT) dir2= UI_DOWN; + if(dir1==UI_TOP || dir1==UI_DOWN) dir2= UI_LEFT; + + if(dir1==UI_LEFT && left==0) dir1= UI_RIGHT; + if(dir1==UI_RIGHT && right==0) dir1= UI_LEFT; + /* this is aligning, not append! */ + if(dir2==UI_LEFT && right==0) dir2= UI_RIGHT; + if(dir2==UI_RIGHT && left==0) dir2= UI_LEFT; + + if(dir1==UI_TOP && top==0) dir1= UI_DOWN; + if(dir1==UI_DOWN && down==0) dir1= UI_TOP; + if(dir2==UI_TOP && top==0) dir2= UI_DOWN; + if(dir2==UI_DOWN && down==0) dir2= UI_TOP; + + if(dir1==UI_LEFT) { + xof= but->x1 - block->maxx; + if(dir2==UI_TOP) yof= but->y1 - block->miny; + else yof= but->y2 - block->maxy; + } + else if(dir1==UI_RIGHT) { + xof= but->x2 - block->minx; + if(dir2==UI_TOP) yof= but->y1 - block->miny; + else yof= but->y2 - block->maxy; + } + else if(dir1==UI_TOP) { + yof= but->y2 - block->miny+1; + if(dir2==UI_RIGHT) xof= but->x2 - block->maxx; + else xof= but->x1 - block->minx; + } + else if(dir1==UI_DOWN) { + yof= but->y1 - block->maxy-1; + if(dir2==UI_RIGHT) xof= but->x2 - block->maxx; + else xof= but->x1 - block->minx; + } + + + + // apply requested offset in the block + + xof += block->xofs; + + yof += block->yofs; + + } + + /* apply */ + bt= block->buttons.first; + while(bt) { + bt->x1 += xof; + bt->x2 += xof; + bt->y1 += yof; + bt->y2 += yof; + + ui_graphics_to_window(block->win, &bt->x1, &bt->y1); + ui_graphics_to_window(block->win, &bt->x2, &bt->y2); + + bt->aspect= 1.0; + + bt= bt->next; + } + + block->minx += xof; + block->miny += yof; + block->maxx += xof; + block->maxy += yof; + + ui_graphics_to_window(block->win, &block->minx, &block->miny); + ui_graphics_to_window(block->win, &block->maxx, &block->maxy); + +} + + +static void ui_autofill(uiBlock *block) +{ + uiBut *but; + float *maxw, *maxh, startx = 0, starty, height = 0; + float totmaxh; + int rows=0, /* cols=0, */ i, lasti; + + + /* first count rows */ + but= block->buttons.last; + rows= but->x1+1; + + /* calculate max width / height for each row */ + maxw= MEM_callocN(sizeof(float)*rows, "maxw"); + maxh= MEM_callocN(sizeof(float)*rows, "maxh"); + but= block->buttons.first; + while(but) { + i= but->x1; + if( maxh[i] < but->y2) maxh[i]= but->y2; + maxw[i] += but->x2; + but= but->next; + } + + totmaxh= 0.0; + for(i=0; i<rows; i++) totmaxh+= maxh[i]; + + /* apply widths/heights */ + starty= block->maxy; + but= block->buttons.first; + lasti= -1; + while(but) { + + i= but->x1; + + if(i!=lasti) { + startx= block->minx; + height= (maxh[i]*(block->maxy-block->miny))/totmaxh; + starty-= height; + lasti= i; + } + + but->y1= starty+but->aspect; + but->y2= but->y1+height-but->aspect; + + but->x2= (but->x2*(block->maxx-block->minx))/maxw[i]; + but->x1= startx+but->aspect; + + startx+= but->x2; + but->x2+= but->x1-but->aspect; + + ui_check_but(but); + + but= but->next; + } + + MEM_freeN(maxw); MEM_freeN(maxh); + block->autofill= 0; +} + +static void ui_drawblock_int(uiBlock *block) +{ + uiBut *but; + + if(block->autofill) ui_autofill(block); + if(block->minx==0.0 && block->maxx==0.0) uiBoundsBlock(block, 0); + + if(block->flag & UI_BLOCK_LOOP) { + BIF_set_color(block->col, COLORSHADE_HILITE); + uiDrawMenuBox(block->minx, block->miny, block->maxx, block->maxy); + } + + for (but= block->buttons.first; but; but= but->next) { + ui_draw_but(but); + } + + if(UIfrontbuf) glDrawBuffer(GL_FRONT); + ui_draw_links(block); + if(UIfrontbuf) { + glFinish(); + glDrawBuffer(GL_BACK); + } +} + +void uiDrawBlock(uiBlock *block) +{ + ui_drawblock_int(block); +} + +/* ************* MENUBUTS *********** */ + +typedef struct { + char *str; + int retval; +} MenuEntry; + +typedef struct { + char *instr; + char *title; + + MenuEntry *items; + int nitems, itemssize; +} MenuData; + +static MenuData *menudata_new(char *instr) { + MenuData *md= MEM_mallocN(sizeof(*md), "MenuData"); + + md->instr= instr; + md->title= NULL; + md->items= NULL; + md->nitems= md->itemssize= 0; + + return md; +} + +static void menudata_set_title(MenuData *md, char *title) { + if (!md->title) + md->title= title; +} + +static void menudata_add_item(MenuData *md, char *str, int retval) { + if (md->nitems==md->itemssize) { + int nsize= md->itemssize?(md->itemssize<<1):1; + MenuEntry *oitems= md->items; + + md->items= MEM_mallocN(nsize*sizeof(*md->items), "md->items"); + if (oitems) { + memcpy(md->items, oitems, md->nitems*sizeof(*md->items)); + MEM_freeN(oitems); + } + + md->itemssize= nsize; + } + + md->items[md->nitems].str= str; + md->items[md->nitems].retval= retval; + md->nitems++; +} + +static void menudata_free(MenuData *md) { + MEM_freeN(md->instr); + if (md->items) + MEM_freeN(md->items); + MEM_freeN(md); +} + + /** + * Parse menu description strings, string is of the + * form "[sss%t|]{(sss[%xNN]|), (%l|)}", ssss%t indicates the + * menu title, sss or sss%xNN indicates an option, + * if %xNN is given then NN is the return value if + * that option is selected otherwise the return value + * is the index of the option (starting with 1). %l + * indicates a seperator. + * + * @param str String to be parsed. + * @retval new menudata structure, free with menudata_free() + */ +static MenuData *decompose_menu_string(char *str) +{ + char *instr= BLI_strdup(str); + MenuData *md= menudata_new(instr); + char *nitem= NULL, *s= instr; + int nretval= 1, nitem_is_title= 0; + + while (1) { + char c= *s; + + if (c=='%') { + if (s[1]=='x') { + nretval= atoi(s+2); + + *s= '\0'; + s++; + } else if (s[1]=='t') { + nitem_is_title= 1; + + *s= '\0'; + s++; + } else if (s[1]=='l') { + nitem= "%l"; + s++; + } + } else if (c=='|' || c=='\0') { + if (nitem) { + *s= '\0'; + + if (nitem_is_title) { + menudata_set_title(md, nitem); + nitem_is_title= 0; + } else { + menudata_add_item(md, nitem, nretval); + nretval= md->nitems+1; + } + + nitem= NULL; + } + + if (c=='\0') + break; + } else if (!nitem) + nitem= s; + + s++; + } + + return md; +} + +static void ui_set_name_menu(uiBut *but, int value) +{ + MenuData *md; + int i; + + md= decompose_menu_string(but->str); + for (i=0; i<md->nitems; i++) + if (md->items[i].retval==value) + strcpy(but->drawstr, md->items[i].str); + menudata_free(md); +} + + +static int ui_do_but_MENU(uiBut *but) +{ + uiBlock *block; + ListBase listb={NULL, NULL}; + double fvalue; + int width, height, a, xmax, ymax, starty, endx, endy; + short startx; + int columns=1, rows=0, boxh, event; + short x1, y1; + short mval[2], mousemove[2]; + MenuData *md; + + but->flag |= UI_SELECT; + ui_draw_but(but); + + block= uiNewBlock(&listb, "menu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT; + + md= decompose_menu_string(but->str); + + /* columns and row calculation */ + columns= (md->nitems+20)/20; + if (columns<1) columns= 1; + + rows= (int) md->nitems/columns; + if (rows<1) rows= 1; + + while (rows*columns<md->nitems) rows++; + + /* size and location */ + if(md->title) width= 2*strlen(md->title)+BMF_GetStringWidth(block->curfont, md->title); + else width= 0; + for(a=0; a<md->nitems; a++) { + xmax= BMF_GetStringWidth(block->curfont, md->items[a].str); + if(xmax>width) width= xmax; + } + + width+= 10; + if (width<50) width=50; + + boxh= TBOXH; + + height= rows*boxh; + if (md->title) height+= boxh; + + xmax = G.curscreen->sizex; + ymax = G.curscreen->sizey; + + getmouseco_sc(mval); + + /* find active item */ + fvalue= ui_get_but_val(but); + for(a=0; a<md->nitems; a++) { + if( md->items[a].retval== (int)fvalue ) break; + } + /* no active item? */ + if(a==md->nitems) { + if(md->title) a= -1; + else a= 0; + } + + if(a>0) startx = mval[0]-width/2 - ((int)(a)/rows)*width; + else startx= mval[0]-width/2; + starty = mval[1]-height + boxh/2 + ((a)%rows)*boxh; + + if (md->title) starty+= boxh; + + mousemove[0]= mousemove[1]= 0; + + if(startx<10) { + mousemove[0]= 10-startx; + startx= 10; + } + if(starty<10) { + mousemove[1]= 10-starty; + starty= 10; + } + + endx= startx+width*columns; + endy= starty+height; + + if(endx>xmax) { + mousemove[0]= xmax-endx-10; + endx= xmax-10; + startx= endx-width*columns; + } + if(endy>ymax) { + mousemove[1]= ymax-endy-10; + endy= ymax-10; + starty= endy-height; + } + + warp_pointer(mval[0]+mousemove[0], mval[1]+mousemove[1]); + + mousemove[0]= mval[0]; + mousemove[1]= mval[1]; + + /* here we go! */ + + if(md->title) { + uiBut *bt; + uiSetCurFont(block, block->font+1); + bt= uiDefBut(block, LABEL, 0, md->title, startx, (short)(starty+rows*boxh), (short)width, (short)boxh, NULL, 0.0, 0.0, 0, 0, ""); + uiSetCurFont(block, block->font); + bt->flag= UI_TEXT_LEFT; + } + + for(a=0; a<md->nitems; a++) { + + x1= startx + width*((int)a/rows); + y1= starty - boxh*(a%rows) + (rows-1)*boxh; + + if (strcmp(md->items[a].str, "%l")==0) { + uiDefBut(block, SEPR, B_NOP, "", x1, y1,(short)(width-(rows>1)), (short)(boxh-1), NULL, 0.0, 0.0, 0, 0, ""); + } + else { + uiDefBut(block, BUTM|but->pointype, but->retval, md->items[a].str, x1, y1,(short)(width-(rows>1)), (short)(boxh-1), but->poin, (float) md->items[a].retval, 0.0, 0, 0, ""); + } + } + + uiBoundsBlock(block, 3); + + event= uiDoBlocks(&listb, 0); + + /* ready, restore stuff */ + UIfrontbuf= 1; + + menudata_free(md); + + if((event & UI_RETURN_OUT)==0) warp_pointer(mousemove[0], mousemove[1]); + + but->flag &= ~UI_SELECT; + ui_check_but(but); + ui_draw_but(but); + + uibut_do_func(but); + + return event; +} + +/* ************* EVENTS ************* */ + +void uiGetMouse(int win, short *adr) +{ + int x, y; + float xwin, ywin; + + getmouseco_sc(adr); + if (win == G.curscreen->mainwin) return; + + bwin_getsuborigin(win, &x, &y); + + adr[0]-= x; + adr[1]-= y; + + xwin= adr[0]; + ywin= adr[1]; + + ui_window_to_graphics(win, &xwin, &ywin); + + adr[0]= (short)(xwin+0.5); + adr[1]= (short)(ywin+0.5); +} + +static void ui_is_but_sel(uiBut *but) +{ + double value; + int lvalue; + short push=0, true=1; + + value= ui_get_but_val(but); + + if( but->type==TOGN ) true= 0; + + if( but->bit ) { + lvalue= (int)value; + if( BTST(lvalue, (but->bitnr)) ) push= true; + else push= !true; + } + else { + switch(but->type) { + case BUT: + push= 0; + break; + case KEYEVT: + if (value==-1) push= 1; + break; + case TOG: + case TOGR: + case TOG3: + case ICONTOG: + if(value!=0.0) push= 1; + break; + case TOGN: + if(value==0.0) push= 1; + break; + case ROW: + if(value == but->max) push= 1; + break; + case COL: + push= 1; + break; + default: + push= 2; + break; + } + } + + if(push==2); + else if(push==1) but->flag |= UI_SELECT; + else but->flag &= ~UI_SELECT; +} + +static int ui_do_but_BUT(uiBut *but) +{ + int activated; + + do { + int oflag= but->flag; + short mval[2]; + + uiGetMouse(mywinget(), mval); + + if (uibut_contains_pt(but, mval)) + but->flag |= UI_SELECT; + else + but->flag &= ~UI_SELECT; + + if (but->flag != oflag) + ui_draw_but(but); + + PIL_sleep_ms(1); + } while (get_mbut() & L_MOUSE); + + activated= (but->flag & UI_SELECT); + + if(activated) { + uibut_do_func(but); + } + + but->flag &= ~UI_SELECT; + ui_draw_but(but); + + return activated?but->retval:0; +} + +static int ui_do_but_KEYEVT(uiBut *but) +{ + unsigned short event= 0; + short val; + + /* flag for ui_check_but */ + ui_set_but_val(but, -1); + ui_check_but(but); + ui_draw_but(but); + + do { + event= extern_qread(&val); + } while (!event || !val || ELEM(event, MOUSEX, MOUSEY)); + + if (!key_event_to_string(event)[0]) event= 0; + + ui_set_but_val(but, (double) event); + ui_check_but(but); + ui_draw_but(but); + + return (event!=0); +} + +static int ui_do_but_TOG(uiBlock *block, uiBut *but) +{ + uiBut *bt; + double value; + int w, lvalue, push; + + value= ui_get_but_val(but); + lvalue= (int)value; + + if(but->bit) { + w= BTST(lvalue, but->bitnr); + if(w) lvalue = BCLR(lvalue, but->bitnr); + else lvalue = BSET(lvalue, but->bitnr); + + if(but->type==TOGR) { + if( (get_qual() & LR_SHIFTKEY)==0 ) { + lvalue= 1<<(but->bitnr); + + ui_set_but_val(but, (double)lvalue); + + bt= block->buttons.first; + while(bt) { + if( bt!=but && bt->poin==but->poin ) { + ui_is_but_sel(bt); + ui_draw_but(bt); + } + bt= bt->next; + } + } + else { + if(lvalue==0) lvalue= 1<<(but->bitnr); + } + } + ui_set_but_val(but, (double)lvalue); + if(but->type==ICONTOG) ui_check_but(but); + ui_draw_but(but); + } + else { + + if(value==0.0) push= 1; + else push= 0; + + if(but->type==TOGN) push= !push; + ui_set_but_val(but, (double)push); + if(but->type==ICONTOG) ui_check_but(but); + ui_draw_but(but); + } + + /* no while loop...this button is used for viewmove */ + + uibut_do_func(but); + + return but->retval; +} + +static int ui_do_but_ROW(uiBlock *block, uiBut *but) +{ + uiBut *bt; + + ui_set_but_val(but, but->max); + ui_draw_but(but); + + bt= block->buttons.first; + while(bt) { + if( bt!=but && bt->type==ROW ) { + if(bt->min==but->min) { + ui_is_but_sel(bt); + ui_draw_but(bt); + } + } + bt= bt->next; + } + return but->retval; +} + +static int ui_do_but_TEX(uiBut *but) +{ + unsigned short dev; + short x, mval[2], len=0, dodraw; + char *str, backstr[UI_MAX_DRAW_STR]; + + str= (char *)but->poin; + + but->flag |= UI_SELECT; + + uiGetMouse(mywinget(), mval); + + /* calculate cursor pos with current mousecoords */ + BLI_strncpy(backstr, but->drawstr, UI_MAX_DRAW_STR); + but->pos= strlen(backstr)-but->ofs; + while((but->aspect*BMF_GetStringWidth(but->font, backstr+but->ofs) + but->x1) > mval[0]) { + if (but->pos <= 0) break; + but->pos--; + backstr[but->pos+but->ofs] = 0; + } + + but->pos -= strlen(but->str); + but->pos += but->ofs; + if(but->pos<0) but->pos= 0; + + /* backup */ + BLI_strncpy(backstr, but->poin, UI_MAX_DRAW_STR); + + ui_draw_but(but); + + while (get_mbut() & L_MOUSE) BIF_wait_for_statechange(); + len= strlen(str); + but->min= 0.0; + + while(TRUE) { + char ascii; + short val; + + dodraw= 0; + dev = extern_qread_ext(&val, &ascii); + + if(dev==INPUTCHANGE) break; + else if(get_mbut() & L_MOUSE) break; + else if(get_mbut() & R_MOUSE) break; + else if(dev==ESCKEY) break; + else if(dev==MOUSEX) val= 0; + else if(dev==MOUSEY) val= 0; + + if(ascii) { + if( ascii>31 && ascii<127) { + if(len < but->max) { + for(x= but->max; x>but->pos; x--) + str[x]= str[x-1]; + str[but->pos]= ascii; + but->pos++; + len++; + str[len]= '\0'; + dodraw= 1; + } + } + } + else if(val) { + + if(dev==RIGHTARROWKEY) { + if(G.qual & LR_SHIFTKEY) but->pos= strlen(str); + else but->pos++; + if(but->pos>strlen(str)) but->pos= strlen(str); + dodraw= 1; + } + else if(dev==LEFTARROWKEY) { + if(G.qual & LR_SHIFTKEY) but->pos= 0; + else if(but->pos>0) but->pos--; + dodraw= 1; + } + else if(dev==PADENTER || dev==RETKEY) { + break; + } + else if(dev==BACKSPACEKEY) { + if(len!=0) { + if(get_qual() & LR_SHIFTKEY) { + str[0]= 0; + but->pos= 0; + len= 0; + dodraw= 1; + } + else if(but->pos>0) { + for(x=but->pos; x<=strlen(str); x++) + str[x-1]= str[x]; + but->pos--; + str[--len]='\0'; + dodraw= 1; + } + } + } + } + if(dodraw) { + ui_check_but(but); + ui_draw_but(but); + } + } + + if(dev==ESCKEY) strcpy(but->poin, backstr); + but->pos= -1; + but->flag &= ~UI_SELECT; + + uibut_do_func(but); + + ui_check_but(but); + ui_draw_but(but); + + if(dev!=ESCKEY) return but->retval; + else return 0; +} + + +static int uiActAsTextBut(uiBut *but) +{ + double value; + float min, max; + int temp, retval, textleft; + char str[UI_MAX_DRAW_STR], *point; + + + value= ui_get_but_val(but); + if( but->pointype==FLO ) { + sprintf(str, "%.3f", value); + } + else { + sprintf(str, "%d", (int)value); + } + point= but->poin; + but->poin= str; + min= but->min; + max= but->max; + but->min= 0.0; + but->max= 15.0; + temp= but->type; + but->type= TEX; + textleft= but->flag & UI_TEXT_LEFT; + but->flag |= UI_TEXT_LEFT; + ui_check_but(but); + + retval= ui_do_but_TEX(but); + + but->type= temp; + but->poin= point; + but->min= min; + but->max= max; + if(textleft==0) but->flag &= ~UI_TEXT_LEFT; + + if( but->pointype==FLO ) value= atof(str); + else value= atoi(str); + + if(value<min) value= min; + if(value>max) value= max; + + ui_set_but_val(but, value); + ui_check_but(but); + ui_draw_but(but); + + return retval; +} + +static int ui_do_but_NUM(uiBut *but) +{ + double value; + float deler, fstart, f, tempf; + int lvalue, temp; /* , firsttime=1; */ + short qual, sx, mval[2], pos=0; + + + but->flag |= UI_SELECT; + ui_draw_but(but); + + uiGetMouse(mywinget(), mval); + value= ui_get_but_val(but); + + sx= mval[0]; + fstart= (value - but->min)/(but->max-but->min); + f= fstart; + + temp= (int)value; + tempf= value; + + if(get_qual() & LR_SHIFTKEY) { /* make it textbut */ + if( uiActAsTextBut(but) ) return but->retval; + else return 0; + } + + /* firsttime: this button can be approached with enter as well */ + while (get_mbut() & L_MOUSE) { + qual= get_qual(); + + deler= 500; + if( but->pointype!=FLO ) { + + if( (but->max-but->min)<100 ) deler= 200.0; + if( (but->max-but->min)<25 ) deler= 50.0; + + } + if(qual & LR_SHIFTKEY) deler*= 10.0; + if(qual & LR_ALTKEY) deler*= 20.0; + + uiGetMouse(mywinget(), mval); + + if(mval[0] != sx) { + + f+= ((float)(mval[0]-sx))/deler; + if(f>1.0) f= 1.0; + if(f<0.0) f= 0.0; + sx= mval[0]; + tempf= ( but->min + f*(but->max-but->min)); + + if( but->pointype!=FLO ) { + + temp= floor(tempf+.5); + + if(tempf==but->min || tempf==but->max); + else if(qual & LR_CTRLKEY) temp= 10*(temp/10); + + if( temp>=but->min && temp<=but->max) { + + value= ui_get_but_val(but); + lvalue= (int)value; + + if(temp != lvalue ) { + pos= 1; + ui_set_but_val(but, (double)temp); + ui_check_but(but); + ui_draw_but(but); + + uibut_do_func(but); + } + } + + } + else { + temp= 0; + if(qual & LR_CTRLKEY) { + if(tempf==but->min || tempf==but->max); + else if(but->max-but->min < 2.10) tempf= 0.1*floor(10*tempf); + else if(but->max-but->min < 21.0) tempf= floor(tempf); + else tempf= 10.0*floor(tempf/10.0); + } + + if( tempf>=but->min && tempf<=but->max) { + value= ui_get_but_val(but); + + if(tempf != value ) { + pos= 1; + ui_set_but_val(but, tempf); + ui_check_but(but); + ui_draw_but(but); + } + } + + } + } + BIF_wait_for_statechange(); + } + + if(pos==0) { /* plus 1 or minus 1 */ + if( but->pointype!=FLO ) { + + if(sx<(but->x1+but->x2)/2) temp--; + else temp++; + + if( temp>=but->min && temp<=but->max) + ui_set_but_val(but, (double)temp); + + } + else { + + if(sx<(but->x1+but->x2)/2) tempf-= 0.01*but->a1; + else tempf+= 0.01*but->a1; + + if (tempf < but->min) tempf = but->min; + if (tempf > but->max) tempf = but->max; + + ui_set_but_val(but, tempf); + + } + } + + but->flag &= ~UI_SELECT; + ui_check_but(but); + ui_draw_but(but); + + return but->retval; +} + +static int ui_do_but_TOG3(uiBut *but) +{ + + if( but->pointype==SHO ) { + short *sp= (short *)but->poin; + + if( BTST(sp[1], but->bitnr)) { + sp[1]= BCLR(sp[1], but->bitnr); + sp[0]= BCLR(sp[0], but->bitnr); + } + else if( BTST(sp[0], but->bitnr)) { + sp[1]= BSET(sp[1], but->bitnr); + } else { + sp[0]= BSET(sp[0], but->bitnr); + } + } + else { + if( BTST(*(but->poin+2), but->bitnr)) { + *(but->poin+2)= BCLR(*(but->poin+2), but->bitnr); + *(but->poin)= BCLR(*(but->poin), but->bitnr); + } + else if( BTST(*(but->poin), but->bitnr)) { + *(but->poin+2)= BSET(*(but->poin+2), but->bitnr); + } else { + *(but->poin)= BSET(*(but->poin), but->bitnr); + } + } + + ui_is_but_sel(but); + ui_draw_but(but); + + return but->retval; +} + +static int ui_do_but_ICONROW(uiBut *but) +{ + ListBase listb= {NULL, NULL}; + uiBlock *block; + int a; + + but->flag |= UI_SELECT; + ui_draw_but(but); + + /* here we go! */ + block= uiNewBlock(&listb, "menu", UI_EMBOSSP, UI_HELV, but->win); + block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT; + + for(a=(int)but->min; a<=(int)but->max; a++) { + uiDefIconBut(block, BUTM|but->pointype, but->retval, but->icon+(a-but->min), 0, (short)(18*a), (short)(but->x2-but->x1-4), 18, but->poin, (float)a, 0.0, 0, 0, ""); + } + block->direction= UI_TOP; + ui_positionblock(block, but); + + /* the block is made with but-win, but is handled in mainwin space... + this is needs better implementation */ + block->win= G.curscreen->mainwin; + + uiDoBlocks(&listb, 0); + + /* ready, restore stuff */ + UIfrontbuf= 1; + + but->flag &= ~UI_SELECT; + ui_check_but(but); + ui_draw_but(but); + + return but->retval; +} + +static int ui_do_but_IDPOIN(uiBut *but) +{ + char str[UI_MAX_DRAW_STR]; + ID *id; + + id= *but->idpoin_idpp; + if(id) strcpy(str, id->name+2); + else str[0]= 0; + + but->type= TEX; + but->poin= str; + but->min= 0.0; + but->max= 22.0; + ui_do_but_TEX(but); + but->poin= NULL; + but->type= IDPOIN; + + but->idpoin_func(str, but->idpoin_idpp); + ui_check_but(but); + ui_draw_but(but); + + return but->retval; +} + +static int ui_do_but_SLI(uiBut *but) +{ + float f, fstart, tempf = 0.0, deler, value; + int sx, h, temp, pos=0, lvalue, redraw; + short mval[2], qual; + float curmatrix[4][4]; + + value= ui_get_but_val(but); + uiGetMouse(mywinget(), mval); + + sx= mval[0]; + h= but->y2-but->y1; + fstart= but->max-but->min; + fstart= (value - but->min)/fstart; + temp= 32767; + + if( but->type==NUMSLI) deler= ( (but->x2-but->x1)/2 - h); + else if( but->type==HSVSLI) deler= ( (but->x2-but->x1)/2 - h); + else deler= (but->x2-but->x1-h); + + + while (get_mbut() & L_MOUSE) { + + qual= get_qual(); + uiGetMouse(mywinget(), mval); + + f= (float)(mval[0]-sx)/deler +fstart; + + if(qual & LR_CTRLKEY) { + if(qual & LR_SHIFTKEY) f= floor(f*100.0)/100.0; + else f= floor(f*10.0)/10.0; + } + else if (qual & LR_SHIFTKEY) { + f= (f-fstart)/10.0 + fstart; + } + + CLAMP(f, 0.0, 1.0); + tempf= but->min+f*(but->max-but->min); + + temp= floor(tempf+.5); + + value= ui_get_but_val(but); + lvalue= (int) value; + + if( but->pointype!=FLO ) + redraw= (temp != lvalue); + else + redraw= (tempf != value); + + if (redraw) { + pos= 1; + + ui_set_but_val(but, tempf); + ui_check_but(but); + ui_draw_but(but); + + if(but->a1) { /* colornummer */ + uiBut *bt= but->prev; + while(bt) { + if(bt->retval == but->a1) ui_draw_but(bt); + bt= bt->prev; + } + bt= but->next; + while(bt) { + if(bt->retval == but->a1) ui_draw_but(bt); + bt= bt->next; + } + } + /* save current window matrix (global UIwinmat) + because button callback function MIGHT change it + - which has until now occured through the Python API + */ + Mat4CpyMat4(curmatrix, UIwinmat); + uibut_do_func(but); + Mat4CpyMat4(UIwinmat, curmatrix); + } + else BIF_wait_for_statechange(); + } + + + if(temp!=32767 && pos==0) { /* plus 1 of min 1 */ + + if( but->type==SLI) f= (float)(mval[0]-but->x1)/(but->x2-but->x1-h); + else f= (float)(mval[0]- (but->x1+but->x2)/2)/( (but->x2-but->x1)/2 - h); + + f= but->min+f*(but->max-but->min); + + if( but->pointype!=FLO ) { + + if(f<temp) temp--; + else temp++; + if( temp>=but->min && temp<=but->max) + ui_set_but_val(but, (float)temp); + + } + else { + + if(f<tempf) tempf-=.01; + else tempf+=.01; + if( tempf>=but->min && tempf<=but->max) + ui_set_but_val(but, tempf); + + } + } + ui_check_but(but); + ui_draw_but(but); + + return but->retval; +} + +static int ui_do_but_NUMSLI(uiBut *but) +{ + short mval[2]; + + /* eerste bepalen of het slider is of textbut */ + uiGetMouse(mywinget(), mval); + + if(mval[0]>= -6+(but->x1+but->x2)/2 ) { /* slider */ + but->flag |= UI_SELECT; + ui_draw_but(but); + ui_do_but_SLI(but); + but->flag &= ~UI_SELECT; + } + else { + uiActAsTextBut(but); + } + + while(get_mbut() & L_MOUSE) BIF_wait_for_statechange(); + + ui_draw_but(but); + + /* hsv patch */ + if(but->type==HSVSLI) { + + if(but->str[0]=='H') { + ui_draw_but(but->next); + ui_draw_but(but->next->next); + } + else if(but->str[0]=='S') { + ui_draw_but(but->next); + ui_draw_but(but->prev); + } + else if(but->str[0]=='V') { + ui_draw_but(but->prev); + ui_draw_but(but->prev->prev); + } + } + + return but->retval; +} + +static int ui_do_but_BLOCK(uiBut *but) +{ + uiBlock *block; + + but->flag |= UI_SELECT; + ui_draw_but(but); + + block= but->block_func(0); + + ui_positionblock(block, but); + block->flag |= UI_BLOCK_LOOP; + block->win= G.curscreen->mainwin; + + /* postpone draw, this will cause a new window matrix, first finish all other buttons */ + block->flag |= UI_BLOCK_REDRAW; + + but->flag &= ~UI_SELECT; + + return 0; +} + +static int ui_do_but_BUTM(uiBut *but) +{ + + ui_set_but_val(but, but->min); + UIafterfunc= but->butm_func; + UIafterfunc_arg= but->butm_func_arg; + UIafterval= but->a2; + + return but->retval; +} + +static int ui_do_but_LABEL(uiBut *but) +{ + uibut_do_func(but); + return but->retval; +} + +static uiBut *ui_get_valid_link_button(uiBlock *block, uiBut *but, short *mval) +{ + uiBut *bt; + + /* find button to link to */ + for (bt= block->buttons.first; bt; bt= bt->next) + if(bt!=but && uibut_contains_pt(bt, mval)) + break; + + if (bt) { + if (but->type==LINK && bt->type==INLINK) { + if( but->link->tocode == (int)bt->min ) { + return bt; + } + } + else if(but->type==INLINK && bt->type==LINK) { + if( bt->link->tocode == (int)but->min ) { + return bt; + } + } + } + + return NULL; +} + +static int ui_is_a_link(uiBut *from, uiBut *to) +{ + uiLinkLine *line; + uiLink *link; + + link= from->link; + if(link) { + line= link->lines.first; + while(line) { + if(line->from==from && line->to==to) return 1; + line= line->next; + } + } + return 0; +} + +static uiBut *ui_find_inlink(uiBlock *block, void *poin) +{ + uiBut *but; + + but= block->buttons.first; + while(but) { + if(but->type==INLINK) { + if(but->poin == poin) return but; + } + but= but->next; + } + return NULL; +} + +static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt) +{ + uiLinkLine *line; + + line= MEM_callocN(sizeof(uiLinkLine), "linkline"); + BLI_addtail(listb, line); + line->from= but; + line->to= bt; +} + + +void uiComposeLinks(uiBlock *block) +{ + uiBut *but, *bt; + uiLink *link; + void ***ppoin; + int a; + + but= block->buttons.first; + while(but) { + if(but->type==LINK) { + link= but->link; + + /* for all pointers in the array */ + if(link) { + if(link->ppoin) { + ppoin= link->ppoin; + for(a=0; a < *(link->totlink); a++) { + bt= ui_find_inlink(block, (*ppoin)[a] ); + if(bt) { + ui_add_link_line(&link->lines, but, bt); + } + } + } + else if(link->poin) { + bt= ui_find_inlink(block, *(link->poin) ); + if(bt) { + ui_add_link_line(&link->lines, but, bt); + } + } + } + } + but= but->next; + } +} + +static void ui_add_link(uiBut *from, uiBut *to) +{ + /* in 'from' we have to add a link to 'to' */ + uiLink *link; + void **oldppoin; + int a; + + if(ui_is_a_link(from, to)) { + printf("already exists\n"); + return; + } + + link= from->link; + + /* are there more pointers allowed? */ + if(link->ppoin) { + oldppoin= *(link->ppoin); + + (*(link->totlink))++; + *(link->ppoin)= MEM_callocN( *(link->totlink)*sizeof(void *), "new link"); + + for(a=0; a< (*(link->totlink))-1; a++) { + (*(link->ppoin))[a]= oldppoin[a]; + } + (*(link->ppoin))[a]= to->poin; + + if(oldppoin) MEM_freeN(oldppoin); + } + else { + *(link->poin)= to->poin; + } + +} + +static int ui_do_but_LINK(uiBlock *block, uiBut *but) +{ + /* + * This button only visualizes, the dobutton mode + * can add a new link, but then the whole system + * should be redrawn/initialized. + * + */ + uiBut *bt=0, *bto=NULL; + short sval[2], mval[2], mvalo[2], first= 1; + + uiGetMouse(curarea->win, sval); + mvalo[0]= sval[0]; + mvalo[1]= sval[1]; + + while (get_mbut() & L_MOUSE) { + uiGetMouse(curarea->win, mval); + + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || first) { + /* clear completely, because of drawbuttons */ + bt= ui_get_valid_link_button(block, but, mval); + if(bt) { + bt->flag |= UI_ACTIVE; + ui_draw_but(bt); + } + if(bto && bto!=bt) { + bto->flag &= ~UI_ACTIVE; + ui_draw_but(bto); + } + bto= bt; + + if (!first) { + glutil_draw_front_xor_line(sval[0], sval[1], mvalo[0], mvalo[1]); + } + glutil_draw_front_xor_line(sval[0], sval[1], mval[0], mval[1]); + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + first= 0; + } + else BIF_wait_for_statechange(); + } + + if (!first) { + glutil_draw_front_xor_line(sval[0], sval[1], mvalo[0], mvalo[1]); + } + + if(bt) { + if(but->type==LINK) ui_add_link(but, bt); + else ui_add_link(bt, but); + + scrarea_queue_winredraw(curarea); + } + + return 0; +} + + +/* ************************************************ */ + +void uiSetButLock(int val, char *lockstr) +{ + UIlock |= val; + if (val) UIlockstr= lockstr; +} + +void uiClearButLock() +{ + UIlock= 0; + UIlockstr= NULL; +} + +/* ********************** NEXT/PREV for arrowkeys etc ************** */ + +static uiBut *ui_but_prev(uiBut *but) +{ + while(but->prev) { + but= but->prev; + if(but->type!=LABEL && but->type!=SEPR) return but; + } + return NULL; +} + +static uiBut *ui_but_next(uiBut *but) +{ + while(but->next) { + but= but->next; + if(but->type!=LABEL && but->type!=SEPR) return but; + } + return NULL; +} + +static uiBut *ui_but_first(uiBlock *block) +{ + uiBut *but; + + but= block->buttons.first; + while(but) { + if(but->type!=LABEL && but->type!=SEPR) return but; + but= but->next; + } + return NULL; +} + +static uiBut *ui_but_last(uiBlock *block) +{ + uiBut *but; + + but= block->buttons.last; + while(but) { + if(but->type!=LABEL && but->type!=SEPR) return but; + but= but->prev; + } + return NULL; +} + +/* *************************************************************** */ + + +/* is called when LEFTMOUSE is pressed or released + * return: butval or zero + */ +static int ui_do_button(uiBlock *block, uiBut *but, uiEvent *uevent) +{ + int retval= 0; + + if(but->lock) { + if (but->lockstr) { + error("%s", but->lockstr); + return 0; + } + } + else { + if( but->pointype ) { /* er is pointer nodig */ + if(but->poin==0 ) { + printf("DoButton pointer error: %s\n",but->str); + return 0; + } + } + } + + block->flag |= UI_BLOCK_BUSY; + + switch(but->type) { + case BUT: + if(uevent->val) retval= ui_do_but_BUT(but); + break; + + case KEYEVT: + if(uevent->val) retval= ui_do_but_KEYEVT(but); + break; + + case TOG: + case TOGR: + case ICONTOG: + case TOGN: + if(uevent->val) { + retval= ui_do_but_TOG(block, but); + } + break; + + case ROW: + if(uevent->val) retval= ui_do_but_ROW(block, but); + break; + + case SCROLL: + /* DrawBut(b, 1); */ + /* do_scrollbut(b); */ + /* DrawBut(b,0); */ + break; + + case NUM: + if(uevent->val) retval= ui_do_but_NUM(but); + break; + + case SLI: + case NUMSLI: + case HSVSLI: + if(uevent->val) retval= ui_do_but_NUMSLI(but); + break; + + case LABEL: + if(uevent->val) retval= ui_do_but_LABEL(but); + break; + + case TOG3: + if(uevent->val) retval= ui_do_but_TOG3(but); + break; + + case TEX: + if(uevent->val) retval= ui_do_but_TEX(but); + break; + + case MENU: + if(uevent->val) retval= ui_do_but_MENU(but); + break; + + case ICONROW: + if(uevent->val) retval= ui_do_but_ICONROW(but); + break; + + case IDPOIN: + if(uevent->val) retval= ui_do_but_IDPOIN(but); + break; + + case BLOCK: + if(uevent->val) retval= ui_do_but_BLOCK(but); + break; + + case BUTM: + retval= ui_do_but_BUTM(but); + break; + + case LINK: + case INLINK: + retval= ui_do_but_LINK(block, but); + break; + } + + block->flag &= ~UI_BLOCK_BUSY; + + return retval; +} + +static void ui_delete_active_linkline(uiBlock *block) +{ + uiBut *but; + uiLink *link; + uiLinkLine *line, *nline; + int a, b; + + but= block->buttons.first; + while(but) { + if(but->type==LINK && but->link) { + line= but->link->lines.first; + while(line) { + + nline= line->next; + + if(line->flag & UI_SELECT) { + BLI_remlink(&but->link->lines, line); + + link= line->from->link; + + /* are there more pointers allowed? */ + if(link->ppoin) { + + if(*(link->totlink)==1) { + *(link->totlink)= 0; + MEM_freeN(*(link->ppoin)); + *(link->ppoin)= NULL; + } + else { + b= 0; + for(a=0; a< (*(link->totlink)); a++) { + + if( (*(link->ppoin))[a] != line->to->poin ) { + (*(link->ppoin))[b]= (*(link->ppoin))[a]; + b++; + } + } + (*(link->totlink))--; + } + } + else { + *(link->poin)= NULL; + } + + MEM_freeN(line); + } + line= nline; + } + } + but= but->next; + } + + /* temporal! these buttons can be everywhere... */ + allqueue(REDRAWBUTSGAME, 0); +} + +static void ui_do_active_linklines(uiBlock *block, short *mval) +{ + uiBut *but; + uiLinkLine *line, *act=NULL; + float mindist= 12.0, fac, v1[2], v2[2], v3[3]; +/* int foundone=0; */ + + if(mval) { + v1[0]= mval[0]; + v1[1]= mval[1]; + + /* find a line close to the mouse */ + but= block->buttons.first; + while(but) { + if(but->type==LINK && but->link) { + line= but->link->lines.first; + while(line) { + v2[0]= line->from->x2; + v2[1]= (line->from->y1+line->from->y2)/2.0; + v3[0]= line->to->x1; + v3[1]= (line->to->y1+line->to->y2)/2.0; + + fac= PdistVL2Dfl(v1, v2, v3); + if(fac < mindist) { + mindist= fac; + act= line; + } + line= line->next; + } + } + but= but->next; + } + } + /* draw */ + glDrawBuffer(GL_FRONT); + + but= block->buttons.first; + while(but) { + if(but->type==LINK && but->link) { + line= but->link->lines.first; + while(line) { + if(line==act) { + if((line->flag & UI_SELECT)==0) { + line->flag |= UI_SELECT; + ui_draw_linkline(but->col, line); + } + } + else if(line->flag & UI_SELECT) { + line->flag &= ~UI_SELECT; + ui_draw_linkline(but->col, line); + } + line= line->next; + } + } + but= but->next; + } + + glFinish(); + glDrawBuffer(GL_BACK); +} + +/* return: + * UI_NOTHING pass event to other ui's + * UI_CONT don't pass event to other ui's + * UI_RETURN something happened, return, swallow event + */ +static int ui_do_block(uiBlock *block, uiEvent *uevent) +{ + uiBut *but, *bt; + int butevent, event, retval=UI_NOTHING, count, act=0; + int inside= 0, active=0; + + if(block->win != mywinget()) return UI_NOTHING; + + /* filter some unwanted events */ + if(uevent->event==LEFTSHIFTKEY || uevent->event==RIGHTSHIFTKEY) return UI_NOTHING; + + if(block->flag & UI_BLOCK_ENTER_OK) { + if(uevent->event == RETKEY && uevent->val) { + // printf("qual: %d %d %d\n", uevent->qual, get_qual(), G.qual); + if ((G.qual & LR_SHIFTKEY) == 0) { + return UI_RETURN_OK; + } + } + } + + Mat4CpyMat4(UIwinmat, block->winmat); + uiGetMouse(mywinget(), uevent->mval); /* transformed mouseco */ + + /* check boundbox */ + if( block->minx <= uevent->mval[0] && block->maxx >= uevent->mval[0] ) { + if( block->miny <= uevent->mval[1] && block->maxy >= uevent->mval[1] ) { + inside= 1; + } + } + + switch(uevent->event) { + case PAD8: case PAD2: + case UPARROWKEY: + case DOWNARROWKEY: + if(inside || (block->flag & UI_BLOCK_LOOP)) { + /* arrowkeys: only handle for block_loop blocks */ + event= 0; + if(block->flag & UI_BLOCK_LOOP) { + event= uevent->event; + if(event==PAD8) event= UPARROWKEY; + if(event==PAD2) event= DOWNARROWKEY; + } + else { + if(uevent->event==PAD8) event= UPARROWKEY; + if(uevent->event==PAD2) event= DOWNARROWKEY; + } + if(event && uevent->val) { + + but= block->buttons.first; + while(but) { + + but->flag &= ~UI_MOUSE_OVER; + + if(but->flag & UI_ACTIVE) { + but->flag &= ~UI_ACTIVE; + ui_draw_but(but); + + bt= ui_but_prev(but); + if(bt && event==UPARROWKEY) { + bt->flag |= UI_ACTIVE; + ui_draw_but(bt); + break; + } + bt= ui_but_next(but); + if(bt && event==DOWNARROWKEY) { + bt->flag |= UI_ACTIVE; + ui_draw_but(bt); + break; + } + } + but= but->next; + } + + /* nothing done */ + if(but==NULL) { + + if(event==UPARROWKEY) but= ui_but_last(block); + else but= ui_but_first(block); + + if(but) { + but->flag |= UI_ACTIVE; + ui_draw_but(but); + } + } + retval= UI_CONT; + } + } + break; + + case ONEKEY: act= 1; + case TWOKEY: if(act==0) act= 2; + case THREEKEY: if(act==0) act= 3; + case FOURKEY: if(act==0) act= 4; + case FIVEKEY: if(act==0) act= 5; + case SIXKEY: if(act==0) act= 6; + case SEVENKEY: if(act==0) act= 7; + case EIGHTKEY: if(act==0) act= 8; + case NINEKEY: if(act==0) act= 9; + case ZEROKEY: if(act==0) act= 10; + + if( block->flag & UI_BLOCK_NUMSELECT ) { + + if(get_qual() & LR_ALTKEY) act+= 10; + + but= block->buttons.first; + count= 0; + while(but) { + if( but->type!=LABEL && but->type!=SEPR) count++; + if(count==act) { + but->flag |= UI_ACTIVE; + if(uevent->val==1) ui_draw_but(but); + else { + uevent->event= RETKEY; + uevent->val= 1; /* patch: to avoid UI_BLOCK_RET_1 type not working */ + addqueue(block->winq, RIGHTARROWKEY, 1); + } + } + else if(but->flag & UI_ACTIVE) { + but->flag &= ~UI_ACTIVE; + ui_draw_but(but); + } + but= but->next; + } + } + + break; + + default: + if (uevent->event!=RETKEY) { /* when previous command was arrow */ + but= block->buttons.first; + while(but) { + + but->flag &= ~UI_MOUSE_OVER; + + /* check boundbox */ + if (uibut_contains_pt(but, uevent->mval)) { + but->flag |= UI_MOUSE_OVER; + UIbuttip= but; + } + /* hilite case 1 */ + if(but->flag & UI_MOUSE_OVER) { + if( (but->flag & UI_ACTIVE)==0) { + but->flag |= UI_ACTIVE; + ui_draw_but(but); + } + } + /* hilite case 2 */ + if(but->flag & UI_ACTIVE) { + if( (but->flag & UI_MOUSE_OVER)==0) { + but->flag &= ~UI_ACTIVE; + ui_draw_but(but); + } + if(but->flag & UI_ACTIVE) active= 1; + } + + but= but->next; + } + + /* if there are no active buttons... otherwise clear lines */ + if(active) ui_do_active_linklines(block, 0); + else ui_do_active_linklines(block, uevent->mval); + + } + } + + /* middlemouse exception, not for regular blocks */ + if( (block->flag & UI_BLOCK_LOOP) && uevent->event==MIDDLEMOUSE) uevent->event= LEFTMOUSE; + + /* the final dobutton */ + but= block->buttons.first; + while(but) { + if(but->flag & UI_ACTIVE) { + + /* UI_BLOCK_RET_1: not return when val==0 */ + + if(uevent->val || (block->flag & UI_BLOCK_RET_1)==0) { + if ELEM3(uevent->event, LEFTMOUSE, PADENTER, RETKEY) { + + butevent= ui_do_button(block, but, uevent); + if(butevent) addqueue(block->winq, UI_BUT_EVENT, (short)butevent); + + /* i doubt about the next line! */ + /* if(but->func) mywinset(block->win); */ + + if( (block->flag & UI_BLOCK_LOOP) && but->type==BLOCK); + else + if(/*but->func ||*/ butevent) retval= UI_RETURN_OK; + } + } + } + + but= but->next; + } + + /* the linkines... why not make buttons from it? Speed? Memory? */ + if(uevent->val && (uevent->event==XKEY || uevent->event==DELKEY)) + ui_delete_active_linkline(block); + + if(block->flag & UI_BLOCK_LOOP) { + + if(inside==0 && uevent->val==1) { + if ELEM3(uevent->event, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) + return UI_RETURN_OUT; + } + + if(uevent->event==ESCKEY && uevent->val==1) return UI_RETURN_CANCEL; + + /* check outside */ + if(block->direction==UI_RIGHT) count= 140; else count= 40; + if(uevent->mval[0]<block->minx-count) return UI_RETURN_OUT; + + if(uevent->mval[1]<block->miny-40) return UI_RETURN_OUT; + + if(block->direction==UI_LEFT) count= 140; else count= 40; + if(uevent->mval[0]>block->maxx+count) return UI_RETURN_OUT; + + if(uevent->mval[1]>block->maxy+40) return UI_RETURN_OUT; + + } + + return retval; +} + +static uiSaveUnder *ui_draw_but_tip(uiBut *but) +{ + uiSaveUnder *su; + float x1, x2, y1, y2; + + x1= (but->x1+but->x2)/2; x2= 10+x1+ but->aspect*BMF_GetStringWidth(but->font, but->tip); + y1= but->y1-19; y2= but->y1-2; + + /* for pulldown menus it doesnt work */ + if(mywinget()==G.curscreen->mainwin); + else { + ui_graphics_to_window(mywinget(), &x1, &y1); + ui_graphics_to_window(mywinget(), &x2, &y2); + } + + if(x2 > G.curscreen->sizex) { + x1 -= x2-G.curscreen->sizex; + x2= G.curscreen->sizex; + } + if(y1 < 0) { + y1 += 36; + y2 += 36; + } + + su= ui_bgnpupdraw((int)(x1-1), (int)(y1-1), (int)(x2+4), (int)(y2+4), 0); + + glColor3ub(0xD0, 0xD0, 0xC0); + glRectf(x1, y1, x2, y2); + + /* below */ + glColor3ub(0,0,0); + fdrawline(x1, y1, x2, y1); + /* right */ + fdrawline(x2, y1, x2, y2); + /* top */ + glColor3ub(255,255,255); + fdrawline(x1, y2, x2, y2); + /* left */ + fdrawline(x1, y1, x1, y2); + + glColor3ub(0,0,0); + glRasterPos2f( x1+3, y1+4); + BMF_DrawString(but->font, but->tip); + + glFinish(); /* for geforce, to show it in the frontbuffer */ + return su; +} + +static void ui_do_but_tip(void) +{ + uiSaveUnder *su; + int time; + + if (UIbuttip && UIbuttip->tip && UIbuttip->tip[0]) { + /* Pause for a moment to see if we + * should really display the tip + * or if the user will keep moving + * the pointer. + */ + for (time= 0; time<10; time++) { + if (anyqtest()) + return; + else + PIL_sleep_ms(2); + } + + /* Display the tip, and keep it displayed + * as long as the mouse remains on top + * of the button that owns it. + */ + su= ui_draw_but_tip(UIbuttip); + + while (1) { + char ascii; + short val; + unsigned short evt= extern_qread_ext(&val, &ascii); + + if (evt==MOUSEX || evt==MOUSEY) { + short mouse[2]; + uiGetMouse(su->oldwin, mouse); + + if (!uibut_contains_pt(UIbuttip, mouse)) + break; + } else { + mainqpushback(evt, val, ascii); + break; + } + } + + ui_endpupdraw(su); + UIbuttip= NULL; + } +} + +/* returns UI_NOTHING, if nothing happened */ +int uiDoBlocks(ListBase *lb, int event) +{ + /* return when: firstblock != BLOCK_LOOP + * The mainloop is constructed in such a way + * that the last mouse event from a sub-block + * is passed on to the next block. + * + * 'cont' is used to make sure you can press a menu button while another + * is active. otherwise you have to press twice... + */ + + uiBlock *block; + uiEvent uevent; + int retval= UI_NOTHING, cont= 1; + + if(lb->first==0) return UI_NOTHING; + + UIfrontbuf= 1; + UIbuttip= NULL; + UIafterfunc= NULL; /* to prevent infinite loops, this shouldnt be a global! */ + + uevent.qual= G.qual; + uevent.event= event; + uevent.val= 1; + + while(cont) { + block= lb->first; + while(block) { + + /* this here, to make sure it also draws when event==0 */ + if(block->flag & UI_BLOCK_REDRAW) { + if( block->flag & UI_BLOCK_LOOP) { + block->saveunder= ui_bgnpupdraw((int)block->minx-1, (int)block->miny-4, (int)block->maxx+4, (int)block->maxy+1, 1); + } + uiDrawBlock(block); + block->flag &= ~UI_BLOCK_REDRAW; + } + + retval= ui_do_block(block, &uevent); + if(retval==UI_CONT || retval & UI_RETURN) break; + + block= block->next; + } + + /* this is here, to allow closed loop-blocks (menu's) to return to the previous block */ + block= lb->first; + if(block==NULL || (block->flag & UI_BLOCK_LOOP)==0) cont= 0; + + while( (block= lb->first) && (block->flag & UI_BLOCK_LOOP)) { + + /* this here, for menu buts */ + if(block->flag & UI_BLOCK_REDRAW) { + + if( block->flag & UI_BLOCK_LOOP) { + block->saveunder= ui_bgnpupdraw((int)block->minx-1, (int)block->miny-4, (int)block->maxx+4, (int)block->maxy+1, 1); + } + uiDrawBlock(block); + block->flag &= ~UI_BLOCK_REDRAW; + } + + uevent.event= extern_qread(&uevent.val); + + if(uevent.event) { + + retval= ui_do_block(block, &uevent); + + if(retval & UI_RETURN) { + /* free this block */ + ui_endpupdraw(block->saveunder); + + BLI_remlink(lb, block); + uiFreeBlock(block); + } + if(retval==UI_RETURN_OK) { + /* free other menus */ + while( (block= lb->first) && (block->flag & UI_BLOCK_LOOP)) { + ui_endpupdraw(block->saveunder); + BLI_remlink(lb, block); + uiFreeBlock(block); + } + } + } + + /* tooltip */ + if(retval==UI_NOTHING && (uevent.event==MOUSEX || uevent.event==MOUSEY)) { + if(U.flag & TOOLTIPS) ui_do_but_tip(); + } + + } + + if(retval==UI_CONT || (retval & UI_RETURN_OK)) cont= 0; + } + + UIfrontbuf= 0; + + + if(retval & UI_RETURN_OK) { + if(UIafterfunc) UIafterfunc(UIafterfunc_arg, UIafterval); + UIafterfunc= NULL; + } + + /* tooltip */ + if(retval==UI_NOTHING && (uevent.event==MOUSEX || uevent.event==MOUSEY)) { + if(U.flag & TOOLTIPS) ui_do_but_tip(); + } + + return retval; +} + +/* ************** DATA *************** */ + + +static double ui_get_but_val(uiBut *but) +{ + void *poin; + double value = 0.0; + + poin= but->poin; + + if(but->type== HSVSLI) { + float h, s, v, *fp= (float *) poin; + + rgb_to_hsv(fp[0], fp[1], fp[2], &h, &s, &v); + + switch(but->str[0]) { + case 'H': value= h; break; + case 'S': value= s; break; + case 'V': value= v; break; + } + + } + else if( but->pointype == CHA ) { + value= *(char *)poin; + } + else if( but->pointype == SHO ) { + value= *(short *)poin; + } + else if( but->pointype == INT ) { + value= *(int *)poin; + } + else if( but->pointype == FLO ) { + value= *(float *)poin; + } + + return value; +} + +static void ui_set_but_val(uiBut *but, double value) +{ + void *poin; + + if(but->pointype==0) return; + poin= but->poin; + + /* value is een hsvwaarde: omzetten naar de rgb */ + if( but->type==HSVSLI ) { + float h, s, v, *fp= (float *)but->poin; + + rgb_to_hsv(fp[0], fp[1], fp[2], &h, &s, &v); + + switch(but->str[0]) { + case 'H': h= value; break; + case 'S': s= value; break; + case 'V': v= value; break; + } + + hsv_to_rgb(h, s, v, fp, fp+1, fp+2); + + } + else if( but->pointype==CHA ) + *((char *)poin)= (char)value; + else if( but->pointype==SHO ) + *((short *)poin)= (short)value; + else if( but->pointype==INT ) + *((int *)poin)= (int)value; + else if( but->pointype==FLO ) + *((float *)poin)= value; + + /* update select flag */ + ui_is_but_sel(but); + +} + +void uiSetCurFont(uiBlock *block, int index) +{ + + if(block->aspect<0.60) { + block->curfont= UIfont[index].xl; + } + else if(block->aspect<1.15) { + block->curfont= UIfont[index].large; + } + else if(block->aspect<1.59) { + block->curfont= UIfont[index].medium; + } + else { + block->curfont= UIfont[index].small; + } + + if(block->curfont==NULL) block->curfont= UIfont[index].large; + if(block->curfont==NULL) block->curfont= UIfont[index].medium; + if(block->curfont==NULL) printf("error block no font %s\n", block->name); +} + +void uiDefFont(unsigned int index, void *xl, void *large, void *medium, void *small) +{ + if(index>=UI_ARRAY) return; + + UIfont[index].xl= xl; + UIfont[index].large= large; + UIfont[index].medium= medium; + UIfont[index].small= small; +} + +static void ui_free_link(uiLink *link) +{ + if(link) { + BLI_freelistN(&link->lines); + MEM_freeN(link); + } +} + +static void ui_free_but(uiBut *but) +{ + if(but->str && but->str != but->strdata) MEM_freeN(but->str); + ui_free_link(but->link); + + MEM_freeN(but); +} + +void uiFreeBlock(uiBlock *block) +{ + uiBut *but; + + if(block->flag & UI_BLOCK_BUSY) printf("var1: %x\n", block); + + while( (but= block->buttons.first) ) { + BLI_remlink(&block->buttons, but); + ui_free_but(but); + } + + MEM_freeN(block); + UIbuttip= NULL; +} + +void uiFreeBlocks(ListBase *lb) +{ + uiBlock *block; + + while( (block= lb->first) ) { + BLI_remlink(lb, block); + uiFreeBlock(block); + } +} + +void uiFreeBlocksWin(ListBase *lb, int win) +{ + uiBlock *block, *blockn; + + block= lb->first; + while(block) { + blockn= block->next; + if(block->win==win) { + BLI_remlink(lb, block); + uiFreeBlock(block); + } + block= blockn; + } +} + +uiBlock *uiNewBlock(ListBase *lb, char *name, short dt, short font, short win) +{ + uiBlock *block; + + /* each listbase only has one block with this name */ + if(lb) { + for (block= lb->first; block; block= block->next) + if (BLI_streq(block->name, name)) + break; + if (block) { + BLI_remlink(lb, block); + uiFreeBlock(block); + } + } + + block= MEM_callocN(sizeof(uiBlock), "iuBlock"); + if(lb) BLI_addhead(lb, block); /* at the beginning of the list! */ + + strcpy(block->name, name); + /* draw win */ + block->win= win; + /* window where queue event should be added, pretty weak this way! + this is because the 'mainwin' pup menu's */ + block->winq= mywinget(); + block->dt= dt; + block->col= BUTGREY; + + /* aspect */ + bwin_getsinglematrix(win, block->winmat); + + if (win==G.curscreen->mainwin) { + block->aspect= 1.0; + } else { + int getsizex, getsizey; + + bwin_getsize(win, &getsizex, &getsizey); + block->aspect= 2.0/( (getsizex)*block->winmat[0][0]); + } + + uiSetCurFont(block, font); + + return block; +} + +uiBlock *uiGetBlock(char *name, ScrArea *sa) +{ + uiBlock *block= sa->uiblocks.first; + + while(block) { + if( strcmp(name, block->name)==0 ) return block; + block= block->next; + } + + return NULL; +} + +static void ui_check_but(uiBut *but) +{ + /* if something changed in the button */ + ID *id; + double value; + short pos; + + ui_is_but_sel(but); + + /* name: */ + switch( but->type ) { + + case MENU: + + if(but->x2 - but->x1 > 24) { + value= ui_get_but_val(but); + ui_set_name_menu(but, (int)value); + } + break; + + case NUM: + case NUMSLI: + case HSVSLI: + + value= ui_get_but_val(but); + + if( but->pointype==FLO ) { + if(but->max<10.001) sprintf(but->drawstr, "%s%.3f", but->str, value); + else sprintf(but->drawstr, "%s%.2f", but->str, value); + } + else { + sprintf(but->drawstr, "%s%d", but->str, (int)value); + } + break; + + case IDPOIN: + id= *(but->idpoin_idpp); + strcpy(but->drawstr, but->str); + if(id) strcat(but->drawstr, id->name+2); + break; + + case TEX: + strcpy(but->drawstr, but->str); + strcat(but->drawstr, but->poin); + break; + + case KEYEVT: + strcpy(but->drawstr, but->str); + if (but->flag & UI_SELECT) { + strcat(but->drawstr, "Press a key"); + } else { + strcat(but->drawstr, key_event_to_string((short) ui_get_but_val(but))); + } + break; + + default: + strcpy(but->drawstr, but->str); + + } + + if(but->drawstr[0]) but->strwidth= but->aspect*BMF_GetStringWidth(but->font, but->drawstr); + else but->strwidth= 0; + + /* automatic width */ + if(but->x2==0.0) { + but->x2= (but->x1+but->strwidth+6); + } + + /* calc but->ofs, to draw the string shorter if too long */ + but->ofs= 0; + while(but->strwidth > (int)(but->x2-but->x1-7) ) { + but->ofs++; + + if(but->drawstr[but->ofs]) + but->strwidth= but->aspect*BMF_GetStringWidth(but->font, but->drawstr+but->ofs); + else but->strwidth= 0; + + /* textbut exception */ + if(but->pos != -1) { + pos= but->pos+strlen(but->str); + if(pos-1 < but->ofs) { + pos= but->ofs-pos+1; + but->ofs -= pos; + if(but->ofs<0) { + but->ofs= 0; + pos--; + } + but->drawstr[ strlen(but->drawstr)-pos ]= 0; + } + } + + if(but->strwidth < 10) break; + } + + /* test for min and max, icon sliders, etc */ + + switch( but->type ) { + case NUM: + case SLI: + case SCROLL: + case NUMSLI: + case HSVSLI: + value= ui_get_but_val(but); + if(value < but->min) value= but->min; + if(value > but->max) value= but->max; + ui_set_but_val(but, value); + break; + + case ICONTOG: + if(but->flag & UI_SELECT) but->iconadd= 1; + else but->iconadd= 0; + break; + + case ICONROW: + value= ui_get_but_val(but); + but->iconadd= (int)value- (int)(but->min); + break; + } +} + +static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short x1, short y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, char *tip) +{ + uiBut *but; + short slen; + + if(type & BUTPOIN) { /* er is pointer nodig */ + if(poin==0) { + /* als pointer nul is wordt button gewist en niet gedefinieerd */ + BIF_set_color(block->col, COLORSHADE_MEDIUM); + glRects(x1, y1, x1+x2, y1+y2); + return NULL; + } + } + + but= MEM_callocN(sizeof(uiBut), "uiBut"); + + but->type= type & BUTTYPE; + but->pointype= type & BUTPOIN; + but->bit= type & BIT; + but->bitnr= type & 31; + + BLI_addtail(&block->buttons, but); + + but->retval= retval; + if( strlen(str)>=UI_MAX_NAME_STR-1 ) { + but->str= MEM_callocN( strlen(str)+2, "uiDefBut"); + strcpy(but->str, str); + } + else { + but->str= but->strdata; + strcpy(but->str, str); + } + but->x1= x1; + but->y1= y1; + if(block->autofill) { + but->x2= x2; + but->y2= y2; + } + else { + but->x2= (x1+x2); + but->y2= (y1+y2); + } + but->poin= poin; + but->min= min; + but->max= max; + but->a1= a1; + but->a2= a2; + but->tip= tip; + + but->font= block->curfont; + but->col= block->col; + + but->lock= UIlock; + but->lockstr= UIlockstr; + + but->aspect= block->aspect; + but->win= block->win; + + if (but->type==BUTM) { + but->butm_func= block->butm_func; + but->butm_func_arg= block->butm_func_arg; + } else { + but->func= block->func; + but->func_arg1= block->func_arg1; + but->func_arg2= block->func_arg2; + } + + if(block->dt==UI_EMBOSSX) but->embossfunc= ui_emboss_X; + else if(block->dt==UI_EMBOSSW) but->embossfunc= ui_emboss_W; + else if(block->dt==UI_EMBOSSF) but->embossfunc= ui_emboss_F; + else if(block->dt==UI_EMBOSSM) but->embossfunc= ui_emboss_M; + else if(block->dt==UI_EMBOSSP) but->embossfunc= ui_emboss_P; + else but->embossfunc= ui_emboss_N; + + but->pos= -1; /* cursor invisible */ + + if(but->type==NUM) { /* spatie toevoegen achter naam */ + slen= strlen(but->str); + if(slen>0 && slen<UI_MAX_NAME_STR-2) { + if(but->str[slen-1]!=' ') { + but->str[slen]= ' '; + but->str[slen+1]= 0; + } + } + } + + if ELEM6(but->type, HSVSLI , NUMSLI, TEX, LABEL, IDPOIN, BLOCK) { + but->flag |= UI_TEXT_LEFT; + } + + return but; +} + +uiBut *uiDefBut(uiBlock *block, int type, int retval, char *str, short x1, short y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, char *tip) +{ + uiBut *but= ui_def_but(block, type, retval, str, x1, y1, x2, y2, poin, min, max, a1, a2, tip); + + ui_check_but(but); + + return but; +} +uiBut *uiDefButF(uiBlock *block, int type, int retval, char *str, short x1, short y1, short x2, short y2, float *poin, float min, float max, float a1, float a2, char *tip) +{ + return uiDefBut(block, type|FLO, retval, str, x1, y1, x2, y2, (void*) poin, min, max, a1, a2, tip); +} +uiBut *uiDefButI(uiBlock *block, int type, int retval, char *str, short x1, short y1, short x2, short y2, int *poin, float min, float max, float a1, float a2, char *tip) +{ + return uiDefBut(block, type|INT, retval, str, x1, y1, x2, y2, (void*) poin, min, max, a1, a2, tip); +} +uiBut *uiDefButS(uiBlock *block, int type, int retval, char *str, short x1, short y1, short x2, short y2, short *poin, float min, float max, float a1, float a2, char *tip) +{ + return uiDefBut(block, type|SHO, retval, str, x1, y1, x2, y2, (void*) poin, min, max, a1, a2, tip); +} +uiBut *uiDefButC(uiBlock *block, int type, int retval, char *str, short x1, short y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, char *tip) +{ + return uiDefBut(block, type|CHA, retval, str, x1, y1, x2, y2, (void*) poin, min, max, a1, a2, tip); +} + +uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, short x1, short y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, char *tip) +{ + uiBut *but= ui_def_but(block, type, retval, "", x1, y1, x2, y2, poin, min, max, a1, a2, tip); + + but->icon= (BIFIconID) icon; + but->flag|= UI_HAS_ICON; + + ui_check_but(but); + + return but; +} + +uiBut *uiDefIconButF(uiBlock *block, int type, int retval, int icon, short x1, short y1, short x2, short y2, float *poin, float min, float max, float a1, float a2, char *tip) +{ + return uiDefIconBut(block, type|FLO, retval, icon, x1, y1, x2, y2, (void*) poin, min, max, a1, a2, tip); +} +uiBut *uiDefIconButI(uiBlock *block, int type, int retval, int icon, short x1, short y1, short x2, short y2, int *poin, float min, float max, float a1, float a2, char *tip) +{ + return uiDefIconBut(block, type|INT, retval, icon, x1, y1, x2, y2, (void*) poin, min, max, a1, a2, tip); +} +uiBut *uiDefIconButS(uiBlock *block, int type, int retval, int icon, short x1, short y1, short x2, short y2, short *poin, float min, float max, float a1, float a2, char *tip) +{ + return uiDefIconBut(block, type|SHO, retval, icon, x1, y1, x2, y2, (void*) poin, min, max, a1, a2, tip); +} +uiBut *uiDefIconButC(uiBlock *block, int type, int retval, int icon, short x1, short y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, char *tip) +{ + return uiDefIconBut(block, type|CHA, retval, icon, x1, y1, x2, y2, (void*) poin, min, max, a1, a2, tip); +} + +void uiAutoBlock(uiBlock *block, float minx, float miny, float sizex, float sizey, int flag) +{ + block->minx= minx; + block->maxx= minx+sizex; + block->miny= miny; + block->maxy= miny+sizey; + + block->autofill= flag; /* also check for if it has to be done */ + +} + +void uiSetButLink(uiBut *but, void **poin, void ***ppoin, short *tot, int from, int to) +{ + uiLink *link; + + link= but->link= MEM_callocN(sizeof(uiLink), "new uilink"); + + link->poin= poin; + link->ppoin= ppoin; + link->totlink= tot; + link->fromcode= from; + link->tocode= to; +} + +/* cruft to make uiBlock and uiBut private */ + +int uiBlocksGetYMin(ListBase *lb) +{ + uiBlock *block; + int min= 0; + + for (block= lb->first; block; block= block->next) + if (block==lb->first || block->miny<min) + min= block->miny; + + return min; +} + +int uiBlockGetCol(uiBlock *block) +{ + return block->col; +} +void uiBlockSetCol(uiBlock *block, int col) +{ + block->col= col; +} +void uiBlockSetEmboss(uiBlock *block, int emboss) +{ + block->dt= emboss; +} +void uiBlockSetDirection(uiBlock *block, int direction) +{ + block->direction= direction; +} +void uiBlockSetFlag(uiBlock *block, int flag) +{ + block->flag= flag; +} +void uiBlockSetXOfs(uiBlock *block, int xofs) +{ + block->xofs= xofs; +} +void* uiBlockGetCurFont(uiBlock *block) +{ + return block->curfont; +} + +void uiButSetFlag(uiBut *but, int flag) +{ + but->flag|= flag; +} + +int uiButGetRetVal(uiBut *but) +{ + return but->retval; +} + + +void uiBlockSetButmFunc(uiBlock *block, void (*menufunc)(void *arg, int event), void *arg) +{ + block->butm_func= menufunc; + block->butm_func_arg= arg; +} + +void uiBlockSetFunc(uiBlock *block, void (*func)(void *arg1, void *arg2), void *arg1, void *arg2) +{ + block->func= func; + block->func_arg1= arg1; + block->func_arg2= arg2; +} +void uiButSetFunc(uiBut *but, void (*func)(void *arg1, void *arg2), void *arg1, void *arg2) +{ + but->func= func; + but->func_arg1= arg1; + but->func_arg2= arg2; +} + +void uiDefIDPoinBut(uiBlock *block, uiIDPoinFuncFP func, int retval, char *str, short x1, short y1, short x2, short y2, void *idpp, char *tip) +{ + uiBut *but= ui_def_but(block, IDPOIN, retval, str, x1, y1, x2, y2, NULL, 0.0, 0.0, 0.0, 0.0, tip); + but->idpoin_func= func; + but->idpoin_idpp= (ID**) idpp; + ui_check_but(but); +} + +void uiDefBlockBut(uiBlock *block, uiBlockFuncFP func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip) +{ + uiBut *but= ui_def_but(block, BLOCK, 0, str, x1, y1, x2, y2, arg, 0.0, 0.0, 0.0, 0.0, tip); + but->block_func= func; + ui_check_but(but); +} + +void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip) +{ + uiBut *but= ui_def_but(block, KEYEVT|SHO, retval, str, x1, y1, x2, y2, spoin, 0.0, 0.0, 0.0, 0.0, tip); + ui_check_but(but); +} + +/* ******************** PUPmenu ****************** */ + +short pupmenu(char *instr) +{ + uiBlock *block; + ListBase listb= {NULL, NULL}; + int event; + static int lastselected= 0; + short width, height, mousexmove = 0, mouseymove, xmax, ymax, mval[2], val= -1; + short a, startx, starty, endx, endy, boxh=TBOXH, x1, y1; + static char laststring[UI_MAX_NAME_STR]; + MenuData *md; + + /* block stuff first, need to know the font */ + block= uiNewBlock(&listb, "menu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_NUMSELECT); + + md= decompose_menu_string(instr); + + /* size and location, title slightly bigger for bold */ + if(md->title) width= 2*strlen(md->title)+BMF_GetStringWidth(uiBlockGetCurFont(block), md->title); + else width= 0; + for(a=0; a<md->nitems; a++) { + xmax= BMF_GetStringWidth(uiBlockGetCurFont(block), md->items[a].str); + if(xmax>width) width= xmax; + } + width+= 10; + + height= boxh*md->nitems; + + xmax = G.curscreen->sizex; + ymax = G.curscreen->sizey; + + getmouseco_sc(mval); + + if(strncmp(laststring, instr, UI_MAX_NAME_STR-1)!=0) lastselected= 0; + BLI_strncpy(laststring, instr, UI_MAX_NAME_STR); + + startx= mval[0]-width/2; + if(lastselected>=0 && lastselected<md->nitems) { + starty= mval[1]-height+boxh/2+lastselected*boxh; + } + else starty= mval[1]-height/2; + + mouseymove= 0; + + if(startx<10) startx= 10; + if(starty<10) { + mouseymove= 10-starty; + starty= 10; + } + + endx= startx+width; + endy= starty+height; + if(endx>xmax) { + endx= xmax-10; + startx= endx-width; + } + if(endy>ymax-20) { + mouseymove= ymax-endy-20; + endy= ymax-20; + starty= endy-height; + + } + + if(mouseymove) { + warp_pointer(mval[0], mouseymove+mval[1]); + mousexmove= mval[0]; + mouseymove= mval[1]; + } + + /* here we go! */ + if(md->title) { + uiBut *bt; + uiSetCurFont(block, UI_HELVB); + bt= uiDefBut(block, LABEL, 0, md->title, startx, (short)(starty+md->nitems*boxh), width, boxh, NULL, 0.0, 0.0, 0, 0, ""); + bt->flag= UI_TEXT_LEFT; + uiSetCurFont(block, UI_HELV); + } + + y1= starty + boxh*(md->nitems-1); + x1= startx; + for(a=0; a<md->nitems; a++, y1-=boxh) { + char *name= md->items[a].str; + + if( strcmp(name, "%l")==0) { + uiDefBut(block, SEPR, B_NOP, "", x1, y1, width, boxh, NULL, 0, 0.0, 0, 0, ""); + } + else { + uiDefButS(block, BUTM, B_NOP, name, x1, y1, width, boxh-1, &val, (float) md->items[a].retval, 0.0, 0, 0, ""); + } + } + + uiBoundsBlock(block, 2); + + event= uiDoBlocks(&listb, 0); + + /* calculate last selected */ + lastselected= 0; + for(a=0; a<md->nitems; a++) { + if(val==md->items[a].retval) lastselected= a; + } + + /* ready, restore stuff */ + UIfrontbuf= 0; + + menudata_free(md); + + if(mouseymove && (event & UI_RETURN_OUT)==0) warp_pointer(mousexmove, mouseymove); + return val; +} + +short pupmenu_col(char *instr, int maxrow) +{ + uiBlock *block; + ListBase listb= {NULL, NULL}; + int columns, rows; + short mousemove[2], mval[2], event; + int width, height, xmax, ymax, val= -1; + int a, startx, starty, endx, endy, boxh=TBOXH, x1, y1; + MenuData *md; + + block= uiNewBlock(&listb, "menu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT); + + md= decompose_menu_string(instr); + + /* collumns and row calculation */ + columns= (md->nitems+maxrow)/maxrow; + if (columns<1) columns= 1; + + rows= (int) md->nitems/columns; + if (rows<1) rows= 1; + + while (rows*columns<md->nitems) rows++; + + /* size and location */ + if(md->title) width= 2*strlen(md->title)+BMF_GetStringWidth(uiBlockGetCurFont(block), md->title); + else width= 0; + for(a=0; a<md->nitems; a++) { + xmax= BMF_GetStringWidth(uiBlockGetCurFont(uiBlockGetCurFont(block)), md->items[a].str); + if(xmax>width) width= xmax; + } + + width+= 10; + if (width<50) width=50; + + boxh= TBOXH; + + height= rows*boxh; + if (md->title) height+= boxh; + + xmax = G.curscreen->sizex; + ymax = G.curscreen->sizey; + + getmouseco_sc(mval); + + /* find active item */ +#if 0 + fvalue= ui_get_but_val(but); + for(a=0; a<md->nitems; a++) { + if( md->items[a].retval== (int)fvalue ) break; + } +#endif + /* no active item? */ + if(a==md->nitems) { + if(md->title) a= -1; + else a= 0; + } + + if(a>0) + startx = mval[0]-width/2 - ((int)(a)/rows)*width; + else + startx= mval[0]-width/2; + starty = mval[1]-height + boxh/2 + ((a)%rows)*boxh; + + if (md->title) starty+= boxh; + + mousemove[0]= mousemove[1]= 0; + + if(startx<10) { + mousemove[0]= 10-startx; + startx= 10; + } + if(starty<10) { + mousemove[1]= 10-starty; + starty= 10; + } + + endx= startx+width*columns; + endy= starty+height; + + if(endx>xmax) { + mousemove[0]= xmax-endx-10; + endx= xmax-10; + startx= endx-width*columns; + } + if(endy>ymax) { + mousemove[1]= ymax-endy-10; + endy= ymax-10; + starty= endy-height; + } + + warp_pointer(mval[0]+mousemove[0], mval[1]+mousemove[1]); + + mousemove[0]= mval[0]; + mousemove[1]= mval[1]; + + /* here we go! */ + + if(md->title) { + uiBut *bt; + uiSetCurFont(block, UI_HELVB); + bt= uiDefBut(block, LABEL, 0, md->title, startx, (short)(starty+rows*boxh), (short)width, (short)boxh, NULL, 0.0, 0.0, 0, 0, ""); + uiSetCurFont(block, UI_HELV); + bt->flag= UI_TEXT_LEFT; + } + + for(a=0; a<md->nitems; a++) { + + x1= startx + width*((int)a/rows); + y1= starty - boxh*(a%rows) + (rows-1)*boxh; + + uiDefButI(block, BUTM, B_NOP, md->items[a].str, x1, y1, (short)(width-(rows>1)), (short)(boxh-1), &val, (float)md->items[a].retval, 0.0, 0, 0, ""); + } + + uiBoundsBlock(block, 3); + + event= uiDoBlocks(&listb, 0); + + /* ready, restore stuff */ + UIfrontbuf= 1; + + menudata_free(md); + + if((event & UI_RETURN_OUT)==0) warp_pointer(mousemove[0], mousemove[1]); + + return val; +} + diff --git a/source/blender/src/keyval.c b/source/blender/src/keyval.c new file mode 100644 index 00000000000..2390bc59d4e --- /dev/null +++ b/source/blender/src/keyval.c @@ -0,0 +1,354 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + + +#include "BIF_keyval.h" + +#include "blendef.h" + +#include "mydevice.h" + +char *key_event_to_string(unsigned short event) +{ + + switch(event) { + case AKEY: + return "A"; + break; + case BKEY: + return "B"; + break; + case CKEY: + return "C"; + break; + case DKEY: + return "D"; + break; + case EKEY: + return "E"; + break; + case FKEY: + return "F"; + break; + case GKEY: + return "G"; + break; + case HKEY: + return "H"; + break; + case IKEY: + return "I"; + break; + case JKEY: + return "J"; + break; + case KKEY: + return "K"; + break; + case LKEY: + return "L"; + break; + case MKEY: + return "M"; + break; + case NKEY: + return "N"; + break; + case OKEY: + return "O"; + break; + case PKEY: + return "P"; + break; + case QKEY: + return "Q"; + break; + case RKEY: + return "R"; + break; + case SKEY: + return "S"; + break; + case TKEY: + return "T"; + break; + case UKEY: + return "U"; + break; + case VKEY: + return "V"; + break; + case WKEY: + return "W"; + break; + case XKEY: + return "X"; + break; + case YKEY: + return "Y"; + break; + case ZKEY: + return "Z"; + break; + + case ZEROKEY: + return "Zero"; + break; + case ONEKEY: + return "One"; + break; + case TWOKEY: + return "Two"; + break; + case THREEKEY: + return "Three"; + break; + case FOURKEY: + return "Four"; + break; + case FIVEKEY: + return "Five"; + break; + case SIXKEY: + return "Six"; + break; + case SEVENKEY: + return "Seven"; + break; + case EIGHTKEY: + return "Eight"; + break; + case NINEKEY: + return "Nine"; + break; + + case LEFTCTRLKEY: + return "Leftctrl"; + break; + case LEFTALTKEY: + return "Leftalt"; + break; + case RIGHTALTKEY: + return "Rightalt"; + break; + case RIGHTCTRLKEY: + return "Rightctrl"; + break; + case RIGHTSHIFTKEY: + return "Rightshift"; + break; + case LEFTSHIFTKEY: + return "Leftshift"; + break; + + case ESCKEY: + return "Esc"; + break; + case TABKEY: + return "Tab"; + break; + case RETKEY: + return "Ret"; + break; + case SPACEKEY: + return "Space"; + break; + case LINEFEEDKEY: + return "Linefeed"; + break; + case BACKSPACEKEY: + return "Backspace"; + break; + case DELKEY: + return "Del"; + break; + case SEMICOLONKEY: + return "Semicolon"; + break; + case PERIODKEY: + return "Period"; + break; + case COMMAKEY: + return "Comma"; + break; + case QUOTEKEY: + return "Quote"; + break; + case ACCENTGRAVEKEY: + return "Accentgrave"; + break; + case MINUSKEY: + return "Minus"; + break; + case SLASHKEY: + return "Slash"; + break; + case BACKSLASHKEY: + return "Backslash"; + break; + case EQUALKEY: + return "Equal"; + break; + case LEFTBRACKETKEY: + return "Leftbracket"; + break; + case RIGHTBRACKETKEY: + return "Rightbracket"; + break; + + case LEFTARROWKEY: + return "Leftarrow"; + break; + case DOWNARROWKEY: + return "Downarrow"; + break; + case RIGHTARROWKEY: + return "Rightarrow"; + break; + case UPARROWKEY: + return "Uparrow"; + break; + + case PAD2: + return "Pad2"; + break; + case PAD4: + return "Pad4"; + break; + case PAD6: + return "Pad6"; + break; + case PAD8: + return "Pad8"; + break; + case PAD1: + return "Pad1"; + break; + case PAD3: + return "Pad3"; + break; + case PAD5: + return "Pad5"; + break; + case PAD7: + return "Pad7"; + break; + case PAD9: + return "Pad9"; + break; + + case PADPERIOD: + return "Padperiod"; + break; + case PADSLASHKEY: + return "Padslash"; + break; + case PADASTERKEY: + return "Padaster"; + break; + + case PAD0: + return "Pad0"; + break; + case PADMINUS: + return "Padminus"; + break; + case PADENTER: + return "Padenter"; + break; + case PADPLUSKEY: + return "Padplus"; + break; + + case F1KEY: + return "F1"; + break; + case F2KEY: + return "F2"; + break; + case F3KEY: + return "F3"; + break; + case F4KEY: + return "F4"; + break; + case F5KEY: + return "F5"; + break; + case F6KEY: + return "F6"; + break; + case F7KEY: + return "F7"; + break; + case F8KEY: + return "F8"; + break; + case F9KEY: + return "F9"; + break; + case F10KEY: + return "F10"; + break; + case F11KEY: + return "F11"; + break; + case F12KEY: + return "F12"; + break; + + case PAUSEKEY: + return "Pause"; + break; + case INSERTKEY: + return "Insert"; + break; + case HOMEKEY: + return "Home"; + break; + case PAGEUPKEY: + return "Pageup"; + break; + case PAGEDOWNKEY: + return "Pagedown"; + break; + case ENDKEY: + return "End"; + break; + } + + return ""; +} diff --git a/source/blender/src/mainqueue.c b/source/blender/src/mainqueue.c new file mode 100644 index 00000000000..ac78beb9440 --- /dev/null +++ b/source/blender/src/mainqueue.c @@ -0,0 +1,99 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * + * Just the functions to maintain a central event + * queue. + */ + +#include <stdlib.h> +#include <string.h> + +#include "BIF_mainqueue.h" + +typedef struct { + unsigned short event; + short val; + char ascii; +} QEvent; + +static QEvent mainqueue[MAXQUEUE]; +static unsigned int nevents= 0; + +unsigned short mainqread(short *val, char *ascii) +{ + if (nevents) { + nevents--; + + *val= mainqueue[nevents].val; + *ascii= mainqueue[nevents].ascii; + return mainqueue[nevents].event; + } else + return 0; +} + +void mainqenter(unsigned short event, short val) +{ + mainqenter_ext(event, val, 0); +} + +void mainqenter_ext(unsigned short event, short val, char ascii) +{ + if (!event) + return; + + if (nevents<MAXQUEUE) { + memmove(mainqueue+1, mainqueue, sizeof(*mainqueue)*nevents); + + mainqueue[0].event= event; + mainqueue[0].val= val; + mainqueue[0].ascii= ascii; + + nevents++; + } +} + +void mainqpushback(unsigned short event, short val, char ascii) +{ + if (nevents<MAXQUEUE) { + mainqueue[nevents].event= event; + mainqueue[nevents].val= val; + mainqueue[nevents].ascii= ascii; + nevents++; + } +} + +unsigned short mainqtest() +{ + if (nevents) + return mainqueue[nevents-1].event; + else + return 0; +} diff --git a/source/blender/src/mywindow.c b/source/blender/src/mywindow.c new file mode 100644 index 00000000000..cf6d002ee5f --- /dev/null +++ b/source/blender/src/mywindow.c @@ -0,0 +1,645 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * vervanging voor een aantal fie's zoals swinopen, winset, (zie onder) + * dit alles omdat GL en X te traag zijn + * feb: Opengl en toch maar naar X! + */ + +#include <string.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_gsqueue.h" + +#include "DNA_screen_types.h" + +#include "BKE_global.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" + +#include "mydevice.h" +#include "blendef.h" + +#include "winlay.h" + + +typedef struct { + unsigned short event; + short val; + char ascii; +} QEvent; + +typedef struct { + struct bWindow *next, *prev; + int id, pad; + + int xmin, xmax, ymin, ymax; + float viewmat[4][4], winmat[4][4]; + + GSQueue *qevents; +} bWindow; + +/* globals */ +static Window *winlay_mainwindow; +static int curswin=0; +static bWindow *swinarray[MAXWIN]= {0}; +static bWindow mainwindow, renderwindow; +static int mainwin_color_depth; + +void mywindow_init_mainwin(Window *win, int orx, int ory, int sizex, int sizey) +{ + int r, g, b; + + winlay_mainwindow= win; + + swinarray[1]= &mainwindow; + curswin= 1; + + mainwindow.xmin= orx; + mainwindow.ymin= ory; + mainwindow.xmax= orx+sizex-1; + mainwindow.ymax= ory+sizey-1; + mainwindow.qevents= NULL; + + myortho2(-0.5, (float)sizex-0.5, -0.5, (float)sizey-0.5); + glLoadIdentity(); + + glGetFloatv(GL_PROJECTION_MATRIX, (float *)mainwindow.winmat); + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)mainwindow.viewmat); + + glGetIntegerv(GL_RED_BITS, &r); + glGetIntegerv(GL_GREEN_BITS, &g); + glGetIntegerv(GL_BLUE_BITS, &b); + + mainwin_color_depth= r + g + b; +} + +/* XXXXXXXXXXXXXXXX very hacky, not allowed to release + * again after 2.24 + */ +void mywindow_build_and_set_renderwin(void) +{ + glGetFloatv(GL_PROJECTION_MATRIX, (float *)renderwindow.winmat); + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)renderwindow.viewmat); + + swinarray[2]= &renderwindow; + renderwindow.qevents= NULL; + + curswin= 2; +} + +/* ------------------------------------------------------------------------- */ + + /* XXXXX, remove later */ +static bWindow *bwin_from_winid(int winid) +{ + bWindow *bwin= swinarray[winid]; + if (!bwin) { + printf("bwin_from_winid: Internal error, bad winid: %d\n", winid); + } + return bwin; +} + +int bwin_qtest(int winid) +{ + return !BLI_gsqueue_is_empty(bwin_from_winid(winid)->qevents); +} +unsigned short bwin_qread(int winid, short *val_r, char *ascii_r) +{ + if (bwin_qtest(winid)) { + QEvent evt; + BLI_gsqueue_pop(bwin_from_winid(winid)->qevents, &evt); + *val_r= evt.val; + *ascii_r= evt.ascii; + return evt.event; + } else { + *val_r= 0; + return 0; + } +} +void bwin_qadd(int winid, unsigned short event, short val, char ascii) +{ + QEvent evt; + evt.event= event; + evt.val= val; + evt.ascii= ascii; + BLI_gsqueue_push(bwin_from_winid(winid)->qevents, &evt); +} + +/* ------------------------------------------------------------------------- */ + +void bwin_get_rect(int winid, rcti *rect_r) +{ + bWindow *win= bwin_from_winid(winid); + + rect_r->xmin= win->xmin; + rect_r->ymin= win->ymin; + rect_r->xmax= win->xmax; + rect_r->ymax= win->ymax; +} + +void bwin_getsize(int win, int *x, int *y) +{ + if(win<4) { + if (win==1) { + window_get_size(winlay_mainwindow, x, y); + } else { + printf("bwin_getsize: Internal error, bad winid: %d\n", win); + *x= *y= 0; + } + } else { + bWindow *bwin= swinarray[win]; + if (bwin) { + *x= bwin->xmax-bwin->xmin+1; + *y= bwin->ymax-bwin->ymin+1; + } + } +} + +void bwin_getsuborigin(int win, int *x, int *y) +{ + if(win<4) { + *x= *y= 0; + } else { + bWindow *bwin= swinarray[win]; + if (bwin) { + *x= bwin->xmin; + *y= bwin->ymin; + } + } +} + +void bwin_getsinglematrix(int winid, float mat[][4]) +{ + bWindow *win; + float matview[4][4], matproj[4][4]; + + win= swinarray[winid]; + if(win==0) { + glGetFloatv(GL_PROJECTION_MATRIX, (float *)matproj); + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)matview); + Mat4MulMat4(mat, matview, matproj); + } + else { + Mat4MulMat4(mat, win->viewmat, win->winmat); + } +} + +/* ------------------------------------------------------------------------- */ + +void bwin_load_viewmatrix(int winid, float mat[][4]) +{ + bWindow *win= bwin_from_winid(winid); + + glLoadMatrixf(mat); + Mat4CpyMat4(win->viewmat, mat); +} +void bwin_load_winmatrix(int winid, float mat[][4]) +{ + bWindow *win= bwin_from_winid(winid); + + glLoadMatrixf(mat); + Mat4CpyMat4(win->winmat, mat); +} + +void bwin_get_viewmatrix(int winid, float mat[][4]) +{ + bWindow *win= bwin_from_winid(winid); + Mat4CpyMat4(mat, win->viewmat); +} +void bwin_get_winmatrix(int winid, float mat[][4]) +{ + bWindow *win= bwin_from_winid(winid); + Mat4CpyMat4(mat, win->winmat); +} + +void bwin_multmatrix(int winid, float mat[][4]) +{ + bWindow *win= bwin_from_winid(winid); + + glMultMatrixf((float*) mat); + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)win->viewmat); +} + +void bwin_clear_viewmat(int swin) +{ + bWindow *win; + + win= swinarray[swin]; + if(win==0) return; + + memset(win->viewmat, 0, sizeof(win->viewmat)); + win->viewmat[0][0]= 1.0; + win->viewmat[1][1]= 1.0; + win->viewmat[2][2]= 1.0; + win->viewmat[3][3]= 1.0; +} + + +void myloadmatrix(float mat[][4]) +{ + if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW) { + bwin_load_viewmatrix(curswin, mat); + } else { + bwin_load_winmatrix(curswin, mat); + } +} + +void mygetmatrix(float mat[][4]) +{ + if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW) { + bwin_get_viewmatrix(curswin, mat); + } else { + bwin_get_winmatrix(curswin, mat); + } +} + +void mymultmatrix(float mat[][4]) +{ + bwin_multmatrix(curswin, mat); +} + +void mygetsingmatrix(float mat[][4]) +{ + bwin_getsinglematrix(curswin, mat); +} + +int mywinget(void) +{ + return curswin; +} + +void mywinset(int wid) +{ + bWindow *win; + + win= swinarray[wid]; + if(win==0) { + printf("mywinset %d: doesn't exist\n", wid); + return; + } + + if (wid == 1) { /* main window */ + glViewport(0, 0, ( win->xmax-win->xmin)+1, ( win->ymax-win->ymin)+1); + glScissor(0, 0, ( win->xmax-win->xmin)+1, ( win->ymax-win->ymin)+1); + } + else { + int width= (win->xmax - win->xmin)+1; + int height= (win->ymax - win->ymin)+1; + + /* CRITICAL, this clamping ensures that + * the viewport never goes outside the screen + * edges (assuming the x, y coords aren't + * outside). This causes a hardware lock + * on Matrox cards if it happens. + * + * Really Blender should never _ever_ try + * to do such a thing, but just to be safe + * clamp it anyway (or fix the bScreen + * scaling routine, and be damn sure you + * fixed it). - zr + */ + if (win->xmin + width>G.curscreen->sizex) + width= G.curscreen->sizex - win->xmin; + if (win->ymin + height>G.curscreen->sizey) + height= G.curscreen->sizey - win->ymin; + + glViewport(win->xmin, win->ymin, width, height); + glScissor(win->xmin, win->ymin, width, height); + } + + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(&win->winmat[0][0]); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(&win->viewmat[0][0]); + + glFinish(); + + curswin= wid; +} + +int myswinopen(int parentid, int xmin, int xmax, int ymin, int ymax) +{ + bWindow *win= NULL; + int freewinid; + + for (freewinid= 4; freewinid<MAXWIN; freewinid++) + if (!swinarray[freewinid]) + break; + + if (freewinid==MAXWIN) { + printf("too many windows\n"); + + return 0; + } else { + win= MEM_callocN(sizeof(*win), "winopen"); + + win->id= freewinid; + swinarray[win->id]= win; + + win->xmin= xmin; + win->ymin= ymin; + win->xmax= xmax; + win->ymax= ymax; + + win->qevents= BLI_gsqueue_new(sizeof(QEvent)); + + Mat4One(win->viewmat); + Mat4One(win->winmat); + + mywinset(win->id); + + return win->id; + } +} + +void mywinclose(int winid) +{ + if (winid<4) { + if (winid==1) { + window_destroy(winlay_mainwindow); + winlay_mainwindow= NULL; + } else { + printf("mwinclose: Internal error, bad winid: %d\n", winid); + } + } else { + bWindow *win= swinarray[winid]; + + if (win) { + BLI_gsqueue_free(win->qevents); + MEM_freeN(win); + } else { + printf("mwinclose: Internal error, bad winid: %d\n", winid); + } + } + + swinarray[winid]= 0; + if (curswin==winid) curswin= 0; +} + +void mywinposition(int winid, int xmin, int xmax, int ymin, int ymax) /* let op: andere syntax */ +{ + bWindow *win= bwin_from_winid(winid); + + win->xmin= xmin; + win->ymin= ymin; + win->xmax= xmax; + win->ymax= ymax; +} + + +void bwin_ortho(int winid, float x1, float x2, float y1, float y2, float n, float f) +{ + bWindow *bwin= bwin_from_winid(winid); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(x1, x2, y1, y2, n, f); + + glGetFloatv(GL_PROJECTION_MATRIX, (float *)bwin->winmat); + glMatrixMode(GL_MODELVIEW); +} + +void bwin_ortho2(int win, float x1, float x2, float y1, float y2) +{ + bwin_ortho(win, x1, x2, y1, y2, -1, 1); +} + +void bwin_frustum(int winid, float x1, float x2, float y1, float y2, float n, float f) +{ + bWindow *win= bwin_from_winid(winid); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(x1, x2, y1, y2, n, f); + + glGetFloatv(GL_PROJECTION_MATRIX, (float *)win->winmat); + glMatrixMode(GL_MODELVIEW); +} + +void myortho(float x1, float x2, float y1, float y2, float n, float f) +{ + bwin_ortho(curswin, x1, x2, y1, y2, n, f); +} + +void myortho2(float x1, float x2, float y1, float y2) +{ + bwin_ortho(curswin, x1, x2, y1, y2, -1, 1); +} + +void mywindow(float x1, float x2, float y1, float y2, float n, float f) +{ + bwin_frustum(curswin, x1, x2, y1, y2, n, f); +} + +unsigned int index_to_framebuffer(int index) +{ + unsigned int i= index; + + switch(mainwin_color_depth) { + case 8: + i= ((i & 48)<<18) + ((i & 12)<<12) + ((i & 3)<<6); + i |= 0x3F3F3F; + break; + case 12: + i= ((i & 0xF00)<<12) + ((i & 0xF0)<<8) + ((i & 0xF)<<4); + /* sometimes dithering subtracts! */ + i |= 0x0F0F0F; + break; + case 15: + case 16: + i= ((i & 0x7C00)<<9) + ((i & 0x3E0)<<6) + ((i & 0x1F)<<3); + i |= 0x070707; + break; + default: + i= ((i & 0x3F000)<<6) + ((i & 0xFC0)<<4) + ((i & 0x3F)<<2); + i |= 0x030303; + break; + } + + return i; +} + +int framebuffer_to_index(unsigned int col) +{ + if (col==0) return 0; + + switch(mainwin_color_depth) { + case 8: + return ((col & 0xC00000)>>18) + ((col & 0xC000)>>12) + ((col & 0xC0)>>6); + case 12: + return ((col & 0xF00000)>>12) + ((col & 0xF000)>>8) + ((col & 0xF0)>>4); + case 15: + case 16: + return ((col & 0xF80000)>>9) + ((col & 0xF800)>>6) + ((col & 0xF8)>>3); + default: + return ((col & 0xFC0000)>>6) + ((col & 0xFC00)>>4) + ((col & 0xFC)>>2); + } +} + + +/* ********** END MY WINDOW ************** */ + +#ifdef WIN32 +static int is_a_really_crappy_nvidia_card(void) { + static int well_is_it= -1; + + /* Do you understand the implication? Do you? */ + if (well_is_it==-1) + well_is_it= (strcmp((char*) glGetString(GL_VENDOR), "NVIDIA Corporation") == 0); + + return well_is_it; +} +#endif + +void myswapbuffers(void) +{ + ScrArea *sa; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->win_swap==WIN_BACK_OK) sa->win_swap= WIN_FRONT_OK; + if(sa->head_swap==WIN_BACK_OK) sa->head_swap= WIN_FRONT_OK; + + sa= sa->next; + } + + /* HACK, some windows drivers feel they should honor the scissor + * test when swapping buffers, disable the test while swapping + * on WIN32. (namely Matrox and NVidia's new drivers around Oct 1 2001) + * - zr + */ + +#ifdef WIN32 + /* HACK, in some NVidia driver release some kind of + * fancy optimiziation (I presume) was put in which for + * some reason causes parts of the buffer not to be + * swapped. One way to defeat it is the following wierd + * code (which we only do for nvidia cards). This should + * be removed if NVidia fixes their drivers. - zr + */ + if (is_a_really_crappy_nvidia_card()) { + glDrawBuffer(GL_FRONT); + + glBegin(GL_LINES); + glEnd(); + + glDrawBuffer(GL_BACK); + } + + glDisable(GL_SCISSOR_TEST); + window_swap_buffers(winlay_mainwindow); + glEnable(GL_SCISSOR_TEST); +#else + window_swap_buffers(winlay_mainwindow); +#endif +} + + +/* *********************** PATTERNS ENZO ***************** */ + +void setlinestyle(int nr) +{ + if(nr==0) { + glDisable(GL_LINE_STIPPLE); + } + else { + + glEnable(GL_LINE_STIPPLE); + glLineStipple(nr, 0xAAAA); + } +} + +/*******************/ +/*******************/ +/* Menu utilities */ + +static int *frontbuffer_save= NULL; +static int ov_x, ov_y, ov_sx, ov_sy; + +void my_put_frontbuffer_image(void) +{ + if (frontbuffer_save) { + glRasterPos2f( (float)ov_x -0.5, (float)ov_y - 0.5 ); + glDrawPixels(ov_sx, ov_sy, GL_RGBA, GL_UNSIGNED_BYTE, frontbuffer_save); + MEM_freeN(frontbuffer_save); + frontbuffer_save= NULL; + } +} + +void my_get_frontbuffer_image(int x, int y, int sx, int sy) +{ + if(frontbuffer_save) return; + + ov_x= x; + ov_y= y; + ov_sx= sx; + ov_sy= sy; + + if(sx>1 && sy>1) { + frontbuffer_save= MEM_mallocN(sx*sy*4, "temp_frontbuffer_image"); + glReadPixels(x, y, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, frontbuffer_save); + } + + #ifdef WIN32 + /* ander coordinatensysteem! */ + y= (G.curscreen->sizey-y); + + if(curswin>3) { + y -= curarea->winrct.ymin; + } + #endif +} + +int mywin_inmenu(void) { + return frontbuffer_save?1:0; +} + +void mywin_getmenu_rect(int *x, int *y, int *sx, int *sy) { + *x= ov_x; + *sx= ov_sx; + *sy= ov_sy; + +#if defined(WIN32) || defined (__BeOS) + *y= ov_y; +#else + *y= (G.curscreen->sizey - ov_y) - ov_sy; +#endif +} diff --git a/source/blender/src/oops.c b/source/blender/src/oops.c new file mode 100644 index 00000000000..06688d2db9d --- /dev/null +++ b/source/blender/src/oops.c @@ -0,0 +1,1044 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_curve_types.h" +#include "DNA_image_types.h" +#include "DNA_ipo_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_object_types.h" +#include "DNA_oops_types.h" +#include "DNA_scene_types.h" +#include "DNA_space_types.h" +#include "DNA_texture_types.h" +#include "DNA_texture_types.h" +#include "DNA_key_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" + +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_toolbox.h" +#include "BIF_oops.h" +#include "BIF_drawoops.h" + +#include "blendef.h" +#include "mydevice.h" + +static int correct_oops_y(Oops *oops); + + +Oops *add_oops(void *id) +{ + Oops *oops; + + if(G.soops==0) return NULL; + oops= MEM_callocN(sizeof(Oops), "oops"); + + BLI_addtail(&G.soops->oops, oops); + + oops->id= id; + oops->type= GS(oops->id->name); + + return oops; +} + + +Oops *find_oops(ID *id) +{ + Oops *oops; + + /* op zoek naar een oops met dit ID */ + oops= G.soops->oops.first; + while(oops) { + if(oops->id == id) { + /* deze fout kwam een keer voor. beveiliging kan geen kwaad */ + if(oops->type != GS(id->name)) oops->id= 0; + else break; + } + oops= oops->next; + } + return oops; +} + +int test_oops(Oops *oops) +{ + /* test of de eigen ID block nog bestaat */ + ListBase *lb; + ID *id; + + if(G.soops==0) return 0; + + lb= wich_libbase(G.main, oops->type); + id= lb->first; + while(id) { + if(id==oops->id) break; + id= id->next; + } + + if(id==0) return 0; + + + return 1; +} + +void test_oopslinko(OopsLink *ol) +{ + /* test of links bestaan */ + Oops *oops; + ListBase *lb; + ID *id, *from; + + if(G.soops==0) return; + + ol->to= 0; + from= *ol->idfrom; + + if(from==0) return; + + lb= wich_libbase(G.main, ol->type); + id= lb->first; + while(id) { + if(id==from) break; + id= id->next; + } + + if(id==0) { + /* ID bestaat niet meer */ + *ol->idfrom= 0; + } + else { + /* op zoek naar een oops met dit ID */ + oops= G.soops->oops.first; + while(oops) { + if(oops->id == id) break; + oops= oops->next; + } + + ol->to= oops; + } +} + +void test_oopslink(OopsLink *ol) +{ + /* test of links bestaan */ + Oops *oops; + ID *from; + + if(G.soops==0) return; + + ol->to= 0; + from= *ol->idfrom; + + if(from==0) return; + + /* op zoek naar een oops met dit ID */ + oops= G.soops->oops.first; + while(oops) { + if(oops->id == from) break; + oops= oops->next; + } + + ol->to= oops; + if(oops) oops->flag |= OOPS_REFER; +} + + +OopsLink *add_oopslink(char *name, Oops *oops, short type, void *from, float xof, float yof) +{ + OopsLink *ol; + + if(G.soops==0) return NULL; + + /* testen offie al bestaat: een andere manier mag ook (linkbuffer) */ + /* ol= oops->link.first; */ + /* while(ol) { */ + /* if(ol->idfrom == from) { */ + /* strncpy(ol->name, name, 11); */ + /* ol->type= type; */ + /* ol->xof= xof; */ + /* ol->yof= yof; */ + /* return ol; */ + /* } */ + /* ol= ol->next; */ + /* } */ + + if(* ((int *)from) == 0) return NULL; + + /* nieuwe maken */ + ol= MEM_callocN(sizeof(OopsLink), "oopslink"); + + BLI_addtail(&oops->link, ol); + + ol->type= type; + ol->idfrom= from; + ol->xof= xof; + ol->yof= yof; + BLI_strncpy(ol->name, name, sizeof(ol->name)); + + return ol; +} + +int oops_test_overlap(Oops *test) +{ + Oops *oops; + rctf rt, ro; + + rt.xmin= test->x; + rt.xmax= (float)(test->x+OOPSX); + rt.ymin= test->y; + rt.ymax= (float)(test->y+OOPSY); + + oops= G.soops->oops.first; + while(oops) { + if(oops!=test) { /* niet op hide testen: is slechts tijdelijke flag */ + + ro.xmin= oops->x; + ro.xmax= (float)(oops->x+OOPSX); + ro.ymin= oops->y; + ro.ymax= (float)(oops->y+OOPSY); + + if( BLI_isect_rctf(&rt, &ro, 0) ) return 1; + + } + oops= oops->next; + } + + return 0; +} + +int oops_test_overlaphide(Oops *test) +{ + Oops *oops; + rctf rt, ro; + + rt.xmin= (float)(test->x); + rt.xmax= (float)(test->x+OOPSX); + rt.ymin= (float)(test->y); + rt.ymax= (float)(test->y+OOPSY); + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0 && oops!=test) { /* wel op hide testen, niet gebruiken tijdens build_oops */ + + ro.xmin= oops->x; + ro.xmax= (float)(oops->x+OOPSX); + ro.ymin= oops->y; + ro.ymax= (float)(oops->y+OOPSY); + + if( BLI_isect_rctf(&rt, &ro, 0) ) return 1; + + } + oops= oops->next; + } + + return 0; +} + +float oopslink_totlen(Oops *oops) +{ + OopsLink *ol; + float vec[4], dx, dy, len= 0.0; + + + ol= oops->link.first; + while(ol) { + if(ol->to) { + give_oopslink_line(oops, ol, vec, vec+2); + + dx= vec[0]-vec[2]; + dy= vec[1]-vec[3]; + + len+= (float)sqrt( dx*dx + dy*dy ); + } + ol= ol->next; + } + return len; +} + + +void add_from_link(Oops *from, Oops *oops) +{ + OopsLink *ol; + + ol= MEM_callocN(sizeof(OopsLink), "oopslinktemp"); + BLI_addtail(&oops->link, ol); + ol->from= from; + +} + +void shuffle_oops() +{ + Oops *o2, *oops; + OopsLink *ol, *oln; + float olen, len1, f1, f2; + int go= 1, tot=0, dir=1, type1, type2; + + + /* we nemen twee oopsen, berkekenen de 'beauty' en de verwisselde beauty */ + + if(G.soops==0) return; + + if(okee("Shuffle oops")==0) return; + + waitcursor(1); + + /* om de zaak 100% OK en snel te doen: voegen tijdelijk + * aan de ooplinklijst - per oops - de 'from' links ook in. + * Wel weer vrijgeven! + */ + + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + ol= oops->link.first; + while(ol) { + if(ol->to && ol->to->hide==0) { + if(ol->to->flag & SELECT) { + add_from_link(oops, ol->to); + } + } + ol= ol->next; + } + } + oops= oops->next; + } + + while(go) { + + go= 0; + dir= 1-dir; + tot++; + + if(dir) oops= G.soops->oops.last; + else oops= G.soops->oops.first; + while(oops) { + + if(oops->link.first && oops->hide==0 && (oops->flag & SELECT)) { + /* vind een goed verwisselbaar paar */ + olen= oopslink_totlen(oops); + + if(dir) o2= oops->prev; + else o2= oops->next; + + if ELEM3(oops->type, ID_OB, ID_LI, ID_SCE) type1= 1; else type1= 0; + + + while(o2) { + if(o2->hide==0 && (o2->flag & SELECT)) { + + if ELEM3(o2->type, ID_OB, ID_LI, ID_SCE) type2= 1; else type2= 0; + + if(type1==type2) { + + len1= oopslink_totlen(o2); + + SWAP(float, oops->x, o2->x); + SWAP(float, oops->y, o2->y); + + f1= oopslink_totlen(oops); + f2= oopslink_totlen(o2); + + if( f1<=olen && f2<len1) { /* 1 x <= !!! */ + olen= oopslink_totlen(oops); + go= 1; + } + else { + SWAP(float, oops->x, o2->x); + SWAP(float, oops->y, o2->y); + } + } + } + if(dir) o2= o2->prev; + else o2= o2->next; + } + } + if(dir) oops= oops->prev; + else oops= oops->next; + + + } + if(tot>5) break; + } + waitcursor(0); + + /* from links vrijgeven */ + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + ol= oops->link.first; + while(ol) { + oln= ol->next; + if(ol->from) { + BLI_remlink(&oops->link, ol); + MEM_freeN(ol); + } + ol= oln; + } + } + oops= oops->next; + } + + allqueue(REDRAWOOPS, 1); +} + +void shrink_oops() +{ + Oops *oops; + OopsLink *ol; + float vec[4]; + int /* go= 1, */tot=4; + + + if(G.soops==0) return; + + if(okee("Shrink oops")==0) return; + + waitcursor(1); + + /* clear */ + oops= G.soops->oops.first; + while(oops) { + oops->dx= oops->dy= 0.0; + oops= oops->next; + } + + while(tot) { + tot--; + + /* shrink */ + oops= G.soops->oops.first; + while(oops) { + if(oops->link.first && oops->hide==0 && (oops->flag & SELECT)) { + + ol= oops->link.first; + while(ol) { + if(ol->to && ol->to->hide==0) { + + give_oopslink_line(oops, ol, vec, vec+2); + + oops->dx= (float)(.8*oops->dx + .2*( vec[2]-vec[0])); + oops->dy= (float)(.8*oops->dy + .2*( vec[3]-vec[1])); + + if(ol->to->flag & SELECT) { + ol->to->dx= (float)(.8*ol->to->dx + .2*( vec[0]-vec[2])); + ol->to->dy= (float)(.8*ol->to->dy + .2*( vec[1]-vec[3])); + } + } + + ol= ol->next; + } + } + oops= oops->next; + } + + /* apply */ + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0 && (oops->flag & SELECT)) { + + /* shrink */ + oops->x+= oops->dx; + oops->y+= oops->dy; + + if(oops_test_overlaphide(oops)) { + oops->x-= oops->dx; + oops->y-= oops->dy; + } + + oops->dx= oops->dy= 0.0; + } + oops= oops->next; + } + } + waitcursor(0); + + allqueue(REDRAWOOPS, 1); +} + +#define LIMSCE -20.0 +#define LIMOB 14.0 +#define LIMDATA 24.0 + +static int correct_oops_y(Oops *oops) +{ + float y; + + y= oops->y; + + switch(oops->type) { + case ID_SCE: + case ID_LI: + if(oops->y > LIMSCE-OOPSY) oops->y= (float)(LIMSCE-OOPSY); + break; + case ID_OB: + CLAMP(oops->y, LIMSCE, LIMOB); + break; + case ID_IP: + case ID_MA: + case ID_TE: + if(oops->y < LIMDATA+OOPSY) oops->y= (float)(LIMDATA+OOPSY); + break; + default: + CLAMP(oops->y, (float)(LIMOB+OOPSY), LIMDATA); + break; + } + + if(y==oops->y) return 0; + else return 1; +} + +float oopslastx=0.0, oopslasty= 0.0; + +void new_oops_location(Oops *new) +{ + float dirvec[4][2]; + static int cnt=0; + int a, b, rc= 1, tel=1, ok=0; + + if(G.soops==0) return; + + if(G.soops->oops.first==G.soops->oops.last) { + oopslastx= oopslasty= 0.0; + } + + cnt++; + + new->x= oopslastx; + new->y= oopslasty; + + correct_oops_y(new); + + /* vanuit centrum vrije plek vinden */ + dirvec[cnt & 3][0]= 1.2*OOPSX; + dirvec[cnt & 3][1]= 0; + cnt++; + dirvec[cnt & 3][0]= 0; + dirvec[cnt & 3][1]= (float)(-1.2*OOPSY); + cnt++; + dirvec[cnt & 3][0]= -1.2*OOPSX; + dirvec[cnt & 3][1]= 0; + cnt++; + dirvec[cnt & 3][0]= 0; + dirvec[cnt & 3][1]= (float)(1.2*OOPSY); + cnt++; + + + new->x+= dirvec[ (rc-2) & 3][0]; + new->y+= dirvec[ (rc-2) & 3][1]; + rc+= correct_oops_y(new); + + if( oops_test_overlap(new)==0 ) { + ok= 1; + } + + rc++; + + if(ok==0) { + new->x+= dirvec[ (rc-1) & 3][0]; + new->y+= dirvec[ (rc-1) & 3][1]; + rc+= correct_oops_y(new); + + if(oops_test_overlap(new)==0 ) { + ok= 1; + } + rc++; + } + + + while(ok==0) { + + for(a=0;a<2;a++) { + for(b=0;b<tel;b++) { + + if( oops_test_overlap(new)==0 ) { + ok= 1; + break; + } + + rc &= 3; + new->x += dirvec[rc][0]; + new->y += dirvec[rc][1]; + rc+= correct_oops_y(new); + } + rc++; + + + + if(ok) break; + } + if(ok || tel>100) break; + tel++; + } + oopslastx= new->x; + oopslasty= new->y; + +} + + +void free_oops(Oops *oops) /* ook oops zelf */ +{ + BLI_freelistN(&oops->link); + MEM_freeN(oops); +} + +void free_oopspace(SpaceOops *so) +{ + Oops *oops; + + while( (oops= so->oops.first) ) { + BLI_remlink(&so->oops, oops); + free_oops(oops); + } +} + +void add_material_oopslinks(Material *ma, Oops *oops, short flag) +{ + int a; + + if(flag & OOPS_TE) { + for(a=0; a<8; a++) { + if(ma->mtex[a]) add_oopslink("tex", oops, ID_TE, &(ma->mtex[a]->tex), (float)(0.5*OOPSX), (float)OOPSY); + } + } + if(flag & OOPS_OB) { + for(a=0; a<8; a++) { + if(ma->mtex[a]) add_oopslink("ob", oops, ID_OB, &(ma->mtex[a]->object), 0.0, (float)(0.2*OOPSY)); + } + } + if(flag & OOPS_IP) { + if(ma->ipo) add_oopslink("ipo", oops, ID_IP, &(ma->ipo), OOPSX, (float)(0.5*OOPSY)); + } +} + + +void add_object_oopslinks(Object *ob, Oops *oops, short flag) +{ + ID *id; + + if(ob->parent) add_oopslink("parent", oops, ID_OB, &ob->parent, (float)(.6*OOPSX), (float)OOPSY); + if(ob->track) add_oopslink("parent", oops, ID_OB, &ob->track, (float)(.4*OOPSX), (float)OOPSY); + + id= ob->data; + if(id) { + switch( GS(id->name) ) { + case ID_ME: + if(flag & OOPS_ME) add_oopslink("data", oops, ID_ME, &ob->data, (float)(.5*OOPSX), (float)OOPSY); + break; + case ID_CU: + if(flag & OOPS_CU) add_oopslink("data", oops, ID_CU, &ob->data, (float)(.5*OOPSX), (float)OOPSY); + break; + case ID_MB: + if(flag & OOPS_MB) add_oopslink("data", oops, ID_MB, &ob->data, (float)(.5*OOPSX), (float)OOPSY); + break; + case ID_LT: + if(flag & OOPS_LT) add_oopslink("data", oops, ID_LT, &ob->data, (float)(.5*OOPSX), (float)OOPSY); + break; + case ID_LA: + if(flag & OOPS_LA) add_oopslink("data", oops, ID_LA, &ob->data, (float)(.5*OOPSX), (float)OOPSY); + break; + } + } + + if(flag & OOPS_MA) { + short a; + + for(a=0; a<ob->totcol; a++) { + if(ob->mat[a]) { + add_oopslink("mat", oops, ID_MA, ob->mat+a, 0, (float)(0.5*OOPSY)); + } + } + } + + if(flag & OOPS_IP) add_oopslink("ipo", oops, ID_IP, &ob->ipo, OOPSX, (float)(0.5*OOPSY)); +} + +void add_mesh_oopslinks(Mesh *me, Oops *oops, short flag) +{ + int a; + + if(flag & OOPS_MA) { + for(a=0; a<me->totcol; a++) { + if(me->mat[a]) { + add_oopslink("ma", oops, ID_MA, me->mat+a, 0.0, (float)(0.5*OOPSY)); + } + } + } + if(flag & OOPS_IP) { + if(me->key) add_oopslink("ipo", oops, ID_IP, &me->key->ipo, OOPSX, (float)(0.5*OOPSY)); + } +} + +void add_curve_oopslinks(Curve *cu, Oops *oops, short flag) +{ + int a; + + if(flag & OOPS_MA) { + for(a=0; a<cu->totcol; a++) { + if(cu->mat[a]) { + add_oopslink("ma", oops, ID_MA, cu->mat+a, 0.0, (float)(0.5*OOPSY)); + } + } + } + if(flag & OOPS_IP) { + add_oopslink("speed", oops, ID_IP, &cu->ipo, OOPSX, (float)(0.5*OOPSY)); + if(cu->key) add_oopslink("ipo", oops, ID_IP, &cu->key->ipo, OOPSX, (float)(0.5*OOPSY)); + } + +} + +void add_mball_oopslinks(MetaBall *mb, Oops *oops, short flag) +{ + int a; + + if(flag & OOPS_MA) { + for(a=0; a<mb->totcol; a++) { + if(mb->mat[a]) { + add_oopslink("ma", oops, ID_MA, mb->mat+a, 0.0, (float)(0.5*OOPSY)); + } + } + } +} + +Oops *add_test_oops(void *id) /* incl links */ +{ + Oops *oops; + Object *ob; + Lamp *la; + Tex *tex; + + if(id==0) return NULL; + + /* eerst test ofie al bestaat */ + oops= find_oops(id); + + if(oops) { + oops->hide= 0; + } + else { + oops= add_oops(id); + new_oops_location(oops); + if(G.soops->flag & SO_NEWSELECTED) { + oops->flag |= SELECT; + } + } + + switch( GS( ((ID *)id)->name)) { + case ID_SCE: + add_oopslink("set", oops, ID_SCE, &((Scene *)id)->set, (float)(.5*OOPSX), (float)OOPSY); + break; + case ID_OB: + ob= (Object *)id; + if(ob->flag & SELECT) oops->flag |= SELECT; + else oops->flag &= ~SELECT; + add_object_oopslinks(ob, oops, G.soops->visiflag); + break; + case ID_ME: + add_mesh_oopslinks((Mesh *)id, oops, G.soops->visiflag); + break; + case ID_CU: + add_curve_oopslinks((Curve *)id, oops, G.soops->visiflag); + break; + case ID_MB: + add_mball_oopslinks((MetaBall *)id, oops, G.soops->visiflag); + break; + case ID_LA: + /* textures nog doen */ + la= (Lamp *)id; + if(la->ipo) if(G.soops->visiflag & OOPS_IP) add_oopslink("ipo", oops, ID_IP, &la->ipo, OOPSX, (float)(0.3*OOPSY)); + break; + case ID_IP: + + break; + case ID_MA: + add_material_oopslinks((Material *)id, oops, G.soops->visiflag); + break; + case ID_TE: + tex= (Tex *)id; + if(tex->ima) if(G.soops->visiflag & OOPS_IM) add_oopslink("image", oops, ID_IM, &tex->ima, OOPSX, (float)(0.3*OOPSY)); + } + + return oops; +} + +void add_texture_oops(Material *ma) +{ + int a; + + for(a=0; a<8; a++) { + if(ma->mtex[a]) { + add_test_oops(ma->mtex[a]->tex); + if(ma->mtex[a]->tex) if(G.soops->visiflag & OOPS_IM) add_test_oops(ma->mtex[a]->tex->ima); + } + } +} + +void build_oops() +{ + Oops *oops; + OopsLink *ol; + ID *id; + Base *base; + Object *ob; + short a, type; + + /* altijd alles bouwen! */ + + if(G.soops==0) return; + + /* set hide flags */ + oops= G.soops->oops.first; + while(oops) { + oops->hide= 1; + oops->flag &= ~OOPS_REFER; + + BLI_freelistN(&oops->link); /* veel veiliger */ + + oops= oops->next; + } + + /* oopsen maken,is ook testen of ie al bestaat */ + + /* altijd */ + if(G.soops->visiflag & OOPS_LI) { + Library *li= G.main->library.first; + while(li) { + oops= add_test_oops(li); + li= li->id.next; + } + } + + /* rest op twee manieren: of alles (OOPS_SCE) of alleen gebruikt in deze scene */ + + if(G.soops->visiflag & OOPS_SCE) { + Scene *sce= G.main->scene.first; + + while(sce) { + + oops= add_test_oops(sce); + + if(G.soops->visiflag & OOPS_OB) { + base= sce->base.first; + while(base) { + + add_oopslink("object", oops, ID_OB, &base->object, (float)(.5*OOPSX), (float)OOPSY); + base= base->next; + } + } + + sce= sce->id.next; + } + + if(G.soops->visiflag & OOPS_OB) { + Object *ob= G.main->object.first; + + while(ob) { + oops= add_test_oops(ob); + ob= ob->id.next; + } + } + if(G.soops->visiflag & OOPS_ME) { + Mesh *me= G.main->mesh.first; + while(me) { + oops= add_test_oops(me); + me= me->id.next; + } + } + + if(G.soops->visiflag & OOPS_CU) { + Curve *cu= G.main->curve.first; + while(cu) { + oops= add_test_oops(cu); + cu= cu->id.next; + } + } + + if(G.soops->visiflag & OOPS_MB) { + MetaBall *mb= G.main->mball.first; + while(mb) { + oops= add_test_oops(mb); + mb= mb->id.next; + } + } + + if(G.soops->visiflag & OOPS_LA) { + Lamp *la= G.main->lamp.first; + while(la) { + oops= add_test_oops(la); + la= la->id.next; + } + } + + if(G.soops->visiflag & OOPS_IP) { + Ipo *ipo= G.main->ipo.first; + while(ipo) { + oops= add_test_oops(ipo); + ipo= ipo->id.next; + } + } + + if(G.soops->visiflag & OOPS_MA) { + Material *ma= G.main->mat.first; + while(ma) { + oops= add_test_oops(ma); + ma= ma->id.next; + } + } + if(G.soops->visiflag & OOPS_TE) { + Tex *tex= G.main->tex.first; + while(tex) { + oops= add_test_oops(tex); + tex= tex->id.next; + } + } + if(G.soops->visiflag & OOPS_IM) { + Image *ima= G.main->image.first; + while(ima) { + oops= add_test_oops(ima); + ima= ima->id.next; + } + } + + } + else { + + /* alleen blokken uit huidige scene */ + + base= FIRSTBASE; + while(base) { + + /* layer? */ + if( (G.soops->visiflag & OOPS_LAY)==0 || (base->lay & G.scene->lay)) { + ob= base->object; + + if(G.soops->visiflag & OOPS_OB) { + oops= add_test_oops(ob); + } + if(G.soops->visiflag & OOPS_MA) { + for(a=0; a<ob->totcol; a++) { + if(ob->mat[a]) { + oops= add_test_oops(ob->mat[a]); + if(G.soops->visiflag & OOPS_TE) add_texture_oops(ob->mat[a]); + } + } + } + if(G.soops->visiflag & OOPS_IP) oops= add_test_oops(ob->ipo); + + id= ob->data; + if(id) { + type= GS(id->name); + + if(type==ID_ME && G.soops->visiflag & OOPS_ME) { + Mesh *me= ob->data; + oops= add_test_oops(ob->data); + + if(G.soops->visiflag & OOPS_MA) { + for(a=0; a<me->totcol; a++) { + if(me->mat[a]) { + oops= add_test_oops(me->mat[a]); + if(G.soops->visiflag & OOPS_TE) add_texture_oops(me->mat[a]); + } + } + } + if(G.soops->visiflag & OOPS_IP) { + if(me->key) oops= add_test_oops(me->key->ipo); + } + } + else if(type==ID_CU && G.soops->visiflag & OOPS_CU) { + Curve *cu= ob->data; + oops= add_test_oops(ob->data); + + if(G.soops->visiflag & OOPS_MA) { + for(a=0; a<cu->totcol; a++) { + if(cu->mat[a]) { + oops= add_test_oops(cu->mat[a]); + if(G.soops->visiflag & OOPS_TE) add_texture_oops(cu->mat[a]); + } + } + } + if(G.soops->visiflag & OOPS_IP) { + if(cu->ipo) oops= add_test_oops(cu->ipo); + if(cu->key) oops= add_test_oops(cu->key->ipo); + } + } + else if(type==ID_MB && G.soops->visiflag & OOPS_MB) { + oops= add_test_oops(ob->data); + + if(G.soops->visiflag & OOPS_MA) { + MetaBall *mb= ob->data; + for(a=0; a<mb->totcol; a++) { + if(mb->mat[a]) { + oops= add_test_oops(mb->mat[a]); + if(G.soops->visiflag & OOPS_TE) add_texture_oops(mb->mat[a]); + } + } + } + } + else if(type==ID_LA && G.soops->visiflag & OOPS_LA) { + oops= add_test_oops(ob->data); + } + } + } + base= base->next; + } + } + + + + + /* links testen */ + oops= G.soops->oops.first; + while(oops) { + if(oops->hide==0) { + ol= oops->link.first; + while(ol) { + test_oopslink(ol); + ol= ol->next; + } + } + oops= oops->next; + } + + G.soops->flag &= ~SO_NEWSELECTED; +} diff --git a/source/blender/src/osx_creator_splash.jpg.c b/source/blender/src/osx_creator_splash.jpg.c new file mode 100644 index 00000000000..cf01f410dc6 --- /dev/null +++ b/source/blender/src/osx_creator_splash.jpg.c @@ -0,0 +1,971 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifdef __APPLE__ + +/* DataToC output of file <splash_jpg> */ +int datatoc_splash_jpg_size= 29805; +char datatoc_splash_jpg[]= { +255,216,255,224, 0, 16, 74, 70, 73, 70, 0, 1, 2, + 0, 0,100, 0,100, 0, 0,255,236, 0, 17, 68,117, 99,107,121, 0, 1, 0, 4, 0, 0, 0, 50, 0, 0,255,238, 0, 14, 65,100, +111, 98,101, 0,100,192, 0, 0, 0, 1,255,219, 0,132, 0, 8, 6, 6, 6, 6, 6, 8, 6, 6, 8, 12, 8, 7, 8, 12, 14, 10, + 8, 8, 10, 14, 16, 13, 13, 14, 13, 13, 16, 17, 12, 14, 13, 13, 14, 12, 17, 15, 18, 19, 20, 19, 18, 15, 24, 24, 26, 26, 24, 24, + 35, 34, 34, 34, 35, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 1, 9, 8, 8, 9, 10, 9, 11, 9, 9, 11, 14, 11, 13, 11, 14, 17, + 14, 14, 14, 14, 17, 19, 13, 13, 14, 13, 13, 19, 24, 17, 15, 15, 15, 15, 17, 24, 22, 23, 20, 20, 20, 23, 22, 26, 26, 24, 24, 26, + 26, 33, 33, 32, 33, 33, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,255,192, 0, 17, 8, 1, 15, 1,244, 3, 1, 34, 0, 2, 17, 1, + 3, 17, 1,255,196, 0,192, 0, 0, 1, 5, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2, 4, 5, 6, 0, 7, + 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 16, 0, 2, 1, 3, 2, + 4, 2, 5, 7, 7, 8, 6, 6, 6, 11, 0, 1, 2, 3, 0, 17, 4, 18, 5, 33, 49, 19, 6, 65, 20, 81, 97,113, 34, 50,129,145, +161,209, 66, 21, 7,193,225, 82,146,178, 35, 51,177, 98,114,130, 67,115, 36, 22,240,210, 83, 99,131, 52,162,163,195,211, 84, 54, +147,179,132,196, 37, 69,241,194,226, 68,100,116,148,164, 53, 38, 23, 17, 0, 2, 1, 3, 2, 4, 3, 6, 4, 6, 3, 1, 0, 0, + 0, 0, 0, 1, 2, 17, 3, 4, 33, 18, 49, 65, 81, 5, 97,113, 19,129,145,161,209, 34, 50,177,193, 66,146,240,225, 82,114, 51, + 20, 98,147, 21, 52,255,218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0,246, 67, 44,170,177,170,200,202, 58,113,216, 2, 64, +248, 22,157, 28,211, 27,222, 70, 63,214, 52, 39,251, 31,221,199,251, 11, 78,136,112,160, 31, 36,211,134, 22,145,173,111,210, 52, +195,147, 48, 63,196,127,214, 53,210, 94,255, 0, 37, 9,175,107,154, 16, 55,152,154,215, 18, 55,235, 26, 97,159, 32,155,117, 92, +127, 88,253,116,197,189,175,110, 52,224, 63, 61, 0, 65, 52,252,140,175,250,199,235,164,234, 77,225, 52,159,172,105, 56, 87,112, + 20, 2,153,114, 57,137, 95,245,141, 55,204,100,218,253, 86,253, 99, 93,198,247,240,166,158, 30,202, 0,121, 25, 89, 74, 20,117, + 93,110,111,112,198,132,217,153, 86,176,158, 75,255, 0, 77,190,186,102, 91, 19, 34,173,248, 1,113,242,159,205, 64,191, 11,212, +101, 14, 50,242,207, 60,137, 63, 93,190,186,119,155,202,183,241,228,253,118,250,232, 11,114, 44, 41,116,250,104, 7,140,204,195, +202,121, 63, 93,190,186,112,202,204, 60, 60,196,159,174,223, 93, 13, 0, 6,187, 80,185, 52, 4,129,147,148, 0,253,252,159,174, +223, 93,115,101,228,143,237,228,253, 99,245,212,114,215,181,171,135, 30, 38,128,145, 30,108,250,142,169,220,122, 46,199,235,162, +140,169,219,148,237,111, 78,179,245,208,225, 95,112,146, 1, 23, 63, 85,119, 78, 34, 73,208, 56,115, 60, 42, 0,167, 43, 33, 64, + 61, 71, 35,211,168,253,116,225,149, 63,140,175,234,247,143,215, 81, 66, 33, 54, 26,138,155,145,107,216, 91,217, 74,177, 48,184, + 12,126, 95, 69, 1, 32,100,228, 17,126,179,241,240,212,126,186,239, 49,147,199,247,175,250,199,235,168,218, 92, 88,171, 2, 7, +170,156, 76,136,190,242,131,236, 60,120,252,148, 1,252,196,246,254, 51,254,177,250,232, 47,147,144,150, 38,121, 63, 93,143,229, +166, 23, 60,244,145,235,166, 18, 30,192, 11, 91,159, 10,160, 41,204,200,182,161, 59,129,107,147,169,190,186,140,217,217,142,196, +137,229, 3,192, 7,111,174,147, 32, 16, 84,125,147, 77, 69,176, 44,220, 7, 59,250, 5, 80, 27,206,101,162,221,178, 36, 62,129, +173,184,159,158,155,231,115, 87,226,200,144,147,196,251,237, 97,244,208, 12,128,176, 39,151, 36, 20,215, 12,198,224,216,122,104, + 3, 28,204,208,110,114,165, 3,208, 29,190,186,112,206,203, 97,117,200,151,245,219,235,168,227, 73, 22, 62,245,169, 1, 55,176, + 22, 20, 1,198,102,117,253,236,153, 7,245,219,235,164,243,249,136,226,249, 50,144,124, 53,183,215, 64,144, 1,196,154,116, 49, +235, 58,156,112,160, 38,121,252,163,192, 79, 33,191,243,219,235,161,249,172,245,185,108,137,120,242, 29, 70,250,235,128, 0,220, + 10, 70, 26,143,178,128,107,102,231,248, 79, 47,235,183,215, 74, 50,183, 6, 23,243, 18,175,245,219,235,174, 0, 6,231,242, 83, + 76,161,156,170,142, 2,128, 42,207,153,194,249, 51, 31,248,140, 7,242,211,219, 59, 34, 62, 7, 34, 75,255, 0, 77,190,186,134, +229,239,197,172, 41, 27, 79,197,107,154, 2, 75,103,102, 91,221,158, 67,127,231,183,215, 76, 57,249,129,108,114, 36,213,234,118, +250,232, 58,137, 94, 60, 9,166,132, 0,223,153,160, 12,185,153,195,137,201,151,229,145,190,186, 47,222, 25, 96, 91,175, 33, 62, +146,237,245,212,106,235, 84,169,104, 27,207,102,159,254,241, 47,235,183,215, 93,231,115,127,241, 50,254,187,125,116, 27,250, 41, + 56,208, 18, 60,238,103,254, 38, 95,215,111,174,187,206,230,255, 0,226, 37,253,118,250,232, 43, 27, 55,194,164,219,157,133, 19, +203,184,248,172,190,178, 71,228,161, 71,121,204,223,252, 76,191,174,223, 93, 47,156,204,255, 0,196, 75,250,237,245,210, 8,163, + 28,216,183,166,195,242,154,112, 69, 81,112,156,127,156,105, 66, 85, 29,231, 51,127,241, 18,254,187,125,116,245,159,112, 99, 97, + 52,191, 43,176,254, 83, 72, 11, 95,221, 54,229,125, 34,212,225, 30,175, 18,125, 55,160,168,241, 54, 88, 54,124,183, 30,144, 29, +137,254, 90, 32,201,144, 0,122,243,185,231,241,144, 15,242,208, 68,126,241, 82, 61,119,163, 8,174,188, 57,114, 62,186, 1,222, +123, 37, 72, 84,118, 23, 63,105,153,191,104,210, 54, 70, 91, 30, 51, 72, 61,140, 64,225,236,174,110,130, 47,190,203,123,250,105, +146,229, 99, 34,168, 4,144, 7,128,231, 66, 14, 25, 25, 36, 92, 79, 39, 47,210,110,127, 61, 59,173,153,123,117,100,183, 11,157, + 77,245,212, 39,220,208,112,142, 47,148,154,103,159,152,241,176,183,162,169, 75, 50,249, 86,184,158, 65,253,115,245,210, 28,169, + 35, 35, 86, 75,124,174, 79,229,170, 89, 38,153,237,169,201,191,174,146, 40, 89,220, 15, 77, 5, 11,179,156, 44,109,147, 33,241, + 98, 11, 27, 15,201, 76,109,217, 84,112,154, 70, 54,181,238, 71,229,170,239, 46,121,120,248,208,229,132,139, 0, 57,208, 23, 31, +120, 47, 71,171,169,245,116, 53,107,185,189,186,250, 57,243,174,168, 90, 63,194,219,255, 0,194,219,255, 0,221, 87, 84, 26,150, + 15,246, 63,187,143,246, 22,136,160,218,212,198,226, 99,254,132,127,176,180, 81,194,169, 0,200,164, 17,199,194,152,110,124, 47, +106, 36,196,106, 30,202, 24,106, 16, 80, 79, 42, 69,102,185,191, 42, 80, 69,113,183, 43,208, 14, 6,184,154, 78, 0,113,174,184, +160, 20, 48, 96, 64,240,166, 53,185, 82,222,222, 20,210, 13,232, 8, 51, 13, 83, 48, 7,213,243, 10, 64,162,245,197,174,229,189, + 60,105, 46,126,122,133, 9,112, 13, 48,177, 53,195,157, 41,240,160, 56, 3, 92, 71, 10,237, 94, 20,134,228,208, 28,197, 80, 18, +120, 0, 56,213, 44,155,236,186,255, 0,115, 26,232, 28,181, 92,147,243, 17, 87,122, 1, 6,252,106,143, 63,104,104,245, 79,138, + 53, 39, 54,143,196,123, 61, 85,243,251,147,202, 86,227, 44,102,210,141, 92,233,247,120,123, 15,118, 2,198,115,113,200, 85,114, +162,141,126,210,235,108,221,113,114,163, 17,159,114, 97,114,200,120,223,250, 54,169, 98, 72,205,205,192, 62,190, 21,133, 86,100, + 96,202, 74,176,226, 8,224, 65,171,236, 13,228, 72, 86, 28,178, 3,219, 74,203,200, 31,233,122,235,134, 23,116,141,202, 91,200, +106, 50,224,165,194, 50,243,232,206,217,157,181,194,183, 44, 86, 81,231, 30,113,242,234,139,164,107,129,165,192, 4,220,241,240, +245, 81,149,184,243, 60,168, 34, 61, 86, 28, 8,183,186,105,161, 69,129,224, 44,109,195,135, 3,236,175,172,124,176,254,233, 60, + 15, 19,198,146, 79,179,224, 65,227,242, 87, 44, 99,152, 98,170,120,158, 55,183,201, 76,100, 55,187, 57, 62,178, 7,141, 0,230, + 32,241,229, 72, 64, 55, 35,149, 48,137,111,204, 31,146,156,188, 5,219,153,231, 85, 0, 83, 41, 98,183,227, 99,107, 84,121, 36, + 14,116,253,133, 60, 79,164,210,228, 77,173,138,175, 33,194,244, 6, 96, 45,164, 85, 3,223, 81,248, 69, 32,226, 44, 91,219, 72, + 25,217,109,106,229,136,243, 39,230,160, 19, 90,169,178,143,109, 43, 6,127,132, 88, 83,130,133,227,252,180,186,212,155, 14, 38, +128,103, 70,226,228,222,136,134,223, 37, 51, 83,223,143, 1, 72,193,126, 35,243, 80, 7,189,197, 32,231,199,133, 10,228,175, 0, + 65,165, 86,178,241,231, 64, 61,157, 67,105, 28, 73,230,104,100,144,108, 61,209, 92, 73, 39,209, 92, 17,155,144, 38,149, 45, 4, + 98, 27,194,244,188,104,171, 3, 31,137,149,125,167,234,189, 61, 97,136, 91, 83, 51, 95,193, 69,190,147, 80, 17,235,184,158, 3, +141, 73, 8,163,225, 64,109,226,198,255, 0, 80,165, 1,143, 5, 54,241, 32, 11, 80, 84, 0,138, 67,225,111,111, 15,229,167, 44, + 43,246,156, 15,103, 19, 70, 9,127, 14, 55,177, 38,136, 34, 0, 27,240,181, 81, 80, 41, 28, 67,236,179, 31, 89,176, 63,150,136, + 44,132,104,141, 86,198,230,227, 81, 31, 43, 94,156, 12, 42, 6,183, 23,245,154,107,102, 98,198, 44, 46,199,194,194,160, 28,194, + 70,247,152,146,180,206,159,160,115,229,122,105,220, 3, 0, 18, 62, 3,210,106, 60,185,179,158, 2,203,236, 21, 72, 77, 16,146, + 56,252,181,207,210, 65,119,113,235,185,170,240,243, 72, 46, 88,159,150,152,209,177,107, 31, 10, 22,132,241,145,142,128,216,223, +216, 41,143,184, 5,176, 72,254,122, 12, 80,251,154,169,100,131, 77,155,195,149, 0,158,114,118,185, 22, 95,101, 14, 73,103,127, +137,201,249,105,225, 2, 45,207,143, 26,145, 20, 75, 56, 10,182, 30, 36,212, 53, 77, 8, 73, 27, 22, 30,186,147,229,143,207,198, +164,152, 70, 61,217,200, 60, 56, 90,163, 12,171,191, 46, 28,133, 83, 36,115, 29,184, 91,141, 28, 71,165, 64, 53, 32,105,190,178, + 61,227,196, 26,137, 49,102,114,163,144,168,105,105,168, 97, 7, 82,197,124, 42, 66, 66,208, 27,183, 6,240, 30,170, 14, 27, 16, +116,183,133, 74,157,137,141,152, 11, 26, 17,186,186,145,222,120, 80,233, 13, 99,234,166,185,141,192, 1,175,127,181, 81, 89, 0, + 23,241, 52,232, 65, 23,244, 81,136,241,212,176,233,127,133,248,133,188,181,188,127,241, 55,174,167,216,121,109, 62, 30, 95,255, + 0,120,174,168,111, 79,137, 36,124, 81,223,194, 56,255, 0, 97,104,151, 20,136,183,210,127,221,199,251, 11, 79, 49, 3,225, 90, + 57, 17,230,182,161,236,160, 26,145, 52, 87,111,146,130, 98, 54,161, 6,131, 75,171,198,144,194, 71,137,167, 8,184,115,160, 18, +254, 55,174,213,227, 74, 33, 35,198,184,163, 91,133, 0,151, 52,174,196, 35, 16,120,128, 72,249,169, 44,195,194,133, 53,250,100, +122,109,106, 2, 56,224, 41, 9, 23,246, 87,105,244,210,129, 80,162,113,168, 19,238,248,145, 62,129,170, 82, 57,149,181,190,115, + 83,229, 93,104,200, 13,139, 2,160,250, 46, 43, 50,251,118,100,108, 84,196, 77,188, 87,136,175,159,220, 50, 50,109, 40, 44,120, + 55,186,181,146, 91,169,224,123,176,108, 99,221,114,245,231, 74, 82,145,174,218,248,150, 99,125,199, 31,217, 63,209, 75,247,238, + 63,251, 39,250, 42,167,200,102,127,176,127,154,184,224,229,128, 73,133,128, 28, 73, 35,149,124,207,247,251,143,244,191,250,255, + 0,145,244, 63,210,192,254,165,251,255, 0,153,111,247,244, 22,254, 19,253, 20,131,127,132,127,100,255, 0, 69, 80,215, 87, 63, +253,108,191,234, 95,181, 29, 63,243, 49,127,165,254,230, 76,205,159, 19, 32,245, 32,137,162,147,237,114,210,125,126,218,135, 82, + 49,240,115, 50,191,229,177,228,148,122, 81, 73, 31, 56,163,190,203,187, 70,186,159, 10, 96, 61, 33, 9,254, 74,242,205, 93,186, +221,223, 77,235,171,113,141, 35,240, 61, 48,118,173, 37,111,122,211,130,148,170,254, 33,118,221,230, 92, 50, 34,154,242, 65,200, +126,146,251, 43, 69, 22, 84, 19, 42, 73, 27,134, 67,198,245,138,101,101, 37, 88, 21, 97,192,131,192,138,145,133,157, 62, 12,154, +226, 55, 83,241, 70,126, 19, 94,220, 46,231, 59, 52,183,122,178,135, 10,254,168,252,209,227,204,237,208,187, 91,150,169, 25,241, +167,233,151,243, 54,183,140,252, 45,123,211, 69,175,196,251, 7,133, 3, 11, 51, 27,113,139,169, 24,247,199,199, 25,181,212,209, +210, 40,155, 87,187,106,253, 12, 39, 25,197, 78, 13, 74, 47, 84,209,240,167, 9, 66, 78, 19, 78, 45,113, 76, 91, 17,196, 26,135, + 60,167,140,106,127,164,106,179,112,238,222,222,218,183, 70,218,179,231,147, 30,100, 10,218,217, 88,199,103, 26,135, 21,213,244, +138,145,143,153,135,158,173, 62, 14, 66,100, 66, 88,129, 36,108, 24,112,240,225,227, 93,125, 57,164,164,226,210,122,167, 77, 14, + 81,185, 9, 55, 24,201, 54,184,170,234,189,129, 2,169,224,120,211,186,104,188,105,108, 71, 30, 0, 83, 24,134, 62,161,202,161, +177, 89,213, 71,166,184,179, 21,247,120,122,104, 51, 77, 20, 8,102,157,214, 40,215,226,145,200, 85, 23,225,204,212,120,247, 93, +182, 87, 17, 67,155, 4,146, 57,178,162,202,140, 73,244, 0, 13,234,164,222,169, 50, 54,147,163,105, 18,197,185, 51, 92,215,113, + 6,202,182, 30, 38,144, 15, 17,206,138,139,170,197,135,176, 84, 40,198, 1,173,196,251, 5, 61, 99,148,139, 4,183,183,243,209, +213, 91,144,225,106,126,131,192,147,106, 2, 55, 68,253,166, 31,203, 74, 35, 65,235,162,185,137,110, 75, 11, 83, 58,240,142, 87, +106, 3,130,128,108, 7,178,136, 16,145,252,181, 31,205,221,189,213,166,201,147, 63, 37, 58,125,148, 4,200,227,225,126, 92, 62, + 74, 95,220,174,157, 78, 47,237,170,226,101, 96,110,196,211,162,132,147,199,149, 66,178, 91,229, 99, 41, 60,216,248, 0, 62,186, + 97,205, 28,209, 56,248, 94,129, 36, 54, 34,194,247,229, 76,158,108, 92, 40,140,217,147, 36, 49, 39,197, 36,140, 21, 71,135, 51, + 87,193, 5,205,189, 18,234, 19,205,228, 72,108, 13,135,168, 82, 74,102, 34,236,196,213, 62, 31,119,118,252,251,140, 59,102, 38, + 65,200,158, 98, 85, 90, 52, 58, 1, 0,177,187,182,159, 1,225, 87,204,233, 32, 32, 26,179,140,163, 77,241,113,170,174,186, 25, +132,225, 58,236,146,149, 29, 52,117, 34, 34, 18, 77, 61,161, 32,139,211,222,209,129,167,137,162, 70,225,197,217,111,198,178,109, +209,104, 54, 56,149, 83,143,137,225, 93, 44,100,183, 1,126, 20,217,157,217,172, 13,128,227,106,114, 57,233,241,231,122, 49, 21, + 86,117,196, 75,164,243,163, 42, 35,141, 68,219,217, 81,153, 75, 57, 39,194,141, 25,208,131,133, 3,124,134, 75, 35, 33, 10,188, +135, 47,101, 18, 41, 25,214,231,195,133,169,179, 43, 94,246,231,202,150, 52,101, 22,183,182,140,177,234,198, 78, 11, 16, 7, 0, +105,216,247, 66,195,213,249,104,226, 30,167,168,142, 68,209,132, 40,138, 1, 96, 90,220,104,137, 39, 86, 6,123,152,200, 28,120, + 84, 48,154,136, 2,172, 21, 99, 28, 25,174, 79, 10,105, 16,167, 4, 94,126, 52, 32, 22, 63,102,252,121, 87, 28,119, 55,117, 23, + 7,209, 69,241,224,188,121,210,135,150,198,198,223,158,129,177, 35, 78,146,155,241, 99, 79, 14, 25,108, 64,246, 26,102,150,191, +188,109,115,107,215,116,195, 29, 55,189,207, 58,180, 37, 65, 54, 48, 36,126,241,109,227,115,202,138, 32,141, 80, 1, 42,223,196, +241,227, 92, 99, 65,194,231, 95, 38, 30, 30,170,120,129,116,139,145,195,137,168, 90,135,210,190, 94,221, 65,255, 0, 47,107,216, +242,235,243,174,174,176,242,247,208,109,229,237,255, 0, 95,254,134,186,130,164,232,192, 8,135,210,145,254,194,211,152,138, 96, +224,137,127,246,105,251, 34,148, 16, 69,234,153, 3, 41, 32,252,148, 59,222,151, 33,189,241,225,194,133,123, 80, 4,225, 74, 8, + 20, 16,192,248,211,239, 64, 59, 80, 62,170,234,101, 40, 32, 80, 11,227,114, 42, 62, 83, 13, 1, 71,166,255, 0, 53, 25,154,161, +228,146, 93, 87,194,212, 97, 2, 4,218,194,184, 92,241,165, 28, 5, 40, 32, 10,133, 18,222, 52,150,187, 82,220,218,161,102,103, +197,134, 52,223, 92,199,146, 15, 15,233, 87, 59,183, 97,106, 14,119, 36,163, 21,205,155,183,110,119, 36,161,110, 46, 77,242, 68, +169,178, 33,197,143, 92,173, 97,224, 60, 79,168, 10,207,102,238, 50,229,146,163,220,138,252, 16,120,255, 0, 74,163,207,145, 46, + 75,245, 37,107,159, 1,224, 7,170,133, 95,157,205,238, 83,191, 88, 91,172, 45,244,231, 47,238,249, 31,123, 15,183,194,205, 39, + 58, 78,127, 8,249,124,206,173,174,195,218,145, 44,105,153,186, 38,185, 26,204,152,231,225, 81,225,175,210,125, 85, 71,218,248, + 73,155,187,196, 36, 23,142, 16,102, 97,233,211,109, 63,244,136,173, 15,226, 7,113, 75,219, 93,181,145,155,138, 64,203,153,151, + 31, 21,143,217,121, 47,239,255, 0, 85, 84,145,235,175, 87,102,192,141,231,234,205, 41,125, 91, 97, 23,194,188,228,207, 55,118, +206,118, 98,237,197,184,210, 59,166,215, 26,116, 67,247,222,247,237,142,215, 35, 27, 55, 36,121,133, 28, 49, 49,215, 91,168,254, +114,175, 5,254,177, 21, 67,143,248,203,218, 83, 73,162, 88,242,241,214,255, 0,196,146, 37, 43,242,244,221,219,232,175, 5,150, + 89, 38,145,230,153,218, 73,100, 37,157,216,146,204,199,137, 36,158,100,211, 43,246,113,237,246,148,105, 38,219,234,180,247, 35, +241,211,238, 87,156,171, 21, 20,186, 61,125,236,250,159,165,176,247, 86, 16,202,198,146, 60,168,159,132,121, 80,145,169, 79,162, +252,193, 31,162,213,133,221,246,153,246,140,163, 4,190,242, 55,189, 20,163,147, 47,214, 60,107,207,127, 15,251,159, 43,183, 55, +252,107, 72,124,142,100,137, 6,100, 36,251,165, 92,233, 18, 91,244,144,155,223,228,175,123,238,156, 37,203,218, 37,123,126,243, + 31,247,168,125,159, 16,253, 90,252,255, 0,123,237, 80, 81,148,226,190,164,156,148,150,142, 73,113,140,143,208,118,110,233, 41, + 56,194, 95,107,106, 50,143, 21, 22,248, 74, 39,159, 97,229, 73,135, 58,207, 25,229,241, 47,131, 15, 16,107,105,141,147, 28,177, + 44,202,195, 76,158,240, 39,133, 97, 43, 75,219,179,179,227,201, 1,254,201,131, 47,177,191, 56,175,143,217,242, 28,110,187, 13, +253, 51, 77,175, 9, 47,154, 62,175,117,176,165,109, 94, 75,234,131, 73,248,197,252,153,229, 95,137, 68, 30,235,200, 42, 65, 29, + 40,120,143,232, 10,210,254, 31,102, 98, 96,246,220,211,229,204,144, 70,185, 47,119,145,130,143,129, 60, 77,102,191, 18,133,187, +175, 32,127,186,135,246, 5, 81,237, 91, 94,231,190, 72, 48,112,129,116,142,238,218,154,209,199,170,192,177,246,219,219, 95,185, +244,227,115, 18,220,101, 45,169, 70, 45,191, 4,143,196, 43,178,183,153,114, 81,142,249, 57, 73, 37,226,217,234,242,119,191,108, + 23,233,157,192,122,200,142, 66,191, 56, 75, 85,158, 14,229,183,110,104, 95, 3, 34, 60,128,188,194, 48, 36,123, 71, 49, 94,113, + 47,225,174,240,176, 25, 33,200,130,105, 0,191, 72, 22, 82,125, 64,176,183,207, 89, 84,147, 63,103,205, 37, 25,241,115, 49,216, +131,111,117,149,135, 48,107,138,196,177,113, 63, 70,235,109,117,254, 17,232,121,185, 22,154,245,237, 36,159, 77, 62,103,172,247, +176, 35,182,115,245,122, 35,225,255, 0, 21, 43,204,251, 87,255, 0, 49,109,214,255, 0,108, 63, 45,109,119, 13,233,119,238,195, +203,204, 96, 23, 37, 58,113,100,168,228, 28, 73, 31, 16, 61, 12, 13,235, 23,218,130,253,197,183, 15,247,195,249, 13,116,198,139, +142, 61,232,203, 70,156,147,253,167, 60,169,198,121, 54, 39, 23, 85, 37, 6,191,113,237,151, 85, 82,206,225, 85, 69,216,146, 0, + 0,122, 73,170, 60,206,252,237,204, 25, 12, 99, 39,174,227,129,232,169,112, 63,173,240,253, 53,138,239,206,225,159, 39, 58, 77, +155, 25,202, 98, 99, 29, 51,128,109,212,144,115,213,234, 94, 86,244,212, 94,213,236,230,223,226,124,204,153,142, 62, 26, 55, 77, + 74,139,187,176, 23, 58,111,192, 1,126,117,194, 24,150,227,109, 93,191, 39, 20,245, 73,120,240, 59,220,204,185, 43,174,206, 60, + 84,154,209,183,225,196,219, 71,248,141,177, 76,250, 76,210, 66, 15, 13, 79, 25,183,253, 29, 85,123,141,157, 14,227, 24,159, 15, + 33,103,136,253,184,216, 48,191,160,218,176,251,191,225,180, 48,226,188,251, 86, 76,143, 50, 2,194, 9,180,157,118, 23,178,178, +133,177,244,112,172,126,195,190,101,236, 57,233,151, 3, 19, 29,192,200,134,254,235,167,136, 35,211,232, 62, 21, 86, 45,155,176, +114,199,147,170,229, 32,242,239,217,154,134, 76, 21, 37,250,162,123,139,199,101,164, 10,136,132,185, 0, 0, 73, 39,128, 0, 87, +155,254, 33,231,200,242,109,147, 99, 76,235, 28,208,188,138, 81,138,220, 49, 82, 15, 15, 85,101,246,230,222,247, 73, 14,211,133, + 44,178,156,162, 58,145,151, 54, 33, 46,110,228,158, 10, 47,198,177,111, 9,206,218,184,230,162,159, 26,174, 20,122,155,185,158, +161,117,218, 86,220,154,225, 71,198,171, 77, 15, 83,200,239, 78,217,193,148,196,249,130, 87, 28, 15, 69, 90, 64, 63,172,163, 79, +211, 82,246,238,230,216, 55,135, 17,225,102, 41,152,242,134, 64, 99,115,253, 16,224, 95,228,172, 43,126, 24,238,171, 14,191, 57, + 1,150,223,195,179,218,254,141, 86,252,149,140,158, 12,140, 28,153, 49,230, 6, 44,136, 28,171, 15, 21,101, 62, 4, 87, 88, 98, + 99, 92, 77, 91,184,220,151,241,192,227, 60,220,171, 77, 74,237,164,162,249,127, 58,159, 66, 64,234,100,210,194,232,104, 91,166, +227,131,182,198, 31, 34,120,241,145,188,100, 96, 9,246, 95,157,102,112, 59,148,227,246, 84,123,254, 80,234,100, 70, 12, 10, 15, +246,147, 6, 40,183,246,129,168,215,150,230,231,110, 27,214,113,200,202,119,200,202,157,130,168,231,196,155, 42, 34,248, 15, 64, + 21,198,198, 20,167, 41,110,123, 99, 6,226,223, 86,186, 29,242, 51,227, 8,195, 98,221, 41,165, 36,186, 39,212,245,244,239,190, +216, 4, 35,103,141, 92,175,211,146,223, 62,139, 85, 95,121,102,225,238, 61,173,149,145,133, 58,100, 71,174, 33,170, 54, 13,111, +222, 47, 3,110, 85,157,196,252, 50,222,231,128, 75,145, 60, 24,206,194,253, 38, 44,204, 63,165,160, 17,244,213, 14,243,177,238, +253,185, 33,198,204,225, 14, 64,176,146, 38, 38, 41, 66,155,250,185, 30, 54, 34,187,219,199,199,245, 35,233, 93,172,162,211,163, +214,180,232,121,238,229,101,122, 82, 87,108,210, 50,139, 85, 90, 82,189,120,134,236,223,252,205,183,255, 0, 77,191,245,109, 94, +208, 10, 68,175, 52,140, 18, 53, 23,103, 99,101, 0,122, 73,175, 24,236,175,252,211,182,240,191,190,220, 63,225,181, 89,247,239, +114, 79,184,110, 50,237, 56,237,211,192,195,109, 12,138,109,212,149,126, 38,127, 78,147,192, 10,185, 86, 37,123, 34, 49, 78,137, + 66,173,248, 85,153,196,200,141,140,105,205,170,183, 58, 37,213,209, 27, 60,222,249,237,188, 89, 10,121,163, 59, 11,223,162,133, +199,235,112, 83,242, 26,102, 47,226, 15,108,200,193, 30,105, 33,212,126, 41, 35, 54, 23,254,134,170,199,246,143, 98,183,112,227, +182,225,153, 57,198,195, 12, 82, 61, 0, 23,144,175,196, 65,110, 0, 95,133, 91,239,191,134, 49, 98,225, 75,151,180,100,201, 36, +144,169,115,143, 48, 82, 92, 1,114, 21,144, 47, 31, 71, 10,230,236,225,198, 94,156,167, 45,220, 27,229, 95,113,213, 95,206,156, +125, 88,194, 27,120,165,205,175,121,190,199,151, 23,112,137,114,176,167,142,120, 91,147,198,193,133,254, 74,144, 98, 81,195, 87, + 10,240,158,218,238, 12,158,223,220, 99,201, 66, 91, 25,136, 92,168, 47,193,211,199,135,233, 15, 3, 90,127,196,204,169, 83,114, +192,147, 22,103, 72,165,197, 14,165, 24,168, 96, 93,172,220, 61, 85,137, 96,181,122, 54,247,105, 36,218,149, 58,114, 55, 14,224, +157,153, 92,219,245, 69,164,227, 94,188,211, 61, 51, 35, 39, 15, 19, 29,167,201,117,138, 24,197,222, 87, 33, 64, 30,178,106,143, + 7,188,246, 29,211,113, 77,179, 5,222, 73,164, 45,211,109, 4, 33,208,165,207, 22,177,228,190,138,242, 28, 36,222,119,169, 83, +105,196,121,114, 90,102, 14, 33, 46, 74,221, 65,247,219, 81,176, 0, 30,102,189, 7,182, 63, 15,247, 29,147,119,197,221, 51,114, +241,202,194, 31, 92, 49,150,102,247,227,104,248, 29, 32,112, 45, 90,158, 45,155, 80,151,169,114,178,163,113, 75, 79, 35, 54,243, + 47, 94,156,125, 59,116,133, 82,155,122,249,235,161,190,213, 37,248,127,165,169,193, 92,248,250, 62,154, 85,147, 29,120,117, 47, +110,118, 23,174,243, 24,232,120, 43, 55,209, 94, 19,232, 29,164,155,141, 94,240,240,165, 17,240,247,185,155, 0,105,158,104, 2, +116,198, 62, 83, 93,231, 38,228,161, 84,123, 42, 20, 48,132,220, 48, 23, 60,192,162,152, 8, 23,210,110, 71, 63, 10,132,114,178, + 15,246,132, 15, 64,225, 65,146, 73, 88, 18, 92,159,150,132, 44, 76, 77,111,125,148, 14, 2,247, 28,133, 55,252, 58,157, 77, 40, + 54,240, 21, 90, 27,135, 30,124, 40,160,112,160, 38, 25,241, 64,226, 75,159,101, 8,229,192,131,221,136,155,122, 77, 70,123, 0, +125, 84, 34,218,190,138,181, 4,225,154,130,218, 96, 3,218,196,210,156,214, 38,226, 36, 4,248,241, 63,150,160,150, 32,240, 23, +184,176,167,169,224, 47,207,198,160, 45,124,204,158, 94,250, 87,248, 26,173,110, 23,243, 26,125, 53,212, 27,255, 0,134,255, 0, +217,191,247,154,234, 2,208,142, 9,253, 4,253,145, 93, 92, 79,193,253, 4,253,145, 93,122,164, 35,228,124, 66,254,138, 1, 23, +225, 70,157,189,240, 61, 84, 49,123,240, 20, 3, 2,170,147,233, 52,237, 39,192,211,133,169, 45,198,128, 64, 13,136, 52,154, 8, + 55,191, 63, 10, 40, 23,165, 34,128, 23, 31, 26,133, 48,213, 43, 17,203,234, 21, 61,133,170,184,184, 44, 91,211,198,212,101, 66, +133, 28,141, 56,128, 61, 64, 83, 67, 85, 6,235,159, 36,146,190, 50, 29, 49,161,210,214,251, 68,115,189,121,114,242,161,141,111, +124,149, 91,116,138, 92,217,232,198,198,158, 69,205,145,209, 45, 91,124,145, 35, 63,119, 11,120,177, 13,207, 35, 47,128,254,141, + 82,146, 88,150, 99,114,120,146,121,210, 85,142,223,181, 73,148, 68,178,221, 33,240,244,183,178,191, 59, 59,153, 57,215,146,251, +159, 40,175,182, 43,248,230,125,232,195, 31, 14,211,124, 23, 57, 63,186, 76,141,141,135, 46, 86,162,130,209,160, 37,156,242, 22, +168,245,178, 88, 99,142, 62,138, 40, 84,181,128, 30,186,200, 75, 25,138, 71,141,185,161, 42,126, 74,233,157,130,177,161,107, 93, +206, 85,220,249, 87, 74, 36,115,195,204,121, 19,187,166,213, 26,109, 92,233,173, 91, 52, 61,149, 42,166,235, 36,103,156,144,176, + 95,104, 42,223,200, 41,223,139,155,100,251,135,105, 52,208, 41,118,193,157, 50, 93, 71, 62,152, 13, 27,159,147, 93,234,131, 15, + 42, 92, 28,168,178,225,248,226, 96,195,215,233, 7,218, 43,211,240,115,177, 55,108, 49, 52, 86,120,228, 26,101,137,172,108, 72, +247,145,197,125, 62,197,149, 24,199,211,253, 86,229,185, 46,177,103,206,239, 88,174,109,203,244,220,142,214,250, 73, 31, 37,215, + 87,180,119, 47,224,212, 89, 51,190, 95,109,228,166, 48,114, 88,225,100, 95,166,164,255, 0,179,117, 12, 64,245, 16,125,181,157, +199,252, 25,238,153, 37, 11,145, 54, 36, 17,248,201,212,103, 54,245, 42,165,126,194, 57,118, 37, 26,239, 75,193,241, 63, 31, 44, + 44,136,203,110,198,252, 87, 3, 27,219,155,100,251,198,251,129,183, 99,169,102,154,100, 12, 71,217, 64,117, 59,159,232,168, 38, +190,156,223,101, 88,118,124,215,115, 96, 98,100, 30,215, 26, 7,210,106,151,179,251, 19,106,237, 8,218, 72, 9,201,207,149,116, +205,153, 32, 0,233,231,162, 53,227,165,106, 15,119,111,113,229, 48,219,113, 91, 84,113,182,169,220,114, 44, 57, 40,246,120,215, +196,239, 57,246,213,169, 52,244,218,227, 10,241,148,164,125,222,205,129,113, 77, 39,197,201, 74,116,225, 24,196,202,213,215,110, +179, 9,167, 0, 18, 10,139,129,237,170, 90,209,246,228, 5, 97,150,114, 63,136,193, 87,216,191,156,215,229, 59,100, 92,178,237, +211,244,213,191, 42, 31,166,238, 50, 81,197,185, 94,116, 75,206,167,149,254, 36, 27,247, 86, 65,177, 31,186,135,159,244, 5,105, + 63, 13, 22, 17,180,100,149, 23,153,178, 8,144,248,233, 8,186,127,148,214,115,241, 39,143,117,228,127,119, 23,236, 10,168,216, +183,252,254,223,157,167,197, 1,162,152,105,150, 23,190,151,211,236,241, 23,231, 95,208,157,169, 92,195,132, 35,199,108, 95,157, + 15,192,198,236,109,102,206,114, 90,110,146,126, 21,230,123,112, 37, 27,249,166,188,159,241, 21, 97, 29,198, 76, 86,214,208, 70, +102,183,233,241, 31,178, 5, 88,205,248,153, 51, 69,104,118,245, 89,109,241, 60,133,148, 31,232,133, 82,126,122,198, 77, 54,110, +239,156,210,201,171, 35, 47, 37,249, 40,185,102, 60, 2,168, 31, 69,115,195,198,185,110,110,119, 22,213, 70,184,157,115,114,173, + 93,182,173,219,123,155,105,240,249,151,123, 49,127,242,167,113, 15,236,199,149,183,244,186,156,106, 31,105,255, 0,230, 77,183, +251,225,249,107, 99,151,177, 29,135,176, 51, 96,154,222,106,110,156,217, 54,240, 99, 34, 0,159,213, 31, 77, 99,123, 79,255, 0, + 50,109,191,223, 15,228, 53,218, 51, 83,183,145, 40,240,110, 95, 8,164,112,156, 37, 11,152,208,151, 20,163, 95,108,219, 34,111, + 58,254,247,220, 58,159, 31,153,155, 85,253, 58,218,167,109,155, 47,115,230, 98, 44,251, 92, 83, 54, 43, 22, 10, 99,148, 42,220, + 27, 55, 13, 98,174,187,251,183, 39,197,206,147,121,198, 66,248,153, 39, 84,228, 11,244,228,228,117,122,155,157,253, 53, 15,181, + 59,206,110,221, 71,196,150, 31, 49,135, 35,107,210, 14,151, 70, 34,196,173,248, 16,109,202,181,234, 74,118, 35, 59, 42, 50,116, + 90, 63,138,243, 50,237,198, 25, 18,133,247, 40, 42,191,169,124, 31,144,131,182,123,232,255, 0, 97,146,127,227,143,251,202,140, +123, 35,186,185,157,185,255, 0, 94, 63,245,235, 71,187,254, 38, 52,248,146, 99,237, 56,207, 4,178,130,167, 34, 86, 23, 64,120, + 93, 21, 47,199,208,111, 82,123, 23,186,119,221,203, 37,118,220,168, 78,108, 10, 61,252,210,116,180, 67,192,200,220,155,249,107, +151,169,149, 27,110,227,133,184,211,138,224,233,239, 58,250, 88,146,184,173,171,151, 37, 94, 13,106,171,238, 40, 59,195, 27, 39, + 15,111,216, 49,243, 20,166, 68,120,172,146, 33, 32,144, 85,148, 1,194,254, 21,105,248, 89, 18, 54, 86,229, 41, 23,117,142, 53, + 83,232, 12, 88,159,217, 20,239,197, 96,163, 47,109,177,191,238,164,253,165,167,126, 21, 50, 44,187,161,111,209,134,223, 60,149, +153, 74,184, 46, 92, 43,175,190,102,163, 20,187,130,143, 26,105,175,132, 15, 72, 28,173,107,215,137,247,202,132,238,157,192, 1, +111,121, 9,246,152,210,245,237,162,120,193,176, 91,250,107,197, 59,232,134,238,172,242, 5,133,227,225,255, 0, 9, 43,135,110, +255, 0, 52,191,177,254, 40,244,119, 63,240,199,251,215,224,195,230, 25,127,200, 59,104, 4,244,142,116,183, 30, 23,210,214,252, +180, 62,193,138, 9,123,167, 9,103,181,135, 81,163,191,233,136,216,173,105,118, 45,168,239,189,130,118,208, 66,201,214,146, 88, + 24,248, 72,173,194,231,208,121, 87,159, 21,206,218, 51,134,160,248,185,184,174, 24, 95,131, 43, 41,184, 53,236,131, 83,141,251, + 73,210, 91,166,191,119, 51,195,113, 59,114,177,121,170,199,108, 31,237,228,125, 23,209,111,209,181,188, 77,100, 63, 18, 98,135, +252,176,237, 54,158,170,205, 17,135,136,190,162,108,109,253, 91,214,103, 27,241, 67, 41, 97, 11,153,130, 38,148, 15,226, 36,133, + 1, 62,146,165, 95,249,107, 57,220, 61,205,184,119, 27,169,157, 68, 88,208,251,209,193, 29,200, 4,240,212,196,243, 62, 21,228, +177,135,122, 55, 99, 41, 45,170, 46,181,175, 26, 30,204,140,219, 18,179, 40,193,185, 57, 42, 82,156, 43,212,127,100,144, 59,167, +109, 44,108, 53,181,207,252, 55,170,124,253, 94,123, 39, 95,199,213,147, 85,249,223, 81,189, 90,246,119,254,101,219,255, 0,166, +223,176,213,103,223, 61,187,145,131,159, 46,235, 4,101,176,178,219, 91,149, 31,195,145,190, 32,222,166, 60, 65,175,115,185, 24, +228,237,122,110,130,167,154,111, 67,192,173,202, 88,187,214,170, 23, 29,124,154, 90,149,187,118,205,221, 89, 88,113,207,182,164, +231, 17,239,211, 49,202, 21,120, 18, 13,151, 88,241, 21, 43,252,191,222,230,227,167,146,125, 63,191, 31,247,148,238,216,239, 57, +182, 24, 78, 20,241, 28,140, 66,197,144, 41,179,161, 63, 22,155,240, 32,250, 42,199,120,252, 69,124,156, 87,198,218,160,124,118, +148, 21,108,135, 97,169, 65,253, 0,190, 62,187,215, 57,203, 39,212,113,141,184, 56,215, 73, 62,158, 58,157, 97, 28, 95, 73, 74, + 87,110, 41, 37,172, 87, 95, 13, 10, 63,242, 95,115,159,254, 94,255, 0,175, 31,250,245, 55,189,147, 42, 36,216,224,205, 5,114, + 33,219,227,142, 69, 38,228, 20, 37,109,113,127, 69,104,123, 35,185,183,237,210,111, 35,147, 1,203,134, 49,239,230,143,117,147, +208, 28,242,107,252,245, 85,248,155,168,238,152, 69,133,191,195,155,126,187, 86, 99,118,235,201,141,187,138, 63, 74,111,233,242, + 53, 43, 86,150, 44,174,218,115,250,154, 77, 75,193,147,127, 11,113,227, 45,184,229,145,251,213, 17,196,173,232, 86,212,205,243, +149, 21,232, 78,108,121,251, 43, 5,248, 88,140,240,110,122,109,193,226,189,253,143, 94,130,113,143,218,113,242, 10,240,230,255, + 0,244, 79,217,248, 30,252, 26, 44,104,123,127, 22, 9, 56,113,244,154, 53,175, 76, 68,240, 28,106, 66,198, 77,121,143, 80, 45, + 53,196, 90,140,176,233, 26,126, 90, 86,138,224,128,104, 64, 58, 65, 91,138, 99,139, 3, 82, 85, 2,173,175,202,129, 38,146, 56, + 30, 38,247,161, 65, 44, 50,177, 4, 33,249,104,139, 20,173,232, 31, 45, 17, 36, 10, 0,241,224, 0,246,210, 43,132,247,136,225, +126, 52, 7, 12, 87,107,221,192,249, 43,134, 40,241,115,242, 10,147, 13,202, 2,120, 19, 78,211, 66, 17,188,170, 14,108,255, 0, +233,242, 82,249,104,189, 46,126, 90,146, 69, 37,168, 2,116, 35,242,214,177,255, 0,151,181,239,198,222, 99, 85,117, 26,223,225, +253, 93, 31,251,106,234,160, 51, 22, 5, 5,190,194,126,200,165,212,125, 20,227,246, 79,243, 19,246, 69, 55, 85, 1, 30,127,140, + 27, 30, 84, 35, 37,188, 13, 72,148,241,184,244, 80,109,168,241,160, 27,168,219,151,205, 72,178, 18,120,139, 81,128,183,178,186, +128,110,171, 10, 93, 64,248,210,144, 57, 26,110,144, 9,189, 0,201, 26,202, 74,155,216, 19,243, 84, 32, 42, 84,224, 8,152,142, + 7,128, 31, 61, 69,210,109,206,163, 42, 56,218,168,243,182,169,222,119,150, 11, 58,200,117, 17,123, 16, 79, 62,117,116, 71,141, +119, 32, 43,207,147,139,111, 34, 10, 23, 43,163,170,107, 70,142,248,249, 55, 44, 73,202,221, 53, 84,105,234,138,156, 45,160, 35, +117, 50,172,196,114,140,113, 31,214,171,158, 32,112, 22,183, 42, 64, 56,209,121, 10,184,248,214,172, 71,101,168,211,171,124, 95, +155, 37,252,139,151,165,186,227,175, 69,201,121, 32, 68,177,170, 77,227, 12,134,243, 72, 46, 15, 9, 63, 33,171,202,105, 10,192, +134, 23, 7,129, 6,166, 86, 60,114, 45, 74,220,180,230,159, 73,114,101,198,191, 43, 23, 85,200,235,201,174,171,161,142,169, 88, + 59,134, 94,221, 55, 91, 18, 83, 27,114, 97,205, 88,122, 24, 30, 6,164,231,109, 79, 17, 50,227, 13,113,243, 41,226,191, 88,170, +202,252,189,219, 55,177,174, 82, 73,194, 75,132,151,227, 22,126,142,221,219, 89, 22,235, 26, 74, 47,138,127,131, 70,203, 23,190, + 70,144, 51,113, 78,175, 23,136,240, 63,213,111,174,164, 63,124, 96, 1,251,188,105,153,189, 13,165, 71,207,118,172, 45,117,122, + 35,221,115, 18,166,244,252, 92, 85, 78, 15,182,226,183, 93,141,120, 38,232, 94,238,125,213,184,231,169,134, 59, 99, 66,220, 25, + 99, 55, 98, 61, 5,254,170,162,174,163,227, 97,207,150,250, 33, 91,143, 23, 60, 20,123, 77,121,167,114,254, 69,197,185,202,228, +158,137,113,247, 35,209, 24, 89,177, 7,181, 70,220, 86,173,252,216,220,108,121, 50,166, 88, 34, 23,102, 60,252, 0,241, 38,182, + 48,196,216,208, 36, 17, 91, 74, 11, 15, 73,244,154, 22, 6,223, 22,223, 29,151,222,145,135,191, 33,230,125, 67,213, 82, 73,231, +111, 26,253, 7,110,194,255, 0, 94, 14, 83,255, 0, 36,248,255, 0,197,116,249,159, 11, 63, 51,215,146,140, 62,200,112,255, 0, +147,234, 80,110,253,183,179,238, 89, 94,111, 59, 5, 36,200,112, 3, 72, 89,238, 66,128, 7, 34, 42, 48,237,109,140,225,156, 6, +195, 79, 45,168,200, 19,143, 7, 32, 2,202,196,234, 28, 7,129,171,220,151, 96,234,160, 94,194,128,125,225,207,219,106,250,170, +229,202, 37,190, 84, 92, 53,122, 31, 59,210,183, 86,246, 70,175,142,139, 83, 44,223,135,189,182, 31, 86,137,130,254,136,144,219, +235,171,157,171, 98,217,182,143,123,111,197, 88,156,139, 25, 77,217,200,254,155,220,212,241,232,183, 15, 73,164, 62,233,230, 79, +168, 85,149,235,178, 84,148,228,215, 70,201, 27, 22,162,235, 27,113, 79,170, 67, 51, 49, 49, 55, 28,119,195,203, 65, 52, 18, 91, + 92,102,224, 27, 16,195,149,143, 49, 85,248,189,171,219,248,121, 49,229, 98,224,164,115, 68,117, 70,225,156,144,125, 60, 90,172, +205,212,234, 28, 61, 52, 64,111,199,211, 89, 83,154, 84, 82,105, 62, 41, 61, 13, 59,112,147, 82,148, 83,107,131,106,172, 86, 85, +101, 42,224, 50,145, 98,167,136, 32,214,111, 51,178,187,111, 50, 70,115,137,209, 99,204,194,204,131,245, 65,211,244, 86,146,187, +161,115,123,243,227, 72,220,156, 53,132,156,124,157, 4,237,194,122, 78, 42, 94,106,166, 82, 62,193,237,184, 88, 51, 67, 36,182, +240,146, 70,183,253, 29, 53,161,194,198,197,193,132, 99,225,196,144, 68,188,145, 0, 81,244, 84,193,142,167,153,165, 49, 70,163, +136,164,238,220,159,223, 41, 75,205,153,133,171,112,251, 33, 24,249, 34,175,113,217,118,157,217,163,125,199, 25,103,104,129, 17, +150, 44, 44, 15, 63,132,138, 77,191,102,218,246,158,161,219,113,150, 3, 45,132,133, 75, 27,233,189,190, 34,125, 52,205,255, 0, +127,194,237,220, 63, 51,144,134, 89,100, 37, 96,129, 77,139,176,231,199,192, 15, 19, 88,184,123,187,188,247,167,115,179,225,175, + 77, 79, 30,140, 90,194,250,153,228, 36, 94,166,249,237,219,185,237,233, 93, 61,198,189, 56,110,223,182, 59,186,211, 95,121,232, +168, 9, 53, 93,153,218,251, 14,225,146,249,121,152, 75, 46, 68,182, 47, 33, 46, 9,210, 2,142, 76, 7, 33, 88,184,187,235,184, +118,140,193,143,191, 97, 43,114, 46,133, 12, 82, 91,150,165, 63, 9,249,171, 77,220,189,210,216, 61,191,135,188,236,173, 28,131, + 42,100, 64,100, 82,195, 67, 36,140, 69,129, 22, 96,201, 99, 72,202, 81,117,139,113,126, 14,130, 81,140,149, 37, 21, 37,226,170, + 93,225,109,216,123, 94, 58,226,224,194, 33,128, 18, 68, 96,147,197,185,159,120,154, 14,235,177,237, 91,178,129,184, 98,164,197, + 69,149,248,135, 3,212,203, 99, 88,129,248,147,158,219, 98, 34, 65, 28,187,172,146, 48,184, 70, 17,164, 96, 13, 62,237,201,102, + 60,124,106,207,181,123,151,119,206,109,192,239,172, 35,143, 30, 53,144, 22,143,165,165,125,237, 71,144,225,238,211,116,147,220, +155,175, 90,235,239, 27, 34,227,181,197,109,233, 77, 61,196,129,248,115,219,167,247,132, 75,111,208,234, 27,125,117,113, 7,104, +236, 17, 97,190, 10, 98, 47,151,150,198, 85,227,118,210,110,186,158,250,141,143,174,177,217, 61,251,187,238, 57,131, 7,183, 48, +195, 2,109, 25,117, 47, 35,129,246,180,130, 21, 71,182,157,145,190,126, 34,108,113,121,205,199, 21, 27, 24, 91, 81,100,141,212, + 14, 94,241,199,107,175, 63, 26,219,189,118, 84,172,228,233,226, 97, 88,179, 26,237,183, 21, 93, 56, 35, 97,137,218, 29,189,131, +144,153, 88,184, 75, 28,241, 27,163,234,123,130, 69,188, 91,209, 86,237,141, 4,138, 81,227, 86, 70, 22,101, 97,112, 65,244,131, + 84,221,171,221, 88,189,203,142,246, 78,134,100, 54,235,193,123,139, 30, 78,135,197,127,146,168,123,167,191,114,118,253,197,246, +125,150, 5,151, 34, 50, 35,146,105, 1,111,222, 31,177, 26, 41, 23, 34,246,227,227,225, 88,148,165, 39, 89, 73,183,226,234,106, + 48,140, 85, 35, 21, 20,249, 37, 66,223, 47,176, 59, 99, 45,203,249, 62,131, 30,102, 7,100, 31,171,114,191, 69, 14, 15,195,174, +215,133,195,156,121, 38,183,132,146, 49, 31, 50,233,170,163, 55,226,154,161,200,232,196, 64, 26,186, 32, 65,170,222,139,106,191, +211,122, 55,104,247,238, 78,239,184, 46,209,186,192,145,228, 72, 24, 67, 52,119, 80, 89, 1, 98,142,140, 77,137, 0,241,191,170, +213,211,215,189, 74,122,146,167,155, 49,254,189,154,215,211,133,124,145,107,188,111,187, 63,103,195,139,138,216,174,144,204, 31, +163, 30, 42, 38,145,163, 78,173, 90,153, 63, 74,153, 6, 38,193,221,216,152,187,174, 70, 17,148, 58,178, 66,102,186,178,170, 72, +202,192,136,222,220,193,175, 60,239, 28,254,225,206,151, 28,111,184,158, 89, 98,105, 70, 41,233,180,122,193, 41,171,226, 38,246, +178,213,223,101,110,125,210,137,182,225, 99,225,107,217,204,133, 91, 39,164,199,220,105, 24,200,117,222,220, 24,159, 10,230,165, + 36,247, 41, 52,250,167,169,209,198, 46, 59, 92, 83, 93, 26,208,244, 29,175,100,218,246,117,145,118,220,101,199, 19, 16,100, 10, + 88,220,173,237,241, 19,233,171, 2,183,172, 55,117,126, 33, 46,209,148,251,110,213, 10,207,149, 23,187, 60,210, 95,166,141,250, + 1, 86,197,136,241,227,194,170, 7,112,254, 36,188, 94,117,112,223,161,109, 90, 70, 48,229,233,210,125,251, 81,182,221,100,219, +111,155, 17,138,138,164, 82, 73,114, 90, 30,136,197,144,144, 56, 95,129,162,249,133, 21,135,237,175,196, 72,247, 12,200,246,253, +243, 22, 56,102,149,130, 71,149, 24, 33, 75,158, 1,100, 70, 39, 77,253, 55,165,239, 14,242,221,123,115,117,143, 15,111,143, 28, +197, 36, 11, 49,234,198, 88,234, 47, 34,112, 33,135, 11, 32,168, 83,108,114, 73, 60, 20,159,101, 15, 94, 83,159,117, 90,222,139, + 87,159,238, 31,137, 91,198, 73,143, 31, 96,199, 82,235, 26, 28,137,196, 69,216,200, 84,107,208,156,149, 67, 95,157,235,109,218, + 27,190,227,186,108,112,101,238,109,254, 41,158, 69,147,221,209,240, 57, 81,117, 22,181, 1, 40,193,154,252,116, 53, 42, 97,228, + 94,236,182, 3,157,205, 89, 23, 99,227,194,132,196,159, 26,130,160,150, 33,123,218,228, 14,116,216, 84, 48, 32,143, 26,144, 56, + 41,249,168, 56,252, 9, 35,192,208, 7, 81,164, 82,218,184,122,105, 65,240, 53, 64,219,113,165,181,113,240,174, 30,170, 2, 79, +246, 31,240,127,237,171,171,191,177,191,251,159,251,106,234, 0,236,120, 45,191, 65, 63,100, 83, 26,252, 13,169, 73,107, 37,249, +232, 75,254,168,164, 60,124, 40, 0,203,123,242,227,106, 64, 62, 79, 77, 44,164,235, 3,208, 40,106,205,115,126, 84, 1, 47,127, + 10,227,195,194,154, 15,166,148,158, 20, 7,115,226,105, 9,189,112, 99,168,130, 44, 41, 24,219,149, 1, 27, 37,193, 85, 30,187, +143,146,132, 88, 1, 78,202, 55,117, 95, 0, 47,127,111,255, 0, 69, 7,215, 81,148,226,110, 43,184,250, 41, 84,112,189, 47,133, + 0,129,184,211,139, 19,192, 80,193,230,105,192,128, 40, 14, 2,244,161, 69,114,145, 75,126, 52, 2,162, 2,224,120, 95,136, 62, +138,110, 78,215,133,145,239, 60, 64,127, 57,120, 31,162,137, 25, 26,193, 38,214,227, 69, 12,182,231,249,171, 19,132, 38,182,206, + 42, 75,163, 85, 53, 9,206, 15,116, 36,226,250,167, 66,142, 94,223,135, 94,152,166,101,191,131, 40,111,167,221,165, 29,180,183, +183,154, 63,169,255, 0,218,171,166, 3, 90,241,249, 5, 19, 85,254, 19,196, 87,145,246,220, 54,235,233, 47,100,164,191, 51,210, +187,134, 90, 84,245, 95,186, 47,242, 43, 96,237,236, 24,236, 95, 84,173,252,227, 97,243, 10,152, 32, 72,192, 72,253,213, 30, 2, +214, 21, 35, 95,143, 58, 97, 11,227,206,189, 22,172, 90,180,169,110, 17,143,146,215,222,112,185,122,237,199, 91,147,114,243,122, +123,129,244,217,155, 65,115, 96, 61, 85,198, 39, 31,108,145,236, 20,244, 62,241,167,139, 3,233, 21,212,230, 86,228,112,148,163, + 27,218,220,126, 75,208, 47,164,240,229,226,104,217, 45,170,103, 97,202,246,227,234,225, 65, 6,252,171, 64, 83, 99,199,159,170, +148, 27,139, 30, 6,152, 77,141, 47,182,128,238, 3,135, 63, 73, 52, 65,206,212, 16, 65, 54, 30, 52,117, 28,111, 70, 5, 85,185, + 21, 34,212, 52, 28, 69, 26,161, 14, 2,153, 34,220, 90,158, 41, 30,214, 53, 65,229,127,137,194, 81,155,128, 79,240,140, 79,163, +250, 90,189,239,163, 77,108,251, 24,227, 30,216,193,242,214,224, 24, 77,110,125, 77, 71, 94,175, 95,228,169, 59,247,110,226,119, + 22, 8,197,201, 38, 57, 16,235,130,117, 0,178, 55,176,243, 7,196, 86, 30, 62,196,239, 13,166, 86, 59, 78,122, 42, 55, 54,134, +103,136,159,233,169, 22,250, 77, 1,172,238,153,251, 83, 25,177,207,112,162,201, 43,135,242,234, 80,185, 0,105,213,240,131, 97, + 89,190,242,109,154, 94,205,193,159, 99,140,199,132,217,163,166, 44,202, 56, 36,225,172,173,252,224,104, 80,254, 29,111,155,134, + 72,201,223,179,214,196,128,236, 29,166,152,139,242, 5,192, 81,243,159,101,105,251,159,181,100,220,246, 28, 77,151,104, 49, 64, +184,178,163,168,152,176, 93, 9, 28,137,205, 21,201, 98, 94,244, 5, 79,225,102, 6, 25,219,114,247, 25, 34, 87,201, 51,152, 3, +176,185, 84, 84, 71,178,250, 46, 95,141, 95,247,186,176,237,109,199,203,160, 15,161, 47, 97,246,122,137,175,254,141,233,189,151, +176,230,118,238,215, 54, 22,107,197, 36,178,100, 52,202,208,150,101,210,201, 26, 88,235, 84, 55,186, 85,244,209, 71,145, 19,193, + 50,135,138, 85, 41, 34, 55, 16, 85,133,136, 62,218, 3,196,251, 74, 62,224,147, 42,117,237,233,163,135, 35, 66,245, 58,130, 50, + 74, 95,236,245, 21,248, 95,157,171, 91,145,131,248,153, 54, 60,177,100,230,227,156,119, 70, 89,131,140,112,165, 8,179, 92,244, +189, 20, 28,223,195,157,199, 7, 52,102,118,230,112,139,222, 45, 18, 72,204,142,159,205, 18, 32,109, 67,219,106, 76,142,216,252, + 65,221,163,242,123,142,225, 31,150, 54,214,173, 37,148,129,250, 75, 18,123,223, 45, 10, 47,100,246,214,233,179,239,139,149, 52, +184,239, 11, 68,241,202,176,204,174,214, 32, 17,238,175,243,128,168,121,157,239,189,110,251,184,193,237,248,161,131,169, 46,140, +105, 12,104,210, 55, 30, 14,205, 32, 42, 61, 60,184, 86,215,181,187, 75, 15,182, 99,118, 87, 57, 25,179, 0,179,100, 17, 97,164, +113,208,131,141,135,167,211, 89, 61,207,240,227,117,199,220, 78,119,111,228,160, 65, 39, 86, 20,102, 49,201, 17,190,160, 20,128, + 65, 3,195,149, 8, 89,174,199,248,137,144, 9,202,223, 97,133, 79, 22,233,240, 97,233,248, 34,140,124,198,177, 93,156,161, 59, +199, 5, 21,250,170,179, 72, 4,131,147, 0,143,239,124,181,177,255, 0, 46,247,238,235, 31,150,222, 55,132,131, 16,251,178, 44, + 90,117,178,248,143,221, 36,119,249, 90,129,178,254, 31,110,219, 62,255, 0,143,185, 44,248,242, 98, 99,202,197, 84,187,245, 76, +100, 50,139,142,144, 93, 90, 79,166,215,160, 25,248,181,255, 0,201,255, 0,246,159,251, 26,209,254, 31,255, 0,229, 61,191,254, + 55,254,190, 74, 15,123,246,212,221,199,141,142,113,100, 72,242, 49, 25,202, 9, 46, 21,132,128,106, 91,168, 54, 62,224,170, 30, +223,237,126,245,219,114,112,215,205,136,182,232,167,142, 73,177,214,118,210, 99,214, 26, 69, 8, 5,189,225,126, 20, 6, 79,108, + 49, 47,120, 66,119, 59,105, 25,199,175,175,150,190,161,248,181,120,106,231,122,247,123, 86, 35,186, 63, 15,225,222,178, 95,113, +219,166, 92, 92,185, 56,205, 27,130, 99,118,253, 43,173,202,147,227,192,213, 26,246,151,226, 10, 69,228,147,114, 35, 24, 13, 33, + 70, 84,129, 52,250, 7, 11,219,213, 64,103,123,199,162,221,215,184,121, 14, 32,204,186,122,127,237,116,175, 82,214,241,234, 94, +172,255, 0, 18,245,125,251,141,174,218,252,154,106,183, 43,245,101,189,105,187,107,240,225, 54,188,184,247, 13,222,116,201,158, + 19,174, 40, 98, 7,166,174, 56,135,102, 96, 11, 91,195,128,164,238,238,203,221,123,147,115,143, 59, 6,108,120,226,142, 17, 9, + 19, 51,171,106, 87,145,238, 52, 70,226,214,127, 77, 1,163,237, 12, 28,108, 14,220,219,134, 58, 4, 51,227,199, 60,204, 7, 22, +121, 84, 72, 75, 31, 30,118,171,207, 26,137,180, 98, 73,131,181,224,224,204, 85,164,197,199,138, 25, 10, 92,169,104,209, 80,233, +184, 6,215, 30,138,151,192, 80, 28, 77, 54,150,184,143, 69, 1,222, 22,161,192, 56, 55,180,209,109,194,133, 0,184,111,105,160, + 12,183, 30, 52,190, 20,203,211,129,240,160, 59,215, 75,126, 22,164,183, 31, 93,117,135, 42, 2, 85,191,113,255, 0, 7,254,218, +186,146,223,184,183,251,159,251,106,234, 0,206,126, 31,232, 39,236,138, 64,126,154,231,191,187,253, 4,253,145, 76,191,207, 64, + 50, 91,106, 30,206, 38,152, 64,244,243,164,152,251,227,217, 76,213,198,244, 1, 47, 97, 93,168, 86, 71, 47,241, 35,178,112,114, +231,195,203,222, 35,139, 39, 26, 71,134,120,202, 74, 74,201, 25, 40,235,193, 8,224, 69, 46,245,248,131,219, 91, 38,209,143,190, +201,144,115, 48,114,164, 49, 99,201,134, 4,186,156, 2, 74,252, 74, 1, 22, 60,205, 1,172,185,164,181,249,154,137,131,153, 30, +225,133,141,159, 8,101,139, 42, 36,157, 21,192, 12, 22, 69, 14,161,172, 72,189,143,166,164,222,212, 4, 41,238,102, 96, 56,218, +192,124,212,203, 55, 42,121, 33,164, 45,224, 77,234,171,184, 59,135,110,237,157,181,247,109,204,184,198, 70, 84, 61, 37,214,218, +155,225, 0, 92, 84, 41,104, 20,242,165,211,225, 81, 54,141,211, 31,120,219,113,119, 92,101,116,131, 46, 53,154, 37,144, 0,225, + 88, 92,106, 10, 88, 95,229,169,122,168, 6,170, 95,133, 46,129,122, 85, 96, 9,168,249, 27,150,223,132,234,153,153,112,227,188, +132,116,214,105, 21, 11, 95,244, 67, 17,122, 2, 80, 80, 45, 75, 96, 5, 38,176,108, 71, 16,120,131, 81,178,247, 61,191, 13,210, + 60,188,168,113,217,254, 5,150, 69, 66,215,225,238,134, 34,244, 4,196, 80, 88, 3,225,115, 78,210,191,162, 62,106, 7,154,198, +129, 12,217, 18,164, 81,139,126,241,216, 42,241,229,197,184, 87, 67,185,109,217, 46, 99,199,203,134, 86,181,244,199, 34,177,176, +230,108, 13, 64, 74, 9, 25,251, 0,154,225, 18,122, 57,212, 29,219,121,219,118, 77,189,247, 29,207, 41,113,177, 35, 33, 94, 86, + 5,128, 44,116,175,192, 9,226, 77, 35,111,155, 92, 91, 87,223,143,146,163,110, 48,140,147,147,199, 79, 73,134,160,246,181,248, +131,232,160, 39, 20, 77, 95, 39, 42,227, 26,112,183,242,154,139,182,238,216, 59,174, 20,123,142,221, 48,159, 19, 35,222,138, 80, + 8, 12, 1, 42, 77,152, 3,204, 84,192,202, 79,179,136, 52, 3, 4, 98,231,152,249,105, 26, 63,231, 55,206,105,228,142, 36, 16, + 42,163,124,238, 93,143,183, 82, 55,222,115, 87, 20,205,113, 12,118,103,119, 35,158,136,227, 14,237,111, 80,160, 28,199,223, 99, +110, 4,147,115, 77, 36, 14, 55,191,170,160,109,123,214,209,189,226, 62,118,221,155, 30, 70, 60, 68,137, 92, 18,166, 50, 5,200, +145, 92, 43, 39, 15,210, 21, 23,108,239, 30,215,221,179, 70,223,182,103, 44,249, 39, 86,133, 17,200,170,250, 62, 46,156,142,138, +143,107,125,147, 90, 5,215,188, 71,186, 45,235,165, 8, 62,209,189, 67,220,119,140, 13,172,227, 12,249,215, 28,101,202,184,248, +229,129,179, 74,255, 0, 10, 92, 2, 1, 62,186,231,220,240, 6,226,187, 87, 88, 28,246,136,228, 8, 44, 73,233, 6,209,172,216, + 88, 13, 92, 56,154, 2, 96,210, 24, 42,142,117, 33, 69, 81,238,125,193,180,108, 77, 1,221,242, 70, 63,152, 44, 32,186, 59,106, + 40, 1, 96, 58,106,220,175, 83, 54,141,247,105,223, 97,121,246,140,180,202,142, 54,209, 38,139,130,141,206,206,172, 3, 15,148, + 84, 96,180, 95, 10,120,166, 47, 58,108, 25, 56,249, 73,213,198,149, 38,142,229, 75,198,193,215, 82,155, 48,186,147,196, 26,164, + 11, 67,149,173, 97,233,162, 26,107,129,107,208, 10,188, 20, 83,129,227, 76, 44, 5,129, 52,183,241,189, 1,210,120, 15, 75, 10, + 32,160,187,128,203,115,227,115, 75,215, 79, 14, 52, 1, 9,240,174,166,151, 22,227, 77,105, 81, 79,143,207, 82,162,131,155,227, + 65,237,167,212,115, 48,212, 8,240,191,211, 69, 15, 74,138, 4,231, 74, 5, 4,202,160, 94,194,134,217, 32, 14, 85, 69, 9,118, + 54,229, 77, 38,220,248, 80, 35,201, 46,214,181,135,166,136, 94,194,245, 27, 69,163, 7, 36,124, 89,239,236,163, 37,130,168,191, +133, 2,105,192, 26, 71, 27,243,166,121,166, 0, 11,114,162, 4,190, 2,184, 17,127,205, 65,134, 86,126, 39,149, 22,252, 46, 57, +212,114, 72,109, 99,201,161,195,109, 36,131,126, 38,153, 36,225, 69,188, 77, 9,102, 42, 44,181, 83,169, 40, 76, 23,191, 35,244, + 82,177, 4,212, 88,178, 11, 16, 26,142, 13,234,129,235,111, 79,209, 72,121,240,174, 21,198,128, 95, 10, 20, 12, 44,220, 45,198, +141,225,122, 14, 63, 16,195,215, 64, 20, 94,150,222,154,238, 70,184,216, 11,154, 16, 82, 43,129,161,245, 86,214,191, 42,238,170, +208,164,219,254,227,151,246, 63,246,213,212,206,168,232, 95,253,205,255, 0,235,173, 93, 64, 35,203, 37,147,143,246,113,147,192, +120,162,211, 58,143,233,174,113,252, 63,238,227,253,133,166, 80,160,178, 36,147, 88, 1,184, 91,208, 40, 66, 89, 44,120,220,250, +197,118, 73, 58,199,179,242,154, 7, 26,160,249,171, 55, 34,104,187,179,189,132, 91, 80,221, 76,255, 0,121,196,247, 93, 94, 85, + 91, 38,231, 48, 13, 45,198, 43,112, 60, 45,126,116,153,178,237,255, 0,255, 0,152,224,227, 97,206,242,204,187,179,203,152,146, + 46,147, 28,143,142, 84, 42,113,107,166,148, 22, 62,155,214,219, 39,240,215,189,163,223,119,221,211,104,220, 48, 49,226,222, 95, + 42, 55,214,210, 25, 60,182, 84,189, 82,132,116, 24, 43, 88, 14, 71,216,105,114,127, 7, 55, 20,237,136,182,156, 12,220,121, 55, + 7,203, 25,121,115, 76, 94, 56,180,172,109, 26,199, 30,132,145,141,181, 94,228, 10,128, 15,114,247,222,235,128,253,187,219,120, +123,167,220,152, 67,110,197,151, 55,113, 88,140,206, 11,197,238,141, 42, 25,180,141, 35,225,244,213, 59,254, 40,247,140,221,158, +178, 46,224, 99,206,199,205, 92,121, 50,150, 56,181,201, 12,145, 52,136, 24,148, 54,101,104,207, 17, 98,107, 99,220, 95,135, 27, +214, 76,251, 54,243,176,229,193, 14,241,182, 98,193,141, 50, 77,115, 19,152, 23, 78,180, 37, 26,252,202,217,150,196, 80,183,238, +196,239, 94,230,216, 35,195,220,178,118,229,207, 76,193,144, 4, 65,162,133, 33, 17, 24,244, 94, 56, 73, 47,173,137,226, 62, 90, + 2,155,183,187,195,187,176,187,215, 3,109,223,183, 17,149,135,147,138,146,203, 18, 40,208, 35,124, 95, 52,140, 61,213,109,107, + 97,115,227,198,179, 93,197,220,221,213,221,219, 38,225,187,101,229, 36, 91, 44, 89,145, 65, 30,220,170,162,204,225,228, 79,120, + 46,163,160, 47, 18, 79, 27,215,161, 71,248,111,188,127,155,246,237,242,121,177, 91, 3, 27, 22, 12, 92,136,131,201,213,110,158, + 47,149,125, 3,165,166,215,229,118,229, 89,255, 0,255, 0,200,123,194, 60, 28,237,155, 27,114,195, 27,108,185, 9,145, 18, 72, + 94,242, 52,122,145, 25,200,137,138, 29, 15,196, 11,241,249,232, 8,217,189,235,184,224, 97,118,191,110, 98,110,159,114, 97,125, +221,143, 54,110,226,177, 25,156, 23, 82, 84,104, 80,205,164,105, 31, 15,167,213, 81, 91,241, 51,187, 37,236,225, 42,231,152,243, +160,205, 92,121, 50,150, 56,181, 73, 12,145, 59,168,107,161,179, 43, 70,125,225, 99, 90,189,211,240,203,125, 9,176,238,123, 38, +102, 60, 59,214,211,139, 14, 44,235, 38,163, 12,134, 16,108,232, 90, 54,191, 6, 42, 67, 45,136,162,239,253,139,222,221,205,176, + 69,133,185,228,237,203,158,185,131, 33, 68, 65,226,133, 33, 17, 24,244, 94, 56, 73, 47,173,137,226, 62, 90,128,208,246, 7,249, +187, 41,114,247, 94,230,147,252, 54,116,120,210,237,112, 43, 43, 8,227, 42,229,181, 5,227,168,174,130,111, 89,159,197, 14,204, +237,188, 77,187,119,238,172,236,137,134,231,148,241,140, 69, 46, 2,117, 44,168,177, 34,105,227,117, 82, 77,205,122,110,211,143, + 38, 6,215,131,131, 49, 13, 38, 54, 60, 80,200,201,114,165,163, 69, 66, 84,144, 13,174, 61, 21,231, 95,136, 29,141,222, 93,227, +187, 71, 52, 25, 88, 48,237,152,130,216, 88,242,201, 45,238,108, 94, 73, 20, 64,203,169,136,229,196, 91,229,160, 52, 63,133,203, +185, 47,100,109,191,121, 22, 46, 67,156,113, 37,245, 8, 11,158,149,239,225,167,225,254,109,171, 45,248,161,217,157,183,139,183, +110,221,215,157,145, 48,221, 50,158, 49,136,165,192, 78,165,149, 22, 36, 77, 60,110,170, 73,185,171,105,123,127,241, 41,187,106, + 12, 8,183,188,116,222, 35,202,105, 36,202, 86,101,140,227,116,244,164, 75,167, 31,193,184,219, 71,203, 85,253,245,216,157,237, +222, 27,132, 18, 38,102, 4,120, 24,104, 23, 22, 9, 36,152,146,246, 29, 73,100, 81,142,203,169,136,249,190, 90, 2, 11,237,253, +193,159,248, 39,133,130, 49,103,204,205,201,157, 6, 52, 72,141, 36,190, 88, 74,210, 71,112, 1, 33, 66,167, 2,120,105,181,119, +224,254, 71,107,227,239,175,183, 29,175, 39,110,238, 88,241, 91, 30,115,145, 33,145, 36, 40, 80,207,104,217, 80,196,250,146,250, +108,108, 46, 47, 91, 8, 54, 95,196,136, 59, 78, 28, 72, 55,188, 63,243, 4, 25,157,110,185,254, 3, 98,116,140, 99, 28,131, 0, +227,169,175,240,120,115,168, 61,141,248,125,187,109,125,195,149,221,253,213,157, 6, 86,235, 56,125, 9, 1,247, 67, 75,193,221, +142,152,197,244,251,160, 40,181, 1,117,248,139, 10,100,236,216,120,130, 48,233,151,186,109,248,238,166,220, 67,100, 39, 14, 62, +155, 86, 79,105,119,204,237, 61,163,178,165, 58,242,134,246,219, 62,104,251, 70, 12, 9, 91, 54, 95,250,152,213,107,115,220,251, + 62, 86,246,155, 66,225,203, 10, 12, 45,215, 19, 63, 32,204,204, 47, 14, 59, 51,186,199,161, 94,238,120, 88, 27, 15, 93, 85,237, +189,153, 54, 23,226, 6,127,116, 62, 68, 45,181, 76,175, 38, 30, 40,102,234, 38, 76,233, 12,115,200,192,168, 95,120, 70,220,155, +198,128,206,118,134,122, 97,126, 26,118,249,109,235,238,115, 35,229,160,104,241,215, 47, 34,102,243, 19,105,142, 24,153,100, 55, + 28,205,144,209,240, 59,223,124,155,182,158, 49,211,159,124,151,124,110,222,194,203,158, 3, 7,130,191,153,159, 31,221,208,202, +164,221, 45,192,218,227,157, 38,201,216,157,209,219,184,251, 12,248, 83,237,249, 27,142,209,231, 34,151, 30,105, 37,242,239, 22, + 91,107,234, 71, 32,136, 50,186,248,251,188,106, 92, 93,137,189,141,155, 55,173,157,134,155,233,223,100,238, 29,186,120,117,182, + 56,145,130, 14,156,170,224, 56, 86,179, 92, 13, 86,225,196,208, 27, 61,143,108,221, 48,113,221,119,141,207,239,105, 89,181, 71, + 41,199,143, 27, 74,219,224,211, 23, 3,199,198,179, 27, 84, 17,102,254, 36,119, 62, 94, 74,131, 46,211,137,131,141,129,171,142, +152,242, 34,105,229,100,191, 47,120, 90,226,180,219, 36,251,251,193, 35,119, 26, 97, 65, 53,192,134, 60, 41, 36,144, 88, 14, 37, +218, 85, 94,103,144, 30, 21, 69,190,236, 91,196, 59,233,238,126,216,155, 24,228,207, 2,226,238, 56, 25,101,150, 41,209, 27, 84, +114, 35,198, 24,172,139,203,136,181,168, 12,230,239,182, 9,251,219,116,218,112,159,203,141,255, 0, 98,144,229, 20,224, 58,203, + 33,134, 57,156, 14,126,235,105, 53, 51,180,247,185,113,101,195,236,222,224,192, 27,126,235,135, 8, 92, 23, 64, 27, 31, 38, 56, + 83, 73,146, 7, 28,155, 69,203, 15,111,178,164,237,251, 6,255, 0, 30,102,229,220, 89,249, 24,173,191,229,227,140, 92, 24,227, + 14,216,184,209, 41,234, 44,100,157, 46,225,159,139,125, 20,200, 54, 94,227,221, 55,237,191,120,238, 63, 39,143, 6,208, 37, 56, +152,248, 77, 36,141, 36,179, 47, 77,158, 71,145, 83, 74,129,200, 15,150,168, 44, 59,207,109,196,221,123,107,113,198,204,144, 64, +145,196,211,199,146,220, 58, 82, 66, 58,137, 37,199, 30, 4,113,245, 85, 31,225,140,146,111,152,153,189,205,157, 42,205,187,102, + 72,184,217, 33, 69,186, 41,140,170,137, 22,159, 13, 87,214,125,181,121,220,219, 54,127,112,195,137,181,227,188,113,224, 73,144, +143,186,134, 44, 36,146, 8,200,126,140, 96, 41, 30,249, 30,241, 36,112,162,109,157,179,155,179,119,110,118,233,183,201, 8,217, +119, 72, 80,230, 98,146,203, 34,229,199,117, 89, 98, 80,165, 52,178,243,247,135, 63, 85, 1, 79,223, 82,203,131,220, 61,161,145, + 6, 52,153,146,166, 70, 81, 92,104, 74,137, 28,244, 64,178,153, 25, 87,198,252, 77, 65,216,247,168,176,247, 30,245,238, 60,236, +118,193,220, 35,134, 41,164,217,156, 17, 32,139, 26, 38,233,200,236, 6,135, 50,159, 21,184, 30,158, 53,164,238,237,147,120,220, +119, 45,139,115,217, 78, 41,151,105,150,121, 94, 60,199,146, 53,126,172, 98, 48, 1,138, 57, 15,166,161,224,246,126,110,102, 94, +245,185,247, 52,208,190, 86,241,139,247,121,199,195, 13,210,135, 31, 77,142,151,148, 6,102, 39,141,236, 62,168, 12,254,211,222, + 91,214, 94,102,215, 4,123,212,121,114,239, 81,201, 30, 68, 11,132, 85,118,249,222, 34,240, 73, 19, 21, 78,170,163,217, 88, 59, +155,250,105,157,145, 46,227,182,246, 76,153,217, 93,192,155,126, 19,101, 72,144,177,197, 70,104,216, 77, 32,144, 38,162,221, 71, +148,252, 35, 79,187,232, 53,169,237,252, 78,246,218,134, 30,213,184,182,223, 54,219,134,130, 31, 59, 25,151,204, 73, 20,104, 86, + 33,210, 32, 34,191, 5,212, 75,124,245, 65,141,217, 93,219,137,129,139,141,141, 38, 11,253,201,184,182,227,182,107,105,109,144, + 36,103,102, 73,215, 71,184,203,175,221, 34,254, 62,218,160,186,236, 62,226,220,247, 93,199,125,218,183, 12,151,205, 77,177,241, +155, 23, 46,124,111, 39, 59,199,146,143, 37,164,131, 76,118,182,142, 7, 72,184,227, 91,105, 13,150,178, 93,173,179,111,120, 59, +238,255, 0,190,111,143,139,213,222, 60,153, 72,241, 26, 66, 19,203, 70,241, 21,110,170,175,164, 88,248,243,176,229, 90,119,147, + 81, 32,114,240,161, 14, 23,102,213, 69, 98, 21, 73, 60,169,131,221, 80, 60,105,174,192,139, 30, 53,142, 44,215, 0, 26,153,137, + 52, 72,148,146, 88,215, 40, 6,159,112, 15, 14, 85,167,192, 33,236, 66,161, 36, 84, 93, 68,220,209,100, 33,128, 28,125,116, 48, +162,162, 84, 12,124, 75,168,221,185, 10,146,156,175, 66, 93, 42, 0,181,115, 48, 9,194,250,143,213, 81,213,178,130,150, 66, 95, +135, 33, 77, 37,143, 15, 77, 48,209,162, 85, 30,241,249, 43, 92, 17, 2,198,186, 20, 83,221,180, 45,205,168,122,135,230,161, 76, +234,205,164,114, 31,203, 88,165, 89, 70, 95, 81, 36,210,170,234, 96,180,193, 82, 96, 80, 1, 98, 56,147,194,182,221, 17, 3, 40, + 10, 0, 95, 10, 43, 54,133,185, 60, 0,160,221,125, 28, 56,208,242, 36, 83,238, 47,202,107,154, 85,101, 2,236, 93,203, 26,238, + 64,113,166,159, 80,163, 66,138, 72,102, 28, 5,116,224,140,132,130, 43, 11,158,102,140,166,198,212,221, 75,225,192,120,215, 49, + 64, 11, 30, 96, 86, 19,117,243, 52,214,129,212,142, 20,230,181,174, 79, 42,138,153, 8, 1,191, 19,232,161,188,205, 33,227,193, +125, 21,208,197, 3,174, 72,107,171, 11, 15, 3, 86, 24,219,111,238, 86, 94,175,241, 0,123,105,229,113,127, 77, 82,151, 26, 74, + 91,226, 35,141,107, 32, 83, 28, 17, 68,220,209, 21, 77,185,112, 22,164,117, 15, 68, 65,108, 27,113,234,127,209,252,245, 95, 54, +174,155, 91,199,133, 94,205,196,112,172,236,185, 9,121, 33,251, 74,197,126, 99,106,173, 82,132, 92, 16,134, 21, 17,235,235, 49, + 58,110,170, 57,222,153,251,157, 23, 18, 72, 95,197,120,125, 84,130, 70,141,150, 67, 31,186,163, 77,207, 35, 76,137,139, 92,219, +137, 55,172,212,213, 11, 30,154,249, 14,166,182,215,208,181,189, 93,125, 87,174,165,185,242, 90,111,253,135, 63,248,246,174,171, + 81, 65,210, 15,225,255, 0,119, 31,236, 45, 14,159, 39,246,127,221,199,251, 11, 76,160, 34,228,219, 88,246,126, 83, 64, 60,168, +249, 63,196, 30,207,202,104, 60,170,131, 34, 59,251,110, 84, 70,146, 7, 82,216, 57, 91,131,241, 4, 47,148,105, 17,225, 39,244, +137,133,237,236,171,168,247,253,186, 71,242,166, 80,185,203, 23, 86, 76, 78, 55, 86, 17,137,154, 61, 86, 10, 92, 43, 92,175, 59, +113,181,171, 31,151,248,125,184, 79, 46,107, 38, 68, 10,153, 27,136,154, 37, 37,253,220, 9, 14, 75,100, 99,176, 9,241, 22,204, +144,170,142, 28,184,213,154,246,166, 96,238, 28,141,192,132,124,119,158,124,184,102,124,140,139,171, 79,141,229,122, 99, 16, 30, +130,176, 37,175, 39, 18, 87,133,189, 0, 92, 97,119, 78,209,147, 22,220,100,157,113,242, 55, 44,120, 50,161,199,123,221, 87, 33, +117, 70,174,192,105, 5,184,133,185,247,136,225, 68,135,186, 59,126,124,121, 50,226,220, 35,104, 34,104,209,228,247,128,188,231, + 76, 54,184,185, 18, 31,132,142, 7,194,179,184,125,169,188, 97,195, 6, 7,248, 73,113,231,194,219,177,115,167,114,204,209, 54, + 12,109, 28,134, 4,100,247,203, 92,116,216,149,210,120,218,186, 30,211,221,228, 24,210,100,182, 60, 82,226, 13,163, 29, 86, 55, +118, 71,135,107,200, 57, 18, 74,111, 24, 33,228, 12, 66,167,135,139, 80, 26, 28,110,232,216, 50,186,134, 12,244,101,134, 23,201, +148,176,100, 11, 20,103, 76,142, 75,170,252, 7,131, 14,107,227, 83,113,119, 61,191, 51, 18, 76,236,105,131,227,197,168, 74,214, + 96, 80,160,187, 43, 35, 0,192,129,198,196, 86, 58, 78,201,220,165,197,147, 28,207, 2,151,196,221, 49,213,131, 73,252, 76,220, +244,206,131,146,131,164, 42, 89,200,226, 15, 43,214,139,182,118,169,246,172,108,175, 49, 26,195, 46, 94, 75,100,180, 99, 34,124, +182, 23, 72,226, 29, 73,242,137,119,107, 70, 61, 3,195,215, 81,128,123,103,121,108, 27,164, 59,124,139,144, 32,155,113, 72,228, +135, 30, 80, 67,142,171, 20, 69,114, 1, 80, 89,148,170,241,247,143, 43,210,247, 39,119,109,253,183, 32,131, 38, 55,150,102,196, +200,205, 85, 65,192,174, 54,155,173,207,139,106, 54,246,113,240,172,238,217,217,155,214, 38, 38, 62,221, 59, 99, 24, 92,109,169, +149, 60,114,185,100, 27, 92,253,101, 49,171, 68,186,186,202, 20,113, 35, 73,191,197, 86,189,235,219,219,151,112,116,254,238,120, + 23,252, 22,126, 20,158, 97,221, 45,230,196, 58, 29,116, 71, 37,244,180, 60, 71, 14, 7,228,168, 11,100,238, 45,179, 34, 76,113, +137, 60,114, 69, 44,242,227, 75, 35, 49,140,163,195, 11,100,176,210,234, 53,123,170, 15,135,186,117,114,169, 27,126,243,181,238, +145, 75, 62, 6, 74,205, 28, 54, 50,155, 50,149, 12,186,213,172,224, 29, 44,188, 84,242, 35,149,103,228,237,141,201,183, 41, 51, +145,241,217, 27,114,200,207, 84,147, 91, 3, 28,219,103,221,234,174,161, 69,207, 83,139, 11,252, 62, 55,225, 70,237,189,147,114, +219,112,243,241,242,132,113, 36,234,145,226,227, 36,210,100, 44, 65, 99, 40,192, 77, 50, 44,157, 61, 95, 2, 27,233, 95,154,128, +177, 94,234,237,215,130, 25,215, 62, 51, 22, 65, 34, 25, 0,109, 44, 6,141, 77,123,112, 65,212, 91,177,247, 65, 54,189,114,119, + 46,217, 23,159, 57,143,229,151, 11, 48,224, 93,174,198, 73, 4, 17,229, 18,138,128,181,130, 73,199,135, 11, 19,202,179, 57,253, +147,159,145,183,108,248, 71,165, 57,198,218,147,105,204, 79, 51,147,143, 16, 32, 69,170, 95,240,218, 26,116,247, 27,247,111,107, +240,169, 27,151,105,110, 83,205,149,153, 19, 71, 41,147,114,151, 54, 56, 6, 84,248,133,162,155, 10, 44, 43, 60,248,192, 58,178, +188,122,138,139,134, 94, 23,240,160, 53, 35,125,217, 83, 43, 31, 4,230, 71,230,178, 85, 26, 37, 82, 88, 17, 40, 45, 21,221, 65, + 81,212, 10,116,220,251,222, 21, 28,247, 71,111,234,200,182,108,127,225,172,178,216, 55, 18,100,232,254,239,221,253,231,239, 61, +207,114,254,247, 14,117,158,147,180,247,117,204,218,196, 47,143,228,118,213,219,122, 72, 39,154, 37, 83,133,117,153,122, 65, 36, +234, 22, 91,104,105, 24,145,107,112,189,234, 52,189,155,188, 76,211,181,241,160,141,101,139, 34, 60, 76,124,169,209, 37,145, 50, +124,196,141, 12,154,122,184, 98, 68, 63, 12,108, 70,190, 62,186, 3,114,155,142,222,219,127,222,163, 34, 63,187,214, 54,153,178, +137,247, 21, 18,250,203, 19,203, 77,141,253, 21, 77,153,222, 91, 76, 41,183,249, 54, 25,141,184,102, 12, 24,128,213, 31, 77,194, + 25, 36,105, 3, 38,161,165,109,238,145,115,113,225,198,154,157,186,223,228,217,187,111, 92, 80,100, 76,147,145,166, 73,102,137, +101,154, 87,200, 26,164,156,153, 92,106,111,121,143, 19,196,216,114,168,233,176,110, 19,231,197,187,100,180, 16,228, 73,188, 38, +231,145,140,146, 52,136,145, 69,128,219,122,162, 63, 77, 53, 57, 54, 99,112, 7,205,196, 9,187,175,122,237, 91, 70,230,251, 78, + 74, 57,158, 33,134,100,112,182, 80,185,147,249, 96, 79,244, 62, 35,234, 60, 56,212,247,238,126,221,232, 99,101,140,196, 72,115, + 11,249,119, 33,133,196,108, 34,144,176, 34,232, 21,253,214, 45,107, 30, 6,169,247,238,222,207,220,187,130, 45,207, 22, 76,113, +139,109,179,172, 36,119, 89, 20,237,249,205,154,218, 85, 99,117,109,105, 33, 2,236, 56,143, 93,197, 54,103, 98,231,205, 4, 48, + 51, 67,144, 29,119, 8, 39,143,205,101, 99,198,169,155,154,217,145,200,195, 27, 67, 76, 4,109,165,163,107, 13, 86,227,227, 64, +108, 55,173,225,182,201, 48, 49,161,196, 57, 89, 59,140,175, 4, 40,174,177,128, 99,134, 76,134, 44,207,195,225,140,213, 70, 63, +121,237,185,240, 75, 51,198,248,145,227,195,139, 60,141, 41, 7,142, 75,207, 10,196,130, 61, 90,142,184, 8, 26,111,170,226,213, + 39,186,246,105, 55,183,218,165,135, 19, 15,112,143, 3, 34, 73,178, 48,119, 6,100,134, 85,120, 37,129,120,136, 50, 69,213,164, + 13,197, 60, 43, 52,189,133,185,199,137, 52,103, 34, 57, 72,242, 15, 4, 49,205, 52, 31,242,153, 57, 83,182, 58,204,171,212,141, + 86, 60,133,142, 39, 94, 62,239, 16, 40, 13, 4,253,207,176,227, 65, 14, 68,249,177,172, 83,163, 75, 19,123,198,232,140, 17,219, +221, 4,128,172,192, 53,249,120,208,231,238, 45,190, 61,227, 27,100,141,250,185, 83,202,240,200,171,202, 34,152,239,151,239,146, + 45,240, 40,224, 15, 11,139,213, 52,253,139,159, 38,218,112,225,108,120, 93,246,189,199, 8,169,150,121, 20,100,103,100,199,148, +167,169, 42,188,142,163, 75,106, 99,196,159,179,232,153, 47,106,110, 82,111, 38, 69,108,117,219, 78,110, 78,113,159, 91,245,255, + 0,197, 96,190, 23, 76, 69,163, 77,209,219, 85,245,241, 30,186,160,184,199,238, 62,222, 24,146,103, 46,124, 93, 8,217, 18, 73, +141,192, 6, 83,104,173,112, 9, 87,251, 44, 56, 55,133, 31,112,222, 27, 26, 44, 73, 48,177, 37,206,124,211,251,148,142,209,168, + 77, 6, 82,242,188,186, 85, 6,145,110, 60,110,109, 89, 93,179,178,247, 28,124, 88,226,148, 67, 28,233, 62,210,206,231, 43, 39, + 40,201, 22,219, 55, 85,219, 86, 64, 58, 53, 93,186,113,170,128, 60, 79,163, 67,221, 24, 27,190,229,137, 22, 30,217,210, 48, 73, + 39,255, 0, 17,138, 89,228,198,105, 96,210,111, 10, 77, 12, 83,178,235,107,106, 32, 95, 77,192, 60,106, 1,205,220, 17, 79,179, + 97,239, 56, 56,211,101, 46,114,194,216,216,234,160, 72, 78, 65, 93, 58,201, 58, 80, 45,238,204, 77,128,244,211,240, 55,220, 60, +173,174,109,218,127,240,112,227, 52,209,101, 9,136,253,219,227,200,208,202, 53, 41, 42,195, 82, 27, 17,206,161,238, 56,189,201, + 38,216,248, 91, 92,120,120, 18,116,177,227,132, 71, 52,128, 70,161,136,200,142, 55,242,254,237,163, 1, 98,110,159,174,194,194, +156, 54,137,255, 0,202,242,236,241,224, 97,194,253, 51, 18, 97, 52,178,207,140, 86,247, 58,230,233,195, 41,103, 23, 37,180,223, + 87, 30, 52, 1,219,185,182, 13, 16,202,217,200,171, 49,116, 80,193,149,131, 33, 85,126,162,178,134,143, 73,117,185,112, 45,113, +233,167,203,220,123,100, 51,182, 12, 83,199, 46, 92,115,195,143, 60, 37,138,104, 51,201, 28, 98,237,164,141, 95,189, 5, 87,237, + 86, 63, 39,177,183,140,149, 81,146,209,206, 38,143, 35, 29,224,151, 55, 41,122, 81, 77, 36,110,157,105,160, 17, 62, 94,149, 70, + 12,178, 90,252, 56,240,189, 95,205,219, 89,207,231,180,201, 8,243, 59,230, 30,236,151, 45,194, 12,127, 41,173, 27,220,248,207, +151,107, 14, 92,184,213, 33,101,254, 98,216,175,152, 27, 50, 59,225, 6,108,130, 73, 1, 86, 54,208,228, 18, 44,218, 88,105, 58, +111, 99,195,157, 27,111,207,196,220,161, 57, 88, 82, 9, 98, 12, 80,240, 42, 85,215,226, 87, 87, 1,148,143, 65, 21,141,199,236, +220,252,115,158,141, 14, 54, 73,120,114,113,241,219, 39, 39, 42, 84,153, 50,114, 70, 78,150,134,225, 49,198,149, 0,244,193, 58, +189,239,109,255, 0,111,224,111, 59, 86, 55,151,206, 49, 60, 18, 52,210,241,149,230,157, 11, 50,116, 99,105, 94, 52,234,217, 53, +106,118,247,175, 97,196,113,168,250, 21, 23, 18, 72,215,225, 66, 50, 63,166,140,171,195,141, 13,210,238, 69,236, 5, 10, 52, 74, +227,198,187,170,254,154, 94,152,253, 33, 75,209, 31,166, 42,144,103, 81,253, 52,162, 71, 30, 52,254,128, 36,141, 67,213, 77, 49, + 17,226, 62,122, 3,186,210,122,107,132,174, 77,137,225, 77,233,181, 33, 82, 57,138, 0,142,193,109,165,245, 95,159, 11, 82,117, +159,151,162,146, 48, 25,192, 60,141, 73, 24,241,154, 2, 55, 85,233, 53,177,169,126, 85, 45,235,174,242,139,233,160, 34,235,106, +120,158, 75, 88, 84,147,134,131,145,164,242,131,211, 80, 0,235,201,234,166,245, 28,243, 2,140, 33, 5, 72,244, 92,222,187,160, + 45,127, 69, 40, 1,235,106,120,153,192,210, 0,165,147, 28,158, 42,109,225, 81,220, 58, 54,150,231, 74, 2,122,182,160, 47,254, +158,170, 4,178, 18,116,142, 66,134,146, 20, 91, 19,241,114,174,168,163,169,106, 31, 29, 18, 86,179,177, 95, 69,170, 88,192,132, +241,235, 55,204, 42,185, 24,171, 11, 26,178,133,245, 47,174,180,101,149, 51,111, 61,165,141, 60,152,249, 29,195,131, 12,241, 49, +142, 72,164,201,129, 25, 93, 77,153, 93, 89,193, 82, 15, 59,213,217,239, 94,203,176,255, 0,251, 30,215,255, 0,235,113,255, 0, +239, 43,231,236,110,223,218,243,183,174,250,223,114,246,153,187,143, 43,109,220,222, 60,125,143, 30, 73, 35,102, 89,242, 37, 15, +144,253, 11,202, 85, 52,219,221,249,107, 59,221,125,169,180,109,189,243,137,177, 98,179,225, 97,102,174, 36,179, 99, 76,225,229, +195,108,149, 86,147, 25,223,197,146,252,205, 71, 37, 24,185, 62, 9, 85,251, 10,162,228,212, 87, 22,232,189,167,211,207,222,189, +155,126, 29,197,182, 91,255, 0,206,227,255, 0,222, 85, 6, 95,113,246,129,150, 89, 87,184,182,226, 89,139, 0, 50,224, 60,205, +255, 0, 78,190,124,238, 45,143,110,135,104,203,205,139,107,155,102,155, 7, 45,113, 97, 19, 72,206, 50,145,181, 93,128,147,237, + 46,155,146,188, 43, 95,218,221,139,219,217,155, 95,110,193, 62,197,149,187,127,152, 98,150, 76,238,225,130,119, 72,246,230, 70, +100,208, 17, 1,143,247,122,110,253, 78,126, 30,138,205,171,241,189, 13,209, 77, 81,211, 90,126, 85, 71, 75,182,165,106, 74, 45, +167, 85, 93, 43,249,209,158,193,182,238,123,102,241, 9, 59,118,108, 57,145, 67,101,144, 99,202,146,217,143, 17,168,198,205,106, +152,177,128,186,163,184, 39,192,215,147,126, 8,121,124, 60,110,224,135,174,143, 26,101,199, 28,115, 92, 0,225, 85,198,161,127, + 72,227, 94,186,172,178, 68, 25, 24, 48,113,117, 96,110, 8, 60,136, 34,180,115, 36, 95,252, 23,243,186, 63,251,197,117, 47, 76, +249,109, 54, 23,232, 91,254,190,245,212, 2,184,225, 31,247,113,254,194,211,105,207,246, 63,187,143,246, 22,153, 90, 4, 92,159, +140,123, 63, 41,160, 27,222,143,146, 61,241,236,252,166,133,106, 3,205,101,239, 29,250, 60, 12,236,204,121, 83, 33,224, 77,205, +165,143,203,176, 76, 95, 41, 44,145,227,177,148,123,141,175, 64, 5, 79, 19,225,200,214,144,119,158, 3,111,239,176, 42, 7,157, + 94, 72, 16, 36,168,211, 52,177, 65,230,155,252, 61,245,132,210, 10,135, 60, 11, 11,122,234,115,118,214, 11,108, 57, 93,188,100, +155,202,101,249,158,164,154,151,168, 60,220,178, 79, 38,147,167, 79, 6,144,233,247,121,122,105, 63,203,152,227, 63, 39, 47,205, +228,172, 25, 45, 36,178, 97, 43, 40,139,173, 52, 67, 30, 73, 46, 23, 89,186, 14, 10, 90,192,241,181, 1, 81, 31,125,227,182, 14, +102, 83, 98,133,147, 14, 76,104,164, 81, 60,109, 18,121,174, 10,211,206,151, 88,250,102,226, 78, 7, 73, 30, 52,225,223,184, 11, +159,133,129, 60, 2, 25,178,252,186,180,111, 52,125, 64,249,110,209, 69,210,140, 27,202,183, 0,179, 47, 0,164, 31,100,140, 62, +205,139, 7, 29,226,198,220,243, 18, 66,152,241,137, 65,132,123,184,129,146, 37, 40,177, 4,101, 40,250, 93, 88, 16,121,243,227, + 68,194,236,236, 45,186, 92,118,194,203,202,138, 40,132, 61,104, 21,227, 11, 59, 99,187,201, 19, 74, 68, 96,143,122, 67,117, 66, +170,120, 11, 90,128,145,187,111,178,109,249,177, 96,226,224, 75,159, 49,133,242,231, 72,136, 12,144,198,233, 25, 40,164,126,241, +201,126, 10, 61, 28,234,151,111,239,137, 34,197,201,125,223, 24,129, 4, 91,134, 84,121, 17,178,129, 36,120, 89,167, 19,167,160, +219, 73,247,144, 92,158, 60, 79, 10,189,221,187,126, 45,215, 34, 44,161,149, 62, 28,171, 19, 99, 76,216,204,170,100,129,217, 36, +104,201,101, 98,190,244, 98,204,150, 60,248,212, 79,242, 94,210,208,188, 45, 36,236,143, 6,110, 49,247,214,225,115,242, 6,108, +140, 8, 79,137, 36, 81,163,213,206,245, 24, 1,143,222,209,103, 99, 68,118,220, 65,155,155, 38, 84,184, 98, 24, 39, 71,132,180, + 48, 12,167,116,200, 80, 85,151,166,194,214, 31, 17,183,164,211,118, 46,236,125,211,121,204,217,222, 22,243, 17,204,100, 16,176, + 17,190, 54, 39,151,198,144, 25,193,185,214,101,152,160, 3,215,232,169,179,118,183, 90, 8,245,110,121,126,126, 41,228,200, 93, +194,241,117, 3, 75, 17,199,145, 21, 58,125, 37, 77, 7,128, 11,192,241,231, 93,133,217,219,110, 6, 92,121,248,210, 78, 50,163, +155,175,215,102, 86,118, 83,143, 30, 35, 67, 35, 50, 18,209,178,196,172,111,199, 87, 27,212, 5,110,255, 0,220,251,214,221,190, +182,217,137,140,141,142,163,107, 40,196,141, 78,115, 51, 27, 26, 69,226,120,106, 85,210, 61, 4, 95,198,147, 39,241, 27,110,193, +194,198,202,204,128, 66,210,140,151,158, 23,158, 53, 42, 49, 39, 56,146,172, 58,244,245,156,186,146,170,163,136, 30, 21,115,185, +118,198, 38,231,186, 71,186,205, 60,241,203, 24,197, 13, 20,101, 4,111,228,242, 60,228, 37,181,198,205,193,201, 6,204, 46, 15, +176,212,115,217,184,136,144,174, 54,102, 86, 49, 79, 50,178,188, 76,129,229,139, 47, 32,230, 75, 19, 49,143,221, 2, 67,238,178, + 89,128,225,127, 26, 3,187,175,119,201,218,229,218, 98,131, 35,202,197,153,145, 36, 89, 19,172, 13,146,202,169,143, 44,203,166, + 36, 4,155,180, 99,144,229, 84,221,189,220,251,182,237,184,227, 99,229,100,180, 72,248,216,115,175,148,193,147, 37, 36, 57, 18, + 78,133,166,146, 37,145,113,195, 44, 74,125,242, 52,220,254,137,182,199, 47,110,131, 51, 55, 3, 54, 86,113, 38,221, 43,205, 0, + 82, 2,150,146, 25, 49,136,123,130, 72,211, 41,229,110, 53, 87,182,118,132, 59, 94, 89,201,219,119, 76,220, 93,106,137, 60, 75, +229,157, 37, 84,150,105,213, 91,171,140,236, 5,231,113,238, 17,195,215,198,128,162,206,239,125,202, 9, 59,145,161,104, 58, 24, +248,217,114,236,163, 69,200,125,185,151, 31, 35, 89,191,189,170, 71,184,245, 81,187,131,184,187,147,105,131,117,219,113,165,135, + 39,115,197,151,109,242, 89, 38, 16,161,147,112,149,224,209, 36, 97,136, 44,173, 17,226, 45,192,138,179,159,240,235,183,102,219, +225,193, 13, 44, 45, 20,115,195, 46,100, 93, 21,200,157,114, 81,163,148,228, 73,210, 58,201,213,171,151,196, 7,178,166,142,213, +192,102,105, 50,243,114, 50,178,229,202,197,204,151, 50,102,136, 72,205,130,226, 88, 35,211, 12, 81,198,177,130, 56,133, 64,120, +158, 55,227, 64,101, 51,187,255, 0,115,151, 39,117,200,218,204, 71,110,199,217, 31, 63, 16,148,212,124,210, 38, 36,247, 45,246, +148, 38, 98,139,122,107,111,178,229, 73, 62, 20,249, 18,205,147,150, 81,155, 72,159, 10, 76, 25,125,213, 13,165, 33,200, 72,153, +175,126, 13,107, 95,133,248, 85, 34,126, 31,246,236, 24,147, 97, 69, 60,201, 20,248,217,152,110, 21,227,191, 79, 54, 88,231,144, +143,221,218,233,210, 85, 79, 66,142, 32,243,171,248, 49, 26, 60, 57,241,114,247, 41,247, 30,184,101,105,114, 6, 58, 58,171, 46, +146,171,229, 33,129,126,112, 77, 1, 69,141,223,152,249, 56,211,200,184, 36,228,193,147,133,137,229,226,158, 41, 70,188,247, 88, +162, 86,145,125,213,116, 98, 67,175,217, 35,153,168, 59,183,127,101,166,201, 54, 94,217,129,167, 62, 60, 76,252,169, 67,186,178, + 64,112,167, 56,108,120,129,213,188,163,128,225,238,143,146,172,112,251, 47,109,196,133, 34,108,220,169,250,109,128,234, 91,164, + 5,246,199,234, 99, 11, 71, 10,240,224, 3,250,125, 71,141, 38, 87, 98,237,121,120,173,132,153,185,120,241, 73, 30,100, 25, 13, + 17,140,188,144,231, 78,115, 37,136,151,133,192,211, 41,247, 72, 23,183, 14, 52, 5,214,249,188,201,181,182, 30, 54, 46, 27,102, +230,231, 72,233, 4, 10,226, 49,104,163,105,228,102,118, 13,111,117, 44, 5,184,146, 61,181, 76,189,235, 28,249,113,196,251,108, +208,226, 60,167, 13,114, 38, 42,174, 50,134, 47,158,104, 94, 31,137,108,170, 86,255, 0,164, 61, 28,106,223,122,218,161,221,252, +180,139,149, 62, 22, 86, 35,179,227,229, 99, 42,235, 94,164,109, 4,139,105, 81,212,134, 71, 62, 28, 13,136,170,163,218, 56, 49, +206, 37,131, 34,118,138, 50,102,135, 22,102, 13, 31,154,242,222, 75,204,179, 20,234, 22, 49,243,187, 90,228,181,175, 68, 8,184, +125,241, 4,233,138,211,237,239,143,231, 6,223, 52,119,117,123, 99,238,108,241, 65, 51, 21,229,105, 19, 75, 47,172, 84, 57,187, +232,229,109,153,249,120,120, 50,195, 22, 46, 0,220, 31, 44, 52, 68,164,114,245,250, 5, 17,199,190,207,208,191, 43,113,160,158, +199,205,139,181,228,219, 86,113,149,187,100,224,225,109,198,105,100,211, 22, 58,226, 13, 74,208, 24,226, 86, 43, 28,172,206,186, +134,163,195,143, 10,189,126,206,218,159, 15, 59, 7, 92,169, 14,126, 14, 62,217, 40, 70, 81,162, 28,101,145, 35, 49, 93, 13,154, +210,155,222,227,151, 10,160,141,151,221,237, 22,224,248,113, 96,191,151, 25, 79,183, 38,105,117,183,153, 76,118,203, 97,210,248, +180,133, 91, 95,211,244,211, 69,223, 27,188,157,191, 30, 72,193, 95,188,146, 45,158,105, 88,186,244,228,143,115,145, 99, 46,170, + 45,164,146,172, 0,191, 11,131,233, 21, 59, 35,181, 51,114,123,144,101,137, 4, 91, 82,229, 28,246, 69,154,250,164,108, 87,196, +107, 64, 97,247, 92,150,185,110,169, 91, 14, 10, 9, 53, 56,118, 78,216, 48,159, 5, 50, 50, 81, 95, 27,111,196, 18,134,143, 90, +174,214,230, 76,105, 22,241,149,215,168,221,174,164, 31, 64,168, 4,238, 46,233, 27, 12,133,124,147,100,149,196,151,112,155, 76, +138,129, 33,199,120,146, 79,136, 29, 77,251,222, 3,198,148,247, 73, 27,155,224, 38, 11,188, 39, 41,246,248,114,140,138,161,242, +211, 28,229,244,180, 30, 33, 74,169, 93,126,159, 11,113,163,238,253,181,133,189, 60,167, 46, 89,129,151, 10,125,181,204,101, 7, +238,178, 26, 55,119,226,135,223,188, 34,222, 28,248, 83,211,182,241, 6,232, 55, 62,180,165, 6, 65,205, 92, 51,163,162, 50,154, + 31, 42,103, 30,238,187,244,239,195, 85,174,111,107,208, 25,157,155,189,243,178,112,227,202,204,199, 50,230,205,143,182,152,177, + 35, 40,145, 52,185,207, 52,106,202,254,243, 40, 61, 61, 77,170,246, 3,135, 26,159, 39,127, 99, 69,184, 98,237,121,120,173,139, +149, 51,195, 12,176, 77, 42, 44,203, 46, 68,173, 4, 98, 40,143,189, 42,106, 75,151, 31,100,131,236, 54, 39, 99,237,216, 80, 54, + 46, 62, 94, 86,181, 92, 69,198,157,204, 76,240,249, 9, 36,155, 31, 64, 17, 42,155,117, 74,157, 96,221,125,124,106, 76, 93,171, + 6, 30, 68, 89, 41,184,102, 19,120,155, 45, 89,208,249,153, 33,121, 38,141,230,109, 26,135,189, 41,186,161, 85, 34,194,214, 21, + 64, 29,235,184,151,100,204,146, 73, 86, 73, 34,131,109,202,220, 30, 4, 8, 3,116, 36,129, 62, 38,247,131,126,243,135,133, 13, +251,182,119, 39, 18, 61,177,159,114, 92,217,112, 70, 39, 85,108,122, 88,235,152,210,117,116,219,248,110, 5,173,241,112,229,198, +167,110,221,183,131,189,188,207,151, 36,168,102,194,159,110,110,145, 81,104,178, 26, 57, 29,134,164,111,124, 24,133,188, 61, 84, + 12,142,214,197,200,158,124,140,124,188,140, 76,169,114,159, 56,100,196, 99, 44,143, 38, 58,225, 72,136, 29, 25,116,152,208,115, + 4,134,227,122,207, 50,144,182,238,236,146, 76,137,162,203,129,215,173,159, 38, 46, 44,108,162, 55,137, 35,219,163,220, 74,204, +167,237, 95, 82,159, 93, 69,159,188,167,203, 27,123,109,184,165, 99,201,125,165,242,102,148,169,233,166,231, 42,129, 16, 95,180, +122,119,187, 14, 68,143,146,116,189,157,133, 18, 39,151,203,201,138, 69,201, 57,107, 54,164,119, 12,216,163,111,117,188,177,189, +195, 68,188,205,206,174, 55,164,199,236,188, 0,112,250, 89, 89, 49,195,134,184, 42,209, 3, 25, 19, 54,218,193,241,158, 82,209, +147,127, 6,209,166,255, 0, 37, 80, 67, 78,254,218,221,247, 21, 72,250,135, 6, 25,242, 18, 56,165, 71,145,215, 30, 81,142, 86, + 68, 83,120,153,221,151, 64,110,106,111, 86,189,189,184,103,110, 79,186,174,124, 75, 11,225,231, 28,100,137, 72,109, 40, 49,224, +150,218,199,197,239, 74,120,250, 41,171,217,216,102, 28,220, 71,202,201,124, 60,148,154, 40,241,181,170,164, 11,145, 33,157,250, + 90, 80, 18,193,248,169,125, 86, 28, 61, 55,157,180,109, 13,181, 12,179, 20,242,229,203,153, 63,154,202,154,126,152, 38, 83, 28, +112,157, 34, 36,141, 66,218, 33,194,212, 4,253, 30,245,173, 76, 96, 47,195,133, 74, 69,234, 33,123, 89,135, 49, 64, 96, 44, 77, + 0,145,240, 20,104,177,155, 41, 79, 16,182,241, 52, 21, 66, 65, 96,218,107,144,100, 1,120,175,111, 85, 82, 18, 70,221, 44, 95, +189, 44, 8, 78, 38,140, 12,119,168,101,242,194,217,181,105, 60, 13,234, 64, 23,229,195,215, 64, 72, 83, 31, 27,210,106,143,157, + 15, 70,145,107,234, 60,233,109,194,128, 45,163, 60,207,203, 79,211, 29,249,242,168,230,231,228,229, 72, 79, 59,208, 18, 58, 81, +219,194,184,192,156,175, 64,185, 7,157, 46,179,122, 1,239, 26,168,176, 53, 11, 50, 63,116, 55,136,163,181,203, 88, 82,116,196, +238,168,126, 30,109,236, 20, 64,136, 49,229, 97, 25, 8,196, 31, 16, 13, 59,161, 63,251, 39,253, 83, 87, 74, 0, 1, 64,176, 28, + 0, 20,224, 7,162,183,179,196,149, 42, 34,197,148,157, 77, 19, 88,120,105, 53, 38, 8,102, 91,142,147, 1,127, 21, 53,100,130, +164, 32,183,174,162,130,175, 17,185,112, 62,122,237,216,224, 94,240,239, 12,201,182,180, 39, 15,114,200, 51,111,185, 27,180,251, + 68, 88,203, 36,206,139, 3, 62, 56, 37,140,140, 57, 86, 39,190, 54,153,231,239, 52,218, 54,253,145,182,236,220,142,146, 38, 42, +102, 73,159,230,101,153,139, 38, 66,100,205,197,132,161,215,253, 47, 86,219,159,115,227,236,221,203,222,123, 86,245,180,253,239, +176,238, 91,182, 67,205, 7, 85,241,217,103,130,121, 90, 55,138,116, 13, 99,102,226, 45,196, 84, 41,247,189,255, 0,115,252, 64, +218, 55, 63, 47, 7,111,228,227,140, 97,180,193,158, 94, 28, 88, 49,177,215,247, 11, 36,146,128,198, 50,170,110,222, 55,172,148, +139,221,125,157,220,251, 70,222,155,134,229,185, 99,238,216,152,178,140, 76,134,196,203, 57, 94, 82,114, 47,208,152, 31,128,240, +240,225, 91,254,206,194,199,151,180,177, 96, 78,219,143, 86,227, 17,233,225, 73,220, 25, 88, 83,110,173, 16,211, 44,176,225,160, +208,110, 87,145,254, 74,175,239,200,241,177,123, 87,112,139,100,109,135, 18, 12,236,152,179, 55,136,182,253,212,231,228,228, 74, + 24,132, 88, 99,100, 77, 17,163, 72, 90,194,169, 59,127,190,223, 30, 45,155, 22,126,217,251,219,184,182,104,204,125,189,152, 36, +153, 89, 81,181, 75, 31, 83, 26, 53, 61,109, 26,139, 39, 17,249,106, 36,146,162, 84, 94, 5,109,183, 86,235,230, 94,254, 24,174, + 44,184, 27,208,108, 73, 98,134, 77,202, 52,131, 18, 55, 5,163,102, 73,116, 66, 76,162,238, 71,195,202,247,175,114,195,195,200, + 76, 88, 16,227,202,154, 99, 81,161,193, 44, 44, 7, 6, 35,129, 53,227,191,131, 83,228, 28, 13,218, 76,150,101,203,147,119,197, +105, 99, 42,218,158, 75, 72,204,140,170, 87, 79,189,250, 92, 1,175,161,198,166, 85,102, 5, 88,128, 89, 46, 13,143,162,226,173, + 8, 85,116,101,232,219,166,215,233, 90,214, 60,250,183,183,205, 93, 86,190, 31, 39,229,174,171, 66, 20,111,246, 63,187,143,246, + 22,155, 78,127,236,255, 0,187,143,246, 22,155,227, 66,145,178, 71,190, 61,159,150,131,234,163,100,124, 99,217,249,104, 39,137, +225, 64,121,179,247,150,253, 30, 83,224,234,136,200,174,219,102,173, 2,255, 0,120, 62,107,195, 9,183, 14, 30, 93, 3,219,249, +215,240,170,189,243, 59,113,125,169, 39,135, 40,226,198,112,251,143, 84, 16,130,138, 91, 31, 48, 70,175,125, 87,213,196, 27,248, +113,183, 58,245, 47,186,182,222,161,144,225,193,212, 51, 12,162,253, 36,213,215, 11,160, 79,123, 95,168, 23,134,174,118,166, 77, +178,108,217, 48,164, 89, 27,118, 52,177,196,101,104,209,224,141,149, 76,228,153,138,169, 83, 99, 38,163,171,211,126, 52, 5,118, +195,153,184,229,141,235, 19, 43, 36, 73, 54, 22,107,226,193,146, 35, 85, 33, 78, 60, 19,169, 40, 56, 29, 45, 49,249, 57,214, 15, +182,183, 93,239, 29, 48,114,188,251, 76, 36,135, 96,139, 33, 37, 80,250,215, 51, 35, 34, 6,247,152,146, 25, 85,190, 33,196,144, + 47, 94,171, 30, 60, 16,180,143, 12, 75, 27, 76,253, 73,153, 20, 41,119,210, 19, 91,145,241, 54,149, 2,231,192, 84, 88,118, 93, +155, 24, 21,199,219,177,162, 82,201, 33, 9, 12,106, 53,196,230, 88,219,221, 94,104,236, 89, 79,129, 55,160, 49, 11,191,238,216, +216, 88,179, 99, 73, 22, 62, 34,207,156,114,186, 72,146, 50, 21,220,100,130, 55,158, 38,110,168,133,128, 96, 94, 49,125,126,170, +157,248,129,184,238, 49,227,103,237,248,153, 62, 86, 20,218,114,179,100, 96,160,188,140,175, 28, 74,129,184, 21,182,178,110,188, +110, 71,203,168,109,139,102,153,161,121, 54,252,103,108,118,105, 32, 38, 36,186, 51,191, 85,217,125,222, 4,191,190,127,157,199, +157, 23, 63,105,218,247, 65, 31,222, 88, 80,102, 8,181,116,198, 68,107, 32, 93, 66,204, 0,112,121,219,141, 1,141,206,222,183, + 92, 89, 55,127,187,153, 34,232,238,146,172,253, 21,141,242, 90, 24,240,113,229,234, 36, 83,176, 18, 5,119, 29, 77, 62,246,142, + 92,106, 62,223,186,239,178,247, 4,184,184,251,154,148,220,243,225,143,169,210,212,145,198,118,149,206,253,194, 72,125,208, 72, + 0, 95,218,120,147, 91,140,173,143,102,205, 12,185,120, 24,243,171,201,215,113, 36, 72,218,165,210, 35, 50, 53,199, 22, 40,161, + 73, 62, 28, 57, 83,198,211,182,174, 88,207, 92, 40, 6, 96,181,178, 68, 73,213, 26, 81,162, 95,222, 91, 87, 4, 98,163,143, 35, +106,203, 7,157,190,239,185, 64,159,121, 97,100, 38, 28,152,123,118,255, 0,148, 35, 8, 26, 41, 14, 38,226,186, 80,163,155, 93, +244,241,110,124, 77,173,122,208,199,220,123,174, 86,236,155,122,186, 66,146,238,147,224, 45,208, 22, 72,147,107, 92,228,231,205, +150,102,227,234,225, 90, 9,118, 45,146, 97, 23, 95,109,197,147,162,204,240,234,134, 51,161,164,126,179,149,247,120,106,127,121, +189, 39,137,162, 29,171,107, 25,231,116, 24, 48,121,242, 65,243,157, 36,234,223, 65,138,253, 75,106,190,131,167,217,194,128,243, +126,219,222,119,120,246,216, 35, 76,133,108,172,156,109,138, 19,184, 72,154,228, 65,153, 54, 76,108, 95, 81, 33,202,129,165,117, +125,163,198,252,170,102,111,117,119, 4, 88,115,180,121, 17,172,184, 24,155,182, 67,205,209, 82, 50, 27,109,205,143, 22, 50, 3, +112, 85,145, 73,213,111,146,213,183, 77,151,100,138, 9,177,162,219,113, 99,131, 32, 5,158, 36,134, 53, 87, 10,204,234, 28, 42, +139,217,157,152,122,201, 53, 38, 29,159,104,104, 4, 7, 3, 28,196,176,182, 42,198, 98, 66,162, 7, 33,158, 27, 17,240, 49, 80, + 74,242, 54,160, 39,167, 65,181,132, 42,218, 14,151, 11, 99,102,176, 54, 54,228,108,105,225, 1,224, 7, 2, 40,113,193,143, 11, + 74,208, 68,145, 52,239,213,156,162,133, 47, 38,149, 77,111,111,137,180,160, 23, 62, 2,136, 29, 87,153,245, 84, 2,233, 94, 2, +223, 69, 34,166,166, 55,240,241,165, 50, 70,121,176,249,233,171, 42, 93,142,170, 0,154,120,145,225, 92, 87,133,148,123,104,109, + 56, 55,176,249,108,105, 4,192,139,241,191, 43, 88,208, 4, 80, 60,120,154,140,233,118, 54, 36, 15, 1, 79,234,250, 1,191,178, +212, 61, 76, 71,215, 85, 1,186, 72,225,170,156,169,126, 36,210,123,228, 95,144, 53,193,157,121,124,245, 64,223, 22,167, 10,104, +185, 36,250,105, 65,183, 58,128, 21,238,111,233,162, 45, 12, 83,193,181, 1,202, 56,147,235, 52,178, 88,138, 84, 28, 61,181,207, +200,213, 33, 25,158,202, 64,230,105, 33,241, 52,199,248,141, 18, 30, 70,161,164, 54,126, 36, 94,150, 3,101,249,233, 89, 11,191, + 2, 5,135,141,116, 98,203,242,154,114, 4,165, 75, 70,163,197,137, 55, 62,128, 42, 58, 9, 8, 58, 31, 72, 67,113,242,241,163, + 74,223,195, 65,250, 55, 63, 47, 10, 96,190,151, 32,124, 67,135,201, 80,163,177,111,118, 45,227,207,219, 67,145, 64,184, 30,154, + 85,144, 95,135,141,184, 83, 93,184,113,241, 52, 3, 44, 52, 17,254,156, 41,240,230,188, 11,161, 64, 32,154,103, 52, 63, 45, 27, + 28,225,232, 2, 80,117,123,109, 90, 50, 61,247, 19, 36,125, 34,128, 23,225,123, 82,175,137,245,211,166, 76, 19, 24,104,143,239, + 46, 52,143,150,146,194,214,160, 28, 79,163,232,165, 0, 21, 30, 39,198,155,111, 77, 82,109,253,219,181,231,239,249,157,185, 16, +150, 60,236, 48, 75, 25, 21, 68,114,105,211,171,164,193,152,155,106, 28,192,160, 47,121,210, 1,115,234,244, 85,124, 59,206, 44, +219,198, 78,198,171, 32,202,197,133, 50, 36,144,129,211, 43, 33, 33, 66,157, 90,175,195,209, 86, 54,249, 77, 1,196,112, 20,150, +177, 53, 18,125,219, 11, 31,114,196,218,101,114, 50,243, 86, 71,199,143, 73, 32,172, 67, 83,146,220,133,170,105, 4,208, 3,183, +190, 15,162,231,232,169, 88,209, 21, 95,123,226, 60, 77, 10, 37,187,223,192, 81,167,157, 49,113,229,200,112, 74, 66,141, 35, 5, +231,101, 26,141,175,106,212,122,145,176,225,125,116,240, 24,114,170, 14,216,238,189,179,187,112, 95, 63,109, 18, 34,199, 33,138, + 72,103, 85, 89, 20,216, 48, 36, 35, 56,179, 3,192,222,166,108, 91,238, 38,253,136,249,152,139, 34, 71, 28,210,227,178,204, 20, + 54,168, 91, 67, 17,165,152, 90,227,133,111,113, 30,188, 11, 80,214,240,162, 35,159, 1, 76, 12,180,245,101,168,186,150,157, 79, + 17,192,201,237,220,108, 31,196,137,123,171, 12,230,237, 45,220, 38, 57,213, 45,212,139,171, 52,145,137,226,241, 12,154,175,194, +179, 95,136,147,108,185,255, 0,136,157,186,248, 91,142, 63,221, 7, 15,111, 72,247, 28,133, 89,224, 88,209,221,117,207, 25,176, +107, 91,222, 86,183,174,213,238, 83,126, 27,118, 46,225,149,145,153,153,179, 67, 52,249, 82, 52,217, 14, 76,131, 92,142,197,217, +216, 7, 2,228,155,214,123, 51,177,123, 15, 27,188,118,238,220, 94,218,195, 56,217,184,147,229, 60,197,166,234, 6,133,130,133, + 31,188,211, 99,122,195, 84, 98,180, 60,203,241, 49,182, 60,206,213,193,108, 76,253,191, 47,116,219,243,167,130,105,161,151, 12, +228,205,142,120, 68,250, 48, 99,137, 52, 31,136, 45,142,145,194,247,189,109,187,127,113,236,188, 44,111,195,165,238, 24,252,174, +232, 48, 82,109,179,119,184, 85, 12, 47, 23,150,157,191, 65,181,240,213,192, 31, 71,141,148,127,133,219, 26,103, 24,114,187,107, + 12, 98,117,228,117,200, 12,111,209,185,233,199,164, 75,123,218,222, 31, 85, 8,254, 28,108,239, 54, 28,139,218,184,178, 71,166, +101,202,195, 50,241, 4, 55,238, 89, 28,203,111,132, 92,139,213,218,233, 81, 83, 53,248,106,136,211,247, 12,154, 87, 88,238, 8, + 66,202, 85, 90,192,188,183, 28, 72,224,107,232, 34, 9,228, 43,207,118,158,215,159,100, 18, 98,237,125,189,143,137,143,144,241, +203, 47,151,156,162,135,140,190,151,187, 74, 94,246,106,244, 24,215, 66, 42,220,157, 32, 11,146, 73,224, 60, 73,226,106, 20, 94, + 62,142, 54,174,165,241,174,160, 40, 31,148,127,221,199,251, 11, 77,245,222,158,255, 0, 96,127,187,143,246, 22,153,199,149, 1, + 27, 32,251,227,217,249,104, 87,162,100,131,172,112,240,250,232, 52, 3,238, 46, 9,164, 12, 1,172,252, 29,209,141, 58,109,206, + 98, 49,166,225,149,153,134,172,236, 45, 25,194,243, 26,221,207,232,183,150, 54,246,209,227,238,109,134, 92, 87,205, 76,216,206, + 60, 79, 28,110,228, 48,247,166,183, 74,192,128, 72,147, 80,210, 71, 3,225, 66, 23, 5,135, 17, 77,230, 57, 85, 68,157,209,176, +195, 28, 19, 73,157, 26,199,144,172,241, 49, 13,240,198,226, 57, 25,133,174,161, 24,217,181, 91, 79,141, 75,139,119,219,101,157, +113, 99,201, 86,153,229,151, 29, 99, 23,185,150, 1,170, 84,229,246, 69, 10, 78, 2,223, 45,112,245,213, 36, 61,213,182,203,157, +155,181,179, 24,179, 49, 38,120, 18, 38,254,212,199, 2,101, 49, 67,109, 35,221,115,192,155,251,166,159,133,220,219, 86,108, 27, +107, 60,194, 12,141,207, 30, 12,152,113,159,139, 42,228, 46,184,213,216, 13, 32,183, 16,183, 62,241, 6,212, 33,114, 13, 60, 90, +169, 83,185,182, 7,108,149, 92,232,201,196,142, 89,242, 24,234, 1, 99,129,186,114,182,162, 44,116, 55, 6,183, 42,141,133,221, +120, 91,132,197, 49,192, 88,151, 50, 76, 19, 36,141,160,177,139, 20,102,179,164,108,186,143, 6,177, 83, 98, 44, 77, 70, 83, 68, +109, 93,107,138,163,143,186,246, 9,113,167,204,143, 62, 54,131, 28, 68,101,112, 27,150, 71, 8,116,141, 55,126,161,224,186,111, +115,195,157, 63, 27,185,118,252,204,204, 28, 76, 22,243, 41,157, 30, 84,137,144,135,221, 83,134,209, 71, 34, 48, 54, 55,213, 55, +209, 80, 22,228, 81, 98,141, 45,169,184,147, 67,184,169, 32,105, 81, 96, 0,168, 4, 88,226, 7,136, 30,170, 36, 73, 29,137,210, + 57,211,120, 90,254,142, 84,248,192, 10, 13,253,124,104, 7,170,174,174, 64, 82, 27,234, 0, 1,167,196,210,135, 91,113,112,191, + 45, 53,229,128,114,113,243,208, 14, 42, 0,231,196, 10,142,165, 72, 60, 47, 99, 79, 51, 37,142,147,115,243,208,250,170, 7,194, +110, 61, 70,128,113, 35,149, 0,241, 28, 20,223,149, 57,165, 6,215, 6,212,210,227,215,243, 85, 64,224, 88,120,114,245,210, 18, +214,176,164,212, 44,120, 26, 66,222,129,194,168, 16, 26, 82,125,211,236,166,147,194,145,137,211, 80, 8, 41,222, 20,130,157,110, + 20, 3,199, 0, 41,178,155, 33, 52,251, 80,230, 23, 75, 26,164, 34, 0, 93,184,120,212,133, 80, 46, 41,144,167, 27,252,212,183, + 34, 66,125,117,158, 44,208,226,188,111, 67, 78, 92,105,224,146,198,255, 0, 37, 51,209, 84, 7,146,196,150,244, 34,255, 0, 45, + 17, 37,141, 88, 70,124, 77,175,235,244, 80,201,178,137, 8,247, 72,208,212, 34, 95, 64, 10,162,199,222,215,232,168, 81,204,170, + 11, 50,139, 89,244,130, 61, 66,230,134,231, 85,168,160,169,178,167, 21,141, 73, 45,233,102,231, 66,107, 90,169, 14, 32,232,229, +206,134,201,196, 27, 84,227,112,128, 16, 8,181, 52,233, 54,247,106,144,136, 0, 18,165,185,112,254, 90,154, 15,207,233,168,132, +222,113,225,232,169,105,198,194,128,117,197,121,156,155, 86, 70,102, 79,112,238,155, 80,255, 0,227, 91, 62,234,114,176,128, 28, + 93,122, 17,137, 96, 63,205,149, 69,173,226,107,211,116,142, 3,198,171,246,237,155, 23,108,203,220, 50,224,121, 26, 77,202, 97, +145, 56,114, 10,134, 10, 18,201,165, 86,194,195,198,244, 12,197,227,119, 4, 89,187,158,243,220, 91,111,189,109,130, 60,152,144, +216,149,146, 51, 59, 24,219,214,172,186, 77, 71,147,100,138, 30,198, 94,234, 76,188,143,191,134, 34,110, 63,121, 25,228,215,212, + 96, 37, 49,233,215,163, 79, 29, 26,116,218,181,120, 29,171,178,108,187,158,227,184,227,107,213,186, 2, 50, 49, 92,169,133, 67, + 18,204, 35, 93, 32,128,196,158, 23, 53, 5,123, 35,109, 56,235,183, 29,207, 56,236,193,181,125,210,101, 94,141,131,107,233,151, +209,213, 49,223,236,234,161, 10, 93,207,106,195,223, 59,187,182,178, 51, 4,200,219,166, 12,179,100,172,115, 73, 29,157, 33, 66, + 2,105, 97,163,215,110,126, 53,232,123,142, 86, 62,223,129,147,155,150,229, 49,224,137,229,149,151,152, 85, 4,157, 54,241,244, + 85, 86,241,219,155,118,243, 62, 14, 83,100,100, 97,100, 96,107, 24,243,225, 73,209,112,146, 0,175, 29,244,183,186, 64,171,140, +172, 60,125,199, 22,124, 44,165,234, 99,100,198,209, 74,135,133,209,193, 86, 23, 30,163, 68, 83,203, 89,114, 49, 51, 59, 99,122, +219,182,185,246,172,108,205,207, 23, 24,102,100,103, 73, 54, 70, 76, 57, 55,225, 52, 4,186,168,100, 23,226,215, 21,234,155,183, +255, 0,198,102,255, 0,113, 47,236, 26,206,193,248,123,133, 24,219,198, 70,237,185,100,195,181,100, 69,149,129, 4,179, 33,141, + 12, 6,232,133,122, 94,240,240,244,219,128, 35,141,106,230,199, 76,156,121, 96,144,144,179, 35, 70,197,121,128,195, 73,181,239, +233,173,197, 25, 60,187,102, 31,229,140, 30,220,238,232, 56,109,153,216,152,216, 59,248, 91,105, 94, 1, 32,203,111,232, 49,208, +199,209, 77,121,230,135,179,166,124,121, 90, 50,221,196,234, 90, 54, 43,117,108,195,113,117,240, 53,232,152,221,185,182,227,118, +250,246,211, 43, 79,183,172, 7, 24,137,136, 46,200, 65, 28, 74,133, 23,227,204, 10,173,198,236, 93,150, 14,217,151,181, 58,153, + 18, 96,200,230, 94,179,186,245,213,203,137, 3,171,162, 40, 5, 88,112,247,106,209,252, 0, 14,232,158,120,251,171,179,227, 73, + 25, 18, 92,140,161, 34, 41, 32, 48, 16, 92,106, 3,157, 85,109,157,191,139,220,187,223,117,197,187,100,101,203, 20, 25,130, 44, +104, 87, 38,100,142, 61, 81, 6,214,168,142,160,144, 79, 0,110, 7,162,175,177,123, 31, 25, 55, 29,191,117,205,221,119, 13,195, + 51,109,103,108,118,201,153, 25, 44,235,160,169, 65, 24, 28,188, 71, 19,226,106,235,107,216,113, 54,188,205,203, 55, 29,228,121, + 55, 73,134, 70, 66,200, 84,170,184, 80,150,143, 74,169, 2,195,196,154,187,107,173, 1,229,152,123, 82,231,254, 22,127,155,242, +179,243,159,125,198,138, 73,113, 50,252,212,195,165,229,167,120, 81, 35, 69,112,128,104, 78, 38,215,191, 27,214,171,119,192,198, +238, 62,244,237,120, 55, 54,149,162,159,104,154, 89,196, 50,201, 1,115,251,182, 33,154, 6, 70,210, 73,228, 13,104,112,251, 43, +108,199,237, 38,236,212,150,115,183, 52,114, 68,102, 44,157,125, 50,200,211, 55,189,211,209,125, 77,195,220,163,110, 93,149,135, +185,101,109,249,209,110, 57,219,126, 86,219,140,112,224,155, 14, 72,145,140,109,107,235,234, 67, 39, 19,167,194,213,134,137,161, +146,199,150,126,210,222,123,175,102,218,166,155, 43,108,219,182,191,189,113,113,167,145,166, 56,211, 5,118,232, 35, 72, 89,180, +189,181, 88,154,160,194,218,123,191, 51,100,192,223,118, 77,159, 57,251,138, 85,135, 49, 55,201, 55, 24, 52, 77,172,137, 29, 30, + 6,200, 3,164,200, 74,132,210, 45,227,227, 94,181,178,246,174,211,177,195,148,152,200,243,203,158,117,103,229,229,185,158,124, +131,109, 63,190,145,249,128, 15, 1,202,169,241,255, 0, 14, 49,112,191,195, 96,239, 91,166, 46,209,171, 88,218, 34,200, 81, 0, +187,106, 49,171, 20, 50, 8,207,138,234,249,106, 87, 74, 13, 74, 89,118,175,243, 15,226, 78,108, 27,150, 70, 76,120,184, 88, 88, + 57, 99, 2, 41,136,137,166, 14, 72, 18, 1,193,148, 88,220, 14,117,233, 26,219,194,171, 34,216,113, 49,247,236,190,225, 71,144, +229,230, 65, 22, 52,177,177, 94,144, 72, 73, 42, 84,105,213,126, 60,125,234,177,183,164,213, 66,146,228, 63, 83,125, 23,250,107, +169, 44, 45,207,195,242,215, 85, 46,191, 2,153,237,238, 31,247,113,254,194,211,105,207,253,152,255, 0,119, 31,236, 45, 37,197, +100,209, 19, 39,227, 28, 60, 63, 41,160,139, 95,194,143,146,125,241,236,250,232, 4, 92,208, 24,156, 94,199,108, 89, 54,252,200, + 98,194,143,114,199,203,220,114, 50,243, 21, 7, 82, 72,242,215, 45, 96, 82,230, 61, 79,167,175, 30,165,110, 28, 56, 95,133, 86, +127,150,251,135,111,195,234,203, 18,100,229, 79,151,179, 49, 68,154,105,206,188, 76,133,234,200,229,162,247, 34,251, 94,232,178, + 47,135, 10,244,155, 91,149, 39, 11,208, 30,109,147,219, 91,241,149,176,163,130, 35, 54,231,183,239, 9,149, 43, 52,158, 95, 29, +183, 44,200,165,208,178, 8,206,166, 69,123,133, 32,106,210,106,219,102,218, 93, 59,215,115,204, 64,255, 0,119,226,198, 4, 44, +232,200, 14, 94, 66, 67, 22, 67, 33, 96, 3, 89, 49, 18,228,112,247,205,108,237,232,174,177,231, 64, 99,223,182, 55,105,119,121, +164,102,129,112, 31,113,147,117,142, 85,119, 51, 93,176, 62,239, 88, 89, 12, 97, 71,188,117, 18, 24,240,168,152,125,145,184, 99, +228,237, 93,110,148,241,227, 65,181,166, 67,249,156,152,210, 57,118,209,239, 20,199,143, 68,115,235, 33, 74, 52,159, 15, 30, 30, + 21,187,185,174,191, 27,208, 24,121, 59, 31,115,147, 22, 72, 26,108,117,102,196,221, 32, 83,119, 35,169,155,158,153,240, 92,104, + 30,232, 84,179,250, 15, 43,209,224,237,157,226, 92,209,184,101,249,104, 94, 77,203, 35, 61,225,142, 87,147, 76,115,109,191,119, +162,106, 49, 37,216, 73,196,240,181,190,106,217, 94,230,184,113,244, 80, 30,125, 47,108,238, 91, 54,219, 30, 99,152,166,147, 3, + 27, 99,141, 99,136, 77, 32,105,118,198,144, 77,168, 71, 19, 72, 35, 61, 91,134, 84, 98, 57,149,225, 86,125,165,181,230, 4,199, +221, 51, 49,146, 57, 12,219,172,151,109,113,186,174,110, 90,204,133, 33,145, 53, 89,214, 59,251,197, 72, 22,225,199,134,187,136, + 21,215,225, 89, 7, 31,134,244, 93, 62,150,111,101,205, 12, 88,128, 61,148, 82, 56,240,168, 4,233,169,231,199,212, 77, 60, 70, +135,134,158,116,128, 30,118,183,174,156, 79,141, 0,141,161, 69,173, 93, 97,164,120, 14, 84,211,102, 2,230,252,105,204,234,188, +136,191,163,133, 0,240, 7,143, 10,226,109, 76, 50,165,129,213,115,232,166,117, 1,230, 15,204,106,129,197,184, 91,194,244,219, +175, 14, 52,215, 58,135,194, 64,244,154, 75, 15, 69, 0,183, 95, 77, 37,213,141,188,105, 57, 48,167,112,184, 62, 53, 65,196, 10, +100,156, 19,218,105,196,241,166, 73,200, 15, 93, 64, 32,231, 78, 62,143,244,231, 77, 28,233,224,251,192,123, 40, 64,148, 25,249, + 90,138, 77,170, 60,134,228, 85, 3,147,128,161,107, 26,236,124,104,132,217,109, 67, 69, 7,137, 23,168,145,166, 58,227,222, 34, +153,224, 47, 76, 12, 22,234, 5,133, 61,151,221,181, 24, 68,200,216, 5,100,110, 32,218,244,178, 68,134, 61, 34,250,124, 42, 58, +201, 97,107,127,160, 21,221,115,200, 19, 82,133, 28,218, 85,116, 39, 1, 65, 38,231,217, 78, 44, 10,243,164,107, 1,113,232, 53, + 72, 62, 57, 68,192,240,181,185,215, 97,197,213, 47,168,155,120,113,246,211, 49,134,148,107,248,253, 85, 47, 13, 81, 3,104, 7, +136, 23,191,166,169, 6,182, 13,157, 93, 90,246,244,251, 40,134, 7, 30, 23,163,179, 89,120,120, 83, 18, 75,141, 68, 90,254, 20, + 21, 4, 85,151,157, 34,250,184,210,188,225,180,133, 60, 24,216,210,173,135, 42, 2,187, 47,248,198,128, 57,209,242, 69,231,107, +114,164, 84, 55,189, 0,171, 19,151, 9,196, 30, 28,189, 21,109, 10, 5, 0, 15, 10, 2,168, 50,151,246, 15,154,165,198, 42,160, + 60,143, 10, 90, 80, 46,109, 79, 43, 91, 70, 27, 25,196,210,133,165,181,188,105,233,122,210, 21,168,208, 8,229, 69, 82,124,105, +192, 19,225, 68, 84, 30, 52,149,121, 10,208,114, 15, 27,209, 65,181, 32, 81,106,112, 28,107, 1,161,193,169, 25,155,236,211,173, + 93,102,169,161,164, 12,177,241, 20,195,110,116,109, 55,231, 77, 40, 42,166,138, 51,134,159,234,255, 0,245,171,169,250, 69,190, + 79,203, 93, 86,191,136, 41, 36,191,238,255, 0,187,143,246, 22,155,232,167,184,224,159,221,199,251, 11, 77, 60,171, 0,139,147, +252, 81,236,252,180, 43, 91,213, 69,201,182,177,236,161,124,159, 45, 0,132, 19, 74,214, 28,171,169,166,244, 7, 95,141, 47, 26, + 65, 79, 2,226,252,232, 65,188,184, 82,123,105,228,113,189,171,188,121, 10, 1, 45,235,164,226, 41,108, 7,141,119, 51,207,133, + 0,163,136,227, 75, 97, 72, 60,125, 84,170,111,122,203, 41,201, 30,179,166,246,176,189, 19,162,111,197,207,209, 75, 15,218,249, + 56,218,138,110,220,252, 42, 0, 5, 20,178,168, 36,250, 69,232,157, 24,137,181,137,245, 19, 73,166,210,114, 3,215, 68, 39,196, + 90,224,208, 10,176, 71,110, 10, 5, 49,149, 65,176, 2,137,175,198,247,166, 22, 81,196,219,141, 0,219, 2,203,111,109, 16,141, + 92, 45, 65, 18, 38,191,136, 90,158,211, 71,194,168, 27, 58,240, 85,185,249, 40, 58, 86,246,185,162, 59, 25, 56,142, 94,177, 77, +208,121,234,227, 64, 38,133,224,109, 77,176, 4, 90,159,111,231, 30, 20,210, 0, 34,212, 2, 53, 49,252, 40,156,205, 13,254, 47, +146,128, 65,241, 83,255, 0,180,166, 47, 58, 86, 54,123,250,141, 8, 17,207, 10,142,109,168,122,234, 66,157, 74, 13, 6, 65,103, +246, 85, 7, 31, 26, 69, 60, 45, 93,122, 19,135, 82,116,242, 53, 13, 14,176,107,240, 30,163, 79,107,145,242, 10, 4,114, 53,194, +250, 77, 74,140,160, 36,185,176,224, 56,209,132, 10,252, 62, 67, 77, 60, 15, 31, 65, 21, 46,208,186,182,159, 3,252,180,198,199, + 7,213,122,133, 35,139, 95,143, 42,123, 91, 79, 15, 69,169,239, 1, 3,129,255, 0, 79,244, 52,198, 22, 79, 95, 42, 1,227,132, +100,255, 0,167, 42, 38,222,204, 99, 98,120,251,223,146,152,120, 66,215,231, 99,252,148,252, 14, 17, 55,173,171, 72,203, 37, 31, + 10, 67, 93,242,215, 80,132,105, 84, 43,198, 7, 43,220,209, 5,201,245, 83, 39,254, 52,107,237,162,128,109,195,157, 10, 64,154, +221,102,244, 95,242, 83,227, 93, 70,222,194,105,146, 92,202,222,218,145, 18,219,143,141, 1, 34, 49, 82,208, 88, 84,104,133, 75, + 81,200, 86,146, 32,225,192, 95,198,146,231,211, 74, 72,174,181,249, 86,226,140,241, 59,135,137,167,163,133,229, 67, 43, 92, 5, + 86, 97,166,157, 73, 33,201,241,162, 41,245,212,117,176,167, 6,227, 87,145,164,215, 50, 72, 99, 68, 6,130,188, 71, 58,118,150, + 28,107, 45, 34,238,168,117, 97, 78,214, 60, 42, 54,163, 78, 12,107, 46, 37, 65,175,126,116,158,232,166,131, 72,199,209, 74, 26, +105, 14,225,111,147,242,215, 83,110,116,255, 0, 87,242,215, 82,159,137, 40,138,103, 60, 19,251,184,255, 0, 97,105,183,167, 56, +248, 63,187,142,199,250,139, 77, 3,159,162,178, 82, 54, 65,247,199, 31, 10, 9,226, 42, 91,195,212, 55,213,111, 11,115,252,180, +209,139,252,251,252,148, 4, 91, 26, 91,112,181,234, 79,149, 22,248,190, 91, 87, 12, 95,231,125, 31,158,128,140, 7,174,184, 84, +159, 44, 65,248,254,143,207, 93,229,135,233,253, 20, 4,114,192,143, 73,164, 23,231,106,144, 49,120,252,127, 71,231,165, 24,227, +145,111,162,128, 7,200, 41, 56,219,157, 31,203,255, 0, 59,232,252,245,222, 88,223,226,250, 63, 61, 0, 1,199,141, 58,194,215, +163,121,123,125,191,162,151,203,255, 0, 59,232,168,192, 36, 14, 1, 11,107,115,227, 79,247,201, 23, 97,127, 27, 10, 52,120,228, + 41, 26,185,155,242,252,244,239, 47,252,238, 62,202,200, 1,211,227,169,156,223,228,229, 74, 34,181,253,227,199,215, 71,233,105, + 31, 21,253,162,148, 68, 71, 54,191,163,133, 80, 70, 49,174,174, 60,173,200,154, 82,136, 0,176, 31, 53, 24, 68, 6,171,183, 63, + 87,231,165,232, 3,195, 87,175,149, 0, 13, 34,246,176,174, 96,188,141,168,205, 18,248,184,191,179,243,211, 58,105,195,222,213, +232,225,198,128,142, 94,204,120, 94,155,172,183, 0, 62,122, 57,128, 18, 78,191,162,154, 32, 0,124, 95, 71,231,160, 2, 3,113, + 23, 28,105,188,117,122,106, 80,199, 39,147,125, 31,158,147,203,113, 62,247,209, 64, 71,185, 6,152,196,147,198,165,249,107,253, +175,163,243,211, 27, 26,228,251,223, 71,231,160, 35,175, 58,100,196,134, 22, 28, 45,252,181, 48, 99, 91,237,125, 31,158,148, 64, + 3, 88,183, 49,232,160, 32,199, 46,144, 69,115, 62,174, 62,154,158,216,113, 30, 36,253, 21, 25,176,198,187, 43,240,246,126,122, + 0, 32, 18, 62, 90,115,241, 70,183,128, 53, 39,202, 88, 15,127,199,209,249,233, 36,197,247, 27,223,181,199,163,243,208,165,108, + 92, 92, 94,142,227,221, 39,215, 70,143, 11, 76,131,223,240,191, 47, 87,182,138,216,122,148,217,172, 47,232,252,244, 97, 17,177, +154,204, 65,228, 71,242, 84,162, 77,169, 97,194,210, 46, 95,143,179,243,209,124,183, 31,142,255, 0, 39,231,168,202, 69,144,159, + 10, 12,156, 22,222,207,229,169,239,143,252,235, 95,135, 47,207, 81,228,196,189,134,191, 31, 71,231,160, 4,125,228,208, 57,159, + 26, 44, 3,163, 3, 22,227, 99,200, 83,198, 45,190,223,209,249,233, 30, 11,130,161,249,250,191, 61,104,200,209,155, 1,225, 98, + 15,174,156,114,177,202,144, 73, 23,241,168,190, 76,220,217,254,143,207, 93,228,219,244,254,143,207, 64, 42, 56,121,144, 95, 85, +129,185,169,170,126,186, 6, 46, 17, 15,175, 87, 47, 87,231,169,158, 95,141,245,125, 20, 41, 92, 83,247,205,127, 3,252,180,117, + 28,168,205,143,169,139, 22,231,234,252,244,248,241,184,252, 95, 69, 8, 58, 53,225, 71, 28, 22,149, 32, 0,113,110, 3,157, 33, +100,189,184,144, 61, 67,235,173, 38,151, 18, 81,242, 58,220, 43,129,181, 40, 43,235,249,135,215, 93,101, 62,159,152,125,117,119, +174,166, 62,190,131,131, 10,112,227,202,154, 20,122,254, 97,245,209, 1, 81,224,126, 97,245,213,223, 30,168,180,151, 65, 44,212, +161,120,242,165, 12, 7,129,249,135,215, 78, 18,143,209, 63, 48,250,234,239,143, 80,226,250, 4, 75, 10, 56,126, 22,168,162, 69, +253, 22,249,135,215, 79, 19,160,251, 45,243, 15,174,163,148,122,149, 71,192, 63, 19,225, 74, 20,208,124,210,126,139,124,195,235, +174,243,107,250, 45,243, 15,174,179,185,117, 17, 82, 92, 80,123, 94,147, 77, 8,101,160,251, 45,243, 15,174,184,229,199,250, 13, +243, 15,174,166,229,212,178, 77,240, 13,167,249, 63, 45,117, 11,204, 46,157, 86,111,135, 87,135,233,105,244,215, 85,220,186,146, +143,224, 85,184, 30,229,249,152,227,253,133,166,113, 7,133, 20,196,236, 35, 96, 86,221, 56,249,186,131,240, 47,129, 34,147,162, +255, 0,204,253,116,255, 0, 90,161,160,124,248,215, 92,113,254, 74, 39, 69,239,205, 63, 93, 62,186, 94,131,223,226, 78, 92,125, +245,255, 0, 90,128,243, 13,133,114,242,247,190,219,105,178,153,225, 71,238, 25, 4, 46, 53,123,240,238, 29, 37,109, 68,243,209, + 38,149,253, 16, 56,115,163,110,253,223,191,224,103,111, 27,116, 38, 51, 54,214,185,153,108,206,151, 81,138, 98,198, 56,108,222, +199,201,107,250,122,102,182,248,176,236,125,104, 60,145,193,234,255, 0,138,242,157, 23,199,215,252, 81,231,122, 90, 26,255, 0, +197,183, 86,223,107,226,227, 81, 32,218,182,156,125,227,120,206,201,205,131, 35, 59, 42, 8,134, 94, 60,242,227,218, 28, 52, 18, +104, 86,140, 88,136,201,103,187, 63, 63,146,128,206,175,113,239,120,155,152,218, 50, 39, 76,161, 14,225, 54, 35,230, 24,149, 58, +177,174,212,119, 37, 22, 79,116, 50, 73, 96,109,225, 83,100,223, 55, 73,123, 71,183,247, 24,229, 72,115,183,143,187, 35,155, 32, + 32, 43, 25,204,233,245, 93, 17,189,219,251,196, 40, 62, 38,167,182, 55,100,141,170, 5,115,180,253,208, 39, 39, 24,180,184,167, + 31,204, 89,137,208, 89,244,117, 45,170,254, 54,189, 78,200,131, 99,109,141, 87, 35,200,253,194, 98,140, 33,121,113,198, 39, 68, +233,232,233, 58,186, 97,126, 29, 22,245, 90,160, 60,243, 23,127,223,176,182, 54, 56,185,170,173,133,141,189,238,146, 75, 44, 98, + 79, 50,248,155,132,145,164, 3, 91,123,169, 99,111,116,220, 93,109,235,187,196,238, 45,234,126,230,139, 26, 73, 85,112,100,220, +230,219,142, 39, 72,106, 8,155, 98,238, 33,140,159, 22,161, 39, 15,101, 93, 60, 29,156,216,123,125,198,208, 48, 68,174,118,207, +222,226,136,122,221, 67,212,242,246, 96,186,186,159, 22,159,181,207,141, 78, 16,236,231, 52,104,242, 3, 59,204,189,180,190, 63, + 91,205,244, 6,191,181,171,171,229,249,253,173, 31,205,160, 51,155, 6, 38,225,182,247, 81,218,103,220, 95, 46, 12, 45,143,111, + 77, 46,182, 14,235, 38, 68, 13, 53,139, 53,153,140, 90,137,185, 60,109,126, 2,169, 31,189,187,133, 50,223, 3, 84, 70, 69,118, +218,131,104, 23,251,198, 76,233, 32,128,219,135, 15, 44,138,246,254,117,249, 10,244, 23,131,110, 59,180,125, 67,135,247,207, 65, +186, 87,120, 6, 87,151,213,239,105,247,186,157, 61,124,252, 47, 81, 14, 63,110,249,131,168,237,190, 99,206,174,171,201,141,175, +207,244,206,139,251,215,243, 29, 59,219,237,105,245, 80, 24,201,123,207,124,134, 29,242,116,149,102, 76,125,191, 47, 59, 10, 86, +133, 18, 33, 38, 54, 67, 99,129, 18,135, 50, 52,126, 7,170, 1, 44, 13,184, 81,231,220,119,188,141,199, 7, 22,109,203,254, 79, +185, 14, 11, 72,145,170,117, 97, 59,113,203, 10,234,166,196, 2,236,182,246, 30, 98,175,211, 27,178, 21,178,244, 54,205,168,172, +231, 59,247,184,100,232,212, 60,207, 91,222,248,117, 91,169,126, 23,231, 83,114,113,251,118,207,231, 14,219,111, 56,157, 78,172, +152,223,243,250, 19,167,171, 83,127, 31, 70,157, 63,106,214,160, 51, 59,222,231,189,225,119,124,240,224,102,152,226,201,198,218, +177,209, 25, 3,164, 30,107, 54,120, 26, 80,164,216,191,187, 96, 79, 50,192, 30, 64, 85,198, 46,241,189,205,218, 57,249,171, 38, + 56,220,241, 38,204,195,131, 42,114,176,195, 43,227,228,201,139, 28,158,241, 8, 53,232, 30, 58,117,122,170,102,233,141,219,103, + 33,134,242,118,223, 52,113,200,111, 53, 46, 48,151,203,107, 23,254, 35,106,233,235,183,171, 87,174,166, 44,123, 74,236,133, 88, + 96,182,195,209, 34,230, 72, 60,167, 67,219,171,167,163,232,168, 12, 6, 71,122,119, 66,196,113,241, 3,207,145,135, 30, 92,249, + 11, 52,120,176, 56, 56,242, 69, 26,195,154,211, 79, 20, 74,171,212, 58,154, 2,220,212,143, 26,188,194,238, 13,251, 39,187,223, +111,233,145,181,140,217,240, 11, 63,151, 84, 2, 28, 65,146, 25, 47, 47,152,121, 75,243, 29, 61, 58, 15,170,245,107,229,251, 12, + 98,237,253, 67,179,249,116,149,254,238,213, 46, 39, 79,173,169, 68,157, 31,122,204,250,244,234,183, 29, 86,191, 26,177,142, 30, +220, 27,251,188,103,111,255, 0, 48,104,180,128, 60, 7, 51, 64, 85,248,133,250,150,209,167,228,183,133,168, 12, 31,119, 62,230, +189,218,208, 65,184,201, 20, 44, 54, 30,156, 32,123,168,210,238,114, 68,205, 96,194,255, 0, 7,189,250, 64,216,240, 20,184,251, +246,241, 42,197, 56,147, 21,247, 53,219,119,132,139, 47, 39, 76, 74,210,226,238,112,224,195,168,146,177,174,177,110, 28,139, 91, +194,183, 91,140, 93,179,247,158, 63,222,167,110,251,218,209,249, 79, 50,216,254,102,221,101,233,116,186,135, 93,186,250,116,219, +237,218,220,104,114, 69,218, 93, 7, 18, 29,175,160, 97,202,234,106,124,109, 29, 14,176,243,186,174,109,163,175,110,175,134,191, +139,141, 1,158, 29,195,185, 67,216,251,222,241,212, 45,184,237,131, 36, 32,200,133, 99,150, 55,133,117, 44,121, 9, 25, 49, 22, + 23,226, 99, 58, 72,181, 1, 55,158,225,155, 54, 77,147,207,164, 82,253,237,145,133,247,145,129, 46, 33,135, 1, 55, 5, 65, 25, +247, 46, 93,200,185,251, 35,211,198,181, 56,208,118,210,236, 82,174, 57,219,190,224, 11, 32,200,210,248,231, 19, 77,207, 87,170, +117, 24,249,223, 86,175,150,153,184,193,218,173,139,150, 55, 67,182,249,111, 50, 60,239, 94, 76,112,158,107,166,182,235, 23,107, +117,122, 90,126, 47,123, 77,188, 40, 15, 60, 27,230,237,157,185,237,155,158, 84,131, 70,126, 39,110,206,248, 12,135,164,143,149, +158,241,188,145,139,240, 60, 11, 3,235, 30,129, 83,229,238,174,224, 76, 72,179, 35,203,138,105, 55, 60,135,131, 31,110,137, 34, +243, 56,234,185,254, 72, 24,122,205, 28,111,238,123,164,202,214,234, 17,225,194,182, 89, 80,246,183,157,196,243,167,108,243,250, + 34,242, 29,103,198,235,116,250,171,209,232,107,109, 90,122,218,116,105,251, 86,183, 26,140,248,189,144, 91,116,234, 54,211,173, +200,251,226,242,226,222,253, 75, 15, 51,239,123,167,171,250, 95,111,215, 84, 17, 32,223,183, 21,236,153,247,156,231,139, 19, 62, + 20,200, 13, 35, 42,206,170, 97,153,224, 71,100,197,119, 66,228, 40, 37, 85,236, 27,133, 80,174,237,190,110, 50,108,194,124,169, + 49,164,199,238, 25, 48, 38, 12,145, 44,146, 70,184,147, 76,171, 56,129,218, 43,142, 42, 66,155,114, 60,197,110, 60,190,194,118, + 50, 53, 96,253,195,209, 32,218, 72, 60,159, 66,220,120,234,233,232,183,201, 80, 98,199,236,197,197, 81, 17,218, 60,160,201,136, + 45,164,196, 49,249,189, 35,163,199, 85,186,218,109,167,237, 91,149, 1, 87,187,239, 27,206, 63,114,197,131, 14, 82, 65,183,202, +208, 99, 35,164,113,206,171, 52,194, 66, 83, 40,106,235, 71, 35,123,166, 46, 26, 15,218,172,191,109,119, 54,247, 14, 47,110,227, +156,198,204,142, 68,219,162,203, 13, 26,157, 35, 55,168, 63,127, 52,143,212,105, 61,223,115, 64, 63, 9,215,206,189, 22,108,126, +218,251,238, 22,201,109,187,239,208, 0,131,169, 38, 63,155,177, 13,167, 64,102,234,114,213,107,120, 95,215, 85,152,216,223,135, +221,120,219, 25,182, 62,189,212, 69,211,147, 11, 86,174,177,209,164, 43,115,235, 94,214,251, 87,241,160, 51, 89, 59,159,112,101, +227,236,187,172,155,151, 77,101,222,242,241,147, 30, 40,130,168,143, 21,119, 8,213, 93,181, 93,245, 8, 56,131,195,145,230, 41, +240,119,126,247,147,137,142,194,104,162,150,124,126,220,115, 47, 76, 16,143,187, 74,241,100,182,146,109,200, 2,163,194,182,147, +193,219, 94, 70, 31, 48,118,223, 33,230,143,150,234, 62, 55, 71,206,117, 94,253, 61, 77,167,173,213,215,203,222,213,127, 26,165, +125,179,176,242,176, 94, 60, 92,141,170, 12, 24,231,195,159, 37,177, 39,195, 84, 99, 20,198, 92,104,231, 32,149, 40,238, 25, 66, +158,124, 66,208, 22, 93,183,186, 79,185,109,204, 51,101, 89, 50,161,201,204,197,234, 40, 11,214, 76, 76,153, 49,132,193, 7,164, + 40,189,184, 94,177,115,119,142,255, 0,139,131,153,157,215,142,102,124, 77,230,120, 35,233, 0, 32,125,179, 45,113,162, 45, 99, +118, 14,175,239, 95,198,214,173,214, 6, 14,193,215,193,155,105,147, 14,241,226,205, 22, 12,120,179, 65,164,227, 52,177, 25,154, + 49, 27,123,202, 36, 68,185, 28, 1,245,154,172,218,246,190,202,193,135,112,134, 60,141,183, 36,145,144,251,156,179, 79,137, 35, +244,164,158, 73,166, 92,146, 8,253,218, 72,229,125,225,194,192, 30, 85, 24, 69,102, 78,251,220,152,125,193, 14,212, 27,205, 65, +141, 38, 4,121,115,149,199,134, 38, 25,210,200,174,205,212,153,101, 5, 80, 90, 37,141, 90,229, 78,171,222,160,191,114,119, 51, + 62, 86, 40,201,137,178,101,117,124, 88,163, 24,228, 75, 1,201, 49,234,219, 38, 50,116,165,110,144,182,137,142,173,119,240,173, +190, 94, 63,111,157,235, 17,179,206,223,247,192, 91, 97,117,164,199,243, 58, 73,107,116,131,182,190,122,173,111, 95,174,171,164, +196,236, 51, 30, 96,213,179,104,121, 80,238, 31,189,196, 22,125,109,167,170,117,240,110,165,237,127,181,127, 27,209, 20,169,205, +220, 36,220,251, 95,103,155, 35, 35,169, 30,126,110, 30, 62,108,168,173,143,170, 38,202, 17, 60,110,183,186,106,210, 17,192, 54, +226, 64,225, 81,183, 29,167, 99, 87,192,198,192,121,101, 72,247,165,195,200,141,158, 85, 88,131,196,243,190, 36,118,208, 12, 96, +176, 97,107,216,240,191, 11, 13,123,227,236, 71,102,180,231, 3,238, 19, 10,129,121, 49,198, 31, 71,236,219,222,233,232,189,173, +225, 75,129,141,219, 73,131,136,155,123,109,199, 4, 79,108, 35, 12,152,230, 47, 51,239,127, 4,171, 91,171,241,114,247,185,208, + 30,111,186,121,156,125,199,116,200,141, 30, 56, 32,222, 6, 34,238, 41,144,250,227, 67,183,195,167, 23,203,240, 83, 27,179, 88, +182,174, 26,175,106,215,203,191, 79,177,246, 22, 54,233, 12, 18,101,100,197,181, 9,208,232, 50, 32,146, 60, 97, 32,105,236,202, +193, 53, 14, 38,245,117,147, 7,111, 24,167,243, 71,111,233,121,149,243, 93, 71,199,211,231, 52, 38,142,174,166,183, 91, 70,139, + 95,222,181,189, 85, 3,108,199,236,111, 41,184,253,198,219, 41,193,233,255, 0,241, 99,135, 38, 31, 75,165,165,255, 0,230,186, + 77,167, 70,157,127, 31, 11, 95,215, 64, 85,238,155,148,153, 59,226,203,162,124, 72,142,199,185,183, 70,112, 99, 58,227,151, 18, +207,166,228, 92, 6, 54, 53, 11,116,202,220,113,182, 62,202,201,199,200,116,110,164, 29,120,128,185,152,141,190,121,116, 57,230, +110, 82,214,244,155,243, 2,181, 91,254, 47,110, 52,112, 14,230,109,187,166, 25,142, 55,222, 18,227,129,112, 61,253, 29,118,244, +124, 86,240,231, 71,220,241,246,159, 47,143,247,169,194,242,253,104,252,175,154,146, 13, 29,127,236,122, 93, 86,182,191,209,183, + 31, 69, 1,159,237, 45,239,117,205,157,177,247, 60,132,204, 18,237,216, 59,154, 77, 28, 98, 49, 27,102,117,131,193,238,146, 10, +142,144, 42, 79, 27,122,106,139, 35,188,247,168,240, 50,114, 81,162,234,197,183,239, 89,107,116,225,212,192,207, 92, 72, 56, 95, +151, 76,241,244,154,219,108,248,155, 24, 92,143,184, 91, 3, 73,146,249, 62, 74, 92,114, 58,132,127,105,210,110,118,244,213, 70, +110,213,217,153,176,238,248, 99, 39,108,198,159, 34, 28,132,220,242, 49,178, 48,211, 34, 56,217,148,100,180,143,168,149,179,233, +215,168, 91, 85,175,198,169, 10,201,247,157,237,115,178, 59,127,206,198, 26, 60,217,160,109,200, 68,190,252, 73,182,141,196, 70, + 18,250, 65,214,246, 36, 27,233, 30,158, 53, 23,105,238, 61,214, 8, 59, 95, 22, 41,186,208, 62, 46,205, 22,100,102, 53, 32,121, +216,136,102,158,105, 28, 72,210, 54,157, 73,211, 4,112, 58,185,214,177,113,187, 47,238,162, 38, 59, 71,221,126,100,183, 25,113, +124,191,154,177, 99,199, 86,142,165,175,195,157,184,114,162, 54, 63,100,121,140, 86, 99,179,249,142,142, 48,193,188,152,154,186, + 26,135,148,232,141, 95, 6,171,116,180,240,253, 26, 3, 7, 15,114,119, 70,216,185,184,216,114,182,115,193,145,187,229, 51, 63, +151, 69,182, 54,119,151, 88,229,124,169,162,209, 15, 19,125, 23, 97,117, 3,128,227,177,239,126,224,206,237,172, 92,109,198, 13, + 39, 21,188,204, 51, 33, 93, 76,103, 56,210, 75,137,111,108,177, 4,254,176,169, 89, 24,253,136,114,127,197,157,155,205, 46, 83, + 22,234, 73,136, 36,243,126,224,125, 87,107,153,126, 11,223,143,195,234,169, 61,201,181, 96,231,193,135,247,182,108,120,184, 88, +249, 80,204,200,242,192,145,205, 42, 56,104, 35,119,148,248,200, 7, 5, 35, 87, 42, 3, 43, 15,112,119, 28, 57,209,249,169,227, +145, 70,115,237, 50,225, 44, 64, 16,209,109,199, 52,229,107, 30,247, 25, 22,246,248,116,145,237,161, 99,247,134,255, 0,147,133, +143,210,150, 24,242, 50, 49,251,109,132,134, 32,193,100,221,229,120,178, 91, 78,161,113, 96, 52,139,240,173,154,227,236, 31,125, +179,106,192,251,243,167,103,253,228, 30,107,167, 97,204,106,234,105,211,111,146,163,237,144,246, 42,196,195,105, 59, 57,143,169, +140, 91,203, 62, 33, 29, 83, 35,121, 59,232,111,139,171,126,151,243,190, 26, 1, 55,237,215, 63,105,159, 98,194,142, 85,144,230, + 60,241,102, 74,232, 1,126,142, 20,249, 1,128, 28, 22,242, 68, 9,183,178,178,112,247,126,253,167,103,220, 39,154, 51,139,149, +133,131, 44,169, 10, 36,136,114,114, 49,218,121, 97,200, 10,221,104, 93,253,222,137, 11,163,211, 91,173,238, 13,137,224,139,252, +200,216, 35, 31,170,166, 31, 62,240,132,235, 5,109, 58, 58,205,109, 90,117,124,151,168,112,227,246,111,222, 24, 45,142,219, 87, +222, 2, 24,198,219,211,147, 23,171,208, 40,122, 62, 92, 43,106,209,211,190,141, 63,102,246,225, 89,110,175,129, 81,145,192,238, +190,234,159,108, 15, 49, 72, 39,201,155,102, 24,211,204,184,236, 66,238,147,116,165,180, 56,179,201,251,181, 22, 49,153, 8, 99, +126, 60,171, 81,220,185,155,158, 26,237, 27,102, 54, 98,195, 38,111, 93,114,179, 90, 53, 37,134, 62, 36,147,144,169,193, 87,168, +201,115,110, 66,246,244,212,157,186, 14,204, 92,102, 27, 89,218,188,177,201,132,183,151,124, 99, 31,155, 46,167, 31,224,107,117, +117,233,233,248,222,218,106,126,251, 14,198,216,104, 59,140,225,121, 62,170,152,252,251,194, 35,234,128,197,116,245,142,157, 90, +117,124,151,240,167,176, 30,123,178,119,102,253, 20,125,187,135,143, 25,151, 18, 44, 29,141, 50,228,144,192, 17,252,242,104,150, + 73,100,158,100,152,184, 2,241,136,209,174,192,223,157, 87, 65,220,155,206,193, 6,227, 38, 54,103,153,200,243,251,150, 86, 74, +116, 16,151, 88, 51,198, 32,105,228,145,215, 76, 90,125,208,177,251,224,144, 7,186, 43,124,248,253,166,217,155, 99, 33,218,252, +216,134, 49,179,218, 76, 81, 39,151, 32,244,188,168,213,125, 22,190,141, 28, 45,123, 80, 51, 49,187, 32,176, 59,147,108,250,131, +100,219,175, 46, 39,197,175,252,101,195,183, 19,212,254, 47,243,190, 46, 53,125,128,129, 63,119,238, 45,186,205,183, 18,130, 3, +186,229,224,112, 91, 55, 66, 45,164,103, 37,141,254, 46,177,231,232,225, 89,173,187,122,238, 12,113,183, 62, 6,123, 59,203,219, +219, 17, 24,174, 99, 50, 49,145,166, 19,156,111, 50,203, 27,228, 21,141,136,213,241,114, 60,133,110,252,183,104,253,238, 73,109, +171,239,147,206,242, 98,249,174, 16,159, 13, 90,255, 0,129,127,234,122,168, 25,184,221,140,209,227, 46,123,108,218, 14, 44, 99, + 11,171, 38, 32,255, 0, 9,169,122, 93, 2,205,252, 45, 90,116,233,247,111,107, 84,246, 2,203,182,183,229,220,246,124, 92,153, +166, 76,140,150, 75,204,202,134, 35,241, 50, 2,241, 18, 74, 31,112,131,225,112,109,194,173,252,236,126,138,168,219, 49,246, 59, +159,185,155, 6,253, 24,111,229, 36,131,254, 95,223,242,255, 0,194,111,225,252,122, 60, 57,219,198,172,124,185,253, 36,255, 0, +210, 39,250,212,167,128,168,111, 59, 31,162,187,206,197,232,160,121,115,250, 73,255, 0,164, 79,245,171,188,185,253, 36,255, 0, +210, 39,250,212,160,169, 35,206,199,250, 53,222,114, 63, 69, 3,160,127, 73, 63, 93, 63,214,167, 8, 63,156,159,174,159, 93, 41, +224, 9, 94, 97, 58,122,173,253,157,254, 78,166,154,234, 30,129,167,167,113,126,143, 59,141, 63,197,253, 46, 85,212, 7,255,217, +}; + +#endif diff --git a/source/blender/src/playanim.c b/source/blender/src/playanim.c new file mode 100644 index 00000000000..ef07d910cc1 --- /dev/null +++ b/source/blender/src/playanim.c @@ -0,0 +1,711 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <sys/types.h> +#include <fcntl.h> +#include <stdlib.h> +#ifndef WIN32 +#include <unistd.h> +#include <sys/times.h> +#include <sys/wait.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "PIL_time.h" + +#include <math.h> + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "BDR_editcurve.h" + +#include "BKE_global.h" +#include "BKE_utildefines.h" + +#include "BIF_gl.h" +#include "BIF_screen.h" +#include "BIF_mywindow.h" + +#include "playanim_ext.h" +#include "mydevice.h" +#include "blendef.h" +#include "winlay.h" + +/* ***************** gl_util.c ****************** */ + +static Window *g_window = NULL; +static int qualN = 0; + +#define LSHIFT (1<<0) +#define RSHIFT (1<<1) +#define SHIFT (LSHIFT | RSHIFT) +#define LALT (1<<2) +#define RALT (1<<3) +#define ALT (LALT | RALT) +#define LCTRL (1<<4) +#define RCTRL (1<<5) +#define LMOUSE (1<<16) +#define MMOUSE (1<<17) +#define RMOUSE (1<<18) +#define MOUSE (LMOUSE | MMOUSE | RMOUSE) + +unsigned short screen_qread(short *val, char *ascii); + +/* implementation */ +static int qreadN(short *val) +{ + char ascii; + int event = screen_qread(val, &ascii); + + switch(event){ + case LEFTMOUSE: + if (*val) qualN |= LMOUSE; + else qualN &= ~LMOUSE; + break; + case MIDDLEMOUSE: + if (*val) qualN |= MMOUSE; + else qualN &= ~MMOUSE; + break; + case RIGHTMOUSE: + if (*val) qualN |= RMOUSE; + else qualN &= ~RMOUSE; + break; + case LEFTSHIFTKEY: + if (*val) qualN |= LSHIFT; + else qualN &= ~LSHIFT; + break; + case RIGHTSHIFTKEY: + if (*val) qualN |= RSHIFT; + else qualN &= ~RSHIFT; + break; + case LEFTCTRLKEY: + if (*val) qualN |= LCTRL; + else qualN &= ~LCTRL; + break; + case RIGHTCTRLKEY: + if (*val) qualN |= RCTRL; + else qualN &= ~RCTRL; + break; + case LEFTALTKEY: + if (*val) qualN |= LALT; + else qualN &= ~LALT; + break; + case RIGHTALTKEY: + if (*val) qualN |= RALT; + else qualN &= ~RALT; + break; + } + + return(event); +} + +/* ***************** gl_util.c ****************** */ + + + + +typedef struct pict{ + struct pict *next, *prev; + char *mem; + int size; + char *name; + struct ImBuf *ibuf; + struct anim *anim; + int frame; + int IB_flags; +}Pict; + +static struct ListBase _picsbase = {0,0}; +static struct ListBase *picsbase = &_picsbase; +static int fromdisk = FALSE; +static float zoomx = 1.0 , zoomy = 1.0; +static double ptottime = 0.0, swaptime = 0.04; + +static int pupdate_time(void) +{ + static double ltime; + double time; + + time = PIL_check_seconds_timer(); + + ptottime += (time - ltime); + ltime = time; + return (ptottime < 0); +} + +static void toscreen(struct ImBuf *ibuf) +{ + if (ibuf == 0){ + printf("no ibuf !\n"); + return; + } + + glRasterPos2f(-1, -1); + + glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + + pupdate_time(); + + window_swap_buffers(g_window); +} + +static void build_pict_list(char * first) +{ + int size,pic,file; + char *mem, name[256]; + short val; + struct pict * picture = 0; + struct ImBuf *ibuf = 0; + int count = 0; + char str[100]; + struct anim * anim; + + if (IMB_isanim(first)) { + anim = IMB_open_anim(first, IB_rect); + if (anim) { + ibuf = IMB_anim_absolute(anim, 0); + if (ibuf) { + toscreen(ibuf); + IMB_freeImBuf(ibuf); + } + + for (pic = 0; pic < IMB_anim_get_duration(anim); pic ++) { + picture = (Pict*)MEM_callocN(sizeof(Pict),"Pict"); + picture->anim = anim; + picture->frame = pic; + picture->IB_flags = IB_rect; + sprintf(str, "%s : %d", first, pic + 1); + picture->name = strdup(str); + BLI_addtail(picsbase, picture); + } + } else printf("couldn't open anim %s\n", first); + } else { + + strcpy(name,first); + + pupdate_time(); + ptottime = 1.0; + +/* + O_DIRECT + If set, all reads and writes on the resulting file descriptor will + be performed directly to or from the user program buffer, provided + appropriate size and alignment restrictions are met. Refer to the + F_SETFL and F_DIOINFO commands in the fcntl(2) manual entry for + information about how to determine the alignment constraints. + O_DIRECT is a Silicon Graphics extension and is only supported on + local EFS and XFS file systems. +*/ + while(IMB_ispic(name)){ + file = open(name, O_BINARY|O_RDONLY, 0); + if (file < 0) return; + picture = (struct pict*)calloc(1, sizeof(struct pict)); + if (picture == 0){ + printf("Not enough memory for pict struct \n"); + close(file); + return; + } + size = BLI_filesize(file); + picture->size = size; + picture->IB_flags = IB_rect; + + if (fromdisk == FALSE) { + mem=(char *)malloc(size); + if (mem==0){ + printf("Couldn't get memory\n"); + close(file); + free(picture); + return; + } + + if (read(file,mem,size) != size){ + printf("Error while reading %s\n",name); + close(file); + free(picture); + free(mem); + return; + } + } else mem = 0; + + picture->mem = mem; + picture->name = strdup(name); + close(file); + BLI_addtail(picsbase,picture); + count++; + + pupdate_time(); + + if (ptottime > 1.0) { + if (picture->mem) ibuf = IMB_ibImageFromMemory((int *) picture->mem, picture->size, picture->IB_flags); + else ibuf = IMB_loadiffname(picture->name, picture->IB_flags); + if (ibuf) { + toscreen(ibuf); + IMB_freeImBuf(ibuf); + glDrawBuffer(GL_FRONT); + + cpack(-1); + glRasterPos2i(10, 10); + sprintf(str, "%4d: %s", count, name); + glCallLists(strlen(str), GL_UNSIGNED_BYTE, str); + glDrawBuffer(GL_BACK); + } + pupdate_time(); + ptottime = 0.0; + } + + BLI_newname(name, +1); + + while(qtest()){ + switch(qreadN(&val)){ + case ESCKEY: + if (val) return; + break; + } + } + } + } + return; +} + +void playanim(int argc, char **argv) +{ + struct ImBuf *ibuf = 0; + struct pict *picture = 0; + char name[256]; + short val = 0, go = TRUE, ibufx = 0, ibufy = 0; + int event, stopped = FALSE, maxwinx, maxwiny; + short /* c233 = FALSE, */ /* yuvx = FALSE, */ once = FALSE, sstep = FALSE, wait2 = FALSE, /* resetmap = FALSE, */ pause = 0; + short pingpong = FALSE, direction = 1, next = 1, turbo = FALSE, /* doubleb = TRUE, */ noskip = FALSE; + int sizex, sizey, ofsx, ofsy, i; + /* This was done to disambiguate the name for use under c++. */ + struct anim * anim = 0; + int start_x= 0, start_y= 0; + + while (argc > 1) { + if (argv[1][0] == '-'){ + switch(argv[1][1]) { + case 'm': + fromdisk = TRUE; + break; + case 'p': + if (argc>3) { + start_x= atoi(argv[2]); + start_y= atoi(argv[3]); + argc-= 2; + argv+= 2; + } else { + printf("too few arguments for -p (need 2): skipping\n"); + } + break; + default: + printf("unknown option '%c': skipping\n", argv[1][1]); + break; + } + argc--; + argv++; + } else break; + } + + if (argc > 1) strcpy(name,argv[1]); + else { + BLI_getwdN(name); + if (name[strlen(name)-1] != '/') strcat(name,"/"); + } + + if (IMB_isanim(name)) { + anim = IMB_open_anim(name, IB_rect); + if (anim) { + ibuf = IMB_anim_absolute(anim, 0); + IMB_close_anim(anim); + anim = NULL; + } + } else if (!IMB_ispic(name)) { + exit(1); + } + + if (ibuf == 0) ibuf = IMB_loadiffname(name, IB_rect); + if (ibuf == 0){ + printf("couldn't open %s\n",name); + exit(1); + } + + #if !defined(WIN32) && !defined(__APPLE__) + if (fork()) exit(0); + #endif + + winlay_get_screensize(&maxwinx, &maxwiny); + + /* XXX, fixme zr */ + { + extern void add_to_mainqueue(Window *win, void *user_data, short evt, short val, char ascii); + + g_window = window_open("Blender:Anim", start_x, start_y, ibuf->x, ibuf->y, 0); + window_set_handler(g_window, add_to_mainqueue, NULL); + } + + ibufx = ibuf->x; + ibufy = ibuf->y; + + if (maxwinx % ibuf->x) maxwinx = ibuf->x * (1 + (maxwinx / ibuf->x)); + if (maxwiny % ibuf->y) maxwiny = ibuf->y * (1 + (maxwiny / ibuf->y)); + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + window_swap_buffers(g_window); + + build_pict_list(name); + + for (i = 2; i < argc; i++){ + strcpy(name, argv[i]); + build_pict_list(name); + } + + IMB_freeImBuf(ibuf); + ibuf = 0; + + pupdate_time(); + ptottime = 0; + + while (go){ + if (pingpong) direction = -direction; + + if (direction == 1) picture = picsbase->first; + else picture = picsbase->last; + + if (picture == 0){ + printf("couldn't find pictures\n"); + go = FALSE; + } + if (pingpong){ + if (direction == 1) picture = picture->next; + else picture = picture->prev; + } + if (ptottime > 0.0) ptottime = 0.0; + + while (picture){ + if (ibuf != 0 && ibuf->type == 0) IMB_freeImBuf(ibuf); + + if (picture->ibuf) ibuf = picture->ibuf; + else if (picture->anim) ibuf = IMB_anim_absolute(picture->anim, picture->frame); + else if (picture->mem) ibuf = IMB_ibImageFromMemory((int *) picture->mem, picture->size, picture->IB_flags); + else ibuf = IMB_loadiffname(picture->name, picture->IB_flags); + + if (ibuf){ + strcpy(ibuf->name, picture->name); + + while (pupdate_time()) PIL_sleep_ms(1); + ptottime -= swaptime; + toscreen(ibuf); + } /* else deleten */ + else { + printf("error: can't play this image type\n"); + exit(0); + } + + if (once){ + if (picture->next == 0) wait2 = TRUE; + else if (picture->prev == 0) wait2 = TRUE; + } + + next = direction; + + while ((qtest() != 0 ) || ( wait2 != 0)){ + if (wait2 && stopped) { + stopped = FALSE; + } + + event = qreadN(&val); + /* printf("%d %d\n", event, val); */ + + if (wait2){ + pupdate_time(); + ptottime = 0; + } + switch (event){ + case AKEY: + if (val) + noskip = !noskip; + break; + case PKEY: + if (val) + pingpong = !pingpong; + break; + case SLASHKEY: + if (val) { + if (qualN & SHIFT) { + if (ibuf) + printf(" Name: %s | Speed: %.2f frames/s\n", ibuf->name, 1.0 / swaptime); + } else { + swaptime = 1.0 / 5.0; + } + } + break; + case LEFTARROWKEY: + if (val){ + sstep = TRUE; + wait2 = FALSE; + if (qualN & SHIFT) { + picture = picsbase->first; + next = 0; + } else { + next = -1; + } + } + break; + case DOWNARROWKEY: + if (val){ + wait2 = FALSE; + if (qualN & SHIFT) { + next = direction = -1; + } else { + next = -10; + sstep = TRUE; + } + } + break; + case RIGHTARROWKEY: + if (val){ + sstep = TRUE; + wait2 = FALSE; + if (qualN & SHIFT) { + picture = picsbase->last; + next = 0; + } else { + next = 1; + } + } + break; + case UPARROWKEY: + if (val){ + wait2 = FALSE; + if (qualN & SHIFT) { + next = direction = 1; + } else { + next = 10; + sstep = TRUE; + } + } + break; + case LEFTMOUSE: + case MOUSEX: + if (qualN & LMOUSE) { + window_get_size(g_window,&sizex,&sizey); + picture = picsbase->first; + i = 0; + while (picture){ + i ++; + picture = picture->next; + } + i = (i * val) / sizex; + picture = picsbase->first; + for (; i > 0; i--){ + if (picture->next == 0) break; + picture = picture->next; + } + sstep = TRUE; + wait2 = FALSE; + next = 0; + } + break; + go= FALSE; + break; + case EQUALKEY: + if (val) { + if (qualN & SHIFT) { + pause ++; + printf("pause:%d\n", pause); + } else swaptime /= 1.1; + } + break; + case MINUSKEY: + if (val) { + if (qualN & SHIFT) { + pause --; + printf("pause:%d\n", pause); + } else swaptime *= 1.1; + } + break; + case PAD0: + if (val){ + if (once) once = wait2 = FALSE; + else { + picture = 0; + once = TRUE; + wait2 = FALSE; + } + } + break; + case RETKEY: + case PADENTER: + if (val){ + wait2 = sstep = FALSE; + } + break; + case PADPERIOD: + if (val){ + if (sstep) wait2 = FALSE; + else { + sstep = TRUE; + wait2 = !wait2; + } + } + break; + case PAD1: + swaptime = 1.0 / 60.0; + break; + case PAD2: + swaptime = 1.0 / 50.0; + break; + case PAD3: + swaptime = 1.0 / 30.0; + break; + case PAD4: + swaptime = 1.0 / 25.0; + break; + case PAD5: + swaptime = 1.0 / 20.0; + break; + case PAD6: + swaptime = 1.0 / 15.0; + break; + case PAD7: + swaptime = 1.0 / 12.0; + break; + case PAD8: + swaptime = 1.0 / 10.0; + break; + case PAD9: + swaptime = 1.0 / 6.0; + break; + case PADPLUSKEY: + if (val == 0) break; + zoomx += 2.0; + zoomy += 2.0; + case PADMINUS: + if (val == 0) break; + if (zoomx > 1.0) zoomx -= 1.0; + if (zoomy > 1.0) zoomy -= 1.0; + window_get_position(g_window,&ofsx,&ofsy); + window_get_size(g_window,&sizex,&sizey); + ofsx += sizex/2; + ofsy += sizey/2; + sizex = zoomx * ibufx; + sizey = zoomy * ibufy; + ofsx -= sizex/2; + ofsy -= sizey/2; +/* window_set_position(g_window,sizex,sizey); */ + window_set_size(g_window,sizex,sizey); + break; + case RESHAPE: + case REDRAW: + window_get_size(g_window,&sizex,&sizey); + window_make_active(g_window); + + glViewport(0, 0, sizex, sizey); + glScissor(0, 0, sizex, sizey); + + zoomx = (float) sizex / ibufx; + zoomy = (float) sizey / ibufy; + zoomx = floor(zoomx + 0.5); + zoomy = floor(zoomy + 0.5); + if (zoomx < 1.0) zoomx = 1.0; + if (zoomy < 1.0) zoomy = 1.0; + + sizex = zoomx * ibufx; + sizey = zoomy * ibufy; + + glPixelZoom(zoomx, zoomy); + glEnable(GL_DITHER); + ptottime = 0.0; + toscreen(ibuf); + while (qtest()) qreadN(&val); + + break; + case ESCKEY: + case WINCLOSE: + case WINQUIT: + go = FALSE; + break; + } + if (go == FALSE) break; + } + + wait2 = sstep; + + if (wait2 == 0 && stopped == 0) { + stopped = TRUE; + } + + pupdate_time(); + + if (picture && next) { + /* altijd minstens 1 stap zetten */ + while (picture){ + if (next < 0) picture = picture->prev; + else picture = picture->next; + + if (once && picture != 0){ + if (picture->next == 0) wait2 = TRUE; + else if (picture->prev == 0) wait2 = TRUE; + } + + if (wait2 || ptottime < swaptime || turbo || noskip) break; + ptottime -= swaptime; + } + if (picture == 0 && sstep) { + if (next < 0) picture = picsbase->last; + else if (next > 0) picture = picsbase->first; + } + } + if (go == FALSE) break; + } + } + picture = picsbase->first; + anim = NULL; + while (picture) { + if (picture && picture->anim && (anim != picture->anim)) { + // to prevent divx crashes + anim = picture->anim; + IMB_close_anim(anim); + } + picture = picture->next; + } +} diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c new file mode 100644 index 00000000000..d93a93028a7 --- /dev/null +++ b/source/blender/src/poseobject.c @@ -0,0 +1,222 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * support for animation modes - Reevan McKay + */ + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" + +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_action.h" +#include "BKE_armature.h" +#include "BKE_global.h" +#include "BKE_displist.h" + +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_space.h" +#include "BIF_toolbox.h" +#include "BIF_screen.h" +#include "BIF_poseobject.h" + +#include "BDR_editobject.h" + +#include "BSE_edit.h" + +#include "mydevice.h" +#include "blendef.h" + +static void armature_filter_pose_keys (bPose *pose, bArmature* arm); +static void armature_bonechildren_filter_pose_keys (bPose *pose, Bone *bone); + +void collect_pose_garbage(Object *ob) +{ + bPoseChannel *pchan, *next; + Bone *bone; + + if (!ob) + return; + + if (!ob->pose) + return; + + switch (ob->type){ + case OB_ARMATURE: + /* Remove unused pose channels */ + for (pchan = ob->pose->chanbase.first; pchan; pchan=next){ + next=pchan->next; + bone = get_named_bone(ob->data, pchan->name); + if (!bone) + BLI_freelinkN(&ob->pose->chanbase, pchan); + } + break; + default: + break; + } + +} + +void enter_posemode(void) +{ + Base *base; + Object *ob; + bArmature *arm; + + if(G.scene->id.lib) return; + base= BASACT; + if(base==0) return; + if((base->lay & G.vd->lay)==0) return; + + ob= base->object; + if(ob->data==0) return; + + if (ob->id.lib){ + error ("Can't pose libdata"); + return; + } + + switch (ob->type){ + case OB_ARMATURE: + arm= get_armature(ob); + if( arm==0 ) return; + G.obpose= ob; + /* make_poseMesh(); */ + allqueue(REDRAWVIEW3D, 0); + break; + default: + return; + } + + if (G.obedit) exit_editmode(1); + G.f &= ~(G_VERTEXPAINT | G_FACESELECT | G_TEXTUREPAINT | G_WEIGHTPAINT); + + +} + +void filter_pose_keys (void) +{ + + + Object *ob; + bPoseChannel *chan; + + ob=G.obpose; + if (!ob) + return; + + switch (ob->type){ + case OB_ARMATURE: + armature_filter_pose_keys (ob->pose, (bArmature*)ob->data); + break; + default: + if (ob->pose){ + for (chan=ob->pose->chanbase.first; chan; chan=chan->next){ + chan->flag |= POSE_KEY; + } + } + break; + } +} + +static void armature_filter_pose_keys (bPose *pose, bArmature *arm) +{ + Bone *bone; + + if (!pose) + return; + if (!arm) + return; + + for (bone=arm->bonebase.first; bone; bone=bone->next){ + armature_bonechildren_filter_pose_keys (pose, bone); + } +} + +static void armature_bonechildren_filter_pose_keys (bPose *pose, Bone *bone) +{ + Bone *curbone; + bPoseChannel *chan; + + if (!bone) + return; + + for (chan=pose->chanbase.first; chan; chan=chan->next){ + if (BLI_streq(chan->name, bone->name)) + break; + } + + if (chan){ + if (bone->flag & BONE_SELECTED){ + chan->flag |= POSE_KEY; + } + else { + chan->flag &= ~POSE_KEY; + } + } + + for (curbone=bone->childbase.first; curbone; curbone=curbone->next){ + armature_bonechildren_filter_pose_keys (pose, curbone); + } +} + +void exit_posemode (int freedata) +{ + Object *ob; + + if(G.obpose==0) return; + + ob= G.obpose; + + G.obpose= 0; + makeDispList(ob); + + if(freedata) { + setcursor_space(SPACE_VIEW3D, CURSOR_STD); + + countall(); + allqueue(REDRAWVIEW3D, 0); + } + else { + G.obpose= ob; + } + + scrarea_queue_headredraw(curarea); +} diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c new file mode 100644 index 00000000000..1180248c16e --- /dev/null +++ b/source/blender/src/previewrender.c @@ -0,0 +1,1074 @@ +/* previewrender.c GRAPHICS + * + * maart 95 + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/* global includes */ + +#include <stdlib.h> +#include <math.h> + +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#endif +#include "MEM_guardedalloc.h" +#include "BLI_arithb.h" +#include "BKE_utildefines.h" + +#include "MTC_matrixops.h" + +#include "render.h" +#include "mydevice.h" + +#include "DNA_texture_types.h" +#include "DNA_world_types.h" +#include "DNA_camera_types.h" +#include "DNA_image_types.h" +#include "DNA_object_types.h" +#include "DNA_lamp_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" + +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_texture.h" +#include "BKE_material.h" +#include "BKE_world.h" +#include "BKE_texture.h" + +#include "BIF_gl.h" +#include "BIF_screen.h" +#include "BIF_space.h" /* allqueue */ +#include "BIF_drawimage.h" /* rectwrite_part */ +//#include "BIF_previewrender.h" +#include "BIF_mywindow.h" + +#include "RE_renderconverter.h" + +//#include "mydevice.h" + +#define PR_RECTX 101 +#define PR_RECTY 101 +#define PR_XMIN 10 +#define PR_YMIN 10 +#define PR_XMAX 190 +#define PR_YMAX 190 + +#define PR_FACY (PR_YMAX-PR_YMIN-4)/(PR_RECTY) + +static rcti prerect; +static int pr_sizex, pr_sizey; +static float pr_facx, pr_facy; + + +/* implementation */ + +static short snijpunt(float *v1, + float *v2, + float *v3, + float *rtlabda, + float *ray1, + float *ray2) +{ + float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22; + float m0,m1,m2,deeldet,det1,det2,det3; + float rtu, rtv; + + t00= v3[0]-v1[0]; + t01= v3[1]-v1[1]; + t02= v3[2]-v1[2]; + t10= v3[0]-v2[0]; + t11= v3[1]-v2[1]; + t12= v3[2]-v2[2]; + t20= ray1[0]-ray2[0]; + t21= ray1[1]-ray2[1]; + t22= ray1[2]-ray2[2]; + + x0= t11*t22-t12*t21; + x1= t12*t20-t10*t22; + x2= t10*t21-t11*t20; + + deeldet= t00*x0+t01*x1+t02*x2; + if(deeldet!=0.0) { + m0= ray1[0]-v3[0]; + m1= ray1[1]-v3[1]; + m2= ray1[2]-v3[2]; + det1= m0*x0+m1*x1+m2*x2; + rtu= det1/deeldet; + if(rtu<=0.0) { + det2= t00*(m1*t22-m2*t21); + det2+= t01*(m2*t20-m0*t22); + det2+= t02*(m0*t21-m1*t20); + rtv= det2/deeldet; + if(rtv<=0.0) { + if(rtu+rtv>= -1.0) { + + det3= m0*(t12*t01-t11*t02); + det3+= m1*(t10*t02-t12*t00); + det3+= m2*(t11*t00-t10*t01); + *rtlabda= det3/deeldet; + + if(*rtlabda>=0.0 && *rtlabda<=1.0) { + return 1; + } + } + } + } + } + return 0; +} + +static float rcubev[7][3]= { + {-0.002055, 6.627364, -3.369742}, + {-6.031684, -3.750204, -1.992980}, + {-6.049086, 3.817431, 1.969788}, + { 6.031685, 3.833064, 1.992979}, + { 6.049086, -3.734571, -1.969787}, + { 0.002054, -6.544502, 3.369744}, + {-0.015348, 1.023131, 7.332510} }; + +static int rcubi[3][4]= { + {3, 6, 5, 4}, + {1, 5, 6, 2}, + {3, 0, 2, 6} }; + + +static int ray_previewrender(int x, + int y, + float *vec) +{ + float scalef= 12.8/100.0; + float ray1[3], ray2[3]; + float minlabda, labda; + int totface= 3, hitface= -1; + int a; + + ray1[0]= ray2[0]= x*scalef; + ray1[1]= ray2[1]= y*scalef; + ray1[2]= -10.0; + ray2[2]= 10.0; + + minlabda= 1.0; + for(a=0; a<totface; a++) { + if(snijpunt( rcubev[rcubi[a][0]], rcubev[rcubi[a][1]], rcubev[rcubi[a][2]], &labda, ray1, ray2)) { + if( labda < minlabda) { + minlabda= labda; + hitface= a; + } + } + if(snijpunt( rcubev[rcubi[a][0]], rcubev[rcubi[a][2]], rcubev[rcubi[a][3]], &labda, ray1, ray2)) { + if( labda < minlabda) { + minlabda= labda; + hitface= a; + } + } + } + + if(hitface > -1) { + + CalcNormFloat(rcubev[rcubi[hitface][0]], rcubev[rcubi[hitface][1]], rcubev[rcubi[hitface][2]], R.vn); + + vec[0]= (minlabda*(ray1[0]-ray2[0])+ray2[0])/3.7; + vec[1]= (minlabda*(ray1[1]-ray2[1])+ray2[1])/3.7; + vec[2]= (minlabda*(ray1[2]-ray2[2])+ray2[2])/3.7; + + return 1; + } + return 0; +} + + +static unsigned int previewback(int type, int x, int y) +{ + if(type & MA_DARK) { + if(abs(x)>abs(y)) return 0; + else return 0x40404040; + } + else { + if(abs(x)>abs(y)) return 0x40404040; + else return 0xa0a0a0a0; + } +} + +static void view2d_to_window(int win, int *x_r, int *y_r) +{ + int x= *x_r, y= *y_r; + int size[2], origin[2]; + float winmat[4][4]; + + bwin_getsinglematrix(win, winmat); + bwin_getsize(win, &size[0], &size[1]); + bwin_getsuborigin(win, &origin[0], &origin[1]); + + *x_r= origin[0] + (size[0]*(0.5 + 0.5*(x*winmat[0][0] + y*winmat[1][0] + winmat[3][0]))); + *y_r= origin[1] + (size[1]*(0.5 + 0.5*(x*winmat[0][1] + y*winmat[1][1] + winmat[3][1]))); +} + +static void set_previewrect(int win, int xmin, int ymin, int xmax, int ymax) +{ + prerect.xmin= xmin; + prerect.ymin= ymin; + prerect.xmax= xmax; + prerect.ymax= ymax; + + view2d_to_window(win, &prerect.xmin, &prerect.ymin); + view2d_to_window(win, &prerect.xmax, &prerect.ymax); + + pr_sizex= (prerect.xmax-prerect.xmin); + pr_sizey= (prerect.ymax-prerect.ymin); + + pr_facx= ( (float)pr_sizex-1)/PR_RECTX; + pr_facy= ( (float)pr_sizey-1)/PR_RECTY; +} + +static void display_pr_scanline(unsigned int *rect, int recty) +{ + /* we display 3 new scanlines, one old */ + + if(recty % 2) return; + if(recty<2) return; + + rect+= (recty-2)*PR_RECTX; + + /* iets meer uitvergroten in y om GL/mesa bugje te verhelpen */ + glPixelZoom(pr_facx, pr_facy); + + glRasterPos2f( (float)PR_XMIN+0.5, 1.0+(float)PR_YMIN + (recty*PR_FACY) ); + glDrawPixels(PR_RECTX, 3, GL_RGBA, GL_UNSIGNED_BYTE, rect); + + glPixelZoom(1.0, 1.0); +} + +static void draw_tex_crop(Tex *tex) +{ + rcti rct; + int ret= 0; + + if(tex==0) return; + + if(tex->type==TEX_IMAGE) { + if(tex->cropxmin==0.0) ret++; + if(tex->cropymin==0.0) ret++; + if(tex->cropxmax==1.0) ret++; + if(tex->cropymax==1.0) ret++; + if(ret==4) return; + + rct.xmin= PR_XMIN+2+tex->cropxmin*(PR_XMAX-PR_XMIN-4); + rct.xmax= PR_XMIN+2+tex->cropxmax*(PR_XMAX-PR_XMIN-4); + rct.ymin= PR_YMIN+2+tex->cropymin*(PR_YMAX-PR_YMIN-4); + rct.ymax= PR_YMIN+2+tex->cropymax*(PR_YMAX-PR_YMIN-4); + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + glColor3ub(0, 0, 0); + glRecti(rct.xmin+1, rct.ymin-1, rct.xmax+1, rct.ymax-1); + + glColor3ub(255, 255, 255); + glRecti(rct.xmin, rct.ymin, rct.xmax, rct.ymax); + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + +} + +void BIF_preview_changed(SpaceButs *sbuts) +{ + sbuts->cury= 0; + addafterqueue(sbuts->area->win, RENDERPREVIEW, 1); +} + +void BIF_previewdraw(SpaceButs *sbuts) +{ + set_previewrect(sbuts->area->win, PR_XMIN, PR_YMIN, PR_XMAX, PR_YMAX); + + if (sbuts->rect==0 || sbuts->cury==0) { + BIF_preview_changed(sbuts); + } else { + int y; + + for (y=0; y<PR_RECTY; y++) { + display_pr_scanline(sbuts->rect, y); + } + + if (sbuts->mainb==BUTS_TEX) { + draw_tex_crop(sbuts->lockpoin); + } + } +} + +static void sky_preview_pixel(float lens, int x, int y, char *rect) +{ + + if(R.wrld.skytype & WO_SKYPAPER) { + R.view[0]= (2*x)/(float)PR_RECTX; + R.view[1]= (2*y)/(float)PR_RECTY; + R.view[2]= 0.0; + } + else { + R.view[0]= x; + R.view[1]= y; + R.view[2]= -lens*PR_RECTX/32.0; + Normalise(R.view); + } + RE_sky(rect); +} + +static void lamp_preview_pixel(LampRen *la, int x, int y, char *rect) +{ + float inpr, i, t, dist, distkw, vec[3]; + int col; + + R.co[0]= (float)x/(PR_RECTX/4); + R.co[1]= (float)y/(PR_RECTX/4); + R.co[2]= 0; + + vec[0]= 0.02*x; + vec[1]= 0.02*y; + vec[2]= 0.005*PR_RECTX; + VECCOPY(R.view, vec); + dist= Normalise(R.view); + + if(la->mode & LA_TEXTURE) do_lamp_tex(la, vec); + + if(la->type==LA_SUN || la->type==LA_HEMI) { + dist= 1.0; + } + else { + + if(la->mode & LA_QUAD) { + + t= 1.0; + if(la->ld1>0.0) + t= la->dist/(la->dist+la->ld1*dist); + if(la->ld2>0.0) { + distkw= la->dist*la->dist; + t= t*distkw/(t*distkw+la->ld2*dist*dist); + } + dist= t; + } + else { + dist= (la->dist/(la->dist+dist)); + } + } + + if(la->type==LA_SPOT) { + + + if(la->mode & LA_SQUARE) { + /* slightly smaller... */ + inpr= 1.7*cos(MAX2(fabs(R.view[0]/R.view[2]) , fabs(R.view[1]/R.view[2]) )); + } + else { + inpr= R.view[2]; + } + + t= la->spotsi; + if(inpr<t) dist= 0.0; + else { + t= inpr-t; + if(t<la->spotbl && la->spotbl!=0.0) { + /* zachte gebied */ + i= t/la->spotbl; + t= i*i; + i= t*i; + inpr*=(3.0*t-2.0*i); + } + } + dist*=inpr; + } + else if(la->type==LA_LOCAL) dist*= R.view[2]; + + col= 255.0*dist*la->r; + if(col<=0) rect[0]= 0; else if(col>=255) rect[0]= 255; else rect[0]= col; + + col= 255.0*dist*la->g; + if(col<=0) rect[1]= 0; else if(col>=255) rect[1]= 255; else rect[1]= col; + + col= 255.0*dist*la->b; + if(col<=0) rect[2]= 0; else if(col>=255) rect[2]= 255; else rect[2]= col; +} + +static void init_previewhalo(HaloRen *har, Material *mat) +{ + + har->type= 0; + if(mat->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA; + har->mat= mat; + har->hard= mat->har; + har->rad= PR_RECTX/2.0; + har->radsq= PR_RECTX*PR_RECTX/4.0; + har->alfa= mat->alpha; + har->add= 255.0*mat->add; + har->r= 255.0*mat->r; + har->g= 255.0*mat->g; + har->b= 255.0*mat->b; + har->xs= PR_RECTX/2.0; + har->ys= PR_RECTX/2.0; + har->zs= har->zd= 0; + har->seed= (mat->seed1 % 256); + + if( (mat->mode & MA_HALOTEX) && mat->mtex[0] ) har->tex= 1; else har->tex=0; + + if(mat->mode & MA_STAR) har->starpoints= mat->starc; else har->starpoints= 0; + if(mat->mode & MA_HALO_LINES) har->linec= mat->linec; else har->linec= 0; + if(mat->mode & MA_HALO_RINGS) har->ringc= mat->ringc; else har->ringc= 0; + if(mat->mode & MA_HALO_FLARE) har->flarec= mat->flarec; else har->flarec= 0; + + if(har->flarec) { + har->xs-= PR_RECTX/3; + har->ys+= PR_RECTX/3; + + har->rad*= 0.3; + har->radsq= har->rad*har->rad; + + har->pixels= har->rad*har->rad*har->rad; + } +} + +static void halo_preview_pixel(HaloRen *har, int startx, int endx, int y, char *rect) +{ + float dist, xn, yn, xsq, ysq; + int x; + char front[4]; + + if(har->flarec) yn= y-PR_RECTX/3; + else yn= y; + ysq= yn*yn; + + for(x=startx; x<endx; x++) { + + if(har->flarec) xn= x+PR_RECTX/3; + else xn= x; + + xsq= xn*xn; + dist= xsq+ysq; + + + + if(dist<har->radsq) { + RE_shadehalo(har, front, 0, dist, xn, yn, har->flarec); + RE_addalphaAddfac(rect, front, har->add); + } + rect+= 4; + } +} + +static void previewflare(SpaceButs *sbuts, HaloRen *har, unsigned int *rect) +{ + float ycor; + unsigned int *rectot; + int afmx, afmy, rectx, recty; + + /* temps */ + ycor= R.ycor; + rectx= R.rectx; + recty= R.recty; + afmx= R.afmx; + afmy= R.afmy; + rectot= R.rectot; + + R.ycor= 1.0; + R.rectx= PR_RECTX; + R.recty= PR_RECTY; + R.afmx= PR_RECTX/2; + R.afmy= PR_RECTY/2; + R.rectot= rect; + + waitcursor(1); + + RE_renderflare(har); + + BIF_previewdraw(sbuts); + + waitcursor(0); + + /* temps */ + R.ycor= ycor; + R.rectx= rectx; + R.recty= recty; + R.afmx= afmx; + R.afmy= afmy; + R.rectot= rectot; +} + +extern float Tin, Tr, Tg, Tb, Ta; /* texture.c */ +static void texture_preview_pixel(Tex *tex, int x, int y, char *rect) +{ + float i, v1, xsq, ysq, texvec[3]; + int rgbnor, tracol, skip=0; + + if(tex->type==TEX_IMAGE) { + v1= 1.0/PR_RECTX; + + texvec[0]= 0.5+v1*x; + texvec[1]= 0.5+v1*y; + + /* geen coordmapping, uitzondering: repeat */ + if(tex->xrepeat>1) { + texvec[0] *= tex->xrepeat; + if(texvec[0]>1.0) texvec[0] -= (int)(texvec[0]); + } + if(tex->yrepeat>1) { + texvec[1] *= tex->yrepeat; + if(texvec[1]>1.0) texvec[1] -= (int)(texvec[1]); + } + + } + else if(tex->type==TEX_ENVMAP) { + if(tex->env) { + ysq= y*y; + xsq= x*x; + if(xsq+ysq < (PR_RECTX/2)*(PR_RECTY/2)) { + texvec[2]= sqrt( (float)((PR_RECTX/2)*(PR_RECTY/2)-xsq-ysq) ); + texvec[0]= -x; + texvec[1]= -y; + Normalise(texvec); + + i= 2.0*(texvec[2]); + texvec[0]= (i*texvec[0]); + texvec[1]= (i*texvec[1]); + texvec[2]= (-1.0+i*texvec[2]); + + } + else { + skip= 1; + Ta= 0.0; + } + } + else { + skip= 1; + Ta= 0.0; + } + } + else { + v1= 2.0/PR_RECTX; + + texvec[0]= v1*x; + texvec[1]= v1*y; + texvec[2]= 0.0; + } + + /* geeft geen Tin terug */ + if(tex->type==TEX_STUCCI) { + tex->nor= R.vn; + R.vn[0]= 1.0; + R.vn[1]= R.vn[2]= 0.0; + } + + if(skip==0) rgbnor= multitex(tex, texvec, 0, 0); + else rgbnor= 1; + + if(rgbnor & 1) { + + rect[0]= 255.0*Tr; + rect[1]= 255.0*Tg; + rect[2]= 255.0*Tb; + + if(Ta!=1.0) { + tracol= 64+100*(abs(x)>abs(y)); + tracol= (1.0-Ta)*tracol; + + rect[0]= tracol+ (rect[0]*Ta) ; + rect[1]= tracol+ (rect[1]*Ta) ; + rect[2]= tracol+ (rect[2]*Ta) ; + + } + } + else { + + if(tex->type==TEX_STUCCI) { + Tin= 0.5 + 0.7*tex->nor[0]; + CLAMP(Tin, 0.0, 1.0); + } + rect[0]= 255.0*Tin; + rect[1]= 255.0*Tin; + rect[2]= 255.0*Tin; + } +} + +static float pr1_lamp[3]= {2.3, -2.4, -4.6}; +static float pr2_lamp[3]= {-8.8, -5.6, -1.5}; +static float pr1_col[3]= {0.8, 0.8, 0.8}; +static float pr2_col[3]= {0.5, 0.6, 0.7}; + +static void shade_preview_pixel(float *vec, + int x, + int y, + char *rect, + int smooth) +{ + Material *mat; + float v1,inp, inprspec=0, isr=0.0, isb=0.0, isg=0.0; + float ir=0.0, ib=0.0, ig=0.0; + float view[3], lv[3], *la, alpha; + float eul[3], tmat[3][3], imat[3][3]; + int temp, a; + char tracol; + + mat= R.matren; + /* pr1_lamp[0]= mat->mtex[0]->ofs[0]; */ + /* pr1_lamp[1]= mat->mtex[0]->ofs[1]; */ + /* pr1_lamp[2]= mat->mtex[0]->ofs[2]; */ + + /* pr2_lamp[0]= mat->mtex[0]->size[0]; */ + /* pr2_lamp[1]= mat->mtex[0]->size[1]; */ + /* pr2_lamp[2]= mat->mtex[0]->size[2]; */ + + v1= 1.0/PR_RECTX; + view[0]= v1*x; + view[1]= v1*y; + view[2]= 1.0; + Normalise(view); + + R.refcol[0]= R.refcol[1]= R.refcol[2]= R.refcol[3]= 0.0; + + /* texture afhandeling */ + if(mat->texco) { + + VECCOPY(R.lo, vec); + + if(mat->pr_type==MA_CUBE) { + + eul[0]= (297)*M_PI/180.0; + eul[1]= 0.0; + eul[2]= (45)*M_PI/180.0; + EulToMat3(eul, tmat); + + MTC_Mat3MulVecfl(tmat, R.lo); + MTC_Mat3MulVecfl(tmat, R.vn); + /* hack for cubemap, why!!! */ + SWAP(float, R.vn[0], R.vn[1]); + } + + if(mat->texco & TEXCO_GLOB) { + VECCOPY(R.gl, R.lo); + } + if(mat->texco & TEXCO_WINDOW) { + VECCOPY(R.winco, R.lo); + } + if(mat->texco & TEXCO_STICKY) { + VECCOPY(R.sticky, R.lo); + } + if(mat->texco & TEXCO_UV) { + VECCOPY(R.uv, R.lo); + } + if(mat->texco & TEXCO_OBJECT) { + VECCOPY(R.co, R.lo); + } + if(mat->texco & TEXCO_NORM) { + R.orn[0]= R.vn[0]; + R.orn[1]= -R.vn[1]; + R.orn[2]= R.vn[2]; + } + if(mat->texco & TEXCO_REFL) { + /* for bump texture */ + VECCOPY(R.view, view); + + inp= -2.0*(R.vn[0]*view[0]+R.vn[1]*view[1]+R.vn[2]*view[2]); + R.ref[0]= (view[0]+inp*R.vn[0]); + R.ref[1]= -(view[1]+inp*R.vn[1]); + R.ref[2]= (view[2]+inp*R.vn[2]); + } + + do_material_tex(); + + if(mat->pr_type==MA_CUBE) { + /* rotate normal back for normals texture */ + SWAP(float, R.vn[0], R.vn[1]); + MTC_Mat3Inv(imat, tmat); + MTC_Mat3MulVecfl(imat, R.vn); + } + + } + + if(mat->mode & MA_SHLESS) { + temp= 255.0*(mat->r); + if(temp>255) rect[0]= 255; else if(temp<0) rect[0]= 0; else rect[0]= temp; + + temp= 255.0*(mat->g); + if(temp>255) rect[1]= 255; else if(temp<0) rect[1]= 0; else rect[1]= temp; + + temp= 255.0*(mat->b); + if(temp>255) rect[2]= 255; else if(temp<0) rect[2]= 0; else rect[2]= temp; + } + else { + + for(a=0; a<2; a++) { + + if(a==0) la= pr1_lamp; + else la= pr2_lamp; + + lv[0]= vec[0]-la[0]; + lv[1]= vec[1]-la[1]; + lv[2]= vec[2]-la[2]; + Normalise(lv); + + inp= R.vn[0]*lv[0]+R.vn[1]*lv[1]+R.vn[2]*lv[2]; + if(inp<0.0) inp= 0.0; + + if(mat->spec) { + + lv[0]+= view[0]; + lv[1]+= view[1]; + lv[2]+= view[2]; + Normalise(lv); + + if(inp>0.0) { + v1= lv[0]*R.vn[0]+lv[1]*R.vn[1]+lv[2]*R.vn[2]; + if(v1>0.0) { + v1= RE_Spec(v1, mat->har); + inprspec= v1*mat->spec; + isr+= inprspec*mat->specr; + isg+= inprspec*mat->specg; + isb+= inprspec*mat->specb; + } + } + } + inp= (mat->ref*inp + mat->emit); + + if(a==0) la= pr1_col; + else la= pr2_col; + + ir+= inp*la[0]; + ig+= inp*la[1]; + ib+= inp*la[2]; + } + + if(R.refcol[0]==0.0) { + a= 255.0*( mat->r*ir +mat->ambr +isr); + if(a>255) a=255; else if(a<0) a= 0; + rect[0]= a; + a= 255.0*(mat->g*ig +mat->ambg +isg); + if(a>255) a=255; else if(a<0) a= 0; + rect[1]= a; + a= 255*(mat->b*ib +mat->ambb +isb); + if(a>255) a=255; else if(a<0) a= 0; + rect[2]= a; + } + else { + a= 255.0*( mat->mirr*R.refcol[1] + (1.0 - mat->mirr*R.refcol[0])*(mat->r*ir +mat->ambr) +isr); + if(a>255) a=255; else if(a<0) a= 0; + rect[0]= a; + a= 255.0*( mat->mirg*R.refcol[2] + (1.0 - mat->mirg*R.refcol[0])*(mat->g*ig +mat->ambg) +isg); + if(a>255) a=255; else if(a<0) a= 0; + rect[1]= a; + a= 255.0*( mat->mirb*R.refcol[3] + (1.0 - mat->mirb*R.refcol[0])*(mat->b*ib +mat->ambb) +isb); + if(a>255) a=255; else if(a<0) a= 0; + rect[2]= a; + } + } + + if(mat->alpha!=1.0) { + + alpha= mat->alpha; + + /* ztra shade */ + if(mat->spectra!=0.0) { + inp= mat->spectra*inprspec; + if(inp>1.0) inp= 1.0; + + alpha= (1.0-inp)*alpha+ inp; + } + + tracol= previewback(mat->pr_back, x, y) & 255; + + tracol= (1.0-alpha)*tracol; + + rect[0]= tracol+ (rect[0]*alpha) ; + rect[1]= tracol+ (rect[1]*alpha) ; + rect[2]= tracol+ (rect[2]*alpha) ; + + } +} + + +void BIF_previewrender(SpaceButs *sbuts) +{ + Material *mat=0; + Tex *tex = NULL; + Image *ima; + Lamp *la; + LampRen *lar = NULL; + HaloRen har; + Object *ob; + World *wrld; + float lens = 0.0, vec[3]; + int x, y, starty, startx, endy, endx, radsq, xsq, ysq, last = 0; + unsigned int *rect; + + if(sbuts->cury>=PR_RECTY) return; + + if ELEM4(sbuts->mainb, BUTS_MAT, BUTS_TEX, BUTS_LAMP, BUTS_WORLD); + else return; + + har.flarec= 0; /* verderop test op postrender flare */ + + if(qtest()) { + addafterqueue(curarea->win, RENDERPREVIEW, 1); + return; + } + + MTC_Mat4One(R.viewmat); + MTC_Mat4One(R.viewinv); + + R.osatex= 0; + if(sbuts->mainb==BUTS_MAT) { + mat= sbuts->lockpoin; + if(mat==0) return; + + /* rendervars */ + init_render_world(); + init_render_material(mat); + + /* clear imats */ + for(x=0; x<8; x++) { + if(mat->mtex[x]) { + if(mat->mtex[x]->tex) { + init_render_texture(mat->mtex[x]->tex); + + if(mat->mtex[x]->tex->env && mat->mtex[x]->tex->env->object) + MTC_Mat4One(mat->mtex[x]->tex->env->object->imat); + } + if(mat->mtex[x]->object) MTC_Mat4One(mat->mtex[x]->object->imat); + if(mat->mtex[x]->object) MTC_Mat4One(mat->mtex[x]->object->imat); + } + } + R.vlr= 0; + R.mat= mat; + R.matren= mat->ren; + + if(mat->mode & MA_HALO) init_previewhalo(&har, mat); + } + else if(sbuts->mainb==BUTS_TEX) { + tex= sbuts->lockpoin; + if(tex==0) return; + ima= tex->ima; + if(ima) last= ima->lastframe; + init_render_texture(tex); + free_unused_animimages(); + if(tex->ima) { + if(tex->ima!=ima) allqueue(REDRAWBUTSTEX, 0); + else if(last!=ima->lastframe) allqueue(REDRAWBUTSTEX, 0); + } + if(tex->env && tex->env->object) + MTC_Mat4Invert(tex->env->object->imat, tex->env->object->obmat); + } + else if(sbuts->mainb==BUTS_LAMP) { + ob= ((G.scene->basact)? (G.scene->basact)->object: 0); + if(ob==0 || ob->type!=OB_LAMP) return; + la= ob->data; + init_render_world(); + init_render_textures(); /* ze mogen niet twee keer!! (brightness) */ + R.totlamp= 0; + RE_add_render_lamp(ob, 0); /* 0=no shadbuf */ + lar= R.la[0]; + + /* uitzonderingen: */ + lar->spottexfac= 1.0; + lar->spotsi= cos( M_PI/3.0 ); + lar->spotbl= (1.0-lar->spotsi)*la->spotblend; + + MTC_Mat3One(lar->imat); + } + else { + wrld= sbuts->lockpoin; + if(wrld==0) return; + + lens= 35.0; + if(G.scene->camera) { + lens= ( (Camera *)G.scene->camera->data)->lens; + } + + init_render_world(); + init_render_textures(); /* dont do it twice!! (brightness) */ + } + + set_previewrect(sbuts->area->win, PR_XMIN, PR_YMIN, PR_XMAX, PR_YMAX); + + if(sbuts->rect==0) { + sbuts->rect= MEM_callocN(sizeof(int)*PR_RECTX*PR_RECTY, "butsrect"); + + /* built in emboss */ + rect= sbuts->rect; + for(y=0; y<PR_RECTY; y++, rect++) *rect= 0xFFFFFFFF; + + rect= sbuts->rect + PR_RECTX-1; + for(y=0; y<PR_RECTY; y++, rect+=PR_RECTX) *rect= 0xFFFFFFFF; + } + + starty= -PR_RECTY/2; + endy= starty+PR_RECTY; + starty+= sbuts->cury; + + /* offset +1 for emboss */ + startx= -PR_RECTX/2 +1; + endx= startx+PR_RECTX -2; + + radsq= (PR_RECTX/2)*(PR_RECTY/2); + + glDrawBuffer(GL_FRONT); + + if(mat) { + if(mat->pr_type==MA_SPHERE) { + pr1_lamp[0]= 2.3; pr1_lamp[1]= -2.4; pr1_lamp[2]= -4.6; + pr2_lamp[0]= -8.8; pr2_lamp[1]= -5.6; pr2_lamp[2]= -1.5; + } + else { + pr1_lamp[0]= 1.9; pr1_lamp[1]= 3.1; pr1_lamp[2]= -8.5; + pr2_lamp[0]= 1.2; pr2_lamp[1]= -18; pr2_lamp[2]= 3.2; + } + } + + for(y=starty; y<endy; y++) { + + rect= sbuts->rect + 1 + PR_RECTX*sbuts->cury; + + if(y== -PR_RECTY/2 || y==endy-1); /* emboss */ + else if(sbuts->mainb==BUTS_MAT) { + + if(mat->mode & MA_HALO) { + for(x=startx; x<endx; x++, rect++) { + rect[0]= previewback(mat->pr_back, x, y); + } + + if(har.flarec) { + if(y==endy-2) previewflare(sbuts, &har, sbuts->rect); + } + else { + halo_preview_pixel(&har, startx, endx, y, (char *) (rect-PR_RECTX)); + } + } + else { + ysq= y*y; + for(x=startx; x<endx; x++, rect++) { + xsq= x*x; + if(mat->pr_type==MA_SPHERE) { + + if(xsq+ysq < radsq) { + R.vn[0]= x; + R.vn[1]= y; + R.vn[2]= sqrt( (float)(radsq-xsq-ysq) ); + Normalise(R.vn); + + vec[0]= R.vn[0]; + vec[1]= R.vn[2]; + vec[2]= -R.vn[1]; + + shade_preview_pixel(vec, x, y, (char *)rect, 1); + } + else { + rect[0]= previewback(mat->pr_back, x, y); + } + } + else if(mat->pr_type==MA_CUBE) { + if( ray_previewrender(x, y, vec) ) { + + shade_preview_pixel(vec, x, y, (char *)rect, 0); + } + else { + rect[0]= previewback(mat->pr_back, x, y); + } + } + else { + vec[0]= x*(2.0/PR_RECTX); + vec[1]= y*(2.0/PR_RECTX); + vec[2]= 0.0; + + R.vn[0]= R.vn[1]= 0.0; + R.vn[2]= 1.0; + + shade_preview_pixel(vec, x, y, (char *)rect, 0); + } + } + } + } + else if(sbuts->mainb==BUTS_TEX) { + for(x=startx; x<endx; x++, rect++) { + texture_preview_pixel(tex, x, y, (char *)rect); + } + } + else if(sbuts->mainb==BUTS_LAMP) { + for(x=startx; x<endx; x++, rect++) { + lamp_preview_pixel(lar, x, y, (char *)rect); + } + } + else { + for(x=startx; x<endx; x++, rect++) { + sky_preview_pixel(lens, x, y, (char *)rect); + } + } + + if(y<endy-2) { + + if(qtest()) { + addafterqueue(curarea->win, RENDERPREVIEW, 1); + break; + } + } + + display_pr_scanline(sbuts->rect, sbuts->cury); + + sbuts->cury++; + } + + if(sbuts->cury>=PR_RECTY && sbuts->mainb==BUTS_TEX) + draw_tex_crop(sbuts->lockpoin); + + glDrawBuffer(GL_BACK); + BIF_previewdraw(sbuts); + + if(sbuts->mainb==BUTS_MAT) { + end_render_material(mat); + for(x=0; x<8; x++) { + if(mat->mtex[x] && mat->mtex[x]->tex) end_render_texture(mat->mtex[x]->tex); + } + } + else if(sbuts->mainb==BUTS_TEX) { + end_render_texture(tex); + } + else if(sbuts->mainb==BUTS_WORLD) { + end_render_textures(); + } + else if(sbuts->mainb==BUTS_LAMP) { + if(R.totlamp) { + if(R.la[0]->org) MEM_freeN(R.la[0]->org); + MEM_freeN(R.la[0]); + } + R.totlamp= 0; + end_render_textures(); + } +} + diff --git a/source/blender/src/pub/license_key.c b/source/blender/src/pub/license_key.c new file mode 100644 index 00000000000..fb6402cbaeb --- /dev/null +++ b/source/blender/src/pub/license_key.c @@ -0,0 +1,451 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include "license_key.h" +#include "keyed_functions.h" +#include "BKE_utildefines.h" +#include "BIF_screen.h" // splash +#include "BIF_toolbox.h" +#include "blenkey.h" +#include <stdio.h> +#include <string.h> + +#include "BLI_blenlib.h" + +#include "BLO_readfile.h" +#include "BLO_keyStore.h" + +int LICENSE_KEY_VALID = FALSE; +int I_AM_PUBLISHER = TRUE; + +static UserStruct User; + +// Python stuff + +#include "Python.h" +#include "marshal.h" +#include "compile.h" /* to give us PyCodeObject */ +#include "eval.h" /* prototype for PyEval_EvalCode */ + +#include "BPY_extern.h" + +#include "IMB_imbuf.h" + +Fptr g_functab[PYKEY_TABLEN]; +Fptr g_ptrtab[PYKEY_TABLEN]; + +static int g_seed[3] = PYKEY_SEED; +static PyObject *g_module_self; +static PyObject *g_main; + + +// end Python stuff + +// **************** PYTHON STUFF ************************** +/* ----------------------------------------------------- */ +/* this is the dummy functions to demonstrate */ + +int sticky_shoes(void *vp) +{ + return 0; +} + +/* +int key_func1(void *vp) { + printf("function 1 called\n"); +} + +*/ +int key_return_true(void *vp) { + return 1; +} + + +/* ----------------------------------------------------- */ + +/* Declarations for objects of type Fplist */ + + +static char prot_getseed__doc__[] = ""; + +static PyObject * +prot_getseed(self, args) + PyObject *self; /* Not used */ + PyObject *args; +{ + PyObject *p; + p = PyTuple_New(3); + PyTuple_SetItem(p, 0, PyInt_FromLong(g_seed[0])); + PyTuple_SetItem(p, 1, PyInt_FromLong(g_seed[1])); + PyTuple_SetItem(p, 2, PyInt_FromLong(g_seed[2])); + return p; +} + +static char prot_getlen__doc__[] = ""; +static PyObject * +prot_getlen(self, args) + PyObject *self; /* Not used */ + PyObject *args; +{ + return Py_BuildValue("i", PYKEY_TABLEN); +} + +static char prot_getptr__doc__[] = +"" +; + +static PyObject * +prot_getptr(self, args) + PyObject *self; /* Not used */ + PyObject *args; +{ + PyObject *p; + Fptr f; + int index; + /* we don't catch errors here, we're in the key code */ + if (!g_functab) + return NULL; + if (!PyArg_ParseTuple(args, "i", &index)) + return NULL; + if (index >= PYKEY_TABLEN) + return NULL; + + f = g_functab[index]; + p = PyCObject_FromVoidPtr(f , NULL); + return p; +} + +static char prot_setptr__doc__[] = +"" +; +static PyObject * +prot_setptr(self, args) + PyObject *self; /* Not used */ + PyObject *args; +{ + PyObject *p; + + int index; + + if (!g_ptrtab) + return NULL; + if (!PyArg_ParseTuple(args, "iO", &index, &p)) + return NULL; + if (index >= PYKEY_TABLEN) + return NULL; + if (!PyCObject_Check(p)) { + return NULL; + } + + g_ptrtab[index] = PyCObject_AsVoidPtr(p); + return Py_BuildValue("i", 1); +} + +static PyObject *callkeycode( + unsigned char *keycode, + int keycodelen) +{ + PyCodeObject *code; + PyObject *maindict = PyModule_GetDict(g_main); + + code = (PyCodeObject *) PyMarshal_ReadObjectFromString(keycode, keycodelen); + if (!PyEval_EvalCode(code, maindict, maindict)) + return NULL; + return Py_BuildValue("i", 1); +} + + + +/* List of methods defined in the module */ + +static struct PyMethodDef prot_methods[] = { + {"getlen", (PyCFunction)prot_getlen, METH_VARARGS, prot_getlen__doc__}, + {"getseed", (PyCFunction)prot_getseed, METH_VARARGS, prot_getseed__doc__}, + {"getptr", (PyCFunction)prot_getptr, METH_VARARGS, prot_getptr__doc__}, + {"setptr", (PyCFunction)prot_setptr, METH_VARARGS, prot_setptr__doc__}, + + {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */ +}; + + +/* Initialization function for the module (*must* be called initprot) */ + +static char prot_module_documentation[] = "No Documentation"; + +static void init_ftable(void) // initializes functiontable +{ + int i; + + g_functab[0] = &key_func1; + g_functab[1] = &key_func2; + g_functab[2] = &key_func3; +/* add more key_funcs here */ + + for (i = 3; i < PYKEY_TABLEN; i++) + { + g_functab[i] = &sticky_shoes; + } +} + + +static void init_ptable(void) // initializes functiontable +{ + int i; + + for (i = 0; i < PYKEY_TABLEN; i++) + { + g_ptrtab[i] = &sticky_shoes; + } +} + + +static void insertname(PyObject *m,PyObject *p, char *name) +{ + PyObject *d = PyModule_GetDict(m); + + PyDict_SetItemString(d, name, p); + Py_DECREF(p); +} + +/* initialisation */ +static void initprot() +{ + PyObject *m, *d; + PyObject *capi1; + PyObject *ErrorObject; + + init_ftable(); + + g_main = PyImport_AddModule("__main__"); + + m = Py_InitModule4("prot", prot_methods, + prot_module_documentation, + (PyObject*)NULL,PYTHON_API_VERSION); + g_module_self = m; + d = PyModule_GetDict(m); + ErrorObject = PyString_FromString("prot.error"); + PyDict_SetItemString(d, "error", ErrorObject); + + /* add global object */ + + capi1 = PyCObject_FromVoidPtr((void *)g_functab , NULL); + if (capi1) { + insertname(m, capi1, "APIfunctab"); + } + + /* Check for errors */ + if (PyErr_Occurred()) + Py_FatalError("can't initialize module prot"); + + init_ptable(); +} + +// ******************************* KEY STUFF ********************* + +static void create_key_name(char * keyname) +{ + sprintf(keyname, "%s/.BPkey", BLI_gethome()); +} + +void checkhome() +{ + int keyresult; + char *HexPriv, *HexPub, *HexPython; + byte *Byte; + char keyname[FILE_MAXDIR + FILE_MAXFILE]; + int wasInitialized; + unsigned char *keycode = NULL; + int keycodelen = 0; + + create_key_name(keyname); + keyresult = ReadKeyFile(keyname, &User, &HexPriv, &HexPub, + &Byte, &HexPython); + if (keyresult != 0) { + // printf("\nReadKeyFile error %d\n", keyresult); + } else { + // printf("\nReadKeyFile OK\n"); + LICENSE_KEY_VALID = TRUE; + + wasInitialized = Py_IsInitialized(); + + // make it failsafe if python interpreter was already initialized + if (wasInitialized) + Py_Initialize(); + + initprot(); // initialize module and function tables + // get python byte code + keycode = DeHexify(HexPython); + keycodelen = strlen(HexPython) / 2; + + callkeycode(keycode, keycodelen); + + Py_Finalize(); + + if (wasInitialized) // if we were initialized, + BPY_start_python(); // restart creator python + + //some debugging stuff + // print_ptable(); + + // Store key stuff for use by stream + keyStoreConstructor( + &User, + HexPriv, + HexPub, + Byte, + HexPython); + + // other initialization code + + // enable png writing in the ImBuf library + IMB_fp_png_encode = IMB_png_encode; + } +} + +void SHOW_LICENSE_KEY(void) +{ + extern int datatoc_tonize; + extern char datatoc_ton[]; + char string[1024]; + int maxtype, type; + char *typestrings[] = { + "", + "Individual", + "Company", + "Unlimited", + "Educational"}; + + maxtype = (sizeof(typestrings) / sizeof(char *)) - 1; + type = User.keytype; + if (type > maxtype) { + type = 0; + } + + if (LICENSE_KEY_VALID) { + sprintf(string, "%s License registered to: %s (%s)", typestrings[type], User.name, User.email); + splash((void *)datatoc_ton, datatoc_tonize, string); + } +} + +void loadKeyboard(char * name) +{ + char keyname[FILE_MAXDIR + FILE_MAXFILE]; + FILE *in, *out; + char string[1024], *match = 0; + int i, c; + int found = 0; + + // make sure we don't overwrite a valid key... + + if (!LICENSE_KEY_VALID) { + in = fopen(name, "rb"); + if (in) { + // scan for blender key magic, read strings + // with anything but a newline + while (fscanf(in, "%1000[^\n\r]", string) != EOF) { + match = strstr(string, BLENKEYMAGIC); + if (match) { + break; + } + fscanf(in, "\n"); + } + + if (match) { + // found blender key magic, open output file + // to copy key information + + create_key_name(keyname); + out = fopen(keyname, "wb"); + if (out) { + // printout first line + fprintf(out, "%s", match); + for (i = 0; i < 350; i++) { + // handle control characters (\n\r) + while (1) { + c = getc(in); + if (c == '\n') { + // output a \n for each \n in the input + fprintf(out, "\n"); + } else if (c == EOF) { + break; + } else if (c < ' ') { + // skip control characters + } else { + ungetc(c, in); + break; + } + } + + if (fscanf(in, "%1000[^\n\r]", string) != EOF) { + if (strcmp(string, BLENKEYSEPERATOR) == 0) { + found++; + } + fprintf(out, "%s", string); + } else { + break; + } + + if (found >= 2) { + break; + } + } + + fclose(out); + + checkhome(); + if (LICENSE_KEY_VALID) { + SHOW_LICENSE_KEY(); + } else { + error("Not a valid license key ! Removing installed key."); + BLI_delete(keyname, 0, 0); + } + + } else { + error("Can't install key"); + } + } else { + error("File doesn't contain a valid key: %s", name); + } + + fclose(in); + + if (LICENSE_KEY_VALID) { + if (okee("Remove input file: '%s'?", name)) { + BLI_delete(name, 0, 0); + } + } + + } else { + error("File doesn't exist: %s", name); + } + } +} diff --git a/source/blender/src/pub/osx_publisher_splash.jpg.c b/source/blender/src/pub/osx_publisher_splash.jpg.c new file mode 100644 index 00000000000..3ac6b870d18 --- /dev/null +++ b/source/blender/src/pub/osx_publisher_splash.jpg.c @@ -0,0 +1,984 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +/* DataToC output of file <splash_jpg> */ +#ifdef __APPLE__ + +int datatoc_tonize= 30248; +char datatoc_ton[]= { +255,216,255,224, 0, 16, 74, 70, + 73, 70, 0, 1, 2, 0, 0,100, 0,100, 0, 0,255,236, 0, 17, 68,117, 99,107,121, 0, 1, 0, 4, 0, 0, 0, 50, 0, 0,255, +238, 0, 14, 65,100,111, 98,101, 0,100,192, 0, 0, 0, 1,255,219, 0,132, 0, 8, 6, 6, 6, 6, 6, 8, 6, 6, 8, 12, 8, + 7, 8, 12, 14, 10, 8, 8, 10, 14, 16, 13, 13, 14, 13, 13, 16, 17, 12, 14, 13, 13, 14, 12, 17, 15, 18, 19, 20, 19, 18, 15, 24, + 24, 26, 26, 24, 24, 35, 34, 34, 34, 35, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 1, 9, 8, 8, 9, 10, 9, 11, 9, 9, 11, 14, + 11, 13, 11, 14, 17, 14, 14, 14, 14, 17, 19, 13, 13, 14, 13, 13, 19, 24, 17, 15, 15, 15, 15, 17, 24, 22, 23, 20, 20, 20, 23, 22, + 26, 26, 24, 24, 26, 26, 33, 33, 32, 33, 33, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,255,192, 0, 17, 8, 1, 15, 1,244, 3, 1, + 34, 0, 2, 17, 1, 3, 17, 1,255,196, 0,194, 0, 0, 1, 5, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2, + 4, 5, 6, 0, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 16, + 0, 2, 1, 3, 2, 4, 3, 4, 5, 6, 10, 6, 7, 6, 2, 11, 1, 2, 3, 0, 17, 4, 18, 5, 33, 49, 19, 6, 65, 81, 20, 97, +113, 34, 50,129,145,209, 21, 7,161,225, 66, 82,146, 35,177,193, 98,114,130,178, 51, 67, 36, 22,240,210, 83, 99,115,131,162,179, +195, 52, 84,116, 54,147,163,211,196, 37, 23,241, 53,194,226, 68,100,132,148,164, 69,133, 38, 71, 17, 0, 2, 1, 3, 2, 4, 3, + 6, 4, 6, 3, 1, 0, 0, 0, 0, 0, 1, 2, 17, 3, 4, 33, 18, 49, 65, 81, 5, 97,113, 19,129,145,161,209, 34, 50,177,193, + 66,146,240,225, 82,114, 51, 20, 98,147, 21, 52,255,218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0,244,254,224,238, 9, 59, +127,111,143, 51, 67,204,154, 98, 78,154,190,139, 94, 48,111,227, 84,189,187,248,157,181,111,121,203,182, 74,211, 97,102,202,116, +192,147, 54,164,144,254,170, 72,167,230,246, 16, 42,195,187, 50, 59,119, 27,111,129,187,154, 24,230,194, 99, 18,162, 76,130, 69, +234,116,174, 13,155,135, 32,107,198, 59,154, 93,139,117,238, 13,167, 19,177, 96, 16,100, 52,145,170, 24, 87, 66, 9,117,130,140, + 20,114,211,109, 71,221,122, 3,232,137, 38,156, 48,180,141,107,126,177,166, 28,153,129,254,209,255, 0,104,215, 73,123,143, 59, + 80,154,246,185,161, 3,122,137,173,113, 35,126,209,166, 25,242, 9,183, 85,199,244,143,219, 76, 91,218,246,227, 78, 3,243,208, + 4, 19, 79,200,202,255, 0,180,126,218, 78,164,222, 19, 73,251, 70,147,133,119, 1, 64, 41,151, 35,152,149,255, 0,104,211,125, + 70, 77,175,213,111,218, 53,220,111,127, 10,105,225,238,160, 7,145,149,148,161, 71, 85,214,230,247, 12,104, 77,153,149,107, 9, +228,191,243,219,237,166,101,177, 50, 42,223,128, 23, 31, 73,252,212, 11,240,189, 70, 80,227, 47, 44,243,200,147,246,219,237,167, +122,188,171,127,111, 39,237,183,219, 64, 91,145, 97, 75,167,206,128,120,204,204, 60,167,147,246,219,237,167, 12,172,195,195,212, + 73,251,109,246,208,208, 0,107,181, 11,147, 64, 72, 25, 57, 64, 15,223,201,251,109,246,215, 54, 94, 72,254,254, 79,218, 63,109, + 71, 45,123, 90,184,113,226,104, 9, 17,230,207,168,234,157,199,149,216,253,180, 81,149, 59,114,157,173,231,172,253,180, 56, 87, +224, 36,128, 69,207,217, 93,211,136,146,116, 14, 28,207, 10,128, 41,202,200, 80, 15, 81,200,243,212,126,218,112,202,159,198, 87, +246,124, 71,237,168,161, 16,155, 13, 69, 77,200,181,236, 45,238,165, 88,152, 92, 6, 63, 79,149, 1, 32,100,228, 17,126,179,241, +240,212,126,218,239, 81,147,199,247,175,251, 71,237,168,218, 92, 88,171, 2, 7,178,156, 76,136,191, 18,131,238, 60,120,253, 20, + 1,253, 68,246,254,217,255, 0,104,253,180, 23,201,200, 75, 19, 60,159,182,199,248,233,133,207, 61, 36,123,105,132,135,176, 2, +214,231,194,168, 10,115, 50, 45,168, 78,224, 90,228,234,111,182,163, 54,118, 99,177, 34,121, 64,240, 1,219,237,164,200, 4, 21, + 31,162,105,168,182, 5,155,128,231,127, 33, 84, 6,245,153,104,183,108,137, 15,144,214,220, 79,215, 77,245,185,171,243,100, 72, + 73,226,126, 54,176,252,180, 3, 32, 44, 9,229,201, 5, 53,195, 49,184, 54, 30,116, 1,142,102,104, 55, 57, 82,129,228, 29,190, +218,112,206,203, 97,117,200,151,246,219,237,168,227, 73, 22, 63, 21,169, 1, 55,176, 22, 20, 1,198,102,117,254, 44,153, 7,244, +219,237,164,245,249,136,226,249, 50,144,124, 53,183,219, 64,144, 1,196,154,116, 49,235, 58,156,112,160, 38,122,252,163,192, 79, + 33,191,242,219,237,161,250,172,245,185,108,137,120,242, 29, 70,251,107,128, 0,220, 10, 70, 26,143,186,128,107,102,231,248, 79, + 47,237,183,219, 74, 50,183, 6, 23,245, 18,175,244,219,237,174, 0, 6,231,244, 83, 76,161,156,170,142, 2,128, 42,207,153,194, +249, 51, 31,249,140, 7,240,211,219, 59, 34, 62, 7, 34, 75,255, 0, 61,190,218,134,229,239,197,172, 41, 27, 79,205,107,154, 2, + 75,103,102, 91,225,158, 67,127,229,183,219, 76, 57,249,129,108,114, 36,213,236,118,251,104, 58,137, 94, 60, 9,166,132, 0,223, +153,160, 12,185,153,195,137,201,151,233,145,190,218, 47,222, 25, 96, 91,175, 33, 62,101,219,237,168,213,214,169, 82,208, 55,174, +205, 63,254,209, 47,237,183,219, 93,235,115,127,241, 50,254,219,125,180, 27,249, 82,113,160, 36,122,220,207,252, 76,191,182,223, +109,119,173,205,255, 0,196, 75,251,109,246,208, 86, 54,111,149, 73,183, 59, 10, 39,167,113,243, 89,125,164,143,226,161, 71,122, +204,223,252, 76,191,182,223,109, 47,172,204,255, 0,196, 75,251,109,246,210, 8,163, 28,216,183,157,135,241,154,112, 69, 81,112, +156,127,148,105, 66, 85, 29,235, 51,127,241, 18,254,219,125,180,245,159,112, 99, 97, 52,191, 75,176,254, 19, 72, 11, 95,225, 54, +229,125, 34,212,225, 30,175, 18,124,239, 65, 81,226,108,176,108,249,110, 60,192,118, 39,248,104,131, 38, 64, 1,235,206,231,159, +206, 64, 63,195, 65, 17,252, 69, 72,246,222,140, 34,186,240,229,200,251,104, 7,122,236,149, 33, 81,216, 92,254,147, 51,127, 88, +210, 54, 70, 91, 30, 51, 72, 61,204, 64,225,238,174,110,130, 47,198,203,123,249,211, 37,202,198, 69, 80, 9, 32, 15, 1,206,132, + 28, 50, 50, 72,184,158, 78, 95,172,220,254,186,119, 91, 50,246,234,201,110, 23, 58,155,237,168, 79,185,160,225, 28, 95, 73, 52, +207, 95, 49,227, 97,111, 42,165, 44,203,229, 90,226,121, 7,244,207,219, 72,114,164,140,141, 89, 45,244,185, 63,199, 84,178, 77, + 51,219, 83,147,127,109, 36, 80,179,184, 30,116, 20, 46,206,112,177,182, 76,135,197,136, 44,108, 63,138,152,219,178,168,225, 52, +140,109,107,220,143,227,170,239, 78,121,120,248,208,229,132,139, 0, 57,208, 23, 31,120, 47, 71,171,169,245,116, 53,107,185,189, +186,250, 57,243,174,168, 90, 63,194,219,255, 0,221,109,255, 0,245, 85,213, 6,165,111,122,246,183,249,183,108,199,219,189, 89, +195,233, 52, 83,245, 4,125, 75,218, 34,154,109,169, 63, 91,206,151,181,251, 27, 97,237,116, 73,112,177,196,155,135, 77, 82,108, +233, 53, 52,140, 64,179,148, 14,205,211, 12,120,144,181,162,110, 38, 63,230, 71,253, 69,162,142, 21, 72, 6, 69, 32,142, 62, 20, +195,115,225,123, 81, 38, 35, 80,247, 80,195, 80,130,130,121, 82, 43, 53,205,249, 82,130, 43,141,185, 94,128,112, 53,196,210,112, + 3,141,117,197, 0,161,131, 2, 7,133, 49,173,202,150,246,240,166,144,111, 64, 65,152,106,153,128, 62,207,168, 82, 5, 23,174, + 45,119, 45,231,198,146,231,235,168, 80,151, 0,211, 11, 19, 92, 57,210,159, 10, 3,128, 53,196,112,174,213,225, 72,110, 77, 1, +204, 85, 1, 39,128, 3,141, 82,201,190,203,175,247, 49,174,129,203, 85,201, 63, 81, 21,119,160, 16,111,198,168,243,246,134,143, + 84,248,163, 82,115,104,252, 71,187,217, 95, 63,185, 60,165,110, 50,198,109, 40,213,206,159,119,135,176,247, 96, 44,103, 55, 28, +133, 87, 42, 40,215,237, 46,182,205,215, 23, 42, 49, 25,248, 38, 23, 44,135,141,255, 0,155,106,150, 36,140,220,220, 3,237,225, + 88, 85,102, 70, 12,164,171, 14, 32,142, 4, 26,190,192,222, 68,133, 97,203, 32, 61,180,172,188,129,254,119,182,184, 97,119, 72, +220,165,188,134,163, 46, 10, 92, 35, 47, 62,140,237,153,219, 92, 43,114,197,101, 30,113,231, 31, 46,168,186, 70,184, 26, 92, 0, + 77,207, 31, 15,101, 25, 91,143, 51,202,130, 35,213, 97,192,139,124, 38,154, 20, 88, 30, 2,198,220, 56,112, 62,234,250,199,203, + 15,240,147,192,241, 60,105, 36,253, 31, 2, 15, 31,162,185, 99, 28,195, 21, 83,196,241,189,190,138, 99, 33,189,217,201,246,144, + 60,104, 7, 49, 7,143, 42, 66, 1,185, 28,169,132, 75,126, 96,253, 20,229,224, 46,220,207, 58,168, 2,153, 75, 21,191, 27, 27, + 90,163,201, 32,115,167,244, 20,241, 62,102,151, 34,109,108, 85,121, 14, 23,160, 51, 1,109, 34,168, 30,250,143,202, 41, 7, 17, + 98,222,250, 64,206,203,107, 87, 44, 71,153, 63, 85, 0,154,213, 77,148,123,233, 88, 51,252,162,194,156, 20, 47, 31,225,165,214, +164,216,113, 52, 3, 58, 55, 23, 38,244, 68, 54,250, 41,154,158,252,120, 10, 70, 11,243, 31,170,128, 61,238, 41, 7, 62, 60, 40, + 87, 37,120, 2, 13, 42,181,151,143, 58, 1,236,234, 27, 72,226, 79, 51, 67, 36,131, 97,240,138,226, 73, 62, 85,193, 25,185, 2, +105, 82,208, 70, 33,188, 47, 75,198,138,176, 49,249,153, 87,222,126,203,211,214, 24,133,181, 51, 53,252, 20, 91,242,154,128,143, + 93,196,240, 28,106, 72, 69, 31, 42, 3,111, 22, 55,251, 5, 40, 12,120, 41,183,137, 0, 90,130,160, 4, 82, 31, 11,123,248,127, + 13, 57, 97, 95,210,112, 61,220, 77, 24, 37,252, 56,222,196,154, 32,136, 0,111,194,213, 69, 64,164,113, 15,209,102, 62,211, 96, +127,142,136, 44,132,104,141, 86,198,230,227, 81, 31, 75, 94,156, 12, 42, 6,183, 23,246,154,107,102, 98,198, 44, 46,199,194,194, +160, 28,194, 70,248,152,146,180,206,159,144,231,202,244,211,184, 6, 0, 36,124, 7,153,168,242,230,206,120, 11, 47,184, 85, 33, + 52, 66, 72,227,244,215, 63, 73, 5,221,199,182,230,171,195,205, 32,185, 98,126,154, 99, 70,197,172,124, 40, 90, 19,198, 70, 58, + 3, 99,127,112,166, 62,224, 22,193, 35,250,232, 49, 67,240,106,165,146, 13, 54,111, 14, 84, 2,122,201,218,228, 89,125,212, 57, + 37,157,254,103, 39,233,167,132, 8,183, 62, 60,106, 68, 81, 44,224, 42,216,120,147, 80,213, 52, 33, 36,108, 88,123,106, 79,166, + 63, 95, 26,146, 97, 24,247,103, 32,240,225,106,140, 50,174,252,184,114, 21, 76,145,204,118,225,110, 52,113, 30,149, 0,212,129, +166,250,200,248,143, 16,106, 36,197,153,202,142, 66,161,165,166,161,132, 29, 75, 21,240,169, 9, 11, 64,110,220, 27,192,123, 40, + 56,108, 65,210,222, 21, 42,118, 38, 54, 96, 44,104, 70,234,234, 71,121,225, 67,164, 53,143,178,154,230, 55, 0, 6,189,255, 0, + 74,162,178, 0, 47,226,105,208,130, 47,229, 70, 35,199, 82,195,165,254, 23,230, 22,244,214,241,255, 0,196,222,186,159, 97,233, +180,248,122,127,254, 98,186,161,189, 62, 36,145,243, 71,127, 8,227,254,162,209, 46, 41, 17,111,164,255, 0,187,143,250,139, 79, + 49, 3,225, 90, 57, 17,230,182,161,238,160, 26,145, 52, 87,111,162,130, 98, 54,161, 6,131, 75,171,198,144,194, 71,137,167, 8, +184,115,160, 18,254, 55,174,213,227, 74, 33, 35,198,184,163, 91,133, 0,151, 52,174,196, 35, 16,120,128, 72,250,169, 44,195,194, +133, 53,250,100,121,218,212, 4,113,192, 82, 18, 47,238,174,211,231, 74, 5, 66,137,198,160, 79,187,226, 68,250, 6,169, 72,230, + 86,214,250,205, 79,149,117,163, 32, 54, 44, 10,131,229,113, 89,151,219,179, 35, 98,166, 34,109,226,188, 69,124,254,225,145,147, +105, 65, 99,193,189,213,172,146,221, 79, 3,221,131, 99, 30,235,151,175, 58, 82,148,141,118,215,196,179, 27,238, 56,254,233,255, + 0, 37, 47,223,184,255, 0,236,159,242, 85, 79,160,204,255, 0, 96,255, 0, 85,113,193,203, 0,147, 11, 0, 56,146, 71, 42,249, +159,239,247, 31,233,127,245,255, 0, 35,232,127,165,129,253, 75,247,255, 0, 50,223,239,232, 45,253,147,254, 74, 65,191,194, 63, +186,127,201, 84, 53,213,207,255, 0, 91, 47,250,151,237, 71, 79,252,204, 95,233,127,185,147, 51,103,196,200, 61, 72, 34,104,164, +253, 46, 90, 79,183,223, 80,234, 70, 62, 14,102, 87,253,219, 30, 73, 71,154, 41, 35,235, 20,119,217,119,104,215, 83,225, 76, 7, +152, 66,127,130,188,179, 87,110,183,119,211,122,234,220, 99, 72,252, 15, 76, 29,171, 73, 91,222,180,224,165, 42,191,136, 93,183, +121,151, 12,136,166,188,144,114, 31,172,190,234,209, 69,149, 4,202,146, 70,225,144,241,189, 98,153, 89, 73, 86, 5, 88,112, 32, +240, 34,164, 97,103, 79,131, 38,184,141,212,252,209,159,148,215,183, 11,185,206,205, 45,222,172,161,194,191,170, 63, 52,120,243, + 59,116, 46,214,229,170, 70,124,105,250,101,252,205,173,227, 63, 43, 94,244,209,107,241, 62,225,225, 64,194,204,198,220, 98,234, + 70, 62, 49,243,198,109,117, 52,116,138, 38,213,240,218,191, 67, 9,198,113, 83,131, 82,139,213, 52,124, 41,194, 80,147,132,211, +139, 92, 83, 22,196,113, 6,161,207, 41,227, 26,159,231, 26,172,220, 59,183,183,182,173,209,182,172,249,228,199,153, 2,182,182, + 86, 49,217,198,161,197,117,126, 81, 82, 49,243, 48,243,213,167,193,200, 76,136, 75, 16, 36,141,131, 14, 30, 28, 60,107,175,167, + 52,148,156, 90, 79, 84,233,161,202, 55, 33, 38,227, 25, 38,215, 21, 93, 87,176, 32, 85, 60, 15, 26,119, 77, 23,141, 45,136,227, +192, 10, 99, 16,199,216, 57, 84, 54, 43, 58,168,243,174, 44,197,126, 30, 30,116, 25,166,138, 4, 51, 78,235, 20,107,243, 72,228, + 42,139,240,230,106, 60,123,174,219, 43,136,161,205,130, 73, 28,217, 81,101, 70, 36,249, 0, 13,234,164,222,169, 50, 54,147,163, +105, 18,197,185, 51, 92,215,113, 6,202,182, 30, 38,144, 15, 17,206,138,139,170,197,135,184, 84, 40,198, 1,173,196,251,133, 61, + 99,148,139, 4,183,191,243,209,213, 91,144,225,106,126,131,192,147,106, 2, 55, 68,254,147, 15,225,165, 17,160,246,209, 92,196, +183, 37,133,169,157,120, 71, 43,181, 1,193, 64, 54, 3,221, 68, 8, 72,254, 26,143,234,238,223, 10,211,100,201,159,146,157, 62, +234, 2,100,113,240,191, 46, 31, 69, 47,238, 87, 78,167, 23,247,213,113, 50,176, 55, 98,105,209, 66, 73,227,202,161, 89, 45,242, +177,148,158,108,124, 0, 31,109, 48,230,142,104,156,124, 47, 64,146, 27, 17, 97,123,242,166, 79, 54, 46, 20, 70,108,201,146, 24, +147,230,146, 70, 10,163,195,153,171,224,130,230,222,137,117, 9,234,242, 36, 54, 6,195,216, 41, 37, 51, 17,118, 98,106,159, 15, +187,187,126,125,198, 29,179, 19, 32,228, 79, 49, 42,173, 26, 29, 0,128, 88,221,219, 79,128,240,171,230,116,144, 16, 13, 89,198, + 81,166,248,184,213, 87, 93, 12,194,112,157,118, 73, 74,142,154, 58,145, 17, 9, 38,158,208,144, 69,233,239,104,192,211,196,209, + 35,112,226,236,183,227, 89, 54,232,180, 27, 28, 74,169,199,196,240,174,150, 50, 91,128,191, 10,108,206,236,214, 6,192,113,181, + 57, 28,244,248,243,189, 24,138,171, 58,226, 37,210,121,209,149, 17,198,162,109,238,168,204,165,156,147,225, 70,140,232, 65,194, +129,190, 67, 37,145,144,133, 94, 67,151,186,137, 20,140,235,115,225,194,212,217,149,175,123,115,229, 75, 26, 50,139, 91,223, 70, + 88,245, 99, 39, 5,136, 3,128, 52,236,123,161, 97,236,254, 58, 56,135,169,236, 35,145, 52, 97, 10, 34,128, 88, 22,183, 26, 34, + 73,213,129,158,230, 50, 7, 30, 21, 12, 38,162, 0,171, 5, 88,199, 6,107,147,194,154, 68, 41,193, 23,159,141, 8, 5,143,232, +223,143, 42,227,142,230,238,162,224,249, 81,124,120, 47, 30,116,161,229,177,177,183,231,160,108, 72,211,164,166,252, 88,211,195, +134, 91, 16, 61,198,153,165,175,241, 27, 92,218,245,221, 48,199, 77,239,115,206,173, 9, 80, 77,140, 9, 31,188, 91,120,220,242, +162,136, 35, 84, 0, 74,183,241, 60,120,215, 24,208,112,185,215,201,135,135,178,158, 32, 93, 34,228,112,226,106, 22,161,244,175, +167,183, 80,127,221,237,123, 30, 93,126,117,213,214, 30,158,250, 13,189, 61,191,247,255, 0,232,107,168, 42, 78,140, 0,136,124, +210, 63,234, 45, 57,136,166, 14, 8,151,255, 0,102,159,213, 20,160,130, 47, 84,200, 25, 73, 7,232,161,222,244,185, 13,241,143, + 14, 20, 43,218,128, 39, 10, 80, 64,160,134, 7,198,159,122, 1,218,129,246, 87, 83, 41, 65, 2,128, 95, 27,145, 81,242,152,104, + 10, 60,239,245, 81,153,170, 30, 73, 37,213,124, 45, 70, 16, 32, 77,172, 43,133,207, 26, 81,192, 82,130, 0,168, 81, 45,227, 73, +107,181, 45,205,170, 22,102,124, 88, 99, 77,245,204,121, 32,240,254,117,115,187,118, 22,160,231,114, 74, 49, 92,217,187,118,231, +114, 74, 22,226,228,223, 36, 74,155, 34, 28, 88,245,202,214, 30, 3,196,251, 0,172,246,110,227, 46, 89, 42, 62, 8,175,193, 7, +143,243,170, 60,249, 18,228,191, 82, 86,185,240, 30, 0,123, 40, 85,249,220,222,229, 59,245,133,186,194,223, 78,114,254,239,145, +247,176,251,124, 44,210,115,164,231,240,143,151,204,234,218,236, 61,169, 18,198,153,155,162,107,145,172,201,142,126, 85, 30, 26, +252,207,178,168,251, 95, 9, 51,119,120,132,130,241,194, 12,204, 60,244,219, 79,253, 34, 43, 67,248,129,220, 82,246,215,109,100, +102,226,144, 50,230,101,199,197, 99,250, 47, 37,254, 63,232,170,146, 61,181,234,236,216, 17,188,253, 89,165, 47,171,108, 34,248, + 87,156,153,230,238,217,206,204, 93,184,183, 26, 71,116,218,227, 78,136,126,251,222,253,177,218,228, 99,102,228,143, 80,163,134, + 38, 58,235,117, 31,202, 85,224,191,210, 34,168,113,255, 0, 25,123, 74,105, 52, 75, 30, 94, 58,223,251, 73, 34, 82,191, 79, 77, +221,191, 37,120, 44,178,201, 52,143, 52,206,210, 75, 33, 44,238,196,150,102, 60, 73, 36,243, 38,153, 95,179,143,111,180,163, 73, + 54,223, 85,167,185, 31,142,159,114,188,229, 88,168,165,209,235,239,103,212,253, 45,135,186,176,134, 86, 52,145,229, 68,252, 35, +202,132,141, 74,124,175,204, 17,250,173, 88, 93,223,105,159,104,202, 48, 75,241, 35,124, 81, 74, 57, 50,253,163,198,188,247,240, +255, 0,185,242,187,115,127,198,180,135,208,230, 72,144,102, 66, 79,194, 85,206,145, 37,191, 89, 9,189,254,138,247,190,233,194, + 92,189,162, 87,183,239, 49,255, 0,122,135,221,243, 15,217,175,207,247,190,213, 5, 25, 78, 43,234, 73,201, 73,104,228,151, 24, +200,253, 7,102,238,146,147,140, 37,246,182,163, 40,241, 81,111,132,162,121,246, 30, 84,152,115,172,241,158, 95, 50,248, 48,241, + 6,182,152,217, 49,203, 18,204,172, 52,201,241, 2,120, 86, 18,180,189,187, 59, 62, 60,144, 31,238,152, 50,251,155,243,138,248, +253,159, 33,198,235,176,223,211, 52,218,240,146,249,163,234,247, 91, 10, 86,213,228,190,168, 52,159,140, 95,201,158, 85,248,148, + 65,238,188,130,164, 17,210,135,136,254, 96,173, 47,225,246,102, 38, 15,109,205, 62, 92,201, 4,107,146,247,121, 24, 40,249, 19, +196,214,107,241, 40, 91,186,242, 7,251,168,127,168, 42,143,106,218,247, 61,242, 65,131,132, 11,164,119,118,212,214,142, 61, 86, + 5,143,190,222,250,253,207,167, 27,152,150,227, 41,109, 74, 49,109,248, 36,126, 33, 93,149,188,203,146,140,119,201,202, 73, 47, + 22,207, 87,147,189,251, 96,191, 76,238, 3,218, 68,114, 21,250,194, 90,172,240,119, 45,187,115, 66,248, 25, 17,228, 5,230, 17, +129, 35,222, 57,138,243,137,127, 13,119,133,128,201, 14, 68, 19, 72, 5,250, 64,178,147,236, 5,133,190,186,202,164,153,251, 62, +105, 40,207,139,153,142,196, 27,124, 44,172, 57,131, 92, 86, 37,139,137,250, 55, 91,107,175,240,143, 67,205,200,180,215,175,105, + 36,250,105,243, 61,103,189,129, 29,179,159,171,202, 62, 31,243, 82,188,207,181,127,245, 22,221,111,246,195,248,235,107,184,111, + 75,191,118, 30, 94, 99, 0,185, 41,211,139, 37, 71, 32,226, 72,248,129,228,192,222,177,125,168, 47,220, 91,112,255, 0,124, 63, +128,215, 76,104,184,227,222,140,180,105,201, 63,218,115,202,156,103,147, 98,113,117, 82, 80,107,247, 30,217,117, 85, 44,238, 21, + 84, 93,137, 32, 0, 7,153, 53, 71,153,223,157,185,131, 33,140,100,245,220,112, 61, 21, 46, 7,244,190, 95,203, 88,174,252,238, + 25,242,115,164,217,177,156,166, 38, 49,211, 56, 6,221, 73, 7, 61, 94,197,229,111, 58,139,218,189,156,219,252, 79,153,147, 49, +199,195, 70,233,169, 81,119,118, 2,231, 77,248, 0, 47,206,184, 67, 18,220,109,171,183,228,226,158,169, 47, 30, 7,123,153,151, + 37,117,217,199,138,147, 90, 54,252, 56,155,104,255, 0, 17,182, 41,159, 73,154, 72, 65,225,169,227, 54,255, 0,163,170,175,113, +179,161,220, 99, 19,225,228, 44,241, 31,211,141,131, 11,249, 27, 86, 31,119,252, 54,134, 28, 87,159,106,201,145,230, 64, 88, 65, + 54,147,174,194,246, 86, 80,182, 62, 92, 43, 31,176,239,153,123, 14,122,101,192,196,199,112, 50, 33,191,194,233,226, 8,243,242, + 62, 21, 86, 45,155,176,114,199,147,170,229, 32,242,239,217,154,134, 76, 21, 37,250,162,123,139,199,101,164, 10,136,132,185, 0, + 0, 73, 39,128, 0, 87,155,254, 33,231,200,242,109,147, 99, 76,235, 28,208,188,138, 81,138,220, 49, 82, 15, 15,101,101,246,230, +222,247, 73, 14,211,133, 44,178,156,162, 58,145,151, 54, 33, 46,110,228,158, 10, 47,198,177,111, 9,206,218,184,230,162,159, 26, +174, 20,122,155,185,158,161,117,218, 86,220,154,225, 71,198,171, 77, 15, 83,200,239, 78,217,193,148,196,249,130, 87, 28, 15, 69, + 90, 64, 63,164,163, 79,229,169,123,119,115,108, 27,195,136,240,179, 20,204,121, 67, 32, 49,185,254,104,112, 47,244, 86, 21,191, + 12,119, 85,135, 95,172,128,203,111,236,236,246,191,150,171,127, 21, 99, 39,131, 35, 7, 38, 76,121,129,139, 34, 7, 42,195,197, + 89, 79,129, 21,214, 24,152,215, 19, 86,238, 55, 37,252,112, 56,207, 55, 42,211, 82,187,105, 40,190, 95,206,167,208,144, 58,153, + 52,176,186, 26, 22,233,184,224,237,177,135,200,158, 60,100,111, 25, 24, 2,125,215,231, 89,156, 14,229, 56,253,149, 30,255, 0, +148, 58,153, 17,131, 2,131,253,228,193,138, 45,253,224,106, 53,229,185,185,219,134,245,156,114, 50,157,242, 50,167, 96,170, 57, +241, 38,202,136,190, 3,200, 10,227, 99, 10, 83,148,183, 61,177,131,113,111,171, 93, 14,249, 25,241,132, 97,177,110,148,210,146, + 93, 19,234,122,250,119,223,108, 2, 17,179,198,174, 87,233,201,111,175, 69,170,175,188,179,112,247, 30,214,202,200,194,157, 50, + 35,215, 16,213, 27, 6,183,239, 23,129,183, 42,206,226,126, 25,111,115,192, 37,200,158, 12,103, 97,126,147, 22,102, 31,206,208, + 8,252,181, 67,188,236,123,191,110, 72,113,179, 56, 67,144, 44, 36,137,137,138, 80,166,254,206, 71,141,136,174,246,241,241,253, + 72,250, 87,107, 40,180,232,245,173, 58, 30,123,185, 89, 94,148,149,219, 52,140,162,213, 86,148,175, 94, 33,187, 55,255, 0, 83, +109,255, 0,207,111,250,182,175,104, 5, 34, 87,154, 70, 9, 26,139,179,177,178,128, 60,201,175, 24,236,175,253, 83,182,240,191, +198,220, 63,229,181, 89,247,239,114, 79,184,110, 50,237, 56,237,211,192,195,109, 12,138,109,212,149,126,102,127, 61, 39,128, 21, +114,172, 74,246, 68, 98,157, 18,133, 91,240,171, 51,137,145, 27, 24,211,155, 85,110,116, 75,171,162, 54,121,189,243,219,120,178, + 20,245, 70,118, 23,191, 69, 11,143,218,224,167,232, 52,204, 95,196, 30,217,145,130, 60,210, 67,168,252,210, 70,108, 47,252,205, + 85,143,237, 30,197,110,225,199,109,195, 50,115,141,134, 24,164,122, 0, 47, 33, 95,152,130,220, 0,191, 10,183,223,127, 12, 98, +197,194,151, 47,104,201,146, 73, 33, 82,231, 30, 96,164,184, 2,228, 43, 32, 94, 62, 92, 43,155,179,135, 25,122,114,156,183,112, +111,149,125,199, 85,127, 58,113,245, 99, 8,109,226,151, 54,189,230,251, 30, 92, 93,194, 37,202,194,158, 57,225,110, 79, 27, 6, + 23,250, 42, 65,137, 71, 13, 92, 43,194,123,107,184, 50,123,127,113,143, 37, 9,108,102, 33,114,160,191, 7, 79, 30, 31,172, 60, + 13,105,255, 0, 19, 50,165, 77,203, 2, 76, 89,157, 34,151, 20, 58,148, 98,161,129,118,179,112,246, 86, 37,130,213,232,219,221, +164,147,106, 84,233,200,220, 59,130,118,101,115,111,213, 22,147,141,122,243, 76,244,204,140,156, 60, 76,118,159, 37,214, 40, 99, + 23,121, 92,133, 0,123, 73,170, 60, 30,243,216,119, 77,197, 54,204, 23,121, 38,144,183, 77,180, 16,135, 66,151, 60, 90,199,146, +249, 87,144,225, 38,243,189, 74,155, 78, 35,203,146,211, 48,113, 9,114, 86,234, 15,198,218,141,128, 0,243, 53,232, 61,177,248, +127,184,236,155,190, 46,233,155,151,142, 86, 16,250,225,140,179, 55,199, 27, 71,192,233, 3,129,106,212,241,108,218,132,189, 75, +149,149, 27,138, 90,121, 25,183,153,122,244,227,233,219,164, 42,148,219,215,207, 93, 13,246,169, 47,195,253, 45, 78, 10,231,199, +203,242,210,172,152,235,195,169,123,115,176,189,119,168,199, 67,193, 89,191, 37,120, 79,160,118,146,110, 53,124, 67,194,148, 71, +195,226,230,108, 1,166,122,160, 9,211, 24,250, 77,119,172,155,146,133, 81,238,168, 80,194, 19,112,192, 92,243, 2,138, 96, 32, + 95, 73,185, 28,252, 42, 17,202,200, 63,222, 16, 60,135, 10, 12,146, 74,192,146,228,253, 52, 33, 98, 98,107,124,108,160,112, 23, +184,228, 41,191,225,212,234,105, 65,183,128,170,208,220, 56,243,225, 69, 3,133, 1, 48,207,138, 7, 18, 92,251,168, 71, 46, 4, + 31, 12, 68,219,204,212,103,176, 7,217, 66, 45,171,242, 85,168, 39, 12,212, 22,211, 0, 30,246, 38,148,230,177, 55, 17, 32, 39, +199,137,254, 58,130, 88,131,192, 94,226,194,158,167,128,191, 63, 26,128,181,245, 50,122,123,233, 95,236, 53, 90,220, 47,234, 52, +249,215, 80,111,254, 27,255, 0,225,191,249,154,234, 2,208,142, 9,252,196,254,168,174,174, 39,228,254, 98,127, 84, 87, 94,169, + 8,249, 31, 48,191,149, 0,139,240,163, 78,223, 24, 30,202, 24,189,248, 10, 1,129, 85, 73,243, 52,237, 39,192,211,133,169, 45, +198,128, 64, 13,136, 52,154, 8, 55,191, 63, 10, 40, 23,165, 34,128, 23, 31, 26,133, 48,213, 43, 17,203,236, 21, 61,133,170,184, +184, 44, 91,207,141,168,202,133, 10, 57, 26,113, 0,123, 0,166,134,170, 13,215, 62, 73, 37,124,100, 58, 99, 67,165,173,250, 68, +115,189,121,114,242,161,141,111,124,149, 91,116,138, 92,217,232,198,198,158, 69,205,145,209, 45, 91,124,145, 35, 63,119, 11,120, +177, 13,207, 35, 47,128,254,109, 82,146, 88,150, 99,114,120,146,121,210, 85,142,223,181, 73,148, 68,178,221, 33,240,243,111,117, +126,118,119, 50,115,175, 37,247, 62, 81, 95,108, 87,241,204,251,209,134, 62, 29,166,248, 46,114,127,116,153, 27, 27, 14, 92,173, + 69, 5,163, 64, 75, 57,228, 45, 81,235,100,176,199, 28,125, 20, 80,169,107, 0, 61,181,144,150, 51, 20,143, 27,115, 66, 84,253, + 21,211, 59, 5, 99, 66,214,187,156,171,185,242,174,148, 72,231,135,152,242, 39,119, 77,170, 52,218,185,211, 90,182,104,123, 42, + 85, 77,214, 72,207, 57, 33, 96,190,240, 85,191,128, 83,191, 23, 54,201,247, 14,210,105,160, 82,237,131, 58,100,186,142,125, 48, + 26, 55, 63, 70,187,213, 6, 30, 84,184, 57, 81,101,195,243,196,193,135,183,204, 31,120,175, 79,193,206,196,221,176,196,209, 89, +227,144,105,150, 38,177,177, 35,226, 71, 21,244,251, 22, 84, 99, 31, 79,245, 91,150,228,186,197,159, 59,189, 98,185,183, 47,211, +114, 59, 91,233, 36,124,151, 93, 94,209,220,191,131, 81,100,206,249,125,183,146,152,193,201, 99,133,145,126,154,147,254,205,212, + 49, 3,216, 65,247,214,119, 31,240,103,186,100,148, 46, 68,216,144, 71,227, 39, 81,156,219,216,170,149,251, 8,229,216,148,107, +189, 47, 7,196,252,124,176,178, 35, 45,187, 27,241, 92, 12,111,110,109,147,239, 27,238, 6,221,142,165,154,105,144, 49, 31,162, +128,234,119, 63,205, 80, 77,125, 57,190,202,176,236,249,174,230,192,196,200, 61,238, 52, 15,202,106,151,179,251, 19,106,237, 8, +218, 72, 9,201,207,149,116,205,153, 32, 0,233,231,162, 53,227,165,106, 15,119,111,113,229, 48,219,113, 91, 84,113,182,169,220, +114, 44, 57, 40,247,120,215,196,239, 57,246,213,169, 52,244,218,227, 10,241,148,164,125,222,205,129,113, 77, 39,197,201, 74,116, +225, 24,196,202,213,215,110,179, 9,167, 0, 18, 10,139,129,239,170, 90,209,246,228, 5, 97,150,114, 63,180, 96,171,238, 95,206, +107,242,157,178, 46, 89,118,233,250,106,223,149, 15,211,119, 25, 40,226,220,175, 58, 37,231, 83,202,255, 0, 18, 13,251,171, 32, +216,143,221, 67,207,249,130,180,159,134,139, 8,218, 50, 74,139,204,217, 4, 72,124,116,132, 93, 63,194,107, 57,248,147,199,186, +242, 63,225,197,253, 65, 85, 27, 22,255, 0,159,219,243,180,248,160, 52, 83, 13, 50,194,247,210,250,125,222, 34,252,235,250, 19, +181, 43,152,112,132,120,237,139,243,161,248, 24,221,141,172,217,206, 75, 77,210, 79,194,188,207,110, 4,163,127, 36,215,147,254, + 34,172, 35,184,201,138,218,218, 8,204,214,253,126, 35,250,160, 85,140,223,137,147, 52, 86,135,111, 85,150,223, 51,200, 89, 65, +254,104, 85, 39,235,172,100,211,102,238,249,205, 44,154,178, 50,242, 95,146,139,150, 99,192, 42,129,249, 43,158, 30, 53,203,115, +115,184,182,170, 53,196,235,155,149,106,237,181,110,219,220,219, 79,135,204,187,217,139,255, 0,149, 59,136,127,118, 61, 45,191, +157,212,227, 80,251, 79,255, 0, 82,109,191,241,135,241,214,199, 47, 98, 59, 15, 96,102,193, 53,189, 84,221, 57,178,109,224,198, + 68, 1, 63,162, 63, 45, 99,123, 79,255, 0, 82,109,191,241,135,240, 26,237, 25,169,219,200,148,120, 55, 47,132, 82, 56, 78, 18, +133,204,104, 75,138, 81,175,182,109,145, 55,157,127,123,238, 29, 79,159,212,205,170,254,122,218,167,109,155, 47,115,230, 98, 44, +251, 92, 83, 54, 43, 22, 10, 99,148, 42,220, 27, 55, 13, 98,174,187,251,183, 39,197,206,147,121,198, 66,248,153, 39, 84,228, 11, +244,228,228,117,123, 27,157,252,234, 31,106,119,156,221,186,143,137, 44, 62,163, 14, 70,215,164, 29, 46,140, 69,137, 91,240, 32, +219,149,107,212,148,236, 70,118, 84,100,232,180,127, 21,230,101,219,140, 50, 37, 11,238, 80, 85,127, 82,248, 63, 33, 7,108,247, +209,254,227, 36,255, 0,207, 31,252, 74,140,123, 35,186,185,157,185,255, 0,110, 63,245,235, 71,187,254, 38, 52,248,146, 99,237, + 56,207, 4,178,130,167, 34, 86, 23, 64,120, 93, 21, 47,199,200,222,164,246, 47,116,239,187,150, 74,237,185, 80,156,216, 20,124, +121,164,233,104,135,129,145,185, 55,240,215, 47, 83, 42, 54,221,199, 11,113,167, 21,193,211,222,117,244,177, 37,113, 91, 87, 46, + 74,188, 26,213, 87,220, 80,119,134, 54, 78, 30,223,176, 99,230, 41, 76,136,241, 89, 36, 66, 65, 32,171, 40, 3,133,252, 42,211, +240,178, 36,108,173,202, 82, 46,235, 28,106,167,200, 49, 98,127,170, 41,223,138,193, 70, 94,219, 99,127,221, 73,253,101,167,126, + 21, 50, 44,187,161,111,213,134,223, 92,149,153, 74,184, 46, 92, 43,175,190,102,163, 20,187,130,143, 26,105,175,132, 15, 72, 28, +173,107,215,137,247,202,132,238,157,192, 1,111,137, 9,247,152,210,245,237,162,120,193,176, 91,249,215,138,119,209, 13,221, 89, +228, 11, 11,199,195,254, 82, 87, 14,221,254,105,127, 99,252, 81,232,238,127,225,143,247,175,193,135,204, 50,255, 0,144,118,208, + 9,233, 28,233,110, 60, 47,165,173,252,116, 62,193,138, 9,123,167, 9,103,181,135, 81,163,191,235,136,216,173,105,118, 45,168, +239,189,130,118,208, 66,201,214,146, 88, 24,248, 72,173,194,231,200,242,175, 62, 43,157,180,103, 13, 65,241,115,113, 92, 48,191, + 6, 86, 83,112,107,217, 6,167, 27,246,147,164,183, 77,126,238,103,134,226,118,229, 98,243, 85,142,216, 63,219,200,250, 47,162, +223,171,107,120,154,200,126, 36,197, 15,249, 97,218,109, 61, 85,154, 35, 15, 17,125, 68,216,219,250, 55,172,206, 55,226,134, 82, +194, 23, 51, 4, 77, 40, 31,218, 36,133, 1, 62,101, 74,191,240,214,115,184,123,155,112,238, 55, 83, 58,136,177,161,248,163,130, + 59,144, 9,225,169,137,230,124, 43,201, 99, 14,244,110,198, 82, 91, 84, 93,107, 94, 52, 61,153, 25,182, 37,102, 81,131,114,114, + 84,165, 56, 87,168,254,201, 32,119, 78,218, 88,216,107,107,159,249,111, 84,249,250,189,118, 78,191,159,171, 38,171,243,190,163, +122,181,236,239,253, 75,183,255, 0, 61,191,168,213,103,223, 61,187,145,131,159, 46,235, 4,101,176,178,219, 91,149, 31,217,200, +223, 48,111, 99, 30, 32,215,185,220,140,114,118,189, 55, 65, 83,205, 55,161,224, 86,229, 44, 93,235, 85, 11,142,190, 77, 45, 74, +221,187,102,238,172,172, 56,231,219, 82,115,136,247,233,152,229, 10,188, 9, 6,203,172,120,138,149,254, 95,239,115,113,211,201, + 62,127,191, 31,252, 74,119,108,119,156,219, 12, 39, 10,120,142, 70, 33, 98,200, 20,217,208,159,155, 77,248, 16,124,170,199,120, +252, 69,124,156, 87,198,218,160,124,118,148, 21,108,135, 97,169, 65,253, 64,190, 62,219,215, 57,203, 39,212,113,141,184, 56,215, + 73, 62,158, 58,157, 97, 28, 95, 73, 74, 87,110, 41, 37,172, 87, 95, 13, 10, 63,242, 95,115,159,255, 0,183,191,237,199,254,189, + 77,239,100,202,137, 54, 56, 51, 65, 92,136,118,248,227,145, 73,185, 5, 9, 91, 92, 95,202,180, 61,145,220,219,246,233, 55,161, +201,128,229,195, 24,248,243, 71,194,201,228, 28,242,107,253,117, 85,248,155,168,238,152, 69,133,191,195,155,126,219, 86, 99,118, +235,201,141,187,138, 63, 74,111,233,242, 53, 43, 86,150, 44,174,218,115,250,154, 77, 75,193,147,127, 11,113,227, 45,184,229,145, +251,213, 17,196,173,228,173,169,155,235, 42, 43,208,156,216,243,247, 86, 11,240,177, 25,224,220,244,219,131,197,123,251,158,189, + 4,227, 31,210,113,244, 10,240,230,255, 0,244, 79,217,248, 30,252, 26, 44,104,123,127, 22, 9, 56,113,243, 52,107, 94,152,137, +224, 56,212,133,140,154,243, 30,160, 90,107,136,181, 25, 97,210, 52,253, 52,173, 21,193, 0,208,128,116,130,183, 20,199, 22, 6, +164,170, 5, 91, 95,149, 2, 77, 36,112, 60, 77,239, 66,130, 88,101, 98, 8, 67,244,209, 22, 41, 91,200,125, 52, 68,144, 40, 3, +199,128, 3,223, 72,174, 19,226, 35,133,248,208, 28, 49, 93,175,119, 3,232,174, 24,163,197,207,208, 42, 76, 55, 40, 9,224, 77, + 59, 77, 8, 70,244,168, 57,179,255, 0,167,209, 75,233,162,243,115,244,212,146, 41, 45, 64, 19,161, 31,166,181,143,253,222,215, +191, 27,122,141, 85,212,107,127,135,246,116,127,237,171,170,128,204, 88, 20, 22,253, 4,254,168,165,212,124,169,199,244, 79,242, + 19,250,162,155,170,128,143, 63,206, 13,143, 42, 17,146,222, 6,164, 74,120,220,121, 80,109,168,241,160, 27,168,219,151,213, 72, +178, 18,120,139, 81,128,183,186,186,128,110,171, 10, 93, 64,248,210,144, 57, 26,110,144, 9,189, 0,201, 26,202, 74,155,216, 19, +245, 84, 32, 42, 84,224, 8,152,142, 7,128, 31, 93, 69,210,109,206,163, 42, 56,218,168,243,182,169,222,119,150, 11, 58,200,117, + 17,123, 16, 79, 62,117,116, 71,141,119, 32, 43,207,147,139,111, 34, 10, 23, 43,163,170,107, 70,142,248,249, 55, 44, 73,202,221, + 53, 84,105,234,138,156, 45,160, 35,117, 50,172,196,114,140,113, 31,210,171,158, 32,112, 22,183, 42, 64, 56,209,121, 10,184,248, +214,172, 71,101,168,211,171,124, 95,155, 37,252,139,151,165,186,227,175, 69,201,121, 32, 68,177,170, 77,227, 12,134,245, 72, 46, + 15, 9, 63,136,213,229, 52,133, 96, 67, 11,131,192,131, 83, 43, 30, 57, 22,165,110, 90,115, 79,164,185, 50,227, 95,149,139,170, +228,117,228,215, 85,208,199, 84,172, 29,195, 47,110,155,173,137, 41,141,185, 48,230,172, 60,152, 30, 6,164,231,109, 79, 17, 50, +227, 13,113,243, 41,226,191,104,170,202,252,189,219, 55,177,174, 82, 73,194, 75,132,151,227, 22,126,142,221,219, 89, 22,235, 26, + 74, 47,138,127,131, 70,203, 23,190, 70,144, 51,113, 78,175, 23,136,240, 63,209,111,182,164, 63,124, 96, 1,251,188,105,153,188, +155, 74,143,174,237, 88, 90,234,244, 71,186,230, 37, 77,233,248,184,170,156, 31,109,197,110,187, 26,240, 77,208,189,220,251,171, +113,207, 83, 12,118,198,133,184, 50,198,110,196,121, 23,251, 42,138,186,143,141,135, 62, 91,232,133,110, 60, 92,240, 81,239, 53, +230,157,203,249, 23, 22,231, 43,146,122, 37,199,220,143, 68, 97,102,196, 30,213, 27,113, 90,183,243, 99,113,177,228,202,153, 96, +136, 93,152,243,240, 3,196,154,216,195, 19, 99, 64,144, 69,109, 40, 44, 60,207,153,161, 96,109,241,109,241,217,126, 41, 24,124, +114, 30,103,216, 61,149, 36,158,118,241,175,208,118,236, 47,245,224,229, 63,242, 79,143,252, 87, 79,153,240,179,243, 61,121, 40, +195,236,135, 15,249, 62,165, 6,239,219,123, 62,229,149,234,243,176, 82, 76,135, 0, 52,133,158,228, 40, 0,114, 34,163, 14,214, +216,206, 25,192,108, 52,244,218,140,129, 56,240,114, 0, 44,172, 78,161,192,120, 26,189,201,118, 14,170, 5,236, 40, 7,226, 28, +253,246,175,170,174, 92,162, 91,229, 69,195, 87,161,243,189, 43,117,111,100,106,248,232,181, 50,205,248,123,219, 97,245,104,152, + 47,234,137, 13,190,218,185,218,182, 45,155,104,248,182,252, 85,137,200,177,148,221,156,143,231,189,205, 79, 30, 86,225,230,105, + 15,194,121,147,236, 21,101,122,236,149, 37, 57, 53,209,178, 70,197,168,186,198,220, 83,234,144,204,204, 76, 77,199, 29,240,242, +208, 77, 4,150,215, 25,184, 6,196, 48,229, 99,204, 85,126, 47,106,246,254, 30, 76,121, 88,184, 41, 28,209, 29, 81,184,103, 36, + 31, 62, 45, 86,102,234,117, 14, 30,116, 64,111,199,206,178,167, 52,168,164,210,124, 82,122, 26,118,225, 38,165, 40,166,215, 6, +213, 88,172,170,202, 85,192,101, 34,197, 79, 16, 65,172,222,103,101,118,222,100,140,231, 19,162,199,153,133,153, 7,236,131,167, +242, 86,146,187,161,115,123,243,227, 72,220,156, 53,132,156,124,157, 4,237,194,122, 78, 42, 94,106,166, 82, 62,193,237,184, 88, + 51, 67, 36,182,240,146, 70,183,253, 29, 53,161,194,198,197,193,132, 99,225,196,144, 68,188,145, 0, 81,249, 43, 17,220,157,225, +186,109, 27,254, 70,221, 10,196,113,161, 49, 88,178, 18,214,120,210, 70,226, 24,126,181, 2,126,234,238,205,200,190, 78,203,183, +186, 96,130, 68,110,176,153, 73, 3,205,136, 42, 79,152, 94, 85,103,114,228,254,249, 57,121,178, 66,213,184,125,144,140,124,145, +183,220,118, 93,167,118,104,223,113,198, 89,218, 32, 68,101,139, 11, 3,207,229, 34,147,111,217,182,189,167,168,118,220,101,128, +203, 97, 33, 82,198,250,111,111,152,159, 58,198,108,191,136,121, 17,229, 46, 46,253, 2, 8,153,180, 52,241,169, 71,140,222,215, +116, 60,192,241,181,143,190,175,123,223,185, 51,187,125,118,246,219, 68, 76,185, 66, 82,230, 69, 46, 44,157, 61, 58,108,195,245, +234,111,158,221,187,158,222,149,211,220, 54, 67,118,253,171,119, 90,107,239, 52,136, 9, 53, 93,153,218,251, 14,225,146,249,121, +152, 75, 46, 68,182, 47, 33, 46, 9,210, 2,142, 76, 7, 33, 93,218,251,148,219,182,205,139,159,152, 20, 79, 63, 83, 88, 65,101, +248, 36,116, 28, 46,124, 22,169,123,215,187, 55, 46,223,206,199,198,219,196, 38, 57, 97,234, 63, 81, 75, 27,234, 43,194,204, 60, +170, 70, 82,139,172, 91,139,240,116, 44,161, 25, 42, 74, 42, 75,142,170,165,134,235,153,129,217, 91, 84, 79,137,135,124,118,155, +166, 33, 71, 43,102,117,103, 45,118,213,250,148, 12, 6,217,251,227,111,124,220,221,185, 87,165, 43, 64,186,154,238, 44,170,247, + 14,154, 72,249,249, 85, 71,122,110, 15,185,118,102,213,151, 48, 29,121,166,134, 73, 52,139, 45,204, 50,222,220,234,131,183, 59, +147,117,219,182,231,218, 54,108, 79, 81,149, 52,207, 51, 62,150,146,202, 86, 52, 26, 81, 61,171,196,158, 20,221, 36,247, 38,247, +117,174,190,241,178, 46, 59, 92, 86,222,148,211,220,108,135,225,207,110,159,222, 17, 45,191, 83,168,109,246,212,252,158,220,237, +253,175,101,205, 11,132, 31, 26, 40,154,121,162, 4,134,147,162, 12,128, 25, 56,183, 53,172, 91,119,175,119,109, 51,170,110,184, +227, 73,226, 34,158, 19, 21,199, 11,232,101,211,245,241,173,167,223, 24,187,239,103,238,153,248,196,128,113, 50, 82, 72,154,218, +145,150, 38,186,155,123,239, 91,119,174,202,149,156,157, 60, 76, 43, 22, 99, 93,182,226,171,167, 4, 80,118,124,253,179,187,110, +198, 60, 29,155,209,228, 99, 68,217, 9, 49,153,159,147, 44,118,183, 15,246,149, 57,187,223, 9,247,179,176, 62,218, 91, 86, 95, +161,105, 25,193, 83,121, 58, 58,138,149,229,227,106,206,254, 22,255, 0,234, 12,159,252,155,255, 0,214,195, 83,127,205,185,255, + 0,230,239,186,189, 54, 39, 71,239, 47, 77,212,232,254,243, 79, 95,167,171, 93,254,107,120,249,214, 37, 41, 73,214, 82,109,248, +186,155,140, 35, 20,212, 98,162,186, 37, 67, 79,151,216, 29,177,150,229,253, 31, 65,143, 51, 3,178, 15,217,185, 95,201, 67,131, +240,235,181,225,112,231, 30, 73,173,225, 36,140, 71,212,186,104, 61,229,222,205,219,211, 38,223,131, 10,205,152,232, 36,119,146, +250, 17, 77,192,248, 84,130, 88,219,206,170, 34,220,255, 0, 19,242,177,215, 62, 12,101,244,238,162, 68, 1, 33, 4,169, 26,129, + 8,205,212, 55, 21,211,215,189, 74,122,146,167,155, 57,255, 0,175,102,181,244,225,238, 70,242, 28,124, 92, 24,151, 19, 18, 37, +130, 37, 31, 4,113,168, 85,246,242,172, 71,121,110,155, 22, 30,225, 6, 62,235,180,250,249,122, 10,233, 47, 84,166,149,105, 28, +105,176,254,109, 11,183,255, 0, 16,114,242,183, 24,182,221,238, 4, 70,149,250, 43, 60, 96,161, 89, 15,194, 22, 68, 98,121,183, + 15, 11, 85, 71,226, 88,182,249,139,255, 0,147, 79,250,217,171,154,148,147,220,155, 79,170,122,157, 28, 34,214,215, 20,215, 70, +180, 61, 35,182,246,237,171, 27,110,135, 51,107,196, 24,107,159, 20, 83,188, 97,153,190,100,214,160,150, 39,150,170,184, 43,122, +242,220, 94,238,238,124,141,183, 19, 11,183, 54,215,104,112,177,226,130, 92,145, 19, 76,197,227,141, 84,218,223, 0,226, 57,113, + 52,221,171,241, 39,119,198,205, 92,125,250, 53,146, 13, 90, 38, 96,157, 57, 99,227,107,216, 88,112,241, 22,163,109,186,201,182, +223, 54, 20, 84, 85, 34,146, 75,146,208,244,134, 44,132,129,194,252, 13, 23,212, 40,170,206,230,238, 61,187,183, 48,211, 39, 34, + 17, 62, 76,196,140,120, 65,177,114, 57,146,120,217, 71,137,172,102, 15,115,119,246,249,212,159,100,194,137, 96, 13,243, 44,104, + 19,135,232,135,201,107, 19,231,106,133, 61, 20,228,146,120, 41, 62,234, 30,188,167, 63, 10,181,188,173, 88, 40,255, 0, 16,123, +155, 98,206, 92, 78,229,193, 66,166,197,180,160,142, 77, 60,181,161, 82, 99, 97,254,151,173,142,255, 0,220,146, 98,118,188,219, +246,211, 34, 75,240,196,248,236,224,149, 34, 73, 17, 13,214,224,242, 99,244,208, 19, 12, 25,175,199, 67, 82,166, 30, 69,238,203, + 96, 57,220,215,158,226,254, 41,238, 67, 3, 33,178,226,142,108,246,117, 92, 72,209, 89, 80, 2, 14,167,147,226, 55,227,107, 1, + 83,251, 67,185,251,151,119,222, 91, 19,119, 26, 49,222, 23,145, 20,195,211,226,165,109,164,145,115,206,161, 77,218,196, 47,123, + 92,129,206,155, 10,134, 4, 17,227, 82, 7, 5, 63, 85, 7, 31,129, 36,120, 26, 16, 58,141, 34,150,213,195,206,148, 31, 3, 84, + 13,183, 26, 91, 87, 31, 10,225,236,160, 36,255, 0,113,255, 0, 39,254,218,186,187,251,155,255, 0,185,255, 0,182,174,160, 14, +199,130,219,245, 19,250,162,152,215,224,109, 74, 75, 89, 47,207, 66, 95,246, 69, 33,227,225, 64, 6, 91,223,151, 27, 82, 1,244, +121,210,202, 78,176, 60,133, 13, 89,174,111,202,128, 37,239,225, 92,120,120, 83, 65,243,165, 39,133, 1,220,248,154, 66,111, 92, + 24,234, 32,139, 10, 70, 54,229, 64, 70,201,112, 85, 71,182,227,232,161, 22, 0, 83,178,141,221, 87,192, 11,223,223,255, 0,225, + 65,246,212,101, 56,155,138,238, 62, 84,170, 56, 94,151,194,128, 64,220,105,197,137,224, 40, 96,243, 52,224, 64, 20, 7, 1,122, + 80,162,185, 72,165,191, 26, 1, 81, 1,112, 60, 47,196, 31, 42,110, 78,215,133,145,241, 60, 64,127, 41,120, 31,201, 68,140,141, + 96,147,107,113,162,134, 91,115,252,213,137,194, 19, 91,103, 21, 37,209,170,154,132,231, 7,186, 18,113,125, 83,161, 71, 47,111, +195,175, 76, 83, 50,223,193,148, 55,229,248,105, 71,109, 45,237,234,143,236,127,250,213,116,192,107, 94, 63, 64,162,106,191,202, +120,138,242, 62,219,134,221,125, 37,236,148,151,230,122, 87,112,203, 74,158,171,247, 69,254, 69,108, 29,189,131, 29,139,234,149, +191,148,108, 62,161, 83, 4, 9, 24, 9, 31,194,163,192, 90,194,164,107,241,231, 76, 33,124,121,215,162,213,139, 86,149, 45,194, + 49,242, 90,251,206, 23, 47, 93,184,235,114,110, 94,111, 79,112, 62,155, 51,104, 46,108, 7,178,184,196,227,244,201, 30,225, 79, + 67,241, 26,120,176, 62, 98,186,156,202,220,142, 18,148, 99,123, 91,143,209,122, 5,244,158, 28,188, 77, 27, 37,181, 76,236, 57, + 94,220,125,156, 40, 32,223,149,104, 10,108,120,243,246, 82,131,113, 99,192,211, 9,177,165,247,208, 29,192,112,231,230, 77, 16, +115,181, 4, 16, 77,135,141, 29, 71, 27,209,129, 85,110, 69, 72,181, 13, 7, 17, 70,168, 67,197, 59,239, 72,238,236,253, 87,211, +120, 53, 91,157,186, 17,242,175, 97,198,244,143,133, 1,193,210,113, 58,107,208,209,242,232,183,195,111,162,188,119,191,127,245, +102,225,255, 0, 39,254,162, 58,208,101,118, 47,115,237,236,240,236,155,155, 28, 22, 36,172, 66,105, 33, 54, 62, 14,171,240, 31, +125, 80, 82,254, 32,156, 67,220, 45,233,180,235, 16,160,201,211,254,214,237,207,219,163, 77, 77,239,133,153, 54, 46,214, 92,139, +245, 70, 51,235,191, 59,232,199,224,111,227,231, 86, 91, 15,225,180,139,146,153,123,236,201, 34, 41, 14, 49,162, 37,181,155,223, +247,142,192,112,243, 3,159,157,106,187,171,182, 98,238, 76, 20,131,169,209,200,128,151,199,146,215, 81,113,102, 86, 30, 70,128, +135,216,139, 19,246,158, 19, 6, 37,151,172,172, 1,228,122,206,108,126,131, 88,239,196,233, 49,206,247,143, 12, 45,119,135, 29, + 68,162,247,179, 51, 51, 0,125,182,177,162, 99,118, 39,121, 96,187, 69,137,154,152,209, 57, 1,222, 28,137, 17, 91,194,228, 34, +130,126,170,147,157,248, 95,185, 58,196,248,185,177, 77, 59,106,108,169,114, 11,173,216,158, 26, 2,164,132,251,201,160, 23,186, + 22, 49,248,121,177, 21, 80, 28,190, 61,219,196,254,226, 90,176,252, 46,108, 47,186,243, 21, 2,156,222,189,230,189,139,116,244, +142,159,244,111,171,233,189, 78,222,123, 83,113,220,123, 87,109,216,224,150, 5,201,195,104,154, 87,118,113, 25, 9, 27,198,116, +144,133,185,183,136,170, 24,191, 13,247,172, 76, 84,200,195,207, 72, 55, 68,102, 7,165, 36,138,133, 13,180,233,144, 42,178,183, + 63, 11, 80, 23,255, 0,136,231, 13,123,105,214,125, 61,118,150, 63, 75,127,155, 88,111,139, 79,244, 53, 86, 83,178,122,223,229, +238,234,255, 0, 97,232,218,215,229,175,165, 55, 47,163,159,209, 79,255, 0,237,247,116,238, 57, 8,219,182,106,121, 25,165,149, +231,112, 63,146, 15,250,194,183, 88,253,179,143,183,118,230,102,199,183, 17,212,201,130, 88,204,242,240,215, 44,168, 83, 91,149, + 6,195,143,128,224, 40, 12, 15,225,111,254,160,201,255, 0,201,191,253,108, 53, 91,255, 0,253, 3,255, 0,243, 63,252,213,109, +123, 51,178,247, 78,220,221, 38,205,206,155, 30, 72,164,199,104, 64,133,157,155, 83, 60,111,115,174, 52, 22,178, 84, 79,242, 14, +240,123,163,239,190,190, 55,166,245,254,179, 70,185, 58,157, 62,183, 90,214,233,219, 85,189,180, 1,251,223,182,176,183,156,209, +151, 6,231,141,139,157, 26, 8,230,199,201,145, 80, 48, 31, 18,159, 22, 83,102,242,170,168,182,127,196,173,187, 29, 19, 3, 37, +166,199, 69, 29, 49, 28,209,186,133,240,210, 38,183, 11,114,181,104,123,187,177, 87,127,156,110, 56, 83,174, 62,110,144,146, 44, +128,152,228, 11,193, 73, 43,114,164, 14, 28,141, 83, 99,118,255, 0,226, 70, 4, 11,135,137,158,139,142,128, 42, 1, 40, 96, 20, +114, 11,173, 53, 0, 40, 10,220, 46,250,222,118,237,195,210,239,216,241, 76, 21,244,100,234,137, 99,153, 13,248,176,233,133, 23, + 28,249,113,166,254, 39,127,249,238, 47,254, 74, 63,250,217,170,207,110,252, 58,206,147, 59,239, 14,224,204, 73,126, 62,164,145, +198, 90, 71,145,190,107, 59,184, 91, 95,199,157, 88,119,127,101,238,157,199,184,193,157,133, 54, 60,113, 71,142,144,149,153,157, + 91, 80,119,126, 26, 35,113,111,143,206,133, 52,253,175, 4, 80,118,230,214,144,168, 85,108, 88,100, 32,120,180,136, 36,115,244, +179, 26,242,159,196, 69, 85,238,188,187, 0, 53, 36, 36,219,196,244,214,189,135,105,198,147, 7,106,193,193,152,171, 75,141,143, + 20, 46,203,114,165,163, 69, 66, 86,224, 27,112,172, 63,117,118, 38,239,191,111, 83,110, 88,147,227, 36, 50, 44,106, 22, 86,144, + 53,209, 66,155,133,141,135,135,157, 8, 82,254, 38, 9, 70,225,182, 22,254,199,209, 46,143, 45, 90,219, 95,228,211, 82,246, 12, +127,196, 25, 54,156,102,217,179, 32, 76, 2,191,184, 91, 65,112, 47,196, 29, 81, 19,123,243,185,173,182,255, 0,219, 24,125,195, +183, 69,135,150,221, 57,224, 3,161,146,130,229, 26,192, 55, 3,107,169,183, 17, 88,204, 62,208,239,141,155, 90,108,187,140,125, + 6,111,149, 92,128, 79,235, 24,228, 66,160,251,168, 0,239,157,189,222,251,170,194,155,230, 94, 35,136,139, 24, 53,188, 49, 17, +123,106,177, 68, 66,121, 10,157,149,129,153,182,126, 25,230,225,102, 60,110,209,200,157, 54,137,196,139,161,178, 34,111,152,127, + 40,154, 28,127,135,189,195,188,230, 46, 87,114,238, 42, 84, 88, 29, 44,100,147, 72,227,165,110, 21, 16,123,190,170,215,111, 93, +184,185, 29,173, 47,110,237, 34, 56, 6,152,146, 14,161, 33, 64, 73, 82, 86, 44, 85, 88,220,233, 62, 28,232, 12, 79,225, 86, 14, + 52,249,155,134,108,168, 30,108, 85,137, 96, 44, 47,167,170, 95, 83, 15,111,193, 94,167, 89, 30,199,237, 93,195,182,125,127,175, +146, 25, 61, 87, 71,167,208,103,107,116,250,151,213,173, 19,245,197,107,200,242,160, 59,194,212, 56, 7, 6,247,154, 45,184, 80, +160, 23, 13,239, 52, 1,150,227,198,151,194,153,122,112, 62, 20, 7,123,105,111,194,212,150,227,237,174,176,229, 64, 74,183,238, + 63,228,255, 0,219, 87, 82, 91,247, 22,255, 0,115,255, 0,109, 93, 64, 25,207,203,252,196,254,168,164, 7,242,215, 61,254, 31, +230, 39,245, 69, 50,255, 0, 93, 0,201,109,168,123,184,154, 97, 3,207,157, 36,199,227, 30,234,102,174, 55,160, 9,123, 10,237, + 66,178, 57,127,137, 29,147,131,151, 62, 30, 94,241, 28, 89, 56,210, 60, 51,198, 82, 82, 86, 72,201, 71, 94, 8, 71, 2, 41,119, +175,196, 30,218,217, 54,140,125,246, 76,131,153,131,149, 33,139, 30, 76, 48, 37,212,224, 18, 87,230, 80, 8,177,230,104, 13,101, +205, 37,175,204,212, 76, 28,200,247, 12, 44,108,248, 67, 44, 89, 81, 36,232,174, 0, 96,178, 40,117, 13, 98, 69,236,124,234, 77, +237, 64, 66,158,230,102, 3,141,172, 7,213, 76,179,114,167,146, 26, 66,222, 4,222,170,187,131,184,118,238,217,219, 95,118,220, +203,140,100,101, 67,210, 93,109,169,190, 80, 5,197, 66,150,129, 79, 42, 93, 62, 21, 19,104,221, 49,247,141,183, 23,117,198, 87, + 72, 50,227, 89,162, 89, 0, 14, 21,133,198,160,165,133,254,154,151,170,128,106,165,248, 82,232, 23,165, 86, 0,154,143,145,185, +109,248, 78,169,153,151, 14, 59,200, 71, 77,102,145, 80,181,255, 0, 84, 49, 23,160, 37, 5, 2,212,182, 0, 82,107, 6,196,113, + 7,136, 53, 27, 47,115,219,240,221, 35,203,202,135, 29,159,228, 89,100, 84, 45,126, 31, 8, 98, 47, 64, 76, 69, 5,128, 62, 23, + 52,237, 43,250,163,234,160,122,172,104, 16,205,145, 42, 69, 24,183,239, 29,130,175, 30, 92, 91,133,116, 59,150,221,146,230, 60, +124,184,101,107, 95, 76,114, 43, 27, 14,102,192,212, 4,160,145,159,208, 4,215, 8,147,203,157, 65,221,183,157,183,100,219,223, +113,220,242,151, 27, 18, 50, 21,229, 96, 88, 2,199, 74,252,128,158, 36,210, 54,249,181,197,181,125,248,249, 42, 54,227, 8,201, + 57, 60,116,244,152,106, 15,107, 95,136, 62, 84, 4,226,137,171,232,229, 92, 99, 78, 22,254, 19, 81,118,221,219, 7,117,194,143, +113,219,166, 19,226,100,124, 81, 74, 1, 1,128, 37, 73,179, 0,121,138,152, 25, 73,247,113, 6,128, 96,140, 92,243, 31, 77, 35, + 71,252,166,250,205, 60,145,196,130, 5, 84,111,157,203,177,246,234, 70,251,206,106,226,153,174, 33,142,204,238,228,115,209, 28, + 97,221,173,236, 20, 3,152,252,108,109,192,146,110,105,164,129,198,247,246, 84, 13,175,122,218, 55,188, 71,206,219,179, 99,200, +199,136,145, 43,130, 84,198, 64,185, 18, 43,133,100,225,250,194,162,237,157,227,218,251,182,104,219,246,204,229,159, 36,234,208, +162, 57, 21, 95, 71,205,211,145,209, 81,237,111,209, 53,160, 93,124, 68,124, 34,222,218, 80,131,244,141,234, 30,227,188, 96,109, +103, 24,103,206,184,227, 46, 85,199,199, 44, 13,154, 87,249, 82,224, 16, 9,246,215, 62,231,128, 55, 21,218,186,192,231,180, 71, + 32, 65, 98, 79, 72, 54,141,102,194,192,106,225,196,208, 19, 6,144,193, 84,115,169, 10, 42,143,115,238, 13,163, 98,104, 14,239, +146, 49,253, 65, 97, 5,209,219, 81, 64, 11, 1,211, 86,229,122,153,180,111,187, 78,251, 11,207,180,101,166, 84,113,182,137, 52, + 92, 20,110,118,117, 96, 24,125, 34,163, 5,162,248, 83,197, 49,121,211, 96,201,199,202, 78,174, 52,169, 52,119, 42, 94, 54, 14, +186,148,217,133,212,158, 32,213, 33,146,223,127, 15,225,222,247, 89,247, 71,206,104, 90,125, 23,140, 70, 24, 13, 8,177,243,212, + 63, 86,181,210,181,172, 60,232,134,154,224, 90,244, 2,175, 5, 20,224,120,211, 11, 1, 96, 77, 45,252,111, 64,116,158, 3,205, +133, 16, 80, 93,192,101,185,241,185,165,235,167,135, 26, 0,132,248, 87, 83, 75,139,113,166,180,168,167,199,235,169, 81, 65,205, +243,160,247,211,234, 57,152,106, 4,120, 95,242,209, 67,210,162,129, 57,210,129, 65, 50,168, 23,176,161,182, 72, 3,149, 81, 66, + 93,141,185, 83, 73,183, 62, 20, 8,242, 75,181,173, 97,231, 68, 47, 97,122,141,162,209,131,146, 62, 44,247,247, 81,146,193, 84, + 95,194,129, 52,224, 13, 35,141,249,211, 61, 83, 0, 5,185, 81, 2, 95, 1, 92, 8,191,230,160,195, 43, 63, 19,202,139,126, 23, + 28,234, 57, 36, 54,177,228,208,225,182,146, 65,191, 19, 76,146,112,162,222, 38,132,179, 21, 22, 90,169,212,148, 38, 11,223,145, +252,148,172, 65, 53, 22, 44,130,196, 6,163,131,122,160,122,219,207,242, 82, 30,124, 43,133,113,160, 23,194,133, 3, 11, 55, 11, +113,163,120, 94,131,143,196, 48,246,208, 5, 23,165,183,157,119, 35, 92,108, 5,205, 8, 41, 21,192,208,250,171,107, 95,149,119, + 85,104, 82,109,255, 0,113,203,251,159,251,106,234,103, 84,116, 47,254,230,255, 0,251,235, 87, 80, 8,242,201,100,227,253,220, +100,240, 30, 40,180,206,163,249,215, 56,254,207,254, 28,127,212, 90,101, 10, 11, 34, 73, 53,128, 27,133,188,133, 8, 75, 37,143, + 27,159,104,174,201, 39, 88,247,127, 25,160,113,170, 15,154,179,114, 38,139,187, 59,216, 69,181, 13,212,207,247,156, 79,117,213, +233, 85,178,110,115, 0,210,220, 98,183, 3,194,215,231, 73,155, 46,223,255, 0,219, 28, 28,108, 57,222, 89,151,118,121,115, 18, + 69,210, 99,145,241,202,133, 78, 45,116,210,130,199,206,245,182,201,252, 53,239,104,247,221,247,116,218, 55, 12, 12,120,183,151, +202,141,245,180,134, 79, 77,149, 47, 84,161, 29, 6, 10,214, 3,145,247, 26, 92,159,193,205,197, 59, 98, 45,167, 3, 55, 30, 77, +193,242,198, 94, 92,211, 23,142, 45, 43, 27, 70,177,199,161, 36, 99,109, 87,185, 2,160, 3,220,189,247,186,224, 63,110,246,222, + 30,233,247, 38, 16,219,177,101,205,220, 86, 35, 51,130,241,124, 35, 74,134,109, 35, 72,249,124,234,157,255, 0, 20,123,198,110, +207, 89, 23,112, 49,231, 99,230,174, 60,153, 75, 28, 90,228,134, 72,154, 68, 12, 74, 27, 50,180,103,136,177, 53,177,238, 47,195, +141,235, 38,125,155,121,216,114,224,135,120,219, 49, 96,198,153, 38,185,137,204, 11,167, 90, 18,141,126,101,108,203, 98, 40, 91, +247, 98,119,175,115,108, 17,225,238, 89, 59,114,231,166, 96,200, 2, 32,209, 66,144,136,140,122, 47, 28, 36,151,214,196,241, 31, + 77, 1, 77,219,221,225,221,216, 93,235,129,182,239,219,136,202,195,201,197, 73,101,137, 20,104, 17,190, 47,170, 70, 31, 10,182, +181,176,185,241,227, 89,174,226,238,110,234,238,237,147,112,221,178,242,146, 45,150, 44,200,160,143,110, 85, 81,102,112,242, 39, +196, 23, 81,208, 23,137, 39,141,235,208,163,252, 55,222, 63,205,251,118,249, 60,216,173,129,141,139, 6, 46, 68, 65,228,234,183, + 79, 23,210,190,129,210,211,107,242,187,114,172,255, 0,255, 0,104,123,194, 60, 28,237,155, 27,114,195, 27,108,185, 9,145, 18, + 72, 94,242, 52,122,145, 25,200,137,138, 29, 15,196, 11,241,250,232, 8,217,189,235,184,224, 97,118,191,110, 98,110,159,114, 97, +125,221,143, 54,110,226,177, 25,156, 23, 82, 84,104, 80,205,164,105, 31, 47,159,178,162,183,226,103,118, 75,217,194, 85,207, 49, +231, 65,154,184,242,101, 44,113,106,146, 25, 34,119, 80,215, 67,102, 86,140,252, 66,198,181,123,167,225,150,250, 19, 97,220,246, + 76,204,120,119,173,167, 22, 28, 89,214, 77, 70, 25, 12, 32,217,208,180,109,126, 12, 84,134, 91, 17, 69,223,251, 23,189,187,155, + 96,139, 11,115,201,219,151, 61,115, 6, 66,136,131,197, 10, 66, 34, 49,232,188,112,146, 95, 91, 19,196,125, 53, 1,161,236, 15, +243,118, 82,229,238,189,205, 39,248,108,232,241,165,218,224, 86, 86, 17,198, 85,203,106, 11,199, 81, 93, 4,222,179, 63,138, 29, +153,219,120,155,118,239,221, 89,217, 19, 13,207, 41,227, 24,138, 92, 4,234, 89, 81, 98, 68,211,198,234,164,155,154,244,221,167, + 30, 76, 13,175, 7, 6, 98, 26, 76,108,120,161,145,146,229, 75, 70,138,132,169, 32, 27, 92,121, 87,157,126, 32,118, 55,121,119, +142,237, 28,208,101, 96,195,182, 98, 11, 97, 99,203, 36,183,185,177,121, 36, 81, 3, 46,166, 35,151, 17,111,166,128,208,254, 23, + 46,228,189,145,182,253,228, 88,185, 14,113,196,151,212, 32, 46,122, 87,191,134,159,151,249, 54,172,183,226,135,102,118,222, 46, +221,187,119, 94,118, 68,195,116,202,120,198, 34,151, 1, 58,150, 84, 88,145, 52,241,186,169, 38,230,173,165,237,255, 0,196,166, +237,168, 48, 34,222,241,211,120,143, 41,164,147, 41, 89,150, 51,141,211,210,145, 46,156,127, 6,227,109, 31, 77, 87,247,215, 98, +119,183,120,110, 16, 72,153,152, 17,224, 97,160, 92, 88, 36,146, 98, 75,216,117, 37,145, 70, 59, 46,166, 35,234,250,104, 8, 47, +183,247, 6,127,224,158, 22, 8,197,159, 51, 55, 38,116, 24,209, 34, 52,146,250, 97, 43, 73, 29,192, 4,133, 10,156, 9,225,166, +213,223,131,249, 29,175,143,190,190,220,118,188,157,187,185, 99,197,108,121,206, 68,134, 68,144,161, 67, 61,163,101, 67, 19,234, + 75,233,177,176,184,189,108, 32,217,127, 18, 32,237, 56,113, 32,222,240,255, 0,204, 16,102,117,186,231,251, 6,196,233, 24,198, + 57, 6, 1,199, 83, 95,228,240,231, 80,123, 27,240,251,118,218,251,135, 43,187,251,171, 58, 12,173,214,112,250, 18, 3,240,134, +151,131,187, 29, 49,139,233,248, 64, 81,106, 2,235,241, 22, 20,201,217,176,241, 4, 97,211, 47,116,219,241,221, 77,184,134,200, + 78, 28,124,237, 89, 61,165,223, 51,180,246,142,202,148,235,202, 27,219,108,249,163,244,140, 24, 18,182,108,191,251,152,213,107, +115,220,251, 62, 86,246,155, 66,225,203, 10, 12, 45,215, 19, 63, 32,204,204, 47, 14, 59, 51,186,199,161, 94,238,120, 88, 27, 15, +109, 85,237,189,153, 54, 23,226, 6,127,116, 62, 68, 45,181, 76,175, 38, 30, 40,102,234, 38, 76,233, 12,115,200,192,168, 95,136, + 70,220,155,198,128,206,118,134,122, 97,126, 26,118,249,109,235,238,115, 35,229,160,104,241,215, 47, 34,102,245, 19,105,142, 24, +153,100, 55, 28,205,144,209,240, 59,223,124,155,182,158, 49,211,159,124,151,124,110,222,194,203,158, 3, 7,130,191,169,159, 31, +225,208,202,164,221, 45,192,218,227,157, 38,201,216,157,209,219,184,251, 12,248, 83,237,249, 27,142,209,235, 34,151, 30,105, 37, +244,239, 22, 91,107,234, 71, 32,136, 50,186,248,252, 60,106, 92, 93,137,189,141,155, 55,173,157,134,155,233,223,100,238, 29,186, +120,117,182, 56,145,130, 14,156,170,224, 56, 86,179, 92, 13, 86,225,196,208, 27, 61,143,108,221, 48,113,221,119,141,207,239,105, + 89,181, 71, 41,199,143, 27, 74,219,228,211, 23, 3,199,198,179, 27, 84, 17,102,254, 36,119, 62, 94, 74,131, 46,211,137,131,141, +129,171,142,152,242, 34,105,229,100,191, 47,136, 90,226,180,219, 36,251,251,193, 35,119, 26, 97, 65, 53,192,134, 60, 41, 36,144, + 88, 14, 37,218, 85, 94,103,144, 30, 21, 69,190,236, 91,196, 59,233,238,126,216,155, 24,228,207, 2,226,238, 56, 25,101,150, 41, +209, 27, 84,114, 35,198, 24,172,139,203,136,181,168, 12,230,239,182, 9,251,219,116,218,112,159,211,141,255, 0, 98,144,229, 20, +224, 58,203, 33,134, 57,156, 14,127, 11,105, 53, 51,180,247,185,113,101,195,236,222,224,192, 27,126,235,135, 8, 92, 23, 64, 27, + 31, 38, 56, 83, 73,146, 7, 28,155, 69,203, 15,127,186,164,237,251, 6,255, 0, 30,102,229,220, 89,249, 24,173,191,229,227,140, + 92, 24,227, 14,216,184,209, 41,234, 44,100,157, 46,225,159,139,126, 74,100, 27, 47,113,238,155,246,223,188,119, 31,163,199,131, +104, 18,156, 76,124, 38,146, 70,146, 89,151,166,207, 35,200,169,165, 64,228, 7,211, 84, 22, 29,231,182,226,110,189,181,184,227, +102, 72, 32, 72,226,105,227,201,110, 29, 41, 33, 29, 68,146,227,143, 2, 56,251, 42,143,240,198, 73, 55,204, 76,222,230,206,149, +102,221,179, 36, 92,108,144,162,221, 20,198, 85, 68,139, 79,134,171,235, 62,250,188,238,109,155, 63,184, 97,196,218,241,222, 56, +240, 36,200, 71,221, 67, 22, 18, 73, 4,100, 63, 70, 48, 20,143,140,143,136,146, 56, 81, 54,206,217,205,217,187,183, 59,116,219, +228,132,108,187,164, 40,115, 49, 73,101,145,114,227,186,172,177, 40, 82,154, 89,121,252, 67,159,178,128,167,239,169,101,193,238, + 30,208,200,131, 26, 76,201, 83, 35, 40,174, 52, 37, 68,142,122, 32, 89, 76,140,171,227,126, 38,160,236,123,212, 88,123,143,122, +247, 30,118, 59, 96,238, 17,195, 20,210,108,206, 8,144, 69,141, 19,116,228,118, 3, 67,153, 79,138,220, 15, 62, 53,164,238,237, +147,120,220,119, 45,139,115,217, 78, 41,151,105,150,121, 94, 60,199,146, 53,126,172, 98, 48, 1,138, 57, 15,157, 67,193,236,252, +220,204,189,235,115,238,105,161,124,173,227, 23,238,243,143,134, 27,165, 14, 62,155, 29, 47, 40, 12,204, 79, 27,216,125,144, 25, +253,167,188,183,172,188,205,174, 8,247,168,242,229,222,163,146, 60,136, 23, 8,170,237,243,188, 69,224,146, 38, 42,157, 85, 71, +178,176,119, 55,243,166,118, 68,187,142,219,217, 50,103,101,119, 2,109,248, 77,149, 34, 66,199, 21, 25,163, 97, 52,130, 64,154, +139,117, 30, 83,242,141, 63, 15,145,173, 79,111,226,119,182,212, 48,246,173,197,182,249,182,220, 52, 16,250,216,204,190,162, 72, +163, 66,177, 14,145, 1, 21,248, 46,162, 91,235,170, 12,110,202,238,220, 76, 12, 92,108,105, 48, 95,238, 77,197,183, 29,179, 91, + 75,108,129, 35, 59, 50, 78,186, 62, 6, 93,127, 9, 23,241,247,213, 5,215, 97,247, 22,231,186,238, 59,238,213,184,100,190,106, +109,143,140,216,185,115,227,122, 57,222, 60,148,121, 45, 36, 26, 99,181,180,112, 58, 69,199, 26,219, 72,108,181,146,237,109,155, +123,193,223,119,253,243,124,124, 94,174,241,232,202, 71,136,210, 16,158,154, 55,136,171,117, 85,124,197,143,143, 59, 14, 85,167, +121, 53, 18, 7, 47, 10, 16,225,118,109, 84, 86, 33, 84,147,202,152, 62, 21, 3,198,154,236, 8,177,227, 88,226,205,112, 1,169, +152,147, 68,137, 73, 37,141,114,128,105,247, 0,240,229, 90,124, 2, 30,196, 42, 18, 69, 69,212, 77,205, 22, 66, 24, 1,199,219, + 67, 10, 42, 37, 64,199,196,186,141,219,144,169, 41,202,244, 37,210,160, 11, 87, 51, 0,156, 47,168,253,149, 29, 91, 40, 41,100, + 37,248,114, 20,210, 88,240,243,166, 26, 52, 74,163,226, 63, 69,107,130, 32, 88,215, 66,138,123,182,133,185,181, 15, 80,252,212, + 41,157, 89,180,142, 67,248,107, 20,171, 40,203,234, 36,154, 85, 93, 76, 22,152, 42, 76, 10, 0, 44, 71, 18,120, 86,219,162, 32, +101, 1, 64, 11,225, 69,102,208,183, 39,128, 20, 27,175,151, 14, 52, 60,137, 20,252, 11,244,154,230,149, 89, 64,187, 23,114,198, +187,144, 28,105,167,216, 40,208,162,146, 25,135, 1, 93, 56, 35, 33, 32,138,194,231,153,163, 41,177,181, 55, 82,248,112, 30, 53, +204, 80, 2,199,152, 21,132,221,124,205, 53,160,117, 35,133, 57,173,107,147,202,162,166, 66, 0,111,196,249, 80,222,102,144,241, +224,190, 85,208,197, 3,174, 72,107,171, 11, 15, 3, 86, 24,219,111,238, 86, 94,175,246,128, 61,180,242,184,191,157, 82,151, 26, + 74, 91,230, 35,141,107, 32, 83, 28, 17, 68,220,209, 21, 77,185,112, 22,164,117, 15, 68, 65,108, 27,113,234,127,209,252,245, 95, + 54,174,155, 91,199,133, 94,205,196,112,172,236,185, 9,121, 33,253, 37, 98,191, 81,181, 86,169, 66, 46, 8, 67, 10,136,245,245, +152,157, 55, 85, 28,239, 76,253,206,139,137, 36, 47,226,188, 62,202, 65, 35, 70,203, 33,143,225, 81,166,231,145,166, 68,197,174, +109,196,155,214,106,106,133,143, 77,125, 7, 83, 91,107,232, 90,222,206,190,171,215, 82,220,250, 45, 55,254,227,159,252,251, 87, + 85,168,160,233, 7,246,127,240,227,254,162,208,233,242,127,119,255, 0, 14, 63,234, 45, 50,128,139,147,109, 99,221,252,102,128, +121, 81,242,127,180, 30,239,227, 52, 30, 85, 65,145, 29,253,183, 42, 35, 73, 3,169,108, 28,173,193,248,130, 23,210, 52,136,240, +147,250,196,194,246,247, 85,212,123,254,221, 35,250, 83, 40, 92,229,139,171, 38, 39, 27,171, 8,196,205, 30,171, 5, 46, 21,174, + 87,157,184,218,213,143,203,252, 62,220, 39,151, 53,147, 34, 5, 76,141,196, 77, 18,146,255, 0, 14, 4,135, 37,178, 49,216, 4, +249,139,102, 72, 85, 71, 14, 92,106,205,123, 83, 48,119, 14, 70,224, 66, 62, 59,207, 62, 92, 51, 62, 70, 69,213,167,198,244,189, + 49,136, 15, 65, 88, 18,215,147,137, 43,194,222, 64, 92, 97,119, 78,209,147, 22,220,100,157,113,242, 55, 44,120, 50,161,199,123, +221, 87, 33,117, 70,174,192,105, 5,184,133,185,248,136,225, 68,135,186, 59,126,124,121, 50,226,220, 35,104, 34,104,209,228,248, +128,188,231, 76, 54,184,185, 18, 31,148,142, 7,194,179,184,125,169,188, 97,195, 6, 7,248, 73,113,231,194,219,177,115,167,114, +204,209, 54, 12,109, 28,134, 4,100,248,203, 92,116,216,149,210,120,218,186, 30,211,221,228, 24,210,100,182, 60, 82,226, 13,163, + 29, 86, 55,118, 71,135,107,200, 57, 18, 74,111, 24, 33,228, 12, 66,167,135,139, 80, 26, 28,110,232,216, 50,186,134, 12,244,101, +134, 23,201,148,176,100, 11, 20,103, 76,142, 75,170,252,135,131, 14,107,227, 83,113,119, 61,191, 51, 18, 76,236,105,131,227,197, +168, 74,214, 96, 80,160,187, 43, 35, 0,192,129,198,196, 86, 58, 78,201,220,165,197,147, 28,207, 2,151,196,221, 49,213,131, 73, +253,166,110,122,103, 65,201, 65,210, 21, 44,228,113, 7,149,235, 69,219, 59, 84,251, 86, 54, 87,168,141, 97,151, 47, 37,178, 90, + 49,145, 62, 91, 11,164,113, 14,164,249, 68,187,181,163, 30, 67,195,219, 81,128,123,103,121,108, 27,164, 59,124,139,144, 32,155, +113, 72,228,135, 30, 80, 67,142,171, 20, 69,114, 1, 80, 89,148,170,241,248,143, 43,210,247, 39,119,109,253,183, 32,131, 38, 55, +150,102,196,200,205, 85, 65,192,174, 54,155,173,207,139,106, 54,247,113,240,172,238,217,217,155,214, 38, 38, 62,221, 59, 99, 24, + 92,109,169,149, 60,114,185,100, 27, 92,253,101, 49,171, 68,186,186,202, 20,113, 35, 73,191,205, 86,189,235,219,219,151,112,116, +254,238,120, 23,252, 22,126, 20,158,161,221, 45,234,196, 58, 29,116, 71, 37,244,180, 60, 71, 14, 7,232,168, 11,100,238, 45,179, + 34, 76,113,137, 60,114, 69, 44,242,227, 75, 35, 49,140,163,195, 11,100,176,210,234, 53,124, 42, 15,135,194,117,114,169, 27,126, +243,181,238,145, 75, 62, 6, 74,205, 28, 54, 50,155, 50,149, 12,186,213,172,224, 29, 44,188, 84,242, 35,149,103,228,237,141,201, +183, 41, 51,145,241,217, 27,114,200,207, 84,147, 91, 3, 28,219,103,221,234,174,161, 69,207, 83,139, 11,252,190, 55,225, 70,237, +189,147,114,219,112,243,241,242,132,113, 36,234,145,226,227, 36,210,100, 44, 65, 99, 40,192, 77, 50, 44,157, 61, 95, 34, 27,233, + 95,170,128,177, 94,234,237,215,130, 25,215, 62, 51, 22, 65, 34, 25, 0,109, 44, 6,141, 77,123,112, 65,212, 91,177,248, 65, 54, +189,114,119, 46,217, 23,175, 57,143,233,151, 11, 48,224, 93,174,198, 73, 4, 17,229, 18,138,128,181,130, 73,199,135, 11, 19,202, +179, 57,253,147,159,145,183,108,248, 71,165, 57,198,218,147,105,204, 79, 83,147,143, 16, 32, 69,170, 95,240,218, 26,116,248, 27, +247,111,107,240,169, 27,151,105,110, 83,205,149,153, 19, 71, 41,147,114,151, 54, 56, 6, 84,248,133,162,155, 10, 44, 43, 60,248, +192, 58,178,188,122,138,139,134, 94, 23,240,160, 53, 35,125,217, 83, 43, 31, 4,230, 71,234,178, 85, 26, 37, 82, 88, 17, 40, 45, + 21,221, 65, 81,212, 10,116,220,252, 94, 21, 28,247, 71,111,234,200,182,108,127,225,172,178,216, 55, 18,100,232,254,239,225,253, +231,239, 62, 15,130,255, 0, 23, 14,117,158,147,180,247,117,204,218,196, 47,143,232,118,213,219,122, 72, 39,154, 37, 83,133,117, +153,122, 65, 36,234, 22, 91,104,105, 24,145,107,112,189,234, 52,189,155,188, 76,211,181,241,160,141,101,139, 34, 60, 76,124,169, +209, 37,145, 50,125, 68,141, 12,154,122,184, 98, 68, 63, 44,108, 70,190, 62,218, 3,114,155,142,222,219,127,222,163, 34, 63,187, +214, 54,153,178,137,248, 21, 18,250,203, 19,203, 77,141,252,170,155, 51,188,182,152, 83,111,244,108, 51, 27,112,204, 24, 49, 1, +170, 62,155,132, 50, 72,210, 6, 77, 67, 74,219,225, 34,230,227,195,141, 53, 59,117,191,201,179,118,222,184,160,200,153, 39, 35, + 76,146,205, 18,203, 52,175,144, 53, 73, 57, 50,184,212,223, 19, 30, 39,137,176,229, 81,211, 96,220, 39,207,139,118,201,104, 33, +200,147,120, 77,207, 35, 25, 36,105, 17, 34,139, 1,182,245, 68,126,154,106,114,108,198,224, 15,171,136, 19,119, 94,245,218,182, +141,205,246,156,148,115, 60, 67, 12,200,225,108,161,115, 39,244,192,159,230,124,199,216,120,113,169,239,220,253,187,208,198,203, + 25,136,144,230, 23,244,238, 67, 11,136,216, 69, 33, 96, 69,208, 43,252, 44, 90,214, 60, 13, 83,239,221,189,159,185,119, 4, 91, +158, 44,152,227, 22,219,103, 88, 72,238,178, 41,219,243,155, 53,180,170,198,234,218,210, 66, 5,216,113, 30,219,138,108,206,197, +207,154, 8, 96,102,135, 32, 58,238, 16, 79, 31,170,202,199,141, 83, 55, 53,179, 35,145,134, 54,134,152, 8,219, 75, 70,214, 26, +173,199,198,128,216,111, 91,195,109,146, 96, 99, 67,136,114,178,119, 25, 94, 8, 81, 93, 99, 0,199, 12,153, 12, 89,159,135,203, + 25,170,140,126,243,219,115,224,150,103,141,241, 35,199,135, 22,121, 26, 82, 15, 28,151,158, 21,137, 4,122,181, 29,112, 16, 52, +223, 85,197,170, 79,117,236,210,111,111,181, 75, 14, 38, 30,225, 30, 6, 68,147,100, 96,238, 12,201, 12,170,240, 75, 2,241, 16, +100,139,171, 72, 27,138,120, 86,105,123, 11,115,143, 18,104,206, 68,114,145,232, 30, 8, 99,154,104, 63,238,153, 57, 83,182, 58, +204,171,212,141, 86, 60,133,142, 39, 94, 63, 15, 16, 40, 13, 4,253,207,176,227, 65, 14, 68,249,177,172, 83,163, 75, 19,124, 70, +232,140, 17,219,225, 4,128,172,192, 53,249,120,208,231,238, 45,190, 61,227, 27,100,141,250,185, 83,202,240,200,171,202, 34,152, +239,151,241,146, 45,242, 40,224, 15, 11,139,213, 52,253,139,159, 38,218,112,225,108,120, 93,246,189,199, 8,169,150,121, 20,100, +103,100,199,148,167,169, 42,188,142,163, 75,106, 99,196,159,209,242,153, 47,106,110, 82,111, 38, 69,108,117,219, 78,110, 78,113, +159, 91,245,255, 0,197, 96,190, 23, 76, 69,163, 77,209,219, 85,245,241, 30,218,160,184,199,238, 62,222, 24,146,103, 46,124, 93, + 8,217, 18, 73,141,192, 6, 83,104,173,112, 9, 87,253, 22, 28, 27,194,143,184,111, 13,141, 22, 36,152, 88,146,231, 62,105,253, +202, 71,104,212, 38,131, 41,121, 94, 93, 42,131, 72,183, 30, 55, 54,172,174,217,217,123,142, 62, 44,113, 74, 33,142,116,159,105, +103,115,149,147,148,100,139,109,155,170,237,171, 32, 29, 26,174,221, 56,213, 64, 30, 39,203, 67,221, 24, 27,190,229,137, 22, 30, +217,210, 48, 73, 39,255, 0, 81,138, 89,228,198,105, 96,210,111, 10, 77, 12, 83,178,235,107,106, 32, 95, 77,192, 60,106, 1,205, +220, 17, 79,179, 97,239, 56, 56,211,101, 46,114,194,216,216,234,160, 72, 78, 65, 93, 58,201, 58, 80, 45,238,204, 77,128,243,167, +224,111,184,121, 91, 92,219,180,255, 0,224,225,198,105,162,202, 19, 17,251,183,199,145,161,148,106, 82, 85,134,164, 54, 35,157, + 67,220,113,123,146, 77,177,240,182,184,240,240, 36,233, 99,199, 8,142,105, 0,141, 67, 17,145, 28,111,233,254, 27, 70, 2,196, +221, 63,109,133,133, 56,109, 19,255, 0,149,229,217,227,192,195,133,250,102, 36,194,105,101,159, 24,173,238,117,205,211,134, 82, +206, 46, 75,105,190,174, 60,104, 3,183,115,108, 26, 33,149,179,145, 86, 98,232,161,131, 43, 6, 66,170,253, 69,101, 13, 30,146, +235,114,224, 90,227,206,159, 47,113,237,144,206,216, 49, 79, 28,185,113,207, 14, 60,240,150, 41,160,207, 36,113,139,182,146, 53, +126,244, 21, 95,210,172,126, 79, 99,111, 25, 42,163, 37,163,156, 77, 30, 70, 59,193, 46,110, 82,244,162,154, 72,221, 58,211, 64, + 34,124,189, 42,140, 25,100,181,248,113,225,122,191,155,182,179,159,215,105,146, 17,234,119,204, 61,217, 46, 91,132, 24,254,147, + 90, 55,193,243,159, 78,214, 28,185,113,170, 66,203,252,197,177, 95, 48, 54,100,119,194, 12,217, 4,146, 2,172,109,161,200, 36, + 89,180,176,210,116,222,199,135, 58, 54,223,159,137,185, 66,114,176,164, 18,196, 24,161,224, 84,171,175,204,174,174, 3, 41, 30, + 68, 86, 55, 31,179,115,241,206,122, 52, 56,217, 37,225,201,199,199,108,156,156,169, 82,100,201,201, 25, 58, 90, 27,132,199, 26, + 84, 3,211, 4,234,248,189,247,253,191,129,188,237, 88,222,159, 56,196,240, 72,211, 75,198, 87,154,116, 44,201,209,141,165,120, +211,171,100,213,169,219,226,189,135, 17,198,163,232, 84, 92, 73, 35, 95,133, 8,200,254,116,101, 94, 28,104,110,151,114, 47, 96, + 40, 81,162, 87, 30, 53,221, 87,243,165,233,143,214, 20,189, 17,250,226,169, 6,117, 31,206,148, 72,227,198,159,208, 4,145,168, +123, 41,166, 34, 60, 71,215, 64,119, 90, 79, 58,225, 43,147, 98,120, 83,122,109, 72, 84,142, 98,128, 35,176, 91,105,125, 87,231, +194,212,157,103,229,229, 73, 24, 12,224, 30, 70,164,140,120,205, 1, 27,170,244,154,216,212,191, 74,150,246,215,122, 69,243,160, + 34,235,106,120,158, 75, 88, 84,147,134,131,145,164,244,131,206,160, 1,215,147,217, 77,234, 57,230, 5, 24, 66, 10,145,229,115, +122,238,128,181,252,169, 64, 15, 91, 83,196,206, 6,144, 5, 44,152,228,241, 83,111, 10,142,225,209,180,183, 58, 80, 19,213,181, + 1,127,244,246, 80, 37,144,147,164,114, 20, 52,144,162,216,159,155,149,117, 69, 29, 75, 80,248,232,146,181,157,138,249, 90,165, +140, 8, 79, 30,179,125, 66,171,145,138,176,177,171, 40, 95, 82,251,107, 70, 89, 83, 54,243,218, 88,211,201,143,145,220, 56, 48, +207, 19, 24,228,138, 76,152, 17,149,212,217,149,213,156, 21, 32,243,189, 93,158,245,236,187, 15,255, 0,216,246,191,255, 0,157, +199,255, 0,226, 87,207,216,221,191,181,231,111, 93,245,190,229,237, 51,119, 30, 86,219,185,188,120,251, 30, 60,146, 70,204,179, +228, 74, 31, 33,250, 23,148,170,105,183,195,244,214,119,186,251, 83,104,219,123,231, 19, 98,197,103,194,194,205, 92, 73,102,198, +153,195,203,134,217, 42,173, 38, 51,191,139, 37,249,154,142, 74, 49,114,124, 18,171,246, 21, 69,201,168,174, 45,209,123, 79,167, +159,189,123, 54,252, 59,139,108,183,254,119, 31,255, 0,137, 84, 25,125,199,218, 6, 89,101, 94,226,219,137,102, 44, 0,203,128, +243, 55,253,122,249,243,184,182, 61,186, 29,163, 47, 54, 45,174,109,154,108, 28,181,197,132, 77, 35, 56,202, 70,213,118, 2, 79, +210, 93, 55, 37,120, 86,191,181,187, 23,183,179, 54,190,221,130,125,139, 43,118,255, 0, 48,197, 44,153,221,195, 4,238,145,237, +204,140,201,160, 34, 3, 31,238,244,221,250,156,252, 60,171, 54,175,198,244, 55, 69, 53, 71, 77,105,249, 85, 29, 46,218,149,169, + 40,182,157, 85,116,175,231, 70,123, 6,219,185,237,155,196, 36,237,217,176,230, 69, 13,150, 65,143, 42, 75,102, 60, 70,163, 27, + 53,170, 98,198, 2,234,142,224,159, 3, 94, 77,248, 33,233,240,241,187,130, 30,186, 60,105,151, 28,113,205,112, 3,133, 87, 26, +133,252,199, 26,245,213,101,146, 32,200,193,131,139,171, 3,112, 65,228, 65, 21,163,153, 34,255, 0,224,191,149,209,255, 0,230, + 43,169,122,103,211,105,176,191, 66,223,251,251,215, 80, 10,227,132,127,240,227,254,162,211,105,207,250, 31,240,227,254,162,211, + 43, 64,139,147,243,143,119,241,154, 1,189,232,249, 35,227, 30,239,227, 52, 43, 80, 30,107, 47,120,239,209,224,103,102, 99,202, +153, 15, 2,110,109, 44,126,157,130, 98,250, 73,100,143, 29,140,163,224,109,122, 0, 42,120,159, 14, 70,180,131,188,240, 27,127, +125,129, 80, 60,234,242, 64,129, 37, 70,153,165,138, 15, 84,223,225,239,172, 38,144, 84, 57,224, 88, 91,219, 83,155,182,176, 91, + 97,202,237,227, 36,222,147, 47,212,245, 36,212,189, 65,234,229,146,121, 52,157, 58,120, 52,135, 79,195,203,206,147,252,185,142, + 51,242,114,253, 94, 74,193,146,210, 75, 38, 18,178,136,186,211, 68, 49,228,146,225,117,155,160,224,165,172, 15, 27, 80, 21, 17, +247,222, 59, 96,230,101, 54, 40, 89, 48,228,198,138, 69, 19,198,209, 39,170,224,173, 60,233,117,143,166,110, 36,224,116,145,227, + 78, 29,251,128,185,248, 88, 19,192, 33,155, 47,211,171, 70,243, 71,212, 15,150,237, 20, 93, 40,193,188,171,112, 11, 50,240, 10, + 65,247, 72,195,236,216,176,113,222, 44,109,207, 49, 36, 41,143, 24,148, 24, 71,195,136, 25, 34, 82,139, 16, 70, 82,143,165,213, +129, 7,159, 62, 52, 76, 46,206,194,219,165,199,108, 44,188,168,162,136, 67,214,129, 94, 48,179,182, 59,188,145, 52,164, 70, 8, +248,164, 55, 84, 42,167,128,181,168, 9, 27,182,251, 38,223,155, 22, 14, 46, 4,185,243, 24, 95, 46,116,136,128,201, 12,110,145, +146,138, 71,239, 28,151,224,163,203,157, 82,237,253,241, 36, 88,185, 47,187,227, 16, 32,139,112,202,143, 34, 54, 80, 36,143, 11, + 52,226,116,244, 27,105, 63, 18, 11,147,199,137,225, 87,187,183,111,197,186,228, 69,148, 50,167,195,149, 98,108,105,155, 25,149, + 76,144, 59, 36,141, 25, 44,172, 87,226,140, 89,146,199,159, 26,137,254, 75,218, 90, 23,133,164,157,145,224,205,198, 63, 26,220, + 46,126, 64,205,145,129, 9,243, 36,138, 52,123, 57,222,163, 0, 49,251,218, 44,236,104,142,219,136, 51,115,100,202,151, 12, 67, + 4,232,240,150,134, 1,148,238,153, 10, 10,178,244,216, 90,195,230, 54,243, 52,221,139,187, 31,116,222,115, 54,119,133,189, 68, +115, 25, 4, 44, 4,111,141,137,233,241,164, 6,112,110,117,153,102, 40, 0,246,249, 84,217,187, 91,173, 4,122,183, 60,191, 95, + 20,242,100, 46,225,120,186,129,165,136,227,200,138,157, 62,146,166,131,192, 5,224,120,243,174,194,236,237,183, 3, 46, 60,252, +105, 39, 25, 81,205,215,235,179, 43, 59, 41,199,143, 17,161,145,153, 9,104,217, 98, 86, 55,227,171,141,234, 2,183,127,238,125, +235,110,223, 91,108,196,198, 70,199, 81,181,148, 98, 70,167, 57,153,141,141, 34,241, 60, 53, 42,233, 30, 68, 95,198,147, 39,241, + 27,110,193,194,198,202,204,128, 66,210,140,151,158, 23,158, 53, 42, 49, 39, 56,146,172, 58,244,245,156,186,146,170,163,136, 30, + 21,115,185,118,198, 38,231,186, 71,186,205, 60,241,203, 24,197, 13, 20,101, 4,111,232,242, 61,100, 37,181,198,205,193,201, 6, +204, 46, 15,184,212,115,217,184,136,144,174, 54,102, 86, 49, 79, 82,178,188, 76,129,229,139, 47, 32,230, 75, 19, 49,143,225, 2, + 67,240,178, 89,128,225,127, 26, 3,187,175,119,201,218,229,218, 98,131, 35,210,197,153,145, 36, 89, 19,172, 13,146,202,169,143, + 44,203,166, 36, 4,155,180, 99,144,229, 84,221,189,220,251,182,237,184,227, 99,229,100,180, 72,248,216,115,175,164,193,147, 37, + 36, 57, 18, 78,133,166,146, 37,145,113,195, 44, 74,126, 50, 52,220,254,169,182,199, 47,110,131, 51, 55, 3, 54, 86,113, 38,221, + 43,205, 0, 82, 2,150,146, 25, 49,136,123,130, 72,211, 41,229,110, 53, 87,182,118,132, 59, 94, 89,201,219,119, 76,220, 93,106, +137, 60, 75,233,157, 37, 84,150,105,213, 91,171,140,236, 5,231,113,240, 17,195,219,198,128,162,206,239,125,202, 9, 59,145,161, +104, 58, 24,248,217,114,236,163, 69,200,125,185,151, 31, 35, 89,191,197,170, 71,184,246, 81,187,131,184,187,147,105,131,117,219, +113,165,135, 39,115,197,151,109,244, 89, 38, 16,161,147,112,149,224,209, 36, 97,136, 44,173, 17,226, 45,192,138,179,159,240,235, +183,102,219,225,193, 13, 44, 45, 20,115,195, 46,100, 93, 21,200,157,114, 81,163,148,228, 73,210, 58,201,213,171,151,204, 7,186, +166,142,213,192,102,105, 50,243,114, 50,178,229,202,197,204,151, 50,102,136, 72,205,130,226, 88, 35,211, 12, 81,198,177,130, 56, +133, 64,120,158, 55,227, 64,101, 51,187,255, 0,115,151, 39,117,200,218,204, 71,110,199,217, 31, 63, 16,148,212,125, 82, 38, 36, +247, 45,250, 74, 19, 49, 69,188,235,111,178,229, 73, 62, 20,249, 18,205,147,150, 81,155, 72,159, 10, 76, 25,126, 21, 13,165, 33, +200, 72,153,175,126, 13,107, 95,133,248, 85, 34,126, 31,246,236, 24,147, 97, 69, 60,201, 20,248,217,152,110, 21,227,191, 79, 54, + 88,231,144,143,221,218,233,210, 85, 79, 37, 28, 65,231, 87,240, 98, 52,120,115,226,229,238, 83,238, 61,112,202,210,228, 12,116, +117, 86, 93, 37, 87,210, 67, 2,253, 96,154, 2,139, 27,191, 49,242,113,167,145,112, 73,201,131, 39, 11, 19,211,197, 60, 82,141, +121,238,177, 68,173, 34,252, 42,232,196,135, 95,209, 35,153,168, 59,183,127,101,166,201, 54, 94,217,129,167, 62, 60, 76,252,169, + 67,186,178, 64,112,167, 56,108,120,129,213,188,163,128,225,240,143,162,172,112,251, 47,109,196,133, 34,108,220,169,250,109,128, +234, 91,164, 5,246,199,234, 99, 11, 71, 10,240,224, 3,249,251, 15, 26, 76,174,197,218,242,241, 91, 9, 51,114,241,226,146, 60, +200, 50, 26, 35, 25,121, 33,206,156,230, 75, 17, 47, 11,129,166, 83,240,144, 47,110, 28,104, 11,173,243,121,147,107,108, 60,108, + 92, 54,205,205,206,145,210, 8, 21,196, 98,209, 70,211,200,204,236, 26,223, 10, 88, 11,113, 36,123,234,153,123,214, 57,242,227, +137,246,217,161,196,121, 78, 26,228, 76, 85, 92,101, 12, 95, 92,208,188, 63, 50,217, 84,173,255, 0, 88,121,113,171,125,235,106, +135,119,244,210, 46, 84,248, 89, 88,142,207,143,149,140,171,173,122,145,180, 18, 45,165, 71, 82, 25, 28,248,112, 54, 34,170,143, +104,224,199, 56,150, 12,137,218, 40,201,154, 28, 89,152, 52,126,171,211,122, 47, 82,204, 83,168, 88,199,206,237,107,146,214,189, + 16, 34,225,247,196, 19,166, 43, 79,183,190, 63,172, 27,124,209,221,213,237,143,185,179,197, 4,204, 87,149,164, 77, 44,190,209, + 80,230,239,163,149,182,103,229,225,224,203, 12, 88,184, 3,112,124,176,209, 18,145,203,215,232, 20, 71, 31, 27, 63, 66,252,173, +198,130,123, 31, 54, 46,215,147,109, 89,198, 86,237,147,131,133,183, 25,165,147, 76, 88,235,136, 53, 43, 64, 99,137, 88,172,114, +179, 58,234, 26,143, 14, 60, 42,245,251, 59,106,124, 60,236, 29,114,164, 57,248, 56,251,100,161, 25, 70,136,113,150, 68,140,197, +116, 54,107, 74,111,123,142, 92, 42,130, 54, 95,119,180, 91,131,225,197,130,254,156,101, 62,220,153,165,214,222,165, 49,219, 45, +135, 75,230,210, 21,109,127, 63,203, 77, 23,124,110,242,118,252,121, 35, 5,126,242, 72,182,121,165, 98,235,211,146, 61,206, 69, +140,186,168,182,146, 74,176, 2,252, 46, 15,152,169,217, 29,169,155,147,220,131, 44, 72, 34,218,151, 40,231,178, 44,215,213, 35, + 98,190, 35, 90, 3, 15,194,228,181,203,117, 74,216,112, 80, 73,169,195,178,118,193,132,248, 41,145,146,138,248,219,126, 32,148, + 52,122,213,118,183, 50, 99, 72,183,140,174,189, 70,237,117, 32,249, 10,128, 78,226,238,145,176,200, 87,209, 54, 73, 92, 73,119, + 9,180,200,168, 18, 28,119,137, 36,249,129,212,223,189,224, 60,105, 79,116,145,185,190, 2, 96,187,194,114,159,111,135, 40,200, +170, 31, 45, 49,206, 95, 75, 65,226, 20,170,149,215,231,225,110, 52,125,223,182,176,183,167,148,229,203, 48, 50,225, 79,182,185, +140,160,253,214, 67, 70,238,252, 80,252,119,132, 91,195,159, 10,122,118,222, 32,221, 6,231,214,148,160,200, 57,171,134,116,116, + 70, 83, 67,233, 76,227,225,215,126,157,248,106,181,205,237,122, 3, 51,179,119,190,118, 78, 28,121, 89,152,230, 92,217,177,246, +211, 22, 36,101, 18, 38,151, 57,230,141, 89, 95,226,101, 7,167,169,181, 94,192,112,227, 83,228,239,236,104,183, 12, 93,175, 47, + 21,177,114,166,120, 97,150, 9,165, 69,153,101,200,149,160,140, 69, 17,248,165, 77, 73,114,227,244, 72, 62,227, 98,118, 62,221, +133, 3, 98,227,229,229,107, 85,196, 92,105,220,196,207, 15,160,146, 73,177,244, 1, 18,169,183, 84,169,214, 13,215,219,198,164, +197,218,176, 97,228, 69,146,155,134, 97, 55,137,178,213,157, 15,169,146, 23,146,104,222,102,209,168,124, 82,155,170, 21, 82, 44, + 45, 97, 84, 1,222,187,137,118, 76,201, 36,149,100,146, 40, 54,220,173,193,224, 64,128, 55, 66, 72, 19,230,111,136, 55,239, 56, +120, 80,223,187,103,114,113, 35,219, 25,247, 37,205,151, 4, 98,117, 86,199,165,142,185,141, 39, 87, 77,191,179,112, 45,111,155, +135, 46, 53, 59,118,237,188, 29,237,230,124,185, 37, 67, 54, 20,251,115,116,138,139, 69,144,209,200,236, 53, 35,124, 96,196, 45, +225,236,160,100,118,182, 46, 68,243,228, 99,229,228, 98,101, 75,148,249,195, 38, 35, 25,100,121, 49,215, 10, 68, 64,232,203,164, +198,131,152, 36, 55, 27,214,121,148,133,183,119,100,146,100, 77, 22, 92, 14,189,108,249, 49,113, 99,101, 17,188, 73, 30,221, 30, +226, 86,101, 63,165,125, 74,125,181, 22,126,242,159, 44,109,237,182,226,149,143, 37,246,151,201,154, 82,167,166,155,156,170, 4, + 65,127, 72,244,239,118, 28,137, 31, 68,233,123, 59, 10, 36, 79, 79,151,147, 20,139,146,114,214,109, 72,238, 25,177, 70,222,235, +121, 99,123,134,137,121,155,157, 92,111, 73,143,217,120, 0,225,244,178,178, 99,135, 13,112, 85,162, 6, 50, 38,109,181,131,227, + 60,165,163, 38,254, 13,163, 77,254,138,160,134,157,253,181,187,238, 42,145,245, 14, 12, 51,228, 36,113, 74,143, 35,174, 60,163, + 28,172,136,166,241, 51,187, 46,128,220,212,222,173,123,123,112,206,220,159,117, 92,248,150, 23,195,206, 56,201, 18,144,218, 80, + 99,193, 45,181,143,155,226,148,241,242,166,175,103, 97,152,115,113, 31, 43, 37,240,242, 82,104,163,198,214,170,144, 46, 68,134, +119,233,105, 64, 75, 7,226,165,245, 88,112,243,188,237,163,104,109,168,101,152,167,151, 46, 92,201,253, 86, 84,211,244,193, 50, +152,227,132,233, 17, 36,106, 22,209, 14, 22,160, 39,232,248,173,106, 99, 1,126, 28, 42, 82, 47, 81, 11,218,204, 57,138, 3, 1, + 98,104, 4,143,128,163, 69,140,217, 74,120,133,183,137,160,170, 18, 11, 6,211, 92,131, 32, 11,197,123,123, 42,144,146, 54,233, + 98,253,233, 96, 66,113, 52, 96, 99,189, 67, 47,150, 22,205,171, 73,224,111, 82, 0,191, 46, 30,218, 2, 66,152,248,222,147, 84, +124,232,122, 52,139, 95, 81,231, 75,110, 20, 1,109, 25,230,126,154,126,152,239,207,149, 71, 55, 63, 71, 42, 66,121,222,128,145, +210,142,222, 21,198, 4,229,122, 5,200, 60,233,117,155,208, 15,120,213, 69,129,168, 89,145,252, 33,188, 69, 29,174, 90,194,147, +166, 39,117, 67,242,243,111,112,162, 4, 65,143, 43, 8,200, 70, 32,248,128,105,221, 9,255, 0,217, 63,236,154,186, 80, 0, 10, + 5,128,224, 0,167, 0, 60,171,123, 60, 73, 82,162, 44, 89, 73,212,209, 53,135,134,147, 82, 96,134,101,184,233, 48, 23,241, 83, + 86, 72, 42, 66, 11,123,106, 40, 42,241, 27,151, 3,231,174,221,142, 5,239, 14,240,204,155,107, 66,112,247, 44,131, 54,251,145, +187, 79,180, 69,140,178, 76,232,176, 51,227,130, 88,200,195,149, 98,123,227,105,158,126,243, 77,163,111,217, 27,110,205,200,233, + 34, 98,166,100,153,254,166, 89,152,178,100, 38, 76,220, 88, 74, 29,127,210,245,109,185,247, 62, 62,205,220,189,231,181,111, 91, + 79,222,251, 14,229,187,100, 60,208,117, 95, 29,150,120, 39,149,163,120,167, 64,214, 54,110, 34,220, 69, 66,159,123,223,247, 63, +196, 13,163,115,244,240,118,254, 78, 56,198, 27, 76, 25,229,225,197,131, 27, 29,127,112,178, 73, 40, 12, 99, 42,166,237,227,122, +201, 72,189,215,217,221,207,180,109,233,184,110, 91,150, 62,237,137,139, 40,196,200,108, 76,179,149,233, 39, 34,253, 9,129,249, + 15, 15, 14, 21,191,236,236, 44,121,123, 75, 22, 4,237,184,245,110, 49, 30,158, 20,157,193,149,133, 54,234,209, 13, 50,203, 14, + 26, 13, 6,229,121, 31,224,170,254,252,143, 27, 23,181,119, 8,182, 70,216,113, 32,206,201,139, 51,120,139,111,221, 78,126, 78, + 68,161,136, 69,134, 54, 68,209, 26, 52,133,172, 42,147,183,251,237,241,226,217,177,103,237,159,189,187,139,102,140,199,219,217, +130, 73,149,149, 27, 84,177,245, 49,163, 83,214,209,168,178,113, 31,199, 81, 36,149, 18,162,240, 43,109,186,183, 95, 50,247,240, +197,113,101,192,222,131, 98, 75, 20, 50,110, 81,164, 24,145,184, 45, 27, 50, 75,162, 18,101, 23,114, 62, 94, 87,189,123,150, 30, + 30, 66, 98,192,135, 30, 84,211, 26,141, 14, 9, 97, 96, 56, 49, 28, 9,175, 29,252, 26,159, 32,224,110,210,100,179, 46, 92,155, +190, 43, 75, 25, 86,212,242, 90, 70,100,101, 82,186,126, 47,214,224, 13,125, 14, 53, 50,171, 48, 42,196, 2,201,112,108,124,174, + 42,208,133, 87, 70, 94,141,186,109,126,149,173, 99,207,171,123,125, 85,213,107,225,244,127, 29,117, 90, 16,163,127,208,255, 0, +135, 31,245, 22,155, 78,127,238,255, 0,225,199,253, 69,166,248,208,164,108,145,241,143,119,241,208,125,148,108,143,156,123,191, +142,130,120,158, 20, 7,155, 63,121,111,209,229, 62, 14,168,140,138,237,182,106,208, 47,247,131,230,188, 48,155,112,225,233,208, + 61,191,149,127, 10,171,223, 51,183, 23,218,146,120,114,142, 44,103, 15,184,245, 65, 8, 40,165,177,243, 4,106,247,213,125, 92, + 65,191,135, 27,115,175, 82,251,171,109,234, 25, 14, 28, 29, 67, 48,202, 47,210, 77, 93,112,186, 4,247,181,250,129,120,106,231, +106,100,219, 38,205,147, 10, 69,145,183, 99, 75, 28, 70, 86,141, 30, 8,217, 84,206, 73,152,170,149, 54, 50,106, 58,188,239,198, +128,174,216,115, 55, 28,177,189, 98,101,100,137, 38,194,205,124, 88, 50, 68,106,164, 41,199,130,117, 37, 7, 3,165,166, 63, 71, + 58,193,246,214,235,189,227,166, 14, 87,175,105,132,144,236, 17,100, 36,170, 31, 90,230,100,100, 64,223, 19, 18, 67, 42,183,204, + 56,146, 5,235,213, 99,199,130, 22,145,225,137, 99,105,159,169, 51, 34,133, 46,250, 66,107,114, 62,102,210,160, 92,248, 10,139, + 14,203,179, 99, 2,184,251,118, 52, 74, 89, 36, 33, 33,141, 70,184,156,203, 27,124, 43,205, 29,139, 41,240, 38,244, 6, 33,119, +253,219, 27, 11, 22,108,105, 34,199,196, 89,243,142, 87, 73, 18, 70, 66,187,140,144, 70,243,196,205,213, 16,176, 12, 11,198, 47, +175,217, 83,191, 16, 55, 29,198, 60,108,253,191, 19, 39,210,194,155, 78, 86,108,140, 20, 23,145,149,227,137, 80, 55, 2,182,214, + 77,215,141,200,250,117, 13,177,108,211, 52, 47, 38,223,140,237,142,205, 36, 4,196,151, 70,119,234,187, 47,195,192,151,248,207, +242,184,243,162,231,237, 59, 94,232, 35,251,203, 10, 12,193, 22,174,152,200,141,100, 11,168, 89,128, 14, 15, 59,113,160, 49,185, +219,214,235,139, 38,239,247,115, 36, 93, 29,210, 85,159,162,177,190, 75, 67, 30, 14, 60,189, 68,138,118, 2, 64,174,227,169,167, +226,209,203,141, 71,219,247, 93,246, 94,224,151, 23, 31,115, 82,155,158,124, 49,245, 58, 90,146, 56,206,210,185,223,184, 73, 15, +194, 9, 0, 11,251,207, 18,107,113,149,177,236,217,161,151, 47, 3, 30,117,121, 58,238, 36,137, 27, 84,186, 68,102, 70,184,226, +197, 20, 41, 39,195,135, 42,120,218,118,213,203, 25,235,133, 0,204, 22,182, 72,137, 58,163, 74, 52, 75,251,203,106,224,140, 84, +113,228,109, 89, 96,243,183,221,247, 40, 19,239, 44, 44,132,195,147, 15,110,223,242,132, 97, 3, 69, 33,196,220, 87, 74, 20,115, +107,190,158, 45,207,137,181,175, 90, 24,251,143,117,202,221,147,111, 87, 72, 82, 93,210,124, 5,186, 2,201, 18,109,107,156,156, +249,178,204,220,125,156, 43, 65, 46,197,178, 76, 34,235,237,184,178,116, 89,158, 29, 80,198,116, 52,143,214,114,191, 15, 13, 79, +241, 55,153,226,104,135,106,218,198,121,221, 6, 12, 30,188,144,125,103, 73, 58,183,208, 98,191, 82,218,175,160,233,247,112,160, + 60,223,182,247,157,222, 61,182, 8,211, 33, 91, 43, 39, 27, 98,132,238, 18, 38,185, 16,102, 77,147, 27, 23,212, 72,114,160,105, + 93, 95,164,120,223,149, 76,205,238,174,224,139, 14,118,143, 34, 53,151, 3, 19,118,200,121,186, 42, 70, 67,109,185,177,226,198, + 64,110, 10,178, 41, 58,173,244, 90,182,233,178,236,145, 65, 54, 52, 91,110, 44,112,100, 0,179,196,144,198,170,225, 89,157, 67, +133, 81,123, 51,179, 15,105, 38,164,195,179,237, 13, 0,128,224, 99,152,150, 22,197, 88,204, 72, 84, 64,228, 51,195, 98, 62, 70, + 42, 9, 94, 70,212, 4,244,232, 54,176,133, 91, 65,210,225,108,108,214, 6,198,220,141,141, 60, 32, 60, 0,224, 69, 14, 56, 49, +225,105, 90, 8,146, 38,157,250,179,148, 80,165,228,210,169,173,237,243, 54,148, 2,231,192, 81, 3,170,243, 62,202,128, 93, 43, +192, 91,242, 82, 42,106, 99,127, 15, 26, 83, 36,103,155, 15,174,154,178,165,216,234,160, 9,167,137, 30, 21,197,120, 89, 71,190, +134,211,131,123, 15,166,198,144, 76, 8,191, 27,242,181,141, 0, 69, 3,199,137,168,206,151, 99, 98, 64,240, 20,254,175,144, 55, +247, 90,135,169,136,251,106,160, 55, 73, 28, 53, 83,149, 47,196,154, 79,140,139,242, 6,184, 51,175, 47,174,168, 27,226,212,225, + 77, 23, 36,159, 58, 80,109,206,160, 5,123,155,249,209, 22,134, 41,224,218,128,229, 28, 73,246,154, 89, 44, 69, 42, 14, 30,250, +231,228,106,144,140,207,101, 32,115, 52,144,248,154, 99,252,198,137, 15, 35, 80,210, 27, 63, 18, 47, 75, 1,178,253,116,172,133, +223,129, 2,195,198,186, 49,101,250, 77, 57, 2, 82,165,163, 81,226,196,155,159, 32, 42, 58, 9, 8, 58, 31, 72, 67,113,244,241, +163, 74,223,217,160,253, 91,159,167,133, 48, 95, 75,144, 62, 97,195,232,168, 81,216,183,187, 22,241,231,239,161,200,160, 92, 15, + 58, 85,144, 95,135,141,184, 83, 93,184,113,241, 52, 3, 44, 52, 17,254,156, 41,240,230,188, 11,161, 64, 32,154,103, 52, 63, 77, + 27, 28,225,232, 2, 80,117,123,237, 90, 50, 61,247, 19, 36,125, 34,128, 23,225,123, 82,175,137,246,211,166, 76, 19, 24,104,143, +239, 46, 52,143,166,146,194,214,160, 28, 79,151,228,165, 0, 21, 30, 39,198,155,111, 58,164,219,251,183,107,207,223,243, 59,114, + 33, 44,121,216, 96,150, 50, 42,136,228,211,167, 87, 73,131, 49, 54,212, 57,129, 64, 94,243,164, 2,231,217,229, 85,240,239, 56, +179,111, 25, 59, 26,172,131, 43, 22, 20,200,146, 66, 7, 76,172,132,133, 10,117,106,191, 15, 42,177,183,210,104, 14, 35,128,164, +181,137,168,147,238,216, 88,251,150, 38,211, 43,145,151,154,178, 62, 60,122, 73, 5, 98, 26,156,150,228, 45, 83, 72, 38,128, 29, +190, 48,124,174,127, 37, 74,198,136,170,252, 95, 49,226,104, 81, 45,222,254, 2,141, 60,233,139,143, 46, 67,130, 82, 20,105, 24, + 47, 59, 40,212,109,123, 86,163,212,141,135, 11,237,167,128,195,149, 80,118,199,117,237,157,219,130,249,251,104,145, 22, 57, 12, + 82, 67, 58,170,200,166,193,129, 33, 25,197,152, 30, 6,245, 51, 98,223,113, 55,236, 71,204,196, 89, 18, 56,230,151, 29,150, 96, +161,181, 66,218, 24,141, 44,194,215, 28, 43,123,136,245,224, 90,134,183,133, 17, 28,248, 10, 96,101,167,171, 45, 69,212,180,234, +120,142, 6, 79,110,227, 96,254, 36, 75,221, 88,103, 55,105,110,225, 49,206,169,110,164, 93, 89,164,140, 79, 23,136,100,213,126, + 21,154,252, 68,155,101,207,252, 68,237,215,194,220,113,254,232, 56,123,122, 71,184,228, 42,207, 2,198,142,235,174,120,205,131, + 90,223, 18,181,189,182,175,114,155,240,219,177,119, 12,172,140,204,205,154, 25,167,202,145,166,200,114,100, 26,228,118, 46,206, +192, 56, 23, 36,222,179,217,157,139,216,120,221,227,183,118,226,246,214, 25,198,205,196,159, 41,230, 45, 55, 80, 52, 44, 20, 40, +253,230,155, 27,214, 26,163, 21,161,230, 95,137,141,177,230,118,174, 11, 98,103,237,249,123,166,223,157, 60, 19, 77, 12,184,103, + 38,108,115,194, 39,209,131, 28, 73,160,252,193,108,116,142, 23,189,235,109,219,251,143,101,225, 99,126, 29, 47,112,199,233,119, + 65,130,147,109,155,189,194,168, 97,120,189, 52,237,250,141,175,134,174, 0,249,120,217, 71,248, 93,177,166,113,135, 43,182,176, +198, 39, 94, 71, 92,128,198,253, 27,158,156,122, 68,183,189,173,225,246, 80,143,225,198,206,243, 97,200,189,171,139, 36,122,102, + 92,172, 51, 47, 16, 67,126,229,145,204,182,249, 69,200,189, 93,174,149, 21, 51, 95,134,168,141, 63,112,201,165,117,142,224,132, + 44,165, 85,172, 11,203,113,196,142, 6,190,130, 32,158, 66,188,247,105,237,121,246, 65, 38, 46,215,219,216,248,152,249, 15, 28, +178,250,121,202, 40,120,203,233,123,180,165,239,102,175, 65,141,116, 34,173,201,210, 0,185, 36,158, 3,196,158, 38,161, 69,227, +229,198,213,212,190, 53,212, 5, 3,242,143,254, 28,127,212, 90,111,182,244,247,253, 1,254,238, 63,234, 45, 51,143, 42, 2, 54, + 65,248,199,187,248,232, 87,162,100,131,172,112,240,251,104, 52, 3,238, 46, 9,164, 12, 1,172,252, 29,209,141, 58,109,206, 98, + 49,166,225,149,153,134,172,236, 45, 25,194,245, 26,221,207,234,183,166, 54,247,209,227,238,109,134, 92, 87,205, 76,216,206, 60, + 79, 28,110,228, 48,248,166,183, 74,192,128, 72,147, 80,210, 71, 3,225, 66, 23, 5,135, 17, 77,230, 57, 85, 68,157,209,176,195, + 28, 19, 73,157, 26,199,144,172,241, 49, 13,242,198,226, 57, 25,133,174,161, 24,217,181, 91, 79,141, 75,139,119,219,101,157,113, + 99,201, 86,153,229,151, 29, 99, 23,185,150, 1,170, 84,229,250, 34,133, 39, 1,111,166,184,123,106,146, 30,234,219,101,206,205, +218,217,140, 89,152,147, 60, 9, 19,127,122, 99,129, 50,152,161,182,145,240,185,224, 77,254, 19, 79,194,238,109,171, 54, 13,181, +158, 97, 6, 70,231,143, 6, 76, 56,207,197,149,114, 23, 92,106,236, 6,144, 91,136, 91,159,136,131,106, 16,185, 6,158, 45, 84, +169,220,219, 3,182, 74,174,116,100,226, 71, 44,249, 12,117, 0,177,192,221, 57, 91, 81, 22, 58, 27,131, 91,149, 70,194,238,188, + 45,194, 98,152,224, 44, 75,153, 38, 9,146, 70,208, 88,197,138, 51, 89,210, 54, 93, 71,131, 88,169,177, 22, 38,163, 41,162, 54, +174,181,197, 81,199,221,123, 4,184,211,230, 71,159, 27, 65,142, 34, 50,184, 13,203, 35,132, 58, 70,155,191, 80,240, 93, 55,185, +225,206,159,141,220,187,126,102,102, 14, 38, 11,122,148,206,143, 42, 68,200, 67,240,169,195,104,163,145, 24, 27, 27,234,155,242, + 84, 5,185, 20, 88,163, 75,106,110, 36,208,238, 42, 72, 26, 84, 88, 0, 42, 1, 22, 56,129,226, 7,178,137, 18, 71, 98,116,142, +116,222, 22,191,151, 42,124, 96, 5, 6,254,222, 52, 3,213, 87, 87, 32, 41, 13,245, 0, 0,211,226,105, 67,173,184,184, 95,166, +154,242,192, 57, 56,250,232, 7, 21, 0,115,226, 5, 71, 82,164, 30, 23,177,167,153,146,199, 73,185,250,232,125, 85, 3,229, 55, + 30,195, 64, 56,145,202,128,120,142, 10,111,202,156,210,131,107,131,106,105,113,237,250,170,160,112, 44, 60, 57,123,105, 9,107, + 88, 82,106, 22, 60, 13, 33,111, 33,194,168, 16, 26, 82,126, 19,238,166,147,194,145,137,211, 80, 8, 41,222, 20,130,157,110, 20, + 3,199, 0, 41,178,155, 33, 52,251, 80,230, 23, 75, 26,164, 34, 0, 93,184,120,212,133, 80, 46, 41,144,167, 27,253, 84,183, 34, + 66,125,181,158, 44,208,226,188,111, 67, 78, 92,105,224,146,198,255, 0, 69, 51,202,168, 15, 37,137, 45,228,139,252, 52, 68,150, + 53, 97, 25,241, 54,191,183,202,134, 77,148, 72, 71,194, 70,134,161, 18,250, 0, 85, 22, 63, 22,191, 42,133, 28,202,160,179, 40, +181,159, 72, 35,216, 46,104,110,117, 90,138, 10,155, 42,113, 88,212,146,222,108,220,232, 77,107, 85, 33,196, 29, 28,185,208,217, + 56,131,106,156,110, 16, 2, 1, 22,166,157, 38,223, 13, 82, 17, 0, 2, 84,183, 46, 31,195, 83, 65,250,252,234, 33, 55,156,120, +121, 84,180,227, 97, 64, 58,226,188,206, 77,171, 35, 51, 39,184,119, 77,168,127,245,173,159,117, 57, 88, 64, 14, 46,189, 8,196, +176, 31,228,202,162,214,241, 53,233,186, 71, 1,227, 85,251,118,205,139,182,101,238, 25,112, 60,141, 38,229, 48,200,156, 57, 5, + 67, 5, 9,100,210,171, 97, 97,227,122, 6, 98,241,187,130, 44,221,207,121,238, 45,183,226,182,193, 30, 76, 72,108, 74,201, 25, +157,140,109,237, 86, 93, 38,163,201,178, 69, 15, 99, 47,117, 38, 94, 71,223,195, 17, 55, 31,188,140,242,107,234, 48, 18,152,244, +235,209,167,142,141, 58,109, 90,188, 14,213,217, 54, 93,207,113,220,113,181,234,221, 1, 25, 24,174, 84,194,161,137,102, 17,174, +144, 64, 98, 79, 11,154,130,189,145,182,156,117,219,142,231,156,118, 96,218,190,233, 50,175, 70,193,181,244,203,232,234,152,239, +250, 58,168, 66,151,115,218,176,247,206,238,237,172,140,193, 50, 54,233,131, 44,217, 43, 28,210, 71,103, 72, 80,128,154, 88,104, +246,219,159,141,122, 30,227,149,143,183,224,100,230,229,185, 76,120, 34,121,101,101,230, 21, 65, 39, 77,188,124,170,171,120,237, +205,187,121,159, 7, 41,178, 50, 48,178, 48, 53,140,121,240,164,232,184, 73, 0, 87,142,250, 91,225, 32, 85,198, 86, 30, 62,227, +139, 62, 22, 82,245, 49,178, 99,104,165, 67,194,232,224,171, 11,143, 97,162, 41,229,172,185, 24,153,157,177,189,109,219, 92,251, + 86, 54,102,231,139,140, 51, 50, 51,164,155, 35, 38, 28,155,240,154, 2, 93, 84, 50, 11,241,107,138,245, 77,219,255, 0,203, 51, +127,224, 75,253, 67, 89,216, 63, 15,112,163, 27,120,200,221,183, 44,152,118,172,136,178,176, 32,150,100, 49,161,128,221, 16,175, + 75,226, 30, 30,118,224, 8,227, 90,185,177,211, 39, 30, 88, 36, 36, 44,200,209,177, 94, 96, 48,210,109,123,249,214,226,140,158, + 93,179, 15,242,198, 15,110,119,116, 28, 54,204,236, 76,108, 29,252, 45,180,175, 0,144,101,183,243, 24,232, 99,229, 77,121,230, +135,179,166,124,121, 90, 50,221,196,234, 90, 54, 43,117,108,195,113,117,240, 53,232,152,221,185,182,227,118,250,246,211, 43, 79, +183,172, 7, 24,137,136, 46,200, 65, 28, 74,133, 23,227,204, 10,173,198,236, 93,150, 14,217,151,181, 58,153, 18, 96,200,230, 94, +179,186,245,213,203,137, 3,171,162, 40, 5, 88,112,248,106,209,252, 0, 14,232,158,120,251,171,179,227, 73, 25, 18, 92,140,161, + 34, 41, 32, 48, 16, 92,106, 3,157, 85,109,157,191,139,220,187,223,117,197,187,100,101,203, 20, 25,130, 44,104, 87, 38,100,142, + 61, 81, 6,214,168,142,160,144, 79, 0,110, 7,149, 95, 98,246, 62, 50,110, 59,126,235,155,186,238, 27,134,102,218,206,216,237, +147, 50, 50, 89,215, 65, 82,130, 48, 57,120,142, 39,196,213,214,215,176,226,109,121,155,150,110, 59,200,242,110,147, 12,140,133, +144,169, 85,112,161, 45, 30,149, 82, 5,135,137, 53,118,215, 90, 3,203, 48,246,165,207,252, 44,255, 0, 55,229,103,231, 62,251, +141, 20,146,226,101,250,169,135, 75,211, 78,240,162, 70,138,225, 0,208,156, 77,175,126, 55,173, 86,239,129,141,220,125,233,218, +240,110,109, 43, 69, 62,209, 52,179,136,101,146, 2,231,247,108, 67, 52, 12,141,164,147,200, 26,208,225,246, 86,217,143,218, 77, +217,169, 44,231,110,104,228,136,204, 89, 58,250,101,145,166,111,139,167,162,250,155,135,193, 70,220,187, 43, 15,114,202,219,243, +162,220,115,182,252,173,183, 24,225,193, 54, 28,145, 35, 24,218,215,215,212,134, 78, 39, 79,133,171, 13, 19, 67, 37,143, 44,253, +165,188,247, 94,205,181, 77, 54, 86,217,183,109,127,122,226,227, 79, 35, 76,113,166, 10,237,208, 70,144,179,105,123,106,177, 53, + 65,133,180,247,126,102,201,129,190,236,155, 62,115,247, 20,171, 14, 98,111,146,110, 48,104,155, 89, 18, 58, 60, 13,144, 7, 73, +144,149, 9,164, 91,199,198,189,107,101,237, 93,167, 99,135, 41, 49,145,231,151, 60,234,207,203,203,115, 60,249, 6,218,127,125, + 35,243, 0, 30, 3,149, 83,227,254, 28, 98,225,127,134,193,222,183, 76, 93,163, 86,177,180, 69,144,162, 1,118,212, 99, 86, 40, +100, 17,159, 21,213,244,212,174,148, 26,148,178,237, 95,230, 31,196,156,216, 55, 44,140,152,241,112,176,176,114,198, 4, 83, 17, + 19, 76, 28,144, 36, 3,131, 40,177,184, 28,235,210, 53,183,133, 86, 69,176,226, 99,239,217,125,194,143, 33,203,204,130, 44,105, + 99, 98,189, 32,144,146, 84,168,211,170,252,120,252, 85, 99,111, 51, 85, 10, 75,144,253, 77,249, 47,249,107,169, 44, 45,207,195, +248,235,170,151, 95,129, 76,246,248, 15,251,184,255, 0,168,180,218,115,255, 0,118, 63,221,199,253, 69,164,184,172,154, 34,100, +252,227,135,135,241,154, 8,181,252, 40,249, 39,227, 30,239,182,128, 69,205, 1,137,197,236,118,197,147,111,204,134, 44, 40,247, + 44,124,189,199, 35, 47, 49, 80,117, 36,143, 45,114,214, 5, 46, 99,212,250,122,241,234, 86,225,195,133,248, 85,103,249,111,184, +118,252, 62,172,177, 38, 78, 84,249,123, 51, 20, 73,166,156,235,196,200, 94,172,142, 90, 47,130, 47,210,248, 69,145,124, 56, 87, +164,218,220,169, 56, 94,128,243,108,158,218,223,140,173,133, 28, 17, 25,183, 61,191,120, 76,169, 89,164,244,248,237,185,102, 69, + 46,133,144, 70,117, 50, 43,220, 41, 3, 86,147, 86,219, 54,210,233,222,187,158, 98, 7,251,191, 22, 48, 33,103, 70, 64,114,242, + 18, 24,178, 25, 11, 0, 26,201,136,151, 35,135,198,107,103,111, 42,235, 30,116, 6, 61,251, 99,118,151,119,154, 70,104, 23, 1, +247, 25, 55, 88,229, 87,115, 53,219, 3,238,245,133,144,198, 20,124, 71, 81, 33,143, 10,137,135,217, 27,134, 62, 78,213,214,233, + 79, 30, 52, 27, 90,100, 63,169,201,141, 35,151,109, 31, 17, 76,120,244, 71, 62,178, 20,163, 73,242,241,225,225, 91,187,154,235, +241,189, 1,135,147,177,247, 57, 49,100,129,166,199, 86,108, 77,210, 5, 55,114, 58,153,185,233,159, 5,198,129,240,133, 75, 63, +145,229,122, 60, 29,179,188, 75,154, 55, 12,191, 77, 11,201,185,100,103,188, 49,202,242,105,142,109,183,238,244, 77, 70, 36,187, + 9, 56,158, 22,183,213, 91, 43,220,215, 14, 62, 84, 7,159, 75,219, 59,150,205,182,199,152,230, 41,164,192,198,216,227, 88,226, + 19, 72, 26, 93,177,164, 19,106, 17,196,210, 8,207, 86,225,149, 24,142,101,120, 85,159,105,109,121,129, 49,247, 76,204,100,142, + 67, 54,235, 37,219, 92,110,171,155,150,179, 33, 72,100, 77, 86,117,142,255, 0, 17, 82, 5,184,113,225,174,226, 5,117,248, 86, + 65,199,229,189, 23, 79,155, 55,186,230,134, 44, 64, 30,234, 41, 28,120, 84, 2,116,212,243,227,236, 38,158, 35, 67,195, 79, 58, + 64, 15, 59, 91,219, 78, 39,198,128, 70,208,162,214,174,176,210, 60, 7, 42,105,179, 1,115,126, 52,230,117, 94, 68, 95,203,133, + 0,240, 7,143, 10,226,109, 76, 50,165,129,213,115,229, 76,234, 3,204, 31,168,213, 3,139,112,183,133,233,183, 94, 28,105,174, +117, 15,148,129,230,105, 44, 60,168, 5,186,249,210, 93, 88,219,198,147,147, 10,119, 11,131,227, 84, 28, 64,166, 73,193, 61,230, +156, 79, 26,100,156,128,246,212, 2, 14,116,227,229,254,156,233,163,157, 60, 31,136, 15,117, 8, 18,131, 63, 43, 81, 73,181, 71, +144,220,138,160,114,112, 20, 45, 99, 93,143,141, 16,155, 45,168,104,160,241, 34,245, 18, 52,199, 92,124, 68, 83, 60, 5,233,129, +130,221, 64,176,167,178,252, 54,163, 8,153, 27, 0,172,141,196, 27, 94,150, 72,144,199,164, 95, 79,133, 71, 89, 44, 45,111,244, + 2,187,174,121, 2,106, 80,163,155, 74,174,132,224, 40, 36,220,251,169,197,129, 94,116,141, 96, 46, 60,141, 82, 15,142, 81, 48, + 60, 45,110,117,216,113,117, 75,234, 38,222, 28,125,244,204, 97,165, 26,254, 63,101, 75,195, 84, 64,218, 1,226, 5,239,231, 84, +131, 91, 6,206,174,173,123,121,251,168,134, 7, 30, 23,163,179, 89,120,120, 83, 18, 75,141, 68, 90,254, 20, 21, 4, 85,151,157, + 34,251, 56,210,188,225,180,133, 60, 24,216,210,173,135, 42, 2,187, 47,251, 99, 64, 28,232,249, 34,243,181,185, 82, 42, 27,222, +128, 85,137,203,132,226, 15, 14, 94, 85,109, 10, 5, 0, 15, 10, 2,168, 50,151,247, 15,170,165,198, 42,160, 60,143, 10, 90, 80, + 46,109, 79, 43, 91, 70, 27, 25,196,210,133,165,181,188,105,233,122,210, 21,168,208, 8,229, 69, 82,124,105,192, 19,225, 68, 84, + 30, 52,149,121, 10,208,114, 15, 27,209, 65,181, 32, 81,106,112, 28,107, 1,161,193,169, 25,155,244,105,214,174,179, 84,208,210, + 6, 88,248,138, 97,183, 58, 54,155,243,166,148, 21, 83, 69, 25,195, 79,244,127,253, 42,234,126,145,111,163,248,235,170,215,241, + 5, 36,151,253,223,252, 56,255, 0,168,180,223, 42,123,142, 9,255, 0, 14, 63,234, 45, 52,242,172, 2, 46, 79,246,163,221,252, +116, 43, 91,217, 69,201,182,177,238,161,125, 31, 77, 0,132, 19, 74,214, 28,171,169,166,244, 7, 95,141, 47, 26, 65, 79, 2,226, +252,232, 65,188,184, 82,123,233,228,113,189,171,188,121, 10, 1, 45,237,164,226, 41,108, 7,141,119, 51,207,133, 0,163,136,227, + 75, 97, 72, 60,125,148,170,111,122,203, 41,201, 30,179,166,246,176,189, 19,162,111,197,207,228,165,135,244,190,142, 54,162,155, +183, 63, 10,128, 1, 69, 44,170, 9, 62, 98,244, 78,140, 68,218,196,251, 9,164,211,105, 57, 1,237,162, 19,226, 45,112,104, 5, + 88, 35,183, 5, 2,152,202,160,216, 1, 68,215,227,123,211, 11, 40,226,109,198,128,109,129,101,183,190,136, 70,174, 22,160,137, + 19, 95,204, 45, 79,105,163,225, 84, 13,157,120, 42,220,253, 20, 29, 43,123, 92,209, 29,140,156, 71, 47,104,166,232, 60,245,113, +160, 19, 66,240, 54,166,216, 2, 45, 79,183,242,143, 10,105, 0, 17,106, 1, 26,152,254, 20, 78,102,134,255, 0, 55,209, 64, 32, +249,169,255, 0,222, 83, 23,157, 43, 27, 61,253,134,132, 8,231,133, 71, 54,212, 61,181, 33, 78,165, 6,131, 32,179,251,170,131, +143,141, 34,158, 22,174,189, 9,195,169, 58,121, 26,134,135, 88, 53,248, 15, 97,167,181,200,250, 5, 2, 57, 26,225,124,205, 74, +140,160, 36,185,176,224, 56,209,132, 10,252, 62,131, 77, 60, 15, 31, 34, 42, 93,161,117,109, 62, 7,248,105,141,142, 15,178,245, + 10, 71, 22,191, 30, 84,246,182,158, 30, 86,167,188, 4, 14, 7,253, 63,208,211, 24, 89, 61,188,168, 7,142, 17,147,254,156,168, +155,123, 49,141,137,227,241,127, 21, 48,240,133,175,206,199,248, 41,248, 28, 34,111,107, 86,145,150, 74, 62, 20,134,187,233,174, +161, 8,210,168, 87,140, 14, 87,185,162, 11,147,236,166, 79,253,180,107,239,162,128,109,195,157, 10, 64,154,221,102,242,191,241, + 83,227, 93, 70,222,226,105,146, 92,202,222,250,145, 18,219,143,141, 1, 34, 49, 82,208, 88, 84,104,133, 75, 81,200, 86,146, 32, +225,192, 95,198,146,231,206,148,145, 93,107,242,173,197, 25,226,119, 15, 19, 79, 71, 11,202,134, 86,184, 10,172,195, 77, 58,146, + 67,147,227, 68, 83,237,168,235, 97, 78, 13,198,175, 35, 73,174,100,144,198,136, 13, 5,120,142,116,237, 44, 56,214, 90, 69,221, + 80,234,194,157,172,120, 84,109, 70,156, 24,214, 92, 74,131, 94,252,233, 62, 17, 77, 6,145,143,149, 40,105,164, 59,133,190,143, +227,174,166,220,233,254,143,241,215, 82,159,137, 40,138,103, 60, 19,254, 28,127,212, 90,109,233,206, 62, 79,248,113,216,255, 0, + 65,105,160,115,242,172,148,141,144,126, 49,199,194,130,120,138,150,240,245, 13,245, 91,194,220,255, 0,142,154, 49,127,151,127, +162,128,139, 99, 75,110, 22,189, 73,244,162,223, 55,211,106,225,139,252,175,201,249,232, 8,192,123,107,133, 73,244,196, 31,159, +242,126,122,239, 76, 63, 95,242, 80, 17,203, 2, 60,205, 32,191, 59, 84,129,139,199,231,252,159,158,148, 99,142, 69,191, 37, 0, + 15,160, 82,113,183, 58, 63,167,254, 87,228,252,245,222,152,223,230,252,159,158,128, 0,227,198,157, 97,107,209,189, 61,191, 79, +242, 82,250,127,229,126, 74,140, 2, 64,224, 16,182,183, 62, 52,255, 0,140,145,118, 23,241,176,163, 71,142, 66,145,171,153,191, + 47,207, 78,244,255, 0,202,227,238,172,128, 29, 62, 58,153,205,254,142, 84,162, 43, 95,226, 60,125,180,126,150,145,243, 95,222, + 41, 68, 68,115,107,249,112,170, 8,198, 53,213,199,149,185, 19, 74, 81, 0, 22, 3,234,163, 8,128,213,118,231,236,252,244,189, + 0,120,106,246,242,160, 1,164, 94,214, 21,204, 23,145,181, 25,162, 95, 23, 23,247,126,122,103, 77, 56,124, 90,188,184,113,160, + 35,151,179, 30, 23,166,235, 45,192, 15,174,142, 96, 4,147,175,242, 83, 68, 0, 15,155,242,126,122, 0, 32, 55, 17,113,198,155, +199, 87,157, 74, 24,228,242,111,201,249,233, 61, 55, 19,241,126, 74, 2, 61,200, 52,198, 36,158, 53, 47,211, 95,244,191, 39,231, +166, 54, 53,201,248,191, 39,231,160, 35,175, 58,100,196,134, 22, 28, 45,252, 53, 48, 99, 91,244,191, 39,231,165, 16, 0,214, 45, +204,121, 80, 16, 99,151, 72, 34,185,159, 87, 31, 58,158,216,113, 30, 36,254, 74,140,216, 99, 93,149,248,123,191, 61, 0, 16, 9, + 31, 77, 57,248,163, 91,192, 26,147,233, 44, 7,199,227,229,249,233, 36,197,248, 27,227,181,199,151,231,161, 74,216,184,184,189, + 29,199,194, 79,182,141, 30, 22,153, 7,199,225,126, 94,207,125, 21,176,245, 41,179, 88, 95,203,243,209,132, 70,198,107, 49, 7, +145, 31,193, 82,137, 54,165,135, 11, 72,185,126, 62,239,207, 69,244,220,126,123,253, 31,158,163, 41, 22, 66,124, 40, 50,112, 91, +123,191,134,167,190, 63,242,173,126, 28,191, 61, 71,147, 18,246, 26,252,124,191, 61, 0, 35,241, 38,129,204,248,209, 96, 29, 24, + 24,183, 27, 30, 66,158, 49,109,250,127,147,243,210, 60, 23, 5, 67,243,246,126,122,209,145,163, 54, 3,194,196, 31,109, 56,229, + 99,149, 32,146, 47,227, 81,125, 25,185,179,254, 79,207, 93,232,219,245,255, 0, 39,231,160, 21, 28, 60,200, 47,170,192,220,212, +213, 63,109, 3, 23, 8,135,215,171,151,179,243,212,207, 79,198,250,191, 37, 10, 87, 20,253,243, 95,192,255, 0, 13, 29, 71, 42, + 51, 99,234, 98,197,185,251, 63, 61, 62, 60,110, 63, 55,228,161, 7, 70,188, 40,227,130,210,164, 0, 14, 45,192,115,164, 44,151, +183, 18, 7,176,125,181,164,210,226, 74, 62, 71, 91,133,112, 54,165, 5,125,191, 80,251,107,172,167,207,234, 31,109, 93,235,169, +143,175,160,224,194,156, 56,242,166,133, 30,223,168,125,180, 64, 84,120, 31,168,125,181,119,199,170, 45, 37,208, 75, 53, 40, 94, + 60,169, 67, 1,224,126,161,246,211,132,163,245, 79,212, 62,218,187,227,212, 56,190,129, 18,194,142, 31,133,170, 40,145,127, 85, +190,161,246,211,196,232, 63, 69,190,161,246,212,114,143, 82,168,248, 7,226,124, 41, 66,154, 15,170, 79,213,111,168,125,181,222, +173,127, 85,190,161,246,214,119, 46,162, 42, 75,138, 15,107,210,105,161, 12,180, 31,162,223, 80,251,107,142, 92,127,168,223, 80, +251,106,110, 93, 75, 36,223, 0,218,127,131,248,235,168, 94,161,116,234,179,124,186,188, 63, 91, 79,157,117, 93,203,169, 40,254, + 5, 91,129,240, 95,153,142, 63,234, 45, 51,136, 60, 40,166, 39, 97, 27, 2,182,233,199,205,212, 31,145,124, 9, 20,157, 23,254, + 71,237,167,250,213, 13, 3,231,198,186,227,143,240, 81, 58, 47,126,105,251,105,246,210,244, 30,255, 0, 50,114,227,241,175,250, +212, 7,152,108, 43,151,151,189,246,219, 77,148,207, 10, 63,112,200, 33,113,171,227,135,112,233, 43,106, 39,158,137, 52,175,234, +129,195,157, 27,119,238,253,255, 0, 3, 59,120,219,161, 49,153,182,181,204,203,102,116,186,140, 83, 22, 49,195,102,247, 62, 75, + 95,207,166,107,111,139, 14,199,214,131,209, 28, 30,175,248,175, 73,209,124,125,127,218,143, 91,210,208,215,254,214,221, 91,126, +151,205,198,162, 65,181,109, 56,251,198,241,157,147,155, 6, 70,118, 84, 17, 12,188,121,229,199,180, 56,104, 36,208,173, 24,177, + 17,146,207,118,126,127, 69, 1,157, 94,227,222,241, 55, 49,180,100, 78,153, 66, 29,194,108, 71,204, 49, 42,117, 99, 93,168,238, + 74, 44,159, 8,100,146,192,219,194,166,201,190,110,146,246,143,111,238, 49,202,144,231,111, 31,118, 71, 54, 64, 64, 86, 51,153, +211,234,186, 35,124, 55,248,136, 80,124, 77, 79,108,110,201, 27, 84, 10,231,105,251,160, 78, 78, 49,105,113, 78, 63,168,179, 19, +160,179,232,234, 91, 85,252,109,122,157,145, 6,198,219, 26,174, 71,161,251,132,197, 24, 66,242,227,140, 78,137,211,209,210,117, +116,194,252,186, 45,236,181, 64,121,230, 46,255, 0,191, 97,108,108,113,115, 85, 91, 11, 27,123,221, 36,150, 88,196,158,165,241, + 55, 9, 35, 72, 6,182,248, 82,198,223, 9,184,186,219,219,119,137,220, 91,212,253,205, 22, 52,146,170,224,201,185,205,183, 28, + 78,144,212, 17, 54,197,220, 67, 25, 62,109, 66, 78, 30,234,186,120, 59, 57,176,246,251,141,160, 96,137, 92,237,159,189,197, 16, +245,186,135,169,233,236,193,117,117, 62,109, 63,165,207,141, 78, 16,236,231, 52,104,244, 3, 59,212,189,180,190, 63, 91,213,244, + 6,191,210,213,213,244,252,255, 0, 75, 71,242,104, 12,230,193,137,184,109,189,212,118,153,247, 23,203,131, 11, 99,219,211, 75, +173,131,186,201,145, 3, 77, 98,205,102, 99, 22,162,110, 79, 27, 95,128,170, 71,239,110,225, 76,183,192,213, 17,145, 93,182,160, +218, 5,254,241,147, 58, 72, 32, 54,225,195,211, 34,189,191,149,126, 66,189, 5,224,219,142,237, 31, 80,225,253,243,208,110,149, +222, 1,149,233,245,124, 90,126, 46,167, 79, 95, 63, 11,212, 67,143,219,190,160,234, 59,111,168,245,171,170,242, 99,107,245,253, + 51,162,255, 0, 21,253, 71, 78,246,253, 45, 62,202, 3, 25, 47,121,239,144,195,190, 78,146,172,201,143,183,229,231, 97, 74,208, +162, 68, 36,198,200,108,112, 34, 80,230, 70,143,192,245, 64, 37,129,183, 10, 60,251,142,247,145,184,224,226,205,185,127,220,251, +144,224,180,137, 26,167, 86, 19,183, 28,176,174,170,108, 64, 46,203,111,113,230, 42,253, 49,187, 33, 91, 47, 67,108,218,138,206, +115,191,123,134, 78,141, 67,212,245,190, 47,151, 85,186,151,225,126,117, 55, 39, 31,183,108,254,176,237,182,245,137,212,234,201, +141,255, 0,127,208,157, 61, 90,155,251,125, 26,116,254,149,173, 64,102,119,189,207,123,194,238,249,225,192,205, 49,197,147,141, +181, 99,162, 50, 7, 72, 61, 86,108,240, 52,161, 73,177,127,134,192,158,101,128, 60,128,171,140, 93,227,123,155,180,115,243, 86, + 76,113,185,226, 77,153,135, 6, 84,229, 97,134, 87,199,201,147, 22, 57, 62, 34, 16,107,208, 60,116,234,246, 84,205,211, 27,182, +206, 67, 13,228,237,190,168,227,144,222,170, 92, 97, 47,166,214, 47,253,163,106,233,235,183,179, 87,182,166, 44,123, 74,236,133, + 88, 96,182,195,209, 34,230, 72, 61, 39, 67,223,171,167,163,242, 84, 6, 3, 35,189, 59,161, 98, 56,248,129,231,200,195,143, 46, +124,133,154, 60, 88, 28, 28,121, 34,141, 97,205,105,167,138, 37, 85,234, 29, 77, 1,110,106, 71,141, 94, 97,119, 6,253,147,221, +239,183,244,200,218,198,108,248, 5,159,211,170, 1, 14, 32,201, 12,151,151,212, 60,165,249,142,158,157, 7,217,122,181,244,253, +134, 49,118,254,161,217,253, 58, 74,255, 0,119,106,151, 19,167,214,212,162, 78,143,197,102,125,122,117, 91,142,171, 95,141, 88, +199, 15,110, 13,253,222, 51,183,255, 0,152, 52, 90, 64, 30, 3,153,160, 42,252,194,253, 75,104,211,244, 91,194,212, 6, 15,187, +159,115, 94,237,104, 32,220,100,138, 22, 27, 15, 78, 16, 62, 20,105,119, 57, 34,102,176, 97,127,147,226,253, 96,108,120, 10, 92, +125,251,120,149, 98,156, 73,138,251,154,237,187,194, 69,151,147,166, 37,105,113,119, 56,112, 97,212, 73, 88,215, 88,183, 14, 69, +173,225, 91,173,198, 46,217,251,207, 31,239, 83,183,125,237,104,253, 39,169,108,127, 83,110,178,244,186, 93, 67,174,221,125, 58, +109,250,118,183, 26, 28,145,118,151, 65,196,135,107,232, 24,114,186,154,159, 27, 71, 67,172, 61,110,171,155,104,235,219,171,225, +175,230,227, 64,103,135,112,238, 80,246, 62,247,188,117, 11,110, 59, 96,201, 8, 50, 33, 88,229,141,225, 93, 75, 30, 66, 70, 76, + 69,133,248,152,206,146, 45, 64, 77,231,184,102,205,147,100,245,233, 20,191,123,100, 97,125,228, 96, 75,136, 97,192, 77,193, 80, + 70,126, 11,151,114, 46,127, 68,121,241,173, 78, 52, 29,180,187, 20,171,142,118,239,184, 2,200, 50, 52,190, 57,196,211,115,213, +234,157, 70, 62,119,213,171,233,166,110, 48,118,171, 98,229,141,208,237,190,155,212,143, 91,215,147, 28, 39,170,233,173,186,197, +218,221, 94,150,159,155,226,211,111, 10, 3,207, 6,249,187,103,110,123,102,231,149, 32,209,159,137,219,179,190, 3, 33,233, 35, +229,103,188,111, 36, 98,252, 15, 2,192,251, 71,144,169,242,247, 87,112, 38, 36, 89,145,229,197, 52,155,158, 67,193,143,183, 68, +145,122,156,117, 92,255, 0, 68, 12, 61,102,142, 55,248, 62, 18,101,107,117, 8,240,225, 91, 44,168,123, 91,214,226,122,211,182, +122,253, 17,122, 14,179,227,117,186,125, 85,232,244, 53,182,173, 61,109, 58, 52,254,149,173,198,163, 62, 47,100, 22,221, 58,141, +180,235,114, 62,248,188,184,183,191, 82,195,212,252, 95, 9,234,254,183,233,251,106,130, 36, 27,246,226,189,147, 62,243,156,241, + 98,103,194,153, 1,164,101, 89,213, 76, 51, 60, 8,236,152,174,232, 92,133, 4,170,189,131,112,170, 21,221,183,205,198, 77,152, + 79,149, 38, 52,152,253,195, 38, 4,193,146, 37,146, 72,215, 18,105,149,103, 16, 59, 69,113,197, 72, 83,110, 71,152,173,199,167, +216, 78,198, 70,172, 31,184,122, 36, 27, 73, 7,163,232, 91,143, 29, 93, 61, 22,250, 42, 12, 88,253,152,184,170, 34, 59, 71,164, + 25, 49, 5,180,152,134, 63, 87,164,116,120,234,183, 91, 77,180,254,149,185, 80, 21,123,190,241,188,227,247, 44, 88, 48,229, 36, + 27,124,173, 6, 50, 58, 71, 28,234,179, 76, 36, 37, 50,134,174,180,114, 55,194, 98,225,160,254,149,101,251,107,185,183,184,113, +123,119, 28,230, 54,100,114, 38,221, 22, 88,104,212,233, 25,189, 65,251,249,164,126,163, 73,240,252, 26, 1,249, 78,190,117,232, +179, 99,246,215,223,112,182, 75,109,223,126,128, 4, 29, 73, 49,253, 93,136,109, 58, 3, 55, 83,150,171, 91,194,254,218,172,198, +198,252, 62,235,198,216,205,177,245,238,162, 46,156,152, 90,181,117,142,141, 33, 91,159, 90,246,183,233, 95,198,128,205,100,238, +125,193,151,143,178,238,178,110, 93, 53,151,123,203,198, 76,120,162, 10,162, 60, 85,220, 35, 85,118,213,119,212, 32,226, 15, 14, + 71,152,167,193,221,251,222, 78, 38, 59, 9,162,138, 89,241,251,113,204,189, 48, 66, 62,237, 43,197,146,218, 73,183, 32, 10,143, + 10,218, 79, 7,109,122, 24,125, 65,219,125, 7,170, 62,155,168,248,221, 31, 89,213,123,244,245, 54,158,183, 87, 95, 47,139, 85, +252,106,149,246,206,195,202,193,120,241,114, 54,168, 48, 99,159, 14,124,150,196,159, 13, 81,140, 83, 25,113,163,156,130, 84,163, +184,101, 10,121,241, 11, 64, 89,118,222,233, 62,229,183, 48,205,149,100,202,135, 39, 51, 23,168,160, 47, 89, 49, 50,100,198, 19, + 4, 30, 97, 69,237,194,245,139,155,188,119,252, 92, 28,204,238,188,115, 51,226,111, 51,193, 31, 72, 1, 3,237,153,107,141, 17, +107, 27,176,117,127,138,254, 54,181,110,176, 48,118, 14,190, 12,219, 76,152,119,143, 22,104,176, 99,197,154, 13, 39, 25,165,136, +204,209,136,219,226, 81, 34, 37,200,224, 15,180,213,102,215,181,246, 86, 12, 59,132, 49,228,109,185, 36,140,135,220,229,154,124, + 73, 31,165, 36,242, 77, 50,228,144, 71,238,210, 71, 43,241, 14, 22, 0,242,168,194, 43, 50,119,222,228,195,238, 8,118,160,222, +170, 12,105, 48, 35,203,156,174, 60, 49, 48,206,150, 69,118,110,164,203, 40, 42,130,209, 44,106,215, 42,117, 94,245, 5,251,147, +185,153,242,177, 70, 76, 77,147, 43,171,226,197, 24,199, 34, 88, 14, 73,143, 86,217, 49,147,165, 43,116,133,180, 76,117,107,191, +133,109,242,241,251,124,239, 88,141,158,118,255, 0,190, 2,219, 11,173, 38, 63,169,210, 75, 91,164, 29,181,243,213,107,123,125, +181, 93, 38, 39, 97,152,243, 6,173,155, 67,202,135,112,253,238, 32,179,235,109, 61, 83,175,131,117, 47,107,254,149,252,111, 68, + 82,167, 55,112,147,115,237,125,158,108,140,142,164,121,249,184,120,249,178,162,182, 62,168,155, 40, 68,241,186,222,233,171, 72, + 71, 0,219,137, 3,133, 70,220,118,157,141, 95, 3, 27, 1,229,149, 35,222,151, 15, 34, 54,121, 85, 98, 15, 19,206,248,145,219, + 64, 49,130,193,133,175, 99,194,252, 44, 53,239,143,177, 29,154,211,156, 15,184, 76, 42, 5,228,199, 24,125, 31,209,183,197,211, +209,123, 91,194,151, 3, 27,182,147, 7, 17, 54,246,219,142, 8,158,216, 70, 25, 49,204, 94,167,226,254,196,171, 91,171,243,114, +248,185,208, 30,111,186,122,156,125,199,116,200,141, 30, 56, 32,222, 6, 34,238, 41,144,250,227, 67,183,195,167, 23,211,240, 83, + 27,179, 88,182,174, 26,175,106,215,203,191, 79,177,246, 22, 54,233, 12, 18,101,100,197,181, 9,208,232, 50, 32,146, 60, 97, 32, +105,236,202,193, 53, 14, 38,245,117,147, 7,111, 24,167,245, 71,111,233,122,149,245, 93, 71,199,211,235, 52, 38,142,174,166,183, + 91, 70,139, 95,226,181,189,149, 3,108,199,236,111, 73,184,253,198,219, 41,193,233,255, 0,245, 99,135, 38, 31, 75,165,165,255, + 0,239, 93, 38,211,163, 78,191,159,133,175,237,160, 42,247, 77,202, 76,157,241,101,209, 62, 36, 71, 99,220,219,163, 56, 49,157, +113,203,137,103,211,114, 46, 3, 27, 26,133,186,101,110, 56,219, 31,101,100,227,228, 58, 55, 82, 14,188, 64, 92,204, 70,223, 60, +186, 28,243, 55, 41,107,121,155,243, 2,181, 91,254, 47,110, 52,112, 14,230,109,187,166, 25,142, 55,222, 18,227,129,112, 62, 61, + 29,118,242,249,173,225,206,143,185,227,237, 62,159, 31,239, 83,133,233,250,209,250, 95, 85, 36, 26, 58,255, 0,220,244,186,173, +109,127,171,110, 62, 84, 6,127,180,183,189,215, 54,118,199,220,242, 19, 48, 75,183, 96,238,105, 52,113,136,196,109,153,214, 15, + 7,194, 72, 42, 58, 64,169, 60,109,231, 84, 89, 29,231,189, 71,129,147,146,141, 23, 86, 45,191,122,203, 91,167, 14,166, 6,122, +226, 65,194,252,186,103,143,153,173,182,207,137,177,133,200,251,133,176, 52,153, 47,147,232,165,199, 35,168, 71,247,157, 38,231, +111, 58,168,205,218,187, 51, 54, 29,223, 12,100,237,152,211,228, 67,144,155,158, 70, 54, 70, 26,100, 71, 27, 50,140,150,145,245, + 18,182,125, 58,245, 11,106,181,248,213, 33, 89, 62,243,189,174,118, 71,111,250,216,195, 71,155, 52, 13,185, 8,151,227,137, 54, +209,184,136,194, 95, 72, 58,222,196,131,125, 35,207,141, 69,218,123,143,117,130, 14,215,197,138,110,180, 15,139,179, 69,153, 25, +141, 72, 30,182, 34, 25,167,154, 71, 18, 52,141,167, 82,116,193, 28, 14,174,117,172, 92,110,203,251,168,137,142,209,247, 95,169, + 45,198, 92, 95, 79,234,172, 88,241,213,163,169,107,240,231,110, 28,168,141,143,217, 30,163, 21,152,236,254,163,163,140, 48,111, + 38, 38,174,134,161,233, 58, 35, 87,201,170,221, 45, 60, 63, 86,128,193,195,220,157,209,182, 46,110, 54, 28,173,156,240,100,110, +249, 76,207,233,209,109,141,157,233,214, 57, 95, 42,104,180, 67,196,223, 69,216, 93, 64,224, 56,236,123,223,184, 51,187,107, 23, + 27,113,131, 73,197,111, 83, 12,200, 87, 83, 25,206, 52,146,226, 91,223, 44, 65, 63,164, 42, 86, 70, 63, 98, 28,159,241,103,102, +245, 75,148,197,186,146, 98, 9, 61, 95,192, 31, 85,218,230, 95,146,247,227,242,251, 42, 79,114,109, 88, 57,240, 97,253,237,155, + 30, 46, 22, 62, 84, 51, 50, 60,176, 36,115, 74,142, 26, 8,221,229, 62, 50, 1,193, 72,213,202,128,202,195,220, 29,199, 14,116, +126,170,120,228, 81,156,251, 76,184, 75, 16, 4, 52, 91,113,205, 57, 90,199,197,198, 69,189,190, 93, 36,123,232, 88,253,225,191, +228,225, 99,244,165,134, 60,140,140,126,219, 97, 33,136, 48, 89, 55,121, 94, 44,150,211,168, 92, 88, 13, 34,252, 43,102,184,251, + 7,223,108,218,176, 62,252,233,217,255, 0,121, 7,170,233,216,115, 26,186,154,116,219,232,168,251,100, 61,138,177, 48,218, 78, +206, 99,234, 99, 22,244,207,136, 71, 84,200,222,142,250, 27,230,234,223,165,252,175,150,128, 77,251,117,207,218,103,216,176,163, +149,100, 57,143, 60, 89,146,186, 0, 95,163,133, 62, 64, 96, 7, 5,188,145, 2,109,238,172,156, 61,223,191,105,217,247, 9,230, +140,226,229, 97, 96,203, 42, 66,137, 34, 28,156,140,118,158, 88,114, 2,183, 90, 23,127,135,162, 66,232,243,173,214,247, 6,196, +240, 69,254,100,108, 17,143,213, 83, 15,175,120, 66,117,130,182,157, 29,102,182,173, 58,190,139,212, 56,113,251, 55,239, 12, 22, +199,109,171,239, 1, 12, 99,109,233,201,139,213,232, 20, 61, 31, 78, 21,181,104,233,223, 70,159,209,189,184, 86, 91,171,224, 84, +100,112, 59,175,186,167,219, 3,204, 82, 9,242,102,217,134, 52,243, 46, 59, 16,187,164,221, 41,109, 14, 44,242,126,237, 69,140, +102, 66, 24,223,143, 42,212,119, 46,102,231,134,187, 70,217,141,152,176,201,155,215, 92,172,214,141, 73, 97,143,137, 36,228, 42, +112, 85,234, 50, 92,219,144,189,188,234, 78,221, 7,102, 46, 51, 13,172,237, 94,152,228,194, 91,211,190, 49,143,213,151, 83,143, +242, 53,186,186,244,244,252,111,109, 53, 63,125,135, 99,108, 52, 29,198,112,189, 31, 85, 76,126,189,225, 17,245, 64, 98,186,122, +199, 78,173, 58,190,139,248, 83,216, 15, 61,217, 59,179,126,138, 62,221,195,199,140,203,137, 22, 14,198,153,114, 72, 96, 8,254, +185, 52, 75, 36,178, 79, 50, 76, 92, 1,120,196,104,215, 96,111,206,171,160,238, 77,231, 96,131,113,147, 27, 51,212,228,122,253, +203, 43, 37, 58, 8, 75,172, 25,227, 16, 52,242, 72,235,166, 45, 63, 8, 88,254, 48, 72, 3,225, 21,190,124,126,211,108,205,177, +144,237,126,172, 67, 24,217,237, 38, 40,147,211,144,122, 94,148,106,190,139, 95, 70,142, 22,189,168, 25,152,221,144, 88, 29,201, +182,125, 65,178,109,215,151, 19,230,215,254, 50,225,219,137,234,127,107,252,175,155,141, 95, 96, 32, 79,221,251,139,110,179,109, +196,160,128,238,185,120, 28, 22,205,208,139,105, 25,201, 99,127,155,172,121,249,112,172,214,221,189,119, 6, 56,219,159, 3, 61, +157,229,237,237,136,140, 87, 49,153, 24,200,211, 9,206, 55,169,101,141,242, 10,198,196,106,249,185, 30, 66,183,126,155,180,126, +247, 36,182,213,247,201,231,121, 49,125, 87, 8, 79,134,173,127,216, 95,250, 30,202, 6,110, 55, 99, 52,120,203,158,219, 54,131, +139, 24,194,234,201,136, 63,194,106, 94,151, 64,179,127,101,171, 78,157, 63, 13,237,106,158,192, 89,118,214,252,187,158,207,139, +147, 52,201,145,146,201,121,153, 80,196,126,102, 64, 94, 34, 73, 67,240, 16,124, 46, 13,184, 85,191,173,143,202,170, 54,204,125, +142,231,238,102,193,191, 70, 27,250, 73, 32,255, 0,187,252,126,159,251, 38,254,207,231,209,225,206,222, 53, 99,233,207,235, 39, +254,209, 63,214,165, 60, 5, 67,122,216,252,171,189,108, 94, 84, 15, 78,127, 89, 63,246,137,254,181,119,167, 63,172,159,251, 68, +255, 0, 90,148, 21, 36,122,216,255, 0, 86,187,214, 71,229, 64,232, 31,214, 79,219, 79,245,169,194, 15,229, 39,237,167,219, 74, +120, 2, 87,168, 78,158,171,127,119,127,163,169,166,186,135,160,105,233,220, 95,163,206,227, 79,246,191,173,202,186,128,255,217, +}; +#endif diff --git a/source/blender/src/pub/unix_publisher_splash.jpg.c b/source/blender/src/pub/unix_publisher_splash.jpg.c new file mode 100644 index 00000000000..c1ec0dc0430 --- /dev/null +++ b/source/blender/src/pub/unix_publisher_splash.jpg.c @@ -0,0 +1,950 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +/* DataToC output of file <splash_jpg> */ +#if !defined(WIN32) && !defined(__APPLE__) +int datatoc_tonize= 29208; +char datatoc_ton[]= { +255,216,255,224, 0, 16, 74, 70, 73, 70, 0, 1, 2, 0, 0,100, 0,100, 0, 0,255,236, 0, 17, + 68,117, 99,107,121, 0, 1, 0, 4, 0, 0, 0, 50, 0, 0,255,238, 0, 14, 65,100,111, 98,101, 0,100,192, 0, 0, 0, 1,255, +219, 0,132, 0, 8, 6, 6, 6, 6, 6, 8, 6, 6, 8, 12, 8, 7, 8, 12, 14, 10, 8, 8, 10, 14, 16, 13, 13, 14, 13, 13, 16, + 17, 12, 14, 13, 13, 14, 12, 17, 15, 18, 19, 20, 19, 18, 15, 24, 24, 26, 26, 24, 24, 35, 34, 34, 34, 35, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 1, 9, 8, 8, 9, 10, 9, 11, 9, 9, 11, 14, 11, 13, 11, 14, 17, 14, 14, 14, 14, 17, 19, 13, 13, 14, 13, 13, + 19, 24, 17, 15, 15, 15, 15, 17, 24, 22, 23, 20, 20, 20, 23, 22, 26, 26, 24, 24, 26, 26, 33, 33, 32, 33, 33, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39,255,192, 0, 17, 8, 1, 15, 1,244, 3, 1, 34, 0, 2, 17, 1, 3, 17, 1,255,196, 0,194, 0, 0, 1, 5, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 2, 4, 5, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 16, 0, 2, 1, 3, 2, 4, 3, 4, 4, 9, 8, 6, 7, 6, 2, 11, + 1, 2, 3, 0, 17, 4, 18, 5, 33, 49, 19, 6, 65, 81, 20, 97,113, 34, 50,129,145,209, 7,161,193,225, 66, 82,146,178, 35, 21, +177, 98,114,130, 51, 67, 36, 22,240,210, 83, 99,115,131,162,179,195, 52, 84,116, 54,147,163,211,196, 37, 23,241, 53,194,226, 68, +100,132,148,164, 69,133, 38, 71, 17, 0, 2, 1, 3, 2, 4, 3, 6, 4, 6, 3, 1, 0, 0, 0, 0, 0, 1, 2, 17, 3, 4, 33, + 18, 49, 65, 81, 5, 97,113, 19,129,145,161,209, 34, 50,177,193, 66,146,240,225, 82,114, 51, 20, 98,147, 21, 52,255,218, 0, 12, + 3, 1, 0, 2, 17, 3, 17, 0, 63, 0,244,254,224,238, 9, 59,127,111,143, 51, 67,204,154, 98, 78,154,190,139, 94, 48,111,227, + 88,189,187,247,157,181,111,121,203,182, 74,211, 97,102,202,116,192,147, 54,164,144,254,138, 72,167,230,246, 16, 43, 67,187, 50, + 59,119, 27,111,129,187,154, 24,230,194, 99, 18,162, 76,130, 69,234,116,174, 13,155,135, 32,107,198, 59,154, 93,139,117,238, 13, +167, 19,177, 96, 16,100, 52,145,170, 24, 87, 66, 9,117,130,140, 20,114,211,109, 71,221,122, 3,232,137, 38,156, 48,180,141,107, +126,145,168, 28,153,129,254,209,255, 0, 88,210,146,247, 30,118,161, 53,237,115, 66, 6,245, 19, 90,226, 70,253, 99, 80, 51,228, + 19,110,171,143,235, 31,182,160,183,181,237,198,164, 7,229,160, 8, 38,159,145,149,255, 0, 88,253,180,221, 73,188, 38,147,245, +141, 55, 10, 92, 5, 0,230, 92,142, 98, 87,253, 99, 81,245, 25, 54,191, 85,191, 88,210,227,123,248, 84, 79, 15,117, 0, 60,140, +172,165, 10, 58,174,183, 55,184, 99, 66,108,204,171, 88, 79, 37,255, 0,166,223,109, 67, 45,137,145, 86,252, 0,184,250, 79,228, +160, 95,133,234, 50,135, 25,121,103,158, 68,159,174,223,109, 75,213,229, 91,251,121, 63, 93,190,218, 2,220,139, 10,125, 62,116, + 4,198,102, 97,229, 60,159,174,223,109, 72,101,102, 30, 30,162, 79,215,111,182,134,128, 3, 75, 80,185, 52, 5,129,147,148, 0, +253,252,159,174,223,109, 38,203,201, 31,223,201,250,199,237,170,229,175,107, 82, 28,120,154, 2,196,121,179,234, 58,167,113,229, +118, 63,109, 20,101, 78,220,167,107,121,235, 63,109, 14, 21,248, 9, 32, 17,115,246, 82,233,196, 73, 58, 7, 14,103,133, 64, 20, +229,100, 40, 7,168,228,121,234, 63,109, 72,101, 79,227, 43,251, 62, 35,246,213, 80,136, 77,134,162,166,228, 90,246, 22,247, 83, +172, 76, 46, 3, 31,167,202,128,176, 50,114, 8,191, 89,248,248,106, 63,109, 47, 81,147,199,247,175,250,199,237,170,218, 92, 88, +171, 2, 7,178,164, 76,136,191, 18,131,238, 60,120,253, 20, 1,253, 68,246,254,217,255, 0, 88,253,180, 23,201,200, 75, 19, 60, +159,174,199,241,212, 11,158,122, 72,246,212, 9, 15, 96, 5,173,207,133, 80, 20,230,100, 91, 80,157,192,181,201,212,223,109, 86, +108,236,199, 98, 68,242,129,224, 3,183,219, 77,144, 8, 42, 63, 52,212, 81,108, 11, 55, 1,206,254, 66,168, 13,235, 50,209,110, +217, 18, 31, 33,173,184,159,174,163,235,115, 87,230,200,144,147,196,252,109, 97,248,104, 6, 64, 88, 19,203,146, 10,139,134, 99, +112,108, 60,232, 3, 28,204,208,110,114,165, 3,200, 59,125,181, 33,157,150,194,235,145, 47,235,183,219, 85,198,146, 44,126, 43, + 83, 2,111, 96, 44, 40, 3,140,204,235,252, 89, 50, 15,235,183,219, 77,235,243, 17,197,242,101, 32,248,107,111,182,129, 32, 3, +137, 53, 40, 99,214,117, 56,225, 64, 92,245,249, 71,128,158, 67,127,231,183,219, 67,245, 89,235,114,217, 18,241,228, 58,141,246, +210, 0, 3,112, 41,152,106, 62,234, 2, 45,155,159,225, 60,191,174,223,109, 56,202,220, 24, 95,212, 74,191,215,111,182,144, 0, + 55, 63,162,162,101, 12,229, 84,112, 20, 1, 86,124,206, 23,201,152,255, 0,204, 96, 63,150,166,217,217, 17,240, 57, 18, 95,250, +109,246,213, 55, 47,126, 45, 97, 76,218,126,107, 92,208, 22, 91, 59, 50,223, 12,242, 27,255, 0, 61,190,218,129,207,204, 11, 99, +145, 38,175, 99,183,219, 65,212, 74,241,224, 77, 68, 32, 6,252,205, 0,101,204,206, 28, 78, 76,191, 76,141,246,209,127,136,101, +129,110,188,132,249,151,111,182,171, 82,181, 74,150,129,189,118,105,255, 0,246,137,127, 93,190,218, 94,183, 55,255, 0, 19, 47, +235,183,219, 65,191,149, 55, 26, 2,199,173,204,255, 0,196,203,250,237,246,210,245,185,191,248,137,127, 93,190,218, 10,198,205, +242,169, 54,231, 97, 68,244,238, 62,107, 47,180,145,248,168, 82, 94,179, 55,255, 0, 19, 47,235,183,219, 79,235, 51, 63,241, 18, +254,187,125,180,194, 40,199, 54, 45,231, 97,248,205, 72, 34,168,184, 78, 63,206, 52,161, 42,133,235, 51,127,241, 18,254,187,125, +181, 53,159,112, 99, 97, 52,191, 75,176,254, 83, 76, 11, 95,225, 54,229,125, 34,213, 33, 30,175, 18,124,239, 65, 82, 98,108,176, +108,249,110, 60,192,118, 39,249,104,131, 38, 64, 1,235,206,231,159,206, 64, 63,203, 65, 17,252, 69, 72,246,222,140, 34,186,240, +229,200,251,104, 9,122,236,149, 33, 81,216, 92,254,115, 51,126,209,166,108,140,182, 60,102,144,123,152,129,195,221, 73,186, 8, +191, 27, 45,239,231, 80,151, 43, 25, 21, 64, 36,128, 60, 7, 58, 16,144,200,201, 34,226,121, 57,126,147,115,250,234, 93,108,203, +219,171, 37,184, 92,234,111,182,169, 62,230,131,132,113,125, 36,212, 61,124,199,141,133,188,170,148,211, 47,149,107,137,228, 31, +215, 63,109, 49,202,146, 50, 53,100,183,210,228,254, 58,197,146,105,158,218,156,155,251,105,162,133,157,192,243,160,161,182,115, +133,141,178,100, 62, 44, 65, 99, 97,248,170, 13,187, 42,142, 19, 72,198,214,189,200,252,117,157,233,207, 47, 31, 26, 28,176,145, + 96, 7, 58, 3, 99,248,130,244,122,186,159, 87, 67, 86,187,155,219,175,163,159, 58, 85, 75, 71,248, 91,127,251,173,191,254,170, +149, 65,169,155,222,189,173,254,109,219, 49,246,239, 86,112,250, 77, 20,253, 65, 31, 82,246,136,166,155,106, 79,210,243,167,237, +126,198,216,123, 93, 18, 92, 44,113, 38,225,211, 84,155, 58, 77, 77, 35, 16, 44,229, 3,179,116,195, 30, 36, 45,116, 77,196,199, +253, 8,255, 0, 97,104,163,133, 82, 1,145, 72, 35,143,133, 64,220,248, 94,212, 73,136,212, 61,212, 48,212, 32,224,158, 84,202, +205,115,126, 84,224,138, 70,220,175, 64, 72, 26, 68,211,112, 3,141, 43,138, 1,195, 6, 4, 15, 10,131, 91,149, 61,237,225, 81, + 32,222,128,163, 48,213, 51, 0,125,159, 80,166, 10, 47, 72,181,220,183,159, 26,107,159,174,161, 66, 92, 3, 80, 44, 77, 33,206, +156,248, 80, 8, 3, 72,142, 20,181,120, 83, 27,147, 64, 38, 42,128,147,192, 1,198,177,100,223,101,215,251,152,215, 64,229,170, +228,159,168,138,219,208, 8, 55,227, 88,121,251, 67, 71,170,124, 81,169, 57,180,126, 35,221,236,175,159,220,158, 82,183, 25, 99, + 54,148,106,231, 79,187,195,216,123,176, 22, 51,155,142, 66,171,149, 20,107,246,155, 91,102,235,139,149, 24,140,252, 19, 11,150, + 67,198,255, 0,209,181, 91, 18, 70,110,110, 1,246,240,174, 21, 89,145,131, 41, 42,195,136, 35,129, 6,183,176, 55,145, 33, 88, +114,200, 15,109, 43, 47, 32,127,165,237,174, 24, 93,210, 55, 41,111, 33,168,203,130,151, 8,203,207,163, 59,102,118,215, 10,220, +177, 89, 71,156,121,199,203,170, 54,145,174, 6,151, 0, 19,115,199,195,217, 70, 86,227,204,242,160,136,245, 88,112, 34,223, 9, +168,133, 22, 7,128,177,183, 14, 28, 15,186,190,177,242,195,252, 36,240, 60, 79, 26,105, 63, 55,192,131,199,232,164,177,142, 97, +138,169,226,120,222,223, 69, 65,144,222,236,228,251, 72, 30, 52, 4,152,131,199,149, 49, 0,220,142, 85, 2, 37,191, 48,126,138, +146,240, 23,110,103,157, 84, 1, 76,165,138,223,141,141,173, 85,228,144, 57,211,249,138,120,159, 51, 79,145, 54,182, 42,188,135, + 11,208, 25,128,182,145, 84, 19,125, 71,229, 20,195,136,177,111,125, 48,103,101,181,169, 44, 71,153, 63, 85, 0,218,213, 77,148, +123,233,216, 51,252,162,194,164, 20, 47, 31,229,167,214,164,216,113, 52, 4, 58, 55, 23, 38,244, 68, 54,250, 42, 26,158,252,120, + 10,102, 11,243, 31,170,128, 61,238, 41,135, 62, 60, 40, 87, 37,120, 2, 13, 58,181,151,143, 58, 2,108,234, 27, 72,226, 79, 51, + 67, 36,131, 97,240,138, 68,146,124,169, 4,102,228, 9,165, 75, 65,152,134,240,189, 63, 26, 42,192,199,230,101, 95,121,251, 47, + 83, 88, 98, 22,212,204,215,240, 81,111,194,106, 2,189, 46, 39,128,227, 86, 66, 40,249, 80, 27,120,177,191,216, 41,192, 99,193, + 77,188, 72, 2,212, 21, 0, 34,144,248, 91,223,195,249,106, 75, 10,254,115,129,238,226,104,193, 47,225,198,246, 36,209, 4, 64, + 3,126, 22,170, 42, 5, 35,136,126,107, 49,246,155, 3,248,232,130,200, 70,136,213,108,110,110, 53, 17,244,181,234, 64,194,160, +107,113,127,105,168,182,102, 44, 98,194,236,124, 44, 42, 2, 76, 36,111,137,137, 43, 80,233,249, 14,124,175, 81, 59,128, 96, 2, + 71,192,121,154,175, 46,108,231,128,178,251,133, 82, 23, 68, 36,142, 63, 77, 39,233, 32,187,184,246,220,214,120,121,164, 23, 44, + 79,211, 80,104,216,181,143,133, 11, 66,248,200,199, 64,108,111,238, 21, 7,220, 2,216, 36,127, 93, 6, 40,126, 13, 84,242, 65, +166,205,225,202,128,111, 89, 59, 92,139, 47,186,135, 36,179,191,204,228,253, 53, 48,129, 22,231,199,141, 88,138, 37,156, 5, 91, + 15, 18,106, 26,166,133, 36,141,139, 15,109, 89,244,199,235,227, 86, 76, 35, 30,236,228, 30, 28, 45, 85,134, 85,223,151, 14, 66, +169,146,185,142,220, 45,198,142, 35,210,160, 26,176, 52,223, 89, 31, 17,226, 13, 84,152,179, 57, 81,200, 84, 52,180,212, 48,131, +169, 98,190, 21, 97, 33,104, 13,219,131,120, 15,101, 7, 13,136, 58, 91,194,173, 78,196,198,204, 5,141, 8,221, 93, 74,239, 60, + 40,116,134,177,246, 84, 92,198,224, 0,215,191,231, 85, 86, 64, 5,252, 77, 74, 16, 69,252,168,196,120,234,104,116,191,194,252, +194,222,154,222, 63,248,155,210,169,216,122,109, 62, 30,159,255, 0,152,165, 80,222,159, 18,200,249,163,191,132,113,254,194,209, + 46, 41,145,111,164,255, 0,187,143,246, 22,166, 98, 7,194,180,114, 43,205,109, 67,221, 64, 53, 98,104,174,223, 69, 4,196,109, + 66, 17, 6,159, 87,141, 49,132,143, 19, 82, 17,112,231, 64, 53,252,111, 75, 87,141, 56,132,143, 26, 69, 26,220, 40, 6,185,167, +118, 33, 24,131,196, 2, 71,213, 77,102, 30, 20, 41,175,211, 35,206,214,160, 43,142, 2,152,145,127,117, 45, 62,116,224, 84, 40, +220,106,132,251,190, 36, 79,160,106,148,142,101,109,111,172,213,249, 87, 90, 50, 3, 98,192,168, 62, 87, 21,204,190,221,153, 27, + 21, 49, 19,111, 21,226, 43,231,247, 12,140,155, 74, 11, 30, 13,238,173,100,150,234,120, 30,236, 27, 24,247, 92,189,121,210,148, +164,107,182,190, 38,152,223,113,199,247, 79,248, 41,255, 0,142,227,255, 0,178,127,193, 89, 62,131, 51,253,131,253, 84,142, 14, + 88, 4,152, 88, 1,196,146, 57, 87,204,255, 0,127,184,255, 0, 75,255, 0,175,249, 31, 67,253, 44, 15,234, 95,191,249,154,255, + 0,199,160,183,246, 79,248, 41,134,255, 0, 8,254,233,255, 0, 5, 96,210,174,127,250,217,127,212,191,106, 58,127,230, 98,255, + 0, 75,253,204,185,155, 62, 38, 65,234, 65, 19, 69, 39,231,114,210,125,190,250,167, 86, 49,240,115, 50,191,238,216,242, 74, 60, +209, 73, 31, 88,163,190,203,187, 70,186,159, 10, 96, 60,194, 19,252,149,229,154,187,117,187,190,155,215, 86,227, 26, 71,224,122, + 96,237, 90, 74,222,245,167, 5, 41, 85,252, 66,237,187,204,184,100, 69, 53,228,131,144,253, 37,247, 87, 69, 22, 84, 19, 42, 73, + 27,134, 67,198,245,197, 50,178,146,172, 10,176,224, 65,224, 69, 88,194,206,159, 6, 77,113, 27,169,249,163, 63, 41,175,110, 23, +115,157,154, 91,189, 89, 67,133,127, 84,126,104,241,230,118,232, 93,173,203, 84,140,248,211,244,203,249,157,173,227, 63, 43, 94, +245, 17,107,241, 62,225,225, 64,194,204,198,220, 98,234, 70, 62, 49,243,198,109,117, 52,116,138, 38,213,240,218,191, 67, 9,198, +113, 83,131, 82,139,213, 52,124, 41,194, 80,147,132,211,139, 92, 83, 30,196,113, 6,169,207, 41,227, 26,159,233, 26,204,220, 59, +183,183,182,173,209,182,172,249,228,199,153, 2,182,182, 86, 49,217,198,161,197,117,126, 17, 86, 49,243, 48,243,213,167,193,200, + 76,136, 75, 16, 36,141,131, 14, 30, 28, 60,107,175,167, 52,148,156, 90, 79, 84,233,161,202, 55, 33, 38,227, 25, 38,215, 21, 93, + 87,176, 32, 85, 60, 15, 26,151, 77, 23,141, 61,136,227,192, 10,131, 16,199,216, 57, 84, 54, 59, 58,168,243,164, 89,138,252, 60, + 60,232, 51, 77, 20, 8,102,157,214, 40,215,230,145,200, 85, 23,225,204,213,120,247, 93,182, 87, 17, 67,155, 4,146, 57,178,162, +202,140, 73,242, 0, 27,213, 73,189, 82,100,109, 39, 70,210, 45,139,114,102,185,165,196, 27, 42,216,120,154, 96, 60, 71, 58, 42, + 46,171, 22, 30,225, 80,164, 24, 6,183, 19,238, 21, 53,142, 82, 44, 18,222,255, 0,203, 71, 85,110, 67,133,170,122, 15, 2, 77, +168, 10,221, 19,249,204, 63,150,156, 70,131,219, 69,115, 18,220,150, 22,168,117,225, 28,174,212, 2, 10, 1,176, 30,234, 32, 66, + 71,242,213,127, 87,118,248, 86,163, 38, 76,252,148,233,247, 80, 23, 35,143,133,249,112,250, 41,255, 0,114,186,117, 56,191,190, +179,137,149,129,187, 19, 82,138, 18, 79, 30, 85, 10,203,111,149,140,164,243, 99,224, 0,251,106, 7, 52,115, 68,227,225,122, 4, +144,216,139, 11,223,149, 66,121,177,112,162, 51,102, 76,144,196,159, 52,146, 48, 85, 30, 28,205, 95, 4, 23, 54,244, 75,168, 79, + 87,145, 33,176, 54, 30,193, 77, 41,152,139,179, 19, 88,248,125,221,219,243,238, 48,237,152,153, 7, 34,121,137, 85,104,208,232, + 4, 2,198,238,218,124, 7,133,111, 51,164,128,128,106,206, 50,141, 55,197,198,170,186,232,102, 19,132,235,178, 74, 84,116,209, +212,168,136, 73, 53, 54,132,130, 47, 83,123, 70, 6,158, 38,137, 27,135, 23,101,191, 26,201,183, 69,161, 24,226, 85, 78, 62, 39, +133, 41, 99, 37,184, 11,240,168,204,238,205, 96,108, 7, 27, 84,145,207, 79,143, 59,209,136,170,177, 92, 68,186, 79, 58, 50,162, + 56,212, 77,189,213, 89,148,179,146,124, 40,209,157, 8, 56, 80, 55,200,132,178, 50, 16,171,200,114,247, 81, 34,145,157,110,124, + 56, 90,163, 50,181,239,110,124,169,227, 70, 81,107,123,232,203, 30,172,132,224,177, 0,112, 6,165,143,116, 44, 61,159,142,142, + 33,234,123, 8,228, 77, 24, 66,136,160, 22, 5,173,198,136,146,117, 96,103,185,140,129,199,133, 83, 9,168,128, 43, 65, 86, 49, +193,154,228,240,168,145, 10,112, 69,231,227, 66, 1, 99,249,183,227,202,145,199,115,119, 81,112,124,168,190, 60, 23,143, 58,112, +242,216,216,219,242,208, 54, 52,105,210, 83,126, 44,106, 97,195, 45,136, 30,227, 80,210,215,248,141,174,109,122, 93, 48,199, 77, +239,115,206,173, 9, 80, 77,140, 9, 31,188, 91,120,220,242,162,136, 35, 84, 0, 74,183,241, 60,120,210, 49,160,225,115,175,147, + 15, 15,101, 76, 64,186, 69,200,225,196,212, 45, 67,233, 95, 79,110,160,255, 0,187,218,246, 60,186,252,233, 82,176,244,247,208, +109,233,237,255, 0,191,255, 0, 67, 74,130,165,232,192, 8,135,205, 35,253,133,169, 49, 21, 1,193, 18,255, 0,236,211,246, 69, + 56, 32,139,213, 50, 6, 82, 65,250, 40,119,189, 62, 67,124, 99,195,133, 10,246,160, 9,194,156, 16, 40, 33,129,241,169,222,128, +150,160,125,148,170, 20,224,129, 64, 63,141,200,170,249, 76, 52, 5, 30,119,250,168,204,213, 79, 36,146,234,190, 22,163, 8, 16, + 38,214, 20,133,207, 26,113,192, 83,130, 0,168, 81,173,227, 77,107,181, 61,205,170,150,102,124, 88, 99, 77,245,204,121, 32,240, +254,149,115,187,118, 22,160,231,114, 74, 49, 92,217,187,118,231,114, 74, 22,226,228,223, 36, 90,155, 34, 28, 88,245,202,214, 30, + 3,196,251, 0,174,123, 55,113,151, 44,149, 31, 4, 87,224,131,199,250, 85, 94,124,137,114, 95,169, 43, 92,248, 15, 0, 61,148, + 42,252,238,111,114,157,250,194,221, 97,111,167, 57,127,119,200,251,216,125,190, 22,105, 57,210,115,248, 71,203,230, 42,237,118, + 30,212,137, 99, 76,205,209, 53,200,214,100,199, 63, 42,143, 13,126,103,217, 88,125,175,132,153,187,188, 66, 65,120,225, 6,102, + 30,122,109,167,254,145, 21,208,253,224,119, 20,189,181,219, 89, 25,184,164, 12,185,153,113,241, 88,254,107,201,127,143,250,170, +164,143,109,122,187, 54, 4,111, 63, 86,105, 75,234,219, 8,190, 21,231, 38,121,187,182,115,179, 23,110, 45,198,145,221, 54,184, +211,162, 39,190,247,191,108,118,185, 24,217,185, 35,212, 40,225,137,142,186,221, 71,243,149,120, 47,245,136,172, 28,127,190, 94, +210,154, 77, 18,199,151,142,183,254,210, 72,148,175,211,211,119,111,193, 94, 11, 44,178, 77, 35,205, 51,180,146,200, 75, 59,177, + 37,153,143, 18, 73, 60,201,168, 87,236,227,219,237, 40,210, 77,183,213,105,238, 71,227,167,220,175, 57, 86, 42, 41,116,122,251, +217,245, 63, 75, 97,238,172, 33,149,141, 36,121, 81, 63, 8,242,161, 35, 82,159, 43,243, 4,126,139, 87, 11,187,237, 51,237, 25, + 70, 9,126, 36,111,138, 41, 71, 38, 95,180,120,215,158,253,223,247, 62, 87,110,111,248,214,144,250, 28,201, 18, 12,200, 73,248, + 74,185,210, 36,183,233, 33, 55,191,209, 94,247,221, 56, 75,151,180, 74,246,253,230, 63,239, 80,251,190, 97,250,181,249,254,247, +218,160,163, 41,197,125, 73, 57, 41, 45, 28,146,227, 25, 31,160,236,221,210, 82,113,132,190,214,212,101, 30, 42, 45,240,148, 79, + 62,195,202,147, 14,117,158, 51,203,230, 95, 6, 30, 32,215,105,141,147, 28,177, 44,202,195, 76,159, 16, 39,133,112,149,210,246, +236,236,248,242, 64,127,186, 96,203,238,111,202, 43,227,246,124,135, 27,174,195,127, 76,211,107,194, 75,230,143,171,221,108, 41, + 91, 87,146,250,160,210,126, 49,127, 38,121, 87,222, 81, 7,186,242, 10,144, 71, 74, 30, 35,250, 2,186, 95,187,236,204, 76, 30, +219,154,124,185,146, 8,215, 37,238,242, 48, 81,242, 39,137,174,107,239, 40, 91,186,242, 7,251,168,127, 96, 86, 30,213,181,238, +123,228,131, 7, 8, 23, 72,238,237,169,173, 28,122,172, 11, 31,125,189,245,251,159, 78, 55, 49, 45,198, 82,218,148, 98,219,240, + 72,252, 66,187, 43,121,151, 37, 24,239,147,148,146, 94, 45,158,175, 39,123,246,193,126,153,220, 7,180,136,228, 43,245,132,181, +105,224,238, 91,118,230,133,240, 50, 35,200, 11,204, 35, 2, 71,188,115, 21,231, 18,253,218,239, 11, 1,146, 28,136, 38,144, 11, +244,129,101, 39,216, 11, 11,125,117,202,164,153,251, 62,105, 40,207,139,153,142,196, 27,124, 44,172, 57,131, 92, 86, 37,139,137, +250, 55, 91,107,175,240,143, 67,205,200,180,215,175,105, 36,250,105,243, 61,103,189,129, 29,179,159,171,202, 62, 31,243, 82,188, +207,181,127,245, 22,221,111,246,195,241,215,107,184,111, 75,191,118, 30, 94, 99, 0,185, 41,211,139, 37, 71, 32,226, 72,248,129, +228,192,222,184,190,212, 23,238, 45,184,127,190, 31,200,107,166, 52, 92,113,239, 70, 90, 52,228,159,237, 57,229, 78, 51,201,177, + 56,186,169, 40, 53,251,143,108,186,170,150,119, 10,170, 46,196,144, 0, 3,204,154,195,204,239,206,220,193,144,198, 50,122,238, + 56, 30,138,151, 3,250,223, 47,225,174, 43,191, 59,134,124,156,233, 54,108,103, 41,137,140,116,206, 1,183, 82, 65,207, 87,177, +121, 91,206,170,246,175,103, 54,255, 0, 19,230,100,204,113,240,209,186,106, 84, 93,221,128,185,211,126, 0, 11,243,174, 16,196, +183, 27,106,237,249, 56,167,170, 75,199,129,222,230,101,201, 93,118,113,226,164,214,141,191, 14, 39,109, 31,222, 54,197, 51,233, + 51, 73, 8, 60, 53, 60,102,223,244,117, 86,238, 54,116, 59,140, 98,124, 60,133,158, 35,249,241,176, 97,127, 35,106,225,247,127, +187,104, 97,197,121,246,172,153, 30,100, 5,132, 19,105, 58,236, 47,101,101, 11, 99,229,194,184,253,135,124,203,216,115,211, 46, + 6, 38, 59,129,145, 13,254, 23, 79, 16, 71,159,145,240,170,177,108,221,131,150, 60,157, 87, 41, 7,151,126,204,212, 50, 96,169, + 47,213, 19,220, 94, 59, 45, 48, 84, 68, 37,200, 0, 2, 73, 60, 0, 2,188,223,239, 15, 62, 71,147,108,155, 26,103, 88,230,133, +228, 82,140, 86,225,138,144,120,123, 43,151,219,155,123,221, 36, 59, 78, 20,178,202,114,136,234, 70, 92,216,132,185,187,146,120, + 40,191, 26,197,188, 39, 59,106,227,154,138,124,106,184, 81,234,110,230,122,133,215,105, 91,114,107,133, 31, 26,173, 52, 61, 79, + 35,189, 59,103, 6, 83, 19,230, 9, 92,112, 61, 21,105, 0,254,178,141, 63,134,173,237,221,205,176,111, 14, 35,194,204, 83, 49, +229, 12,128,198,231,250, 33,192,191,209, 92, 43,125,216,238,171, 14,191, 89, 1,150,223,217,217,237,127, 45, 86,252, 85,198, 79, + 6, 70, 14, 76,152,243, 3, 22, 68, 14, 85,135,138,178,159, 2, 43,172, 49, 49,174, 38,173,220,110, 75,248,224,113,158,110, 85, +166,165,118,210, 81,124,191,157, 79,161, 32,117, 50,105, 97,116, 52, 45,211,113,193,219, 99, 15,145, 60,120,200,222, 50, 48, 4, +251,175,206,185,156, 14,229, 56,253,149, 30,255, 0,148, 58,153, 17,131, 2,131,253,228,193,138, 45,253,224,106, 53,229,185,185, +219,134,245,156,114, 50,157,242, 50,167, 96,170, 57,241, 38,202,136,190, 3,200, 10,227, 99, 10, 83,148,183, 61,177,131,113,111, +171, 93, 14,249, 25,241,132, 97,177,110,148,210,146, 93, 19,234,122,250,119,223,108, 2, 17,179,198,174, 87,233,201,111,175, 69, +171, 47,188,179,112,247, 30,214,202,200,194,157, 50, 35,215, 16,213, 27, 6,183,239, 23,129,183, 42,231,113, 62,236,183,185,224, + 18,228, 79, 6, 51,176,191, 73,139, 51, 15,233,104, 4,126, 26,193,222,118, 61,223,183, 36, 56,217,156, 33,200, 22, 18, 68,196, +197, 40, 83,127,103, 35,198,196, 87,123,120,248,254,164,125, 43,181,148, 90,116,122,214,157, 15, 61,220,172,175, 74, 74,237,154, + 70, 81,106,171, 74, 87,175, 16,221,155,255, 0,169,182,255, 0,233,183,253, 91, 87,180, 2,145, 43,205, 35, 4,141, 69,217,216, +217, 64, 30,100,215,140,118, 87,254,169,219,120, 95,227,110, 31,242,218,180,251,247,185, 39,220, 55, 25,118,156,118,233,224, 97, +182,134, 69, 54,234, 74,191, 51, 63,158,147,192, 10,185, 86, 37,123, 34, 49, 78,137, 66,173,248, 85,153,196,200,141,140,105,205, +170,183, 58, 37,213,209, 29,158,111,124,246,222, 44,133, 61, 81,157,133,239,209, 66,227,245,184, 41,250, 13, 67, 23,239, 7,182, +100, 96,143, 52,144,234, 63, 52,145,155, 11,255, 0, 67, 85,113,253,163,216,173,220, 56,237,184,102, 78,113,176,195, 20,143, 64, + 5,228, 43,243, 16, 91,128, 23,225, 90,251,239,221,140, 88,184, 82,229,237, 25, 50, 73, 36, 42, 92,227,204, 20,151, 0, 92,133, +100, 11,199,203,133,115,118,112,227, 47, 78, 83,150,238, 13,242,175,184,234,175,231, 78, 62,172, 97, 13,188, 82,230,215,188,239, +177,229,197,220, 34, 92,172, 41,227,158, 22,228,241,176, 97,127,162,172, 24,148,112,213,194,188, 39,182,187,131, 39,183,247, 24, +242, 80,150,198, 98, 23, 42, 11,240,116,241,225,250, 67,192,215, 79,247,153,149, 42,110, 88, 18, 98,204,233, 20,184,161,212,163, + 21, 12, 11,181,155,135,178,177, 44, 22,175, 70,222,237, 36,155, 82,167, 78, 70,225,220, 19,179, 43,155,126,168,180,156,107,215, +154,103,166,100,100,225,226, 99,180,249, 46,177, 67, 24,187,202,228, 40, 3,218, 77, 97,224,247,158,195,186,110, 41,182, 96,187, +201, 52,133,186,109,160,132, 58, 20,185,226,214, 60,151,202,188,135, 9, 55,157,234, 84,218,113, 30, 92,150,153,131,136, 75,146, +183, 80,126, 54,212,108, 0, 7,153,175, 65,237,143,187,253,199,100,221,241,119, 76,220,188,114,176,135,215, 12,101,153,190, 56, +218, 62, 7, 72, 28, 11, 86,167,139,102,212, 37,234, 92,172,168,220, 82,211,200,205,188,203,215,167, 31, 78,221, 33, 84,166,222, +190,122,232,119,218,164,191, 15,244,181, 72, 43,159, 31, 47,195, 78,178, 99,175, 14,165,237,206,194,244,189, 70, 58, 30, 10,205, +248, 43,194,125, 1,105, 38,227, 87,196, 60, 41,196,124, 62, 46,102,192, 26,135,170, 0,157, 49,143,164,210,245,147,114, 80,170, + 61,213, 10, 24, 66,110, 24, 11,158, 96, 81, 76, 4, 11,233, 55, 35,159,133, 82, 57, 89, 7,251,194, 7,144,225, 65,146, 73, 88, + 18, 92,159,166,132, 52, 76, 77,111,141,148, 14, 2,247, 28,133, 71,252, 58,157, 77, 40, 54,240, 21,154, 27,135, 30,124, 40,160, +112,160, 46, 25,241, 64,226, 75,159,117, 8,229,192,131,225,136,155,121,154,172,246, 0,251, 40, 69,181,126, 10,181, 5,225,154, +130,218, 96, 3,222,196,211,156,214, 38,226, 36, 4,248,241, 63,142,168,150, 32,240, 23,184,176,169,169,224, 47,207,198,160, 53, +125, 76,158,158,250, 87,251, 13, 86,183, 11,250,141, 62,116,168, 55,255, 0, 13,255, 0,240,223,252,205, 42, 3, 80,142, 9,253, + 4,253,145, 74,145, 63, 39,244, 19,246, 69, 43,213, 33, 95, 35,230, 23,242,160, 17,126, 20,105,219,227, 3,217, 67, 23,191, 1, + 64, 64, 42,169, 62,102,165,164,248, 26,144,181, 53,184,208, 12, 1,177, 6,155, 65, 6,247,231,225, 69, 2,244,228, 80, 2,227, +227, 84,166, 26,165, 98, 57,125,130,175,176,181,103, 23, 5,139,121,241,181, 25, 80,225, 71, 35, 82, 32, 15, 96, 21, 16,213,129, +186,231,201, 36,175,140,135, 76,104,116,181,191, 56,142,119,175, 46, 94, 84, 49,173,239,146,171,110,145, 75,155, 61, 24,216,211, +200,185,178, 58, 37,171,111,146, 44,103,238,225,111, 22, 33,185,228,101,240, 31,209,172, 82, 75, 18,204,110, 79, 18, 79, 58,106, +209,219,246,169, 50,136,150, 91,164, 62, 30,109,238,175,206,206,230, 78,117,228,190,231,202, 43,237,138,254, 57,159,122, 48,199, +195,180,223, 5,206, 79,238,147, 43, 99, 97,203,149,168,160,180,104, 9,103, 60,133,170,189,118, 75, 12,113,199,209, 69, 10,150, +176, 3,219, 92,132,177,152,164,120,219,154, 18,167,232,174,153,216, 43, 26, 22,181,220,229, 93,207,149,116,162, 71, 60, 60,199, +145, 59,186,109, 81,166,213,206,154,213,179,161,236,169, 85, 55, 89, 35, 60,228,133,130,251,193, 86,254, 65, 82,251,220,219, 39, +220, 59, 73,166,129, 75,182, 12,233,146,234, 57,244,192,104,220,253, 26,239, 88, 24,121, 82,224,229, 69,151, 15,207, 19, 6, 30, +223, 48,125,226,189, 63, 7, 59, 19,118,195, 19, 69,103,142, 65,166, 88,154,198,196,143,137, 28, 87,211,236, 89, 81,140,125, 63, +213,110, 91,146,235, 22,124,238,245,138,230,220,191, 77,200,237,111,164,145,242, 93, 42,246,142,229,251,154,139, 38,119,203,237, +188,148,198, 14, 75, 28, 44,139,244,212,159,246,110,161,136, 30,194, 15,190,185,220,127,185,158,233,146, 80,185, 19, 98, 65, 31, +140,157, 70,115,111, 98,170, 87,236, 35,151, 98, 81,174,244,188, 31, 19,241,242,194,200,140,182,236,111,197,112, 56,222,220,219, + 39,222, 55,220, 13,187, 29, 75, 52,211, 32, 98, 63, 53, 1,212,238,127,162,160,154,250,115,125,149, 97,217,243, 93,205,129,137, +144,123,220,104, 31,132,214, 47,103,246, 38,213,218, 17,180,144, 19,147,159, 42,233,155, 50, 64, 1,211,207, 68,107,199, 74,213, + 30,238,222,227,202, 97,182,226,182,168,227,109, 83,184,228, 88,114, 81,238,241,175,137,222,115,237,171, 82,105,233,181,198, 21, +227, 41, 72,251,189,155, 2,226,154, 79,139,146,148,233,194, 49,137,202,214,215,110,179, 9,167, 0, 18, 10,139,129,239,172, 90, +232,251,114, 2,176,203, 57, 31,218, 48, 85,247, 47,229, 53,249, 78,217, 23, 44,187,116,253, 53,111,202,135,233,187,140,148,113, +110, 87,157, 18,243,169,229,127,121, 6,253,213,144,108, 71,238,161,231,253, 1, 93, 39,221,162,194, 54,140,146,162,243, 54, 65, + 18, 31, 29, 33, 23, 79,242,154,231, 62,242,120,247, 94, 71,252, 56,191, 96, 86, 70,197,191,231,246,252,237, 62, 40, 13, 20,195, + 76,176,189,244,190,159,119,136,191, 58,254,132,237, 74,230, 28, 33, 30, 59, 98,252,232,126, 6, 55, 99,107, 54,115,146,211,116, +147,240,175, 51,219,129, 40,223,205, 53,228,255, 0,120,171, 8,238, 50, 98,182,182,130, 51, 53,191, 79,136,253,144, 43, 70,111, +188,201,154, 43, 67,183,170,203,111,153,228, 44,160,255, 0, 68, 42,147,245,215, 25, 52,217,187,190,115, 75, 38,172,140,188,151, +228,162,229,152,240, 10,160,126, 10,231,135,141,114,220,220,238, 45,170,141,113, 58,230,229, 90,187,109, 91,182,247, 54,211,225, +243, 54,246, 98,255, 0,229, 78,226, 31,221,143, 75,111,233,117, 56,213, 62,211,255, 0,212,155,111,252, 97,248,235,177,203,216, +142,195,216, 25,176, 77,111, 85, 55, 78,108,155,120, 49,145, 0, 79,234,143,195, 92,111,105,255, 0,234, 77,183,254, 48,254, 67, + 93,163, 53, 59,121, 18,143, 6,229,240,138, 71, 9,194, 80,185,141, 9,113, 74, 53,246,205,178,166,243,175,248,190,225,212,249, +253, 76,218,175,231,173,170,246,217,178,247, 62,102, 34,207,181,197, 51, 98,177, 96,166, 57, 66,173,193,179,112,214, 43,107,191, +187,114,124, 92,233, 55,156,100, 47,137,146,117, 78, 64,191, 78, 78, 71, 87,177,185,223,206,169,246,167,121,205,219,168,248,146, +195,234, 48,228,109,122, 65,210,232,196, 88,149,191, 2, 13,185, 86,189, 73, 78,196,103,101, 70, 78,139, 71,241, 94,102, 93,184, +195, 34, 80,190,229, 5, 87,245, 47,131,242, 24,118,207,125, 31,238, 50, 79,252,241,255, 0,196,170,199,178, 59,171,153,219,159, +245,227,255, 0, 94,186, 61,223,239, 49,167,196,147, 31,105,198,120, 37,148, 21, 57, 18,176,186, 3,194,232,169,126, 62, 70,245, +103,177,123,167,125,220,178, 87,109,202,132,230,192,163,227,205, 39, 75, 68, 60, 12,141,201,191,150,185,122,153, 81,182,238, 56, + 91,141, 56,174, 14,158,243,175,165,137, 43,138,218,185,114, 85,224,214,170,190,227, 3,188, 49,178,112,246,253,131, 31, 49, 74, +100, 71,138,201, 34, 18, 9, 5, 89, 64, 28, 47,225, 90,159,117,145, 35,101,110, 82,145,119, 88,227, 85, 62, 65,139, 19,251, 34, +165,247,172, 20,101,237,182, 55,253,212,159,180,181, 47,186,166, 69,151,116, 45,250, 48,219,235,146,179, 41, 87, 5,203,133,117, +247,204,212, 98,151,112, 81,227, 77, 53,240,129,233, 3,149,173,122,241, 62,249, 80,157,211,184, 0, 45,241, 33, 62,243, 26, 94, +189,180, 79, 24, 54, 11,127, 58,241, 78,250, 33,187,171, 60,129, 97,120,248,127,202, 74,225,219,191,205, 47,236,127,138, 61, 29, +207,252, 49,254,245,248, 48,249,134, 95,242, 14,218, 1, 61, 35,157, 45,199,133,244,181,191, 29, 15,176, 98,130, 94,233,194, 89, +237, 97,212,104,239,250, 98, 54, 43, 93, 46,197,181, 29,247,176, 78,218, 8, 89, 58,210, 75, 3, 31, 9, 21,184, 92,249, 30, 85, +231,197,115,182,140,225,168, 62, 46,110, 43,134, 23,224,202,202,110, 13,123, 32,212,227,126,210,116,150,233,175,221,204,240,220, + 78,220,172, 94,106,177,219, 7,251,121, 31, 69,244, 91,244,109,111, 19, 92,135,222, 76, 80,255, 0,150, 29,166,211,213, 89,162, + 48,241, 23,212, 77,141,191,171,122,230,113,190,244, 50,150, 16,185,152, 34,105, 64,254,209, 36, 40, 9,243, 42, 85,255, 0,150, +185,206,225,238,109,195,184,221, 76,234, 34,198,135,226,142, 8,238, 64, 39,134,166, 39,153,240,175, 37,140, 59,209,187, 25, 73, +109, 81,117,173,120,208,246,100,102,216,149,153, 70, 13,201,201, 82,148,225, 94,164,251, 36,129,221, 59,105, 99, 97,173,174,127, +229,189, 99,231,234,245,217, 58,254,126,172,154,175,206,250,141,235, 87,179,191,245, 46,223,253, 54,253,134,173, 62,249,237,220, +140, 28,249,119, 88, 35, 45,133,150,218,220,168,254,206, 70,249,131,123, 24,241, 6,189,206,228, 99,147,181,233,186, 10,158,105, +189, 15, 2,183, 41, 98,239, 90,168, 92,117,242,105,106,102,237,219, 55,117,101, 97,199, 62,218,147,156, 71,191, 76,199, 40, 85, +224, 72, 54, 93, 99,196, 85,175,242,255, 0,123,155,142,158, 73,243,253,248,255, 0,226, 84,187, 99,188,230,216, 97, 56, 83,196, +114, 49, 11, 22, 64,166,206,132,252,218,111,192,131,229, 90, 59,199,222, 43,228,226,190, 54,213, 3,227,180,160,171,100, 59, 13, + 74, 15,232, 5,241,246,222,185,206, 89, 62,163,140,109,193,198,186, 73,244,241,212,235, 8,226,250, 74, 82,187,113, 73, 45, 98, +186,248,104, 97,255, 0,146,251,156,255, 0,253,189,255, 0, 94, 63,245,234,239,123, 38, 84, 73,177,193,154, 10,228, 67,183,199, + 28,138, 77,200, 40, 74,218,226,254, 85,208,246, 71,115,111,219,164,222,135, 38, 3,151, 12, 99,227,205, 31, 11, 39,144,115,201, +175,245,214, 87,222,110,163,186, 97, 22, 22,255, 0, 14,109,250,237, 89,141,219,175, 38, 54,238, 40,253, 41,191,167,200,212,173, + 90, 88,178,187,105,207,234,105, 53, 47, 6, 93,251,173,199,140,182,227,150, 71,239, 84, 71, 18,183,146,182,166,111,172,168,175, + 66,115, 99,207,221, 92, 23,221, 98, 51,193,185,233,183, 7,138,247,247, 61,122, 9,198, 63,156,227,232, 21,225,205,255, 0,232, +159,179,240, 61,248, 52, 88,208,246,254, 44, 18,112,227,230,104,214,189, 65, 19,192,113,171, 11, 25, 53,230, 61, 64,180,210, 34, +212,101,135, 72,211,244,211,180, 87, 4, 3, 66, 1,210, 10,220, 84, 28, 88, 26,178,168, 21,109,126, 84, 9, 52,145,192,241, 55, +189, 10, 9, 97,149,136, 33, 15,211, 68, 88,165,111, 33,244,209, 18, 64,160, 15, 30, 0, 15,125, 50,184, 79,136,142, 23,227, 64, + 33,138,237,123,184, 31, 69, 33,138, 60, 92,253, 2,172,195,114,128,158, 4,212,180,208,133,111, 74,131,155, 63,250,125, 20,254, +154, 47, 55, 63, 77, 89, 34,154,212, 1, 58, 17,250,107, 88,255, 0,221,237,123,241,183,168,213, 74,141,111,240,254,206,143,253, +181, 42,160, 51, 22, 5, 5,191, 49, 63,100, 83,234, 62, 85, 35,249,167,249,137,251, 34,163,170,128,175, 63,206, 13,143, 42, 17, +146,222, 6,172, 74,120,220,121, 80,109,168,241,160, 35,168,219,151,213, 76,178, 18,120,139, 81,128,183,186,149, 1, 29, 86, 20, +250,129,241,167, 32,114, 53, 29, 32, 19,122, 2, 18, 53,148,149, 55,176, 39,234,170, 64, 85,169,192, 17, 49, 28, 15, 0, 62,186, +171,164,219,157, 70, 84, 35,106,195,206,218,167,121,222, 88, 44,235, 33,212, 69,236, 65, 60,249,214,209, 30, 52,185, 1, 94,124, +156, 91,121, 16, 80,185, 93, 29, 83, 90, 52,119,199,201,185, 98, 78, 86,233,170,163, 79, 84,100,225,109, 1, 27,169,149,102, 35, +148, 99,136,254,181,108,241, 3,128,181,185, 83, 1,198,139,200, 85,199,198,181, 98, 59, 45, 70,157, 91,226,252,217, 47,228, 92, +189, 45,215, 29,122, 46, 75,201, 2, 37,141, 98,111, 24,100, 55,170, 65,112,120, 73,248,141,110, 84, 72, 86, 4, 48,184, 60, 8, + 53, 50,177,227,145,106, 86,229,167, 52,250, 75,147, 46, 53,249, 88,186,174, 71, 94, 77,117, 93, 14, 58,173, 96,238, 25,123,116, +221,108, 73, 76,109,201,135, 53, 97,228,192,240, 53,103, 59,106,120,137,151, 24,107,143,153, 79, 21,251, 69,102, 87,229,238,217, +189,141,114,146, 78, 18, 92, 36,191, 24,179,244,118,238,218,200,183, 88,210, 81,124, 83,252, 26, 59, 44, 94,249, 26, 64,205,197, + 58,188, 94, 35,192,255, 0, 85,190,218,176,253,241,128, 7,238,241,166,102,242,109, 42, 62,187,181,112,180,171,209, 30,235,152, +149, 55,167,226,226,170,112,125,183, 21,186,236,107,193, 55, 67,119,115,238,173,199, 61, 76, 49,219, 26, 22,224,203, 25,187, 17, +228, 95,236,172, 42, 84,124,108, 57,242,223, 68, 43,113,226,231,130,143,121,175, 52,238, 95,200,184,183, 57, 92,147,209, 46, 62, +228,122, 35, 11, 54, 32,246,168,219,138,213,191,155, 35,141,143, 38, 84,203, 4, 66,236,199,159,128, 30, 36,215, 99, 12, 77,141, + 2, 65, 21,180,160,176,243, 62,102,133,129,183,197,183,199,101,248,164, 97,241,200,121,159, 96,246, 85,146,121,219,198,191, 65, +219,176,191,215,131,148,255, 0,201, 62, 63,241, 93, 62,103,194,207,204,245,228,163, 15,178, 28, 63,228,250,152, 27,191,109,236, +251,150, 87,171,206,193, 73, 50, 28, 0,210, 22,123,144,160, 1,200,138,172, 59, 91, 99, 56,103, 1,176,211,211,106, 50, 4,227, +193,200, 0,178,177, 58,135, 1,224,107,119, 37,216, 58,168, 23,176,160, 31,136,115,247,218,190,170,185,114,137,111,149, 23, 13, + 94,135,206,244,173,213,189,145,171,227,162,212,229,155,238,247,182,195,234,209, 48, 95,209, 18, 27,125,181,179,181,108, 91, 54, +209,241,109,248,171, 19,145, 99, 41,187, 57, 31,211,123,154,190, 60,173,195,204,211, 31,132,243, 39,216, 42,202,245,217, 42, 74, +114,107,163,100,141,139, 81,117,141,184,167,213, 34, 25,152,152,155,142, 59,225,229,160,154, 9, 45,174, 51,112, 13,136, 97,202, +199,152,172,252, 94,213,237,252, 60,152,242,177,112, 82, 57,162, 58,163,112,206, 72, 62,124, 90,180,205,212,234, 28, 60,232,128, +223,143,157,101, 78,105, 81, 73,164,248,164,244, 52,237,194, 77, 74, 81, 77,174, 13,170,177,217, 85,148,171,128,202, 69,138,158, + 32,131, 92,222,103,101,118,222,100,140,231, 19,162,199,153,133,153, 7,234,131,167,240, 87, 73, 75,161,115,123,243,227, 72,220, +156, 53,132,156,124,157, 4,237,194,122, 78, 42, 94,106,167, 41, 31, 96,246,220, 44, 25,161,146, 91,120, 73, 35, 91,254,142,154, +232,112,177,177,112, 97, 24,248,113, 36, 17, 47, 36, 64, 20,126, 10,226, 59,147,188, 55, 77,163,127,200,219,161, 88,142, 52, 38, + 43, 22, 66, 90,207, 26, 72,220, 67, 15,210,160, 79,221, 93,217,185, 23,201,217,118,247, 76, 16, 72,141,214, 19, 41, 32,121,177, + 5, 73,243, 11,202,172,238, 92,159,223, 39, 47, 54, 72, 90,183, 15,178, 17,143,146, 59,125,199,101,218,119,102,141,247, 28,101, +157,162, 4, 70, 88,176,176, 60,254, 82, 41,182,253,155,107,218,122,135,109,198, 88, 12,182, 18, 21, 44,111,166,246,249,137,243, +174, 51,101,251,195,200,143, 41,113,119,232, 16, 68,205,161,167,141, 74, 60,102,246,187,161,230, 7,141,172,125,245,187,222,253, +201,157,219,235,183,182,218, 34,101,202, 18,151, 50, 41,113,100,233,233,211,102, 31,167, 83,124,246,237,220,246,244,174,158,225, +178, 27,183,237, 91,186,211, 95,121,210, 32, 36,214,118,103,107,236, 59,134, 75,229,230, 97, 44,185, 18,216,188,132,184, 39, 72, + 10, 57, 48, 28,133, 46,215,220,166,221,182,108, 92,252,192,162,121,250,154,194, 11, 47,193, 35,160,225,115,224,181,139,222,189, +217,185,118,254,118, 62, 54,222, 33, 49,203, 15, 81,250,138, 88,223, 81, 94, 22, 97,229, 82, 50,148, 93, 98,220, 95,131,161,101, + 8,201, 82, 81, 82, 92,117, 85, 52, 55, 92,204, 14,202,218,162,124, 76, 59,227,180,221, 49, 10, 57, 91, 51,171, 57,107,182,175, +208,160, 96, 54,207,223, 27,123,230,230,237,202,189, 41, 90, 5,212,215,113,101, 87,184,116,210, 71,207,202,178, 59,211,112,125, +203,179, 54,172,185,128,235,205, 52, 50, 73,164, 89,110, 97,150,246,231, 88, 29,185,220,155,174,221,183, 62,209,179, 98,122,140, +169,166,121,153,244,180,150, 82,177,160,210,137,237, 94, 36,240,166,233, 39,185, 55,187,173,117,247,141,145,113,218,226,182,244, +166,158,227,178, 31,119, 61,186,127,120, 68,182,253, 14,161,183,219, 87,242,123,115,183,246,189,151, 52, 46, 16,124,104,162,105, +230,136, 18, 26, 78,136, 50, 0,100,226,220,214,184,182,239, 94,238,218,103, 84,221,113,198,147,196, 69, 60, 38, 43,142, 23,208, +203,167,235,227, 93,167,241,140, 93,247,179,247, 76,252, 98, 64, 56,153, 41, 36, 77,109, 72,203, 19, 93, 77,189,247,173,187,215, +101, 74,206, 78,158, 38, 21,139, 49,174,219,113, 85,211,130, 48, 59, 62,126,217,221,183, 99, 30, 14,205,232,242, 49,162,108,132, +152,204,207,201,150, 59, 91,135,251, 74,188,221,239,132,251,217,216, 31,109, 45,171, 47,208,180,140,224,169,188,157, 29, 69, 74, +242,241,181,115,191,117,191,250,131, 39,255, 0, 38,255, 0,245,176,213,223,243,110,127,249,187,248, 87,166,196,232,255, 0, 18, +244,221, 78,143,239, 52,245,250,122,181,223,230,183,143,157, 98, 82,148,157,101, 38,223,139,169,184,194, 49, 77, 70, 42, 43,162, + 84, 58,124,190,192,237,140,183, 47,232,250, 12,121,152, 29,144,126,173,202,254, 10, 28, 31,119, 93,175, 11,135, 56,242, 77,111, + 9, 36, 98, 62,165,211, 65,239, 46,246,110,222,153, 54,252, 24, 86,108,199, 65, 35,188,151,208,138,110, 7,194,164, 18,198,222, +117,145, 22,231,247,159,149,142,185,240, 99, 47,167,117, 18, 32, 9, 8, 37, 72,212, 8, 70,110,161,184,174,158,189,234, 83,212, +149, 60,217,207,253,123, 53,175,167, 15,114, 59,200,113,241,112, 98, 92, 76, 72,150, 8,148,124, 17,198,161, 87,219,202,184,142, +242,221, 54, 44, 61,194, 12,125,215,105,245,242,244, 21,210, 94,169, 77, 42,210, 56,211, 97,253, 26, 23,111,253,224,229,229,110, + 49,109,187,220, 8,141, 43,244, 86,120,193, 66,178, 31,132, 44,136,196,243,110, 30, 22,172,143,188,177,109,243, 23,255, 0, 38, +159,245,179, 87, 53, 41, 39,185, 54,159, 84,245, 58, 56, 69,173,174, 41,174,141,104,122, 71,109,237,219, 86, 54,221, 14,102,215, +136, 48,215, 62, 40,167,120,195, 51,124,201,173, 65, 44, 79, 45, 85,176, 86,245,229,184,189,221,220,249, 27,110, 38, 23,110,109, +174,208,225, 99,197, 4,185, 34, 38,153,139,199, 26,169,181,190, 1,196,114,226,106, 59, 87,222, 78,239,141,154,184,251,244,107, + 36, 26,180, 76,193, 58,114,199,198,215,176,176,225,226, 45, 70,219,117,147,109,190,108, 40,168,170, 69, 36,151, 37,161,233, 12, + 89, 9, 3,133,248, 26, 47,168, 81, 89,157,205,220,123,119,110, 97,166, 78, 68, 34,124,153,137, 24,240,131, 98,228,115, 36,241, +178,143, 19, 92,102, 15,115,119,246,249,212,159,100,194,137, 96, 13,243, 44,104, 19,135,230,135,201,107, 19,231,106,133, 61, 20, +228,146,120, 41, 62,234, 30,188,167, 63, 10,181,188,173, 92, 20,127,120, 61,205,177,103, 46, 39,114,224,161, 83, 98,218, 80, 71, + 38,158, 90,208,169, 49,176,255, 0, 75,215, 99,191,247, 36,152,157,175, 54,253,180,200,146,252, 49, 62, 59, 56, 37, 72,146, 68, + 67,117,184, 60,152,253, 52, 5,195, 6,107,241,208,212,233,135,145,123,178,216, 14,119, 53,231,184,191,122,123,144,192,200,108, +184,163,155, 61,157, 87, 18, 52, 86, 84, 0,131,169,228,248,141,248,218,192, 85,254,208,238,126,229,221,247,150,196,221,198,140, +119,133,228, 69, 48,244,248,169, 91,105, 36, 92,243,168, 83,187, 88,133,239,107,144, 57,212, 97, 80,192,130, 60,106,192,224,167, +234,160,227,240, 36,143, 3, 66, 7, 81,164, 83,218,144,243,167, 7,192,213, 4,109,198,158,212,143,133, 33,236,160, 44,255, 0, +113,255, 0, 39,254,218,149, 47,238,111,254,231,254,218,149, 0,118, 60, 22,223,160,159,178, 42, 13,126, 6,212,228,181,146,252, +244, 37,255, 0, 84, 83, 30, 62, 20, 0,101,189,249,113,181, 48, 31, 71,157, 60,164,235, 3,200, 80,213,154,230,252,168, 2, 94, +254, 20,143, 15, 10,136, 62,116,228,240,160, 23, 62, 38,152,155,210, 12,117, 16, 69,133, 51, 27,114,160, 43,100,184, 42,163,219, +113,244, 80,139, 0, 42, 89, 70,238,171,224, 5,239,239,255, 0,240,160,251,106, 50,136,155,138, 92,124,169,212,112,189, 63,133, + 0,193,184,212,139, 19,192, 80,193,230,106, 64,128, 40, 4, 5,233,194,138, 74, 69, 61,248,208, 14,136, 11,129,225,126, 32,249, + 84,114,118,188, 44,143,137,226, 3,249,203,192,254, 10, 36,100,107, 4,155, 91,141, 20, 50,219,159,228,172, 78, 16,154,219, 56, +169, 46,141, 84,212, 39, 56, 61,208,147,139,234,157, 12, 57,123,126, 29,122, 98,153,150,254, 12,161,191, 15,195, 78, 59,105,111, +111, 84,127, 83,255, 0,214,173,166, 3, 90,241,250, 5, 19, 85,254, 83,196, 87,145,246,220, 54,235,233, 47,100,164,191, 51,210, +187,134, 90, 84,245, 95,186, 47,242, 51, 96,237,236, 24,236, 95, 84,173,252,227, 97,245, 10,184, 32, 72,192, 72,254, 21, 30, 2, +214, 21, 99, 95,143, 58,129, 11,227,206,189, 22,172, 90,180,169,110, 17,143,146,215,222,112,185,122,237,199, 91,147,114,243,122, +123,129,244,217,155, 65,115, 96, 61,148,140, 78, 63, 60,145,238, 21, 52, 63, 17,169,139, 3,230, 43,169,204,205,200,225, 41, 70, + 55,181,184,253, 23,160, 95, 73,225,203,196,209,178, 91, 84,206,195,149,237,199,217,194,130, 13,249, 86,128,230,199,143, 63,101, + 56, 55, 22, 60, 13, 64,155, 26,127,125, 0,184, 14, 28,252,201,162, 14,118,160,130, 9,176,241,163,168,227,122, 48, 58,173,200, +171, 22,161,160,226, 40,213, 8,120,167,125,233, 29,221,159,170,250,111, 6,171,115,183, 66, 62, 85,236, 56,222,145,240,160, 56, + 58, 78, 39, 77,122, 26, 62, 93, 22,248,109,244, 87,142,247,239,254,172,220, 63,228,255, 0,212, 71, 93, 6, 87, 98,247, 62,222, +207, 14,201,185,177,193, 98, 74,196, 38,146, 19, 99,224,234,191, 1,247,213, 6, 47,222, 9,196, 61,194,222,155, 78,177, 10, 12, +157, 63,237,110,220,253,186, 52,213,222,248, 89,147, 98,237,101,200,191, 84, 99, 62,187,243,190,140,126, 6,254, 62,117,165,176, +253,219, 72,185, 41,151,190,204,146, 34,144,227, 26, 34, 91, 89,189,255, 0,120,236, 7, 15, 48, 57,249,215, 85,221, 93,179, 23, +114, 96,164, 29, 78,142, 68, 4,190, 60,150,186,139,139, 50,176,242, 52, 5, 62,196, 88,159,180,240,152, 49, 44,189,101, 96, 15, + 35,214,115, 99,244, 26,227,190,243,164,199, 59,222, 60, 48,181,222, 28,117, 18,139,222,204,204,204, 1,246,218,198,137,141,216, +157,229,130,237, 22, 38,106, 99, 68,228, 7,120,114, 36, 69,111, 11,144,138, 9,250,170,206,119,221,126,228,235, 19,226,230,197, + 52,237,169,178,165,200, 46,183, 98,120,104, 10,146, 19,239, 38,128,126,232, 88,199,221,230,196, 85, 64,114,248,247,111, 19,251, +137,107, 67,238,185,176,191,133,230, 42, 5, 57,189,123,205,123, 22,233,233, 29, 63,234,223, 87,211,122,189,188,246,166,227,184, +246,174,219,177,193, 44, 11,147,134,209, 52,174,236,226, 50, 18, 55,140,233, 33, 11,115,111, 17, 88, 49,125,219,239, 88,152,169, +145,135,158,144,110,136,204, 15, 74, 73, 21, 10, 27,105,211, 32, 85,101,110,126, 22,160, 55,254,241,206, 26,246,211,172,250,122, +237, 44,126,150,255, 0, 54,176,223, 22,159,234,106,174, 83,178,122,223,229,238,234,255, 0, 97,232,218,215,229,175,165, 55, 47, +163,159,209, 83,255, 0,237,247,116,238, 57, 8,219,182,106,121, 25,165,149,231,112, 63,154, 15,250,194,187,172,126,217,199,219, +187,115, 51, 99,219,136,234,100,193, 44,102,121,120,107,150, 84, 41,173,202,131, 97,199,192,112, 20, 7, 3,247, 91,255, 0,168, + 50,127,242,111,255, 0, 91, 13,102,255, 0,255, 0, 64,255, 0,252,207,255, 0, 53, 93,175,102,118, 94,233,219,155,164,217,185, +211, 99,201, 20,152,237, 8, 16,179,179,106,103,141,238,117,198,130,214, 74,169,254, 65,222, 15,116,127, 27,235,227,122,111, 95, +235, 52,107,147,169,211,235,117,173,110,157,181, 91,219, 64, 31,189,251,107, 11,121,205, 25,112,110,120,216,185,209,160,142,108, +124,153, 21, 3, 1,241, 41,241,101, 54,111, 42,202,139,103,251,202,219,177,209, 48, 50, 90,108,116, 81,211, 17,205, 27,168, 95, + 13, 34,107,112,183, 43, 87, 67,221,221,138,187,252,227,113,194,157,113,243,116,132,145,100, 4,199, 32, 94, 10, 73, 91,149, 32, +112,228,107, 27, 27,183,254,242, 48, 32, 92, 60, 76,244, 92,116, 1, 80, 9, 67, 0,163,144, 93,105,168, 1, 64,102,225,119,214, +243,183,110, 30,151,126,199,138, 96,175,163, 39, 84, 75, 28,200,111,197,135, 76, 40,184,231,203,141, 71,239, 59,255, 0,207,113, +127,242, 81,255, 0,214,205, 90,123,119,221,214,116,153,223,196, 59,131, 49, 37,248,250,146, 71, 25,105, 30, 70,249,172,238,225, +109,127, 30,117,161,221,253,151,186,119, 30,227, 6,118, 20,216,241,197, 30, 58, 66, 86,102,117,109, 65,221,248,104,141,197,190, + 63, 58, 20,233,251, 94, 8,160,237,205,173, 33, 80,170,216,176,200, 64,241,105, 16, 72,231,233,102, 53,229, 63,120,138,171,221, +121,118, 0,106, 72, 73,183,137,233,173,123, 14,211,141, 38, 14,213,131,131, 49, 86,151, 27, 30, 40, 93,150,229, 75, 70,138,132, +173,192, 54,225, 92, 63,117,118, 38,239,191,111, 83,110, 88,147,227, 36, 50, 44,106, 22, 86,144, 53,209, 66,155,133,141,135,135, +157, 8, 98,253,230, 9, 70,225,182, 22,254,199,209, 46,143, 45, 90,219, 95,224,211, 86,246, 12,127,188, 25, 54,156,102,217,179, + 32, 76, 2,191,184, 91, 65,112, 47,196, 29, 81, 19,123,243,185,174,219,127,237,140, 62,225,219,162,195,203,110,156,240, 1,208, +201, 65,114,141, 96, 27,129,181,212,219,136,174, 51, 15,180, 59,227,102,214,155, 46,227, 31, 65,155,229, 87, 32, 19,250, 70, 57, + 16,168, 62,234, 0, 59,231,111,119,190,234,176,166,249,151,136,226, 34,198, 13,111, 12, 68, 94,218,172, 81, 16,158, 66,175,101, + 96,102,109,159,118,121,184, 89,143, 27,180,114, 39, 77,162,113, 34,232,108,136,155,230, 31,206, 38,135, 31,221,239,112,239, 57, +139,149,220,187,138,149, 22, 7, 75, 25, 36,210, 56,233, 91,133, 68, 30,239,170,186,237,235,183, 23, 35,181,165,237,221,164, 71, + 0,211, 18, 65,212, 36, 40, 9, 42, 74,197,138,171, 27,157, 39,195,157, 1,196,253,213, 96,227, 79,153,184,102,202,129,230,197, + 88,150, 2,194,250,122,165,245, 48,246,252, 21,234,117,200,246, 63,106,238, 29,179,235,253,124,144,201,234,186, 61, 62,131, 59, + 91,167,212,190,173,104,159,166, 43,175, 35,202,128, 94, 22,161,192, 56, 55,188,209,109,194,133, 0,184,111,121,160, 12,183, 30, + 52,254, 21, 11,212,129,240,160, 23,182,158,252, 45, 77,110, 62,218, 86, 28,168, 11, 86,253,199,252,159,251,106, 84,214,253,197, +191,220,255, 0,219, 82,160, 12,231,229,254,130,126,200,166, 7,240,210,123,252, 63,208, 79,217, 21, 11,253,116, 4, 37,182,161, +238,226,106, 4, 15, 62,116,211, 31,140,123,170, 26,184,222,128, 37,236, 41,106, 21,200,229,253,228,118, 78, 14, 92,248,121,123, +196,113,100,227, 72,240,207, 25, 73, 73, 89, 35, 37, 29,120, 33, 28, 8,167,222,190,240,123,107,100,218, 49,247,217, 50, 14,102, + 14, 84,134, 44,121, 48,192,151, 83,128, 73, 95,153, 64, 34,199,153,160, 58,203,154,107, 95,153,170,152, 57,145,238, 24, 88,217, +240,134, 88,178,162, 73,209, 92, 0,193,100, 80,234, 26,196,139,216,249,213,155,218,128,165, 61,204,204, 7, 27, 88, 15,170,161, +102,229, 83, 36, 52,133,188, 9,189,101,119, 7,112,237,221,179,182,190,237,185,151, 24,200,202,135,164,186,219, 83,124,160, 11, +138,133, 53, 2,158, 84,250,124, 42,166,209,186, 99,239, 27,110, 46,235,140,174,144,101,198,179, 68,178, 0, 28, 43, 11,141, 65, + 75, 11,253, 53,111, 85, 1, 21, 75,240,167,208, 47, 78,172, 1, 53, 95, 35,114,219,240,157, 83, 51, 46, 28,119,144,142,154,205, + 34,161,107,254,136, 98, 47, 64, 90, 10, 5,169,236, 0,166,214, 13,136,226, 15, 16,106,182, 94,231,183,225,186, 71,151,149, 14, + 59, 63,200,178,200,168, 90,252, 62, 16,196, 94,128,184,138, 11, 0,124, 46,106, 90, 87,244, 71,213, 64,245, 88,208, 33,155, 34, + 84,138, 49,111,222, 59, 5, 94, 60,184,183, 10, 80,238, 91,118, 75,152,241,242,225,149,173,125, 49,200,172,108, 57,155, 3, 80, + 22,130, 70,127, 48, 19, 72, 68,158, 92,233,139,141, 23, 87, 20,203, 34,248, 30, 62, 52, 3,148, 77, 95, 71, 42, 70, 52,225,111, +229, 52,186,128,106,246,154,144,101, 39,221,196, 26, 2, 2, 49,115,204,125, 52,205, 31,243,155,235, 53, 50, 71, 18, 8, 21, 22, + 34,196,147,225,203,194,128,204, 99,241,177,183, 2, 73,185,168,146, 7, 27,223,217, 83,233,146, 62, 51, 75,224, 94, 67,141,104, + 17,248,136,248, 69,189,180,225, 7,231, 27,211,179,183,184, 84, 24,131,199,153,160, 36, 52,134, 10,163,157, 88, 81, 85,163,185, + 96, 79,133, 89, 6,163, 1, 23,194,166, 42, 11,206,167, 84,135, 27,190,253,223,195,189,238,179,238,143,156,208,180,250, 47, 24, +140, 48, 26, 17, 99,231,168,126,141,117,210,181,172, 60,232,134,162,224, 90,244, 3,175, 5, 21, 32,120,212, 11, 1, 96, 77, 61, +252,111, 64, 41, 60, 7,155, 10, 32,160,187,128,203,115,227,115, 79,215, 79, 14, 52, 1, 9,240,165, 81, 46, 45,198,162,210,162, +159, 31,174,165, 69, 9, 55,206,131,223, 83,170,230, 97,168, 17,225,127,195, 69, 15, 74,138, 4,231, 78, 5, 4,202,160, 94,194, +134,217, 32, 14, 85, 69, 11,118, 54,229, 81, 38,220,248, 80, 35,201, 46,214,181,135,157, 16,189,133,234, 54,139, 70, 14, 72,248, +179,223,221, 70, 75, 5, 81,127, 10, 4,211,128, 52,142, 55,231, 80,245, 76, 0, 22,229, 68, 11,124, 5, 32, 69,255, 0, 37, 6, + 25, 89,248,158, 84, 91,240,184,231, 81,201, 33,181,147, 38,135, 13,180,146, 13,248,154,132,147,133, 22,241, 52, 37,152,168,178, +213, 78,164,161,112, 94,252,143,224,167, 98, 9,170,177,100, 22, 32, 53, 28, 27,213, 4,214,222,127,130,152,243,225, 72, 82, 52, + 3,248, 80,160, 97,102,225,110, 52,111, 11,208,113,248,134, 30,218, 0,162,244,246,243,165,200,210, 54, 2,230,132, 28,138, 64, +208,250,171,107, 95,149, 46,170,208,165,219,254,227,151,247, 63,246,212,170, 29, 81,208,191,251,155,255, 0,239,173, 74,128,103, +150, 75, 39, 31,238,227, 39,128,241, 69,168,117, 31,206,147,143,236,255, 0,225,199,251, 11, 80,161, 65,100, 73, 38,176, 3,112, +183,144,161, 9,100,177,227,115,237, 20,178, 73,214, 61,223,140,208, 56,213, 7,205, 89,185, 19, 69,221,157,236, 34,218,134,234, +103,254, 39, 19,221,117,122, 85,108,155,156,192, 52,183, 24,173,192,240,181,249,211,102,203,183,255, 0,246,199, 7, 27, 14,119, +150,101,221,158, 92,196,145,116,152,228,124,114,161, 83,139, 93, 52,160,177,243,189,118,217, 63,118,189,237, 30,251,190,238,155, + 70,225,129,143, 22,242,249, 81,190,182,144,201,233,178,165,234,148, 35,160,193, 90,192,114, 62,227, 79,147,247, 57,184,167,108, + 69,180,224,102,227,201,184, 62, 88,203,203,154, 98,241,197,165, 99,104,214, 56,244, 36,140,109,170,247, 32, 84, 0,123,151,190, +247, 92, 7,237,222,219,195,221, 63,130, 97, 13,187, 22, 92,221,197, 98, 51, 56, 47, 23,194, 52,168,102,210, 52,143,151,206,177, +223,239, 71,188,102,236,245,145,119, 3, 30,118, 62,106,227,201,148,177,197,174, 72,100,137,164, 64,196,161,179, 43, 70,120,139, + 19, 93,143,113,125,220,111, 89, 51,236,219,206,195,151, 4, 59,198,217,139, 6, 52,201, 53,204, 78, 96, 93, 58,208,148,107,243, + 43,102, 91, 17, 66,223,187, 19,189,123,155, 96,143, 15,114,201,219,151, 61, 51, 6, 64, 17, 6,138, 20,132, 68, 99,209,120,225, + 36,190,182, 39,136,250,104, 12,110,222,239, 14,238,194,239, 92, 13,183,126,220, 70, 86, 30, 78, 42, 75, 44, 72,163, 64,141,241, +125, 82, 48,248, 85,181,173,133,207,143, 26,230,187,139,185,187,171,187,182, 77,195,118,203,202, 72,182, 88,179, 34,130, 61,185, + 85, 69,153,195,200,159, 16, 93, 71, 64, 94, 36,158, 55,175, 66,143,238,223,120,255, 0, 55,237,219,228,243, 98,182, 6, 54, 44, + 24,185, 17, 7,147,170,221, 60, 95, 74,250, 7, 75, 77,175,202,237,202,185,255, 0,254,208,247,132,120, 57,219, 54, 54,229,134, + 54,217,114, 19, 34, 36,144,189,228,104,245, 34, 51,145, 19, 20, 58, 31,136, 23,227,245,208, 21,179,123,215,113,192,194,237,126, +220,196,221, 63,130, 97,127, 14,199,155, 55,113, 88,140,206, 11,169, 42, 52, 40,102,210, 52,143,151,207,217, 85, 91,239, 51,187, + 37,236,225, 42,231,152,243,160,205, 92,121, 50,150, 56,181, 73, 12,145, 59,168,107,161,179, 43, 70,126, 33, 99, 93, 94,233,247, +101,190,132,216,119, 61,147, 51, 30, 29,235,105,197,135, 22,117,147, 81,134, 67, 8, 54,116, 45, 27, 95,131, 21, 33,150,196, 81, +119,254,197,239,110,230,216, 34,194,220,242,118,229,207, 92,193,144,162, 32,241, 66,144,136,140,122, 47, 28, 36,151,214,196,241, + 31, 77, 64,116, 61,129,254,110,202, 92,189,215,185,164,255, 0, 13,157, 30, 52,187, 92, 10,202,194, 56,202,185,109, 65,120,234, + 43,160,155,215, 51,247,161,217,157,183,137,183,110,253,213,157,145, 48,220,242,158, 49,136,165,192, 78,165,149, 22, 36, 77, 60, +110,170, 73,185,175, 77,218,113,228,192,218,240,112,102, 33,164,198,199,138, 25, 25, 46, 84,180,104,168, 74,146, 1,181,199,149, +121,215,222, 7, 99,119,151,120,238,209,205, 6, 86, 12, 59,102, 32,182, 22, 60,178, 75,123,155, 23,146, 69, 16, 50,234, 98, 57, +113, 22,250,104, 14,135,238,185,119, 37,236,141,183,248,145, 98,228, 57,199, 18, 95, 80,128,185,233, 94,254, 26,126, 95,230,218, +185,111,189, 14,204,237,188, 93,187,118,238,188,236,137,134,233,148,241,140, 69, 46, 2,117, 44,168,177, 34,105,227,117, 82, 77, +205,107, 75,219,255, 0,121, 77,219, 80, 96, 69,189,227,166,241, 30, 83, 73, 38, 82,179, 44,103, 27,167,165, 34, 93, 56,254, 13, +198,218, 62,154,207,239,174,196,239,110,240,220, 32,145, 51, 48, 35,192,195, 64,184,176, 73, 36,196,151,176,234, 75, 34,140,118, + 93, 76, 71,213,244,208, 20, 95,111,238, 12,255, 0,185, 60, 44, 17,139, 62,102,110, 76,232, 49,162, 68,105, 37,244,194, 86,146, + 59,128, 9, 10, 21, 56, 19,195, 77,169,125,207,228,118,190, 62,250,251,113,218,242,118,238,229,143, 21,177,231, 57, 18, 25, 18, + 66,133, 12,246,141,149, 12, 79,169, 47,166,198,194,226,245,216, 65,178,253,228, 65,218,112,226, 65,189,225,255, 0,152, 32,204, +235,117,207,246, 13,137,210, 49,140,114, 12, 3,142,166,191,201,225,206,168,246, 55,221,246,237,181,247, 14, 87,119,247, 86,116, + 25, 91,172,225,244, 36, 7,225, 13, 47, 7,118, 58, 99, 23,211,240,128,162,212, 7,164, 0, 11,234, 68, 22, 38,198,254, 66,164, + 34, 82,120,168,227, 66, 5, 72, 63,188, 10, 9,252, 30, 84, 94,164,119,230, 45,239, 21, 0,198, 52,190,157, 2,222,116,230, 40, +194,234,208, 62,170, 99, 42,147,164, 21,246,220,248,123, 41, 60,168, 23,225, 96,110, 57, 92, 80, 17, 88,144,168,107, 15,111, 10, +139,196,130, 54,109, 32, 16, 15,224,169,117, 16, 1,118, 30,235,208,167,116,104,136, 12, 13,237,195,233,170, 10, 76,110,111,206, +152,155,251,253,148,143, 3,231, 76,120,113,254, 74,160, 87,181, 58, 33,115,194,162, 1,118, 0, 11,147,200, 85,228,141, 99, 26, + 71,210,104, 1,232,208,163,219,206,144,169,202,120, 40,250,106, 34,160, 30,228,114, 23,164, 26, 70,228,181, 23, 98,188,188,168, +145,179,104, 38,169, 7, 66,215,179, 11, 83,200,108,180, 52,147,141,219,157, 69,228,212, 72, 28,188, 40, 4, 46,205,170,138,196, + 42,146,121, 84, 7,194,160,120,212, 93,129, 22, 60,107, 28, 89,174, 0, 53, 51, 18,104,145, 41, 36,177,164,160, 26,157,192, 60, + 57, 86,159, 0,137,177, 10,132,145, 85,117, 19,115, 69,144,134, 0,113,246,208,194,138,137, 80, 50,113, 46,163,118,228, 42,202, +114,189, 9,116,168, 2,212,153,128, 78, 23,212,126,202,142,173,148, 20,178, 18,252, 57, 10,137, 44,120,121,212, 13, 26, 37, 81, +241, 31,162,181,193, 16, 44,107,161, 69, 77,219, 66,220,218,135,168,126, 74, 20,206,172,218, 71, 33,252,181,138, 85,148,133,245, + 18, 77, 58,174,166, 11, 80, 21,102, 5, 0, 22, 35,137, 60, 43,109,209, 16, 50,128,160, 5,240,162,179,104, 91,147,192, 10, 13, +215,203,135, 26, 30, 68,138,126, 5,250, 77,115, 74,172,160, 93,139,185, 99, 75,144, 28,106, 39,216, 40,208,162,146, 25,135, 1, + 93, 56, 35, 33, 32,138,194,231,153,163, 41,177,181, 71, 82,248,112, 30, 52,152,160, 5,143, 48, 43, 9,186,249,154,107, 64,234, + 71, 10,147, 90,215, 39,149, 85, 76,132, 0,223,137,242,161,188,205, 33,227,193,124,171,161,138, 7, 92,144,215, 86, 22, 30, 6, +180, 49,182,223,220,172,189, 95,237, 0,123,105,229,113,127, 58,197, 46, 52,148,183,204, 71, 26,235, 32, 83, 28, 17, 68,220,209, + 21, 77,185,112, 22,164,117, 15, 68, 81,108, 27,113,234,127,209,252,181,159, 54,174,155, 91,199,133,110,205,196,112,174,118, 92, +132,188,144,254,114,177, 95,168,218,171, 84,161, 23, 4, 49,133, 68,122,250,204, 78,155,170,142,119,168,126,231, 69,196,146, 23, +241, 94, 31,101, 48,145,163,101,144,199,240,168,211,115,200,212, 34, 98,215, 54,226, 77,235, 53, 53, 67, 71,166,190,131,169,173, +181,244, 45,111,103, 95, 85,233, 83,220,250, 45, 55,254,227,159,252,251, 82,171, 81, 66, 82, 15,236,255, 0,225,199,251, 11, 67, +169,201,253,223,252, 56,255, 0, 97,106, 20, 5, 92,155,107, 30,239,198,104, 7,149, 31, 39,251, 65,238,252,102,131,202,168, 57, + 17,223,219,114,162, 52,144, 58,150,193,202,220, 31,136, 33,125, 35, 72,143, 9, 63,164, 76, 47,111,117,109, 71,191,237,210, 63, +165, 50,133,206, 88,186,178, 98,113,186,176,140, 76,209,234,176, 82,225, 90,229,121,219,141,173, 92,126, 95,221,246,225, 60,185, +172,153, 16, 42,100,110, 34,104,148,151,248,112, 36, 57, 45,145,142,192, 39,204, 91, 50, 66,170, 56,114,227, 90,107,218,153,131, +184,114, 55, 2, 17,241,222,121,242,225,153,242, 50, 46,173, 62, 55,165,233,140, 64,122, 10,192,150,188,156, 73, 94, 22,242, 3, + 99, 11,186,118,140,152,182,227, 36,235,143,145,185, 99,193,149, 14, 59,222,234,185, 11,170, 53,118, 3, 72, 45,196, 45,207,196, + 71, 10, 36, 61,209,219,243,227,201,151, 22,225, 27, 65, 19, 70,143, 39,196, 5,231, 58, 97,181,197,200,144,252,164,112, 62, 21, +206,225,246,166,241,135, 12, 24, 31,225, 37,199,159, 11,110,197,206,157,203, 51, 68,216, 49,180,114, 24, 17,147,227, 45,113,211, + 98, 87, 73,227,106, 80,246,158,239, 32,198,147, 37,177,226,151, 16,109, 24,234,177,187,178, 60, 59, 94, 65,200,146, 83,120,193, + 15, 32, 98, 21, 60, 60, 90,128,232,113,187,163, 96,202,234, 24, 51,209,150, 24, 95, 38, 82,193,144, 44, 81,157, 50, 57, 46,171, +242, 30, 12, 57,175,141, 93,197,220,246,252,204, 73, 51,177,166, 15,143, 22,161, 43, 89,129, 66,130,236,172,140, 3, 2, 7, 27, + 17, 92,116,157,147,185, 75,139, 38, 57,158, 5, 47,137,186, 99,171, 6,147,251, 76,220,244,206,131,146,131,164, 42, 89,200,226, + 15, 43,215, 69,219, 59, 84,251, 86, 54, 87,168,141, 97,151, 47, 37,178, 90, 49,145, 62, 91, 11,164,113, 14,164,249, 68,187,181, +163, 30, 67,195,219, 81,128,123,103,121,108, 27,164, 59,124,139,144, 32,155,113, 72,228,135, 30, 80, 67,142,171, 20, 69,114, 1, + 80, 89,148,170,241,248,143, 43,211,247, 39,119,109,253,183, 32,131, 38, 55,150,102,196,200,205, 85, 65,192,174, 54,155,173,207, +139,106, 54,247,113,240,174,119,108,236,205,235, 19, 19, 31,110,157,177,140, 46, 54,212,202,158, 57, 92,178, 13,174,126,178,152, +213,162, 93, 93,101, 10, 56,145,164,223,230,173, 94,245,237,237,203,184, 58,127,195,158, 5,255, 0, 5,159,133, 39,168,119, 75, +122,177, 14,135, 93, 17,201,125, 45, 15, 17,195,129,250, 42, 3, 89, 59,139,108,200,147, 28, 98, 79, 28,145, 75, 60,184,210,200, +204, 99, 40,240,194,217, 44, 52,186,141, 95, 10,131,225,240,157, 92,170,198,223,188,237,123,164, 82,207,129,146,179, 71, 13,140, +166,204,165, 67, 46,181,107, 56, 7, 75, 47, 21, 60,136,229, 92,252,157,177,185, 54,229, 38,114, 62, 59, 35,110, 89, 25,234,146, +107, 96, 99,155,108,254, 30,170,234, 20, 92,245, 56,176,191,203,227,126, 20,110,219,217, 55, 45,183, 15, 63, 31, 40, 71, 18, 78, +169, 30, 46, 50, 77, 38, 66,196, 22, 50,140, 4,211, 34,201,211,213,242, 33,190,149,250,168, 13, 21,238,174,221,120, 33,157,115, +227, 49,100, 18, 33,144, 6,210,192,104,212,215,183, 4, 29, 69,187, 31,132, 19,107,210, 78,229,219, 34,245,231, 49,253, 50,225, +102, 28, 11,181,216,201, 32,130, 60,162, 81, 80, 22,176, 73, 56,240,225, 98,121, 87, 51,159,217, 57,249, 27,118,207,132,122, 83, +156,109,169, 54,156,196,245, 57, 56,241, 2, 4, 90,165,255, 0, 13,161,167, 79,129,191,118,246,191, 10,177,185,118,150,229, 60, +217, 89,145, 52,114,153, 55, 41,115, 99,128,101, 79,136, 90, 41,176,162,194,179,207,140, 3,171, 43,199,168,168,184,101,225,127, + 10, 3,169, 27,238,202,153, 88,248, 39, 50, 63, 85,146,168,209, 42,146,192,137, 65,104,174,234, 10,142,160, 83,166,231,226,240, +170,231,186, 59,127, 86, 69,179, 99,255, 0, 13,101,150,193,184,147, 39, 71,247,127, 15,239, 63,121,240,124, 23,248,184,115,174, +122, 78,211,221,215, 51,107, 16,190, 63,161,219, 87,109,233, 32,158,104,149, 78, 21,214,101,233, 4,147,168, 89,109,161,164, 98, + 69,173,194,247,170,210,246,110,241, 51, 78,215,198,130, 53,150, 44,136,241, 49,242,167, 68,150, 68,201,245, 18, 52, 50,105,234, +225,137, 16,252,177,177, 26,248,251,104, 14,229, 55, 29,189,182,255, 0,226,163, 34, 63,225,235, 27, 76,217, 68,252, 10,137,125, +101,137,229,166,198,254, 85,141,153,222, 91, 76, 41,183,250, 54, 25,141,184,102, 12, 24,128,213, 31, 77,194, 25, 36,105, 3, 38, +161,165,109,240,145,115,113,225,198,162,157,186,223,228,217,187,111, 92, 80,100, 76,147,145,166, 73,102,137,101,154, 87,200, 26, +164,156,153, 92,106,111,137,143, 19,196,216,114,170,233,176,110, 19,231,197,187,100,180, 16,228, 73,188, 38,231,145,140,146, 52, +136,145, 69,128,219,122,162, 63, 77, 53, 57, 54, 99,112, 7,213,196, 11,187,175,122,237, 91, 70,230,251, 78, 74, 57,158, 33,134, +100,112,182, 80,185,147,250, 96, 79,244, 62, 99,236, 60, 56,213,247,238,126,221,232, 99,101,140,196, 72,115, 11,250,119, 33,133, +196,108, 34,144,176, 34,232, 21,254, 22, 45,107, 30, 6,177,247,238,222,207,220,187,130, 45,207, 22, 76,113,139,109,179,172, 36, +119, 89, 20,237,249,205,154,218, 85, 99,117,109,105, 33, 2,236, 56,143,109,198, 54,103, 98,231,205, 4, 48, 51, 67,144, 29,119, + 8, 39,143,213,101, 99,198,169,155,154,217,145,200,195, 27, 67, 76, 4,109,165,163,107, 13, 86,227,227, 64,118, 27,214,240,219, +100,152, 24,208,226, 28,172,157,198, 87,130, 20, 87, 88,192, 49,195, 38, 67, 22,103,225,242,198,107, 35, 31,188,246,220,248, 37, +153,227,124, 72,241,225,197,158, 70,148,131,199, 37,231,133, 98, 65, 30,173, 71, 92, 4, 13, 55,213,113,106,179,221,123, 52,155, +219,237, 82,195,137,135,184, 71,129,145, 36,217, 24, 59,131, 50, 67, 42,188, 18,192,188, 68, 25, 34,234,210, 6,226,158, 21,205, + 47, 97,110,113,226, 77, 25,200,142, 82, 61, 3,193, 12,115, 77, 7,253,211, 39, 42,118,199, 89,149,122,145,170,199,144,177,196, +235,199,225,226, 5, 1,208, 79,220,251, 14, 52, 16,228, 79,155, 26,197, 58, 52,177, 55,196,110,136,193, 29,190, 16, 72, 10,204, + 3, 95,151,141, 14,126,226,219,227,222, 49,182, 72,223,171,149, 60,175, 12,138,188,162, 41,142,249,127, 25, 34,223, 34,142, 0, +240,184,189, 99, 79,216,185,242,109,167, 14, 22,199,133,223,107,220,112,138,153,103,145, 70, 70,118, 76,121, 74,122,146,171,200, +234, 52,182,166, 60, 73,252,223, 43,146,246,166,229, 38,242,100, 86,199, 93,180,230,228,231, 25,245,191, 95,252, 86, 11,225,116, +196, 90, 52,221, 29,181, 95, 95, 17,237,170, 13,140,126,227,237,225,137, 38,114,231,197,208,141,145, 36,152,220, 0,101, 54,138, +215, 0,149,127,205, 97,193,188, 40,251,134,240,216,209, 98, 73,133,137, 46,115,230,159,220,164,118,141, 66,104, 50,151,149,229, +210,168, 52,139,113,227,115,106,229,118,206,203,220,113,241, 99,138, 81, 12,115,164,251, 75, 59,156,172,156,163, 36, 91,108,221, + 87,109, 89, 0,232,213,118,233,198,170, 0,241, 62, 93, 15,116, 96,110,251,150, 36, 88,123,103, 72,193, 36,159,253, 70, 41,103, +147, 25,165,131, 73,188, 41, 52, 49, 78,203,173,173,168,129,125, 55, 0,241,168, 9, 55,112, 69, 62,205,135,188,224,227, 77,148, +185,203, 11, 99, 99,170,129, 33, 57, 5,116,235, 36,233, 64,183,187, 49, 54, 3,206,167,129,190,225,229,109,115,110,211,255, 0, +131,135, 25,166,139, 40, 76, 71,238,223, 30, 70,134, 81,169, 73, 86, 26,144,216,142,117, 79,113,197,238, 73, 54,199,194,218,227, +195,192,147,165,143, 28, 34, 57,164, 2, 53, 12, 70, 68,113,191,167,248,109, 24, 11, 19,116,253,182, 22, 21, 33,180, 79,254, 87, +151,103,143, 3, 14, 23,233,152,147, 9,165,150,124, 98,183,185,215, 55, 78, 25, 75, 56,185, 45,166,250,184,241,160, 14,221,205, +176,104,134, 86,206, 69, 89,139,162,134, 12,172, 25, 10,171,245, 21,148, 52,122, 75,173,203,129,107,143, 58,156,189,199,182, 67, + 59, 96,197, 60,114,229,199, 60, 56,243,194, 88,166,131, 60,145,198, 46,218, 72,213,251,208, 85,127, 58,184,252,158,198,222, 50, + 85, 70, 75, 71, 56,154, 60,140,119,130, 92,220,165,233, 69, 52,145,186,117,166,128, 68,249,122, 85, 24, 50,201,107,240,227,194, +245,191, 55,109,103, 63,174,211, 36, 35,212,239,152,123,178, 92,183, 8, 49,253, 38,180,111,131,231, 62,157,172, 57,114,227, 84, +134,151,249,139, 98,190, 96,108,200,239,132, 25,178, 9, 36, 5, 88,219, 67,144, 72,179,105, 97,164,233,189,143, 14,116,109,191, + 63, 19,114,132,229, 97, 72, 37,136, 49, 67,192,169, 87, 95,153, 93, 92, 6, 82, 60,136,174, 55, 31,179,115,241,206,122, 52, 56, +217, 37,225,201,199,199,108,156,156,169, 82,100,201,201, 25, 58, 90, 27,132,199, 26, 84, 3,211, 4,234,248,189,251,253,191,129, +188,237, 88,222,159, 56,196,240, 72,211, 75,198, 87,154,116, 44,201,209,141,165,120,211,171,100,213,169,219,226,189,135, 17,198, +163,232, 84,108, 73, 35, 95,133, 8,200,254,116,101, 94, 28,104,110,151,114, 47, 96, 40, 82, 34, 87, 30, 52,186,175,231, 79,211, + 31,164, 41,250, 35,244,197, 82, 16,234, 63,157, 56,145,199,141, 79,160, 9, 35, 80,246, 84, 76, 68,120,143,174,128, 93,105, 60, +233, 9, 92,155, 19,194,163,211,106, 98,164,115, 20, 1, 29,130,219, 75,234,191, 62, 22,166,235, 63, 47, 42,104,192,103, 0,242, + 53,100, 99,198,104, 10,221, 87,166,214,198,173,250, 84,183,182,151,164, 95, 58, 2,174,182,169,137,228,181,133, 89, 56,104, 57, + 26,111, 72, 60,234, 0, 29,121, 61,149, 30,163,158, 96, 81,132, 32,169, 30, 87, 55,165,208, 22,191,149, 40, 1,235,106,152,153, +192,210, 0,167,147, 28,158, 42,109,225, 85,220, 58, 54,150,231, 74, 2,250,182,160, 47,254,158,202, 4,178, 18,116,142, 66,134, +146, 20, 91, 19,243,114,165, 81, 71, 82,212, 62, 58, 36,173,103, 98,190, 86,171, 99, 2, 19,199,172,223, 80,172,228, 98,172, 44, +107, 74, 23,212,190,218,209,150,100,205,188,246,150, 52,242, 99,228,119, 14, 12, 51,196,198, 57, 34,147, 38, 4,101,117, 54,101, +117,103, 5, 72, 60,239, 91,103,189,123, 46,195,255, 0,246, 61,175,255, 0,231,113,255, 0,248,149,243,246, 55,111,237,121,219, +215,125,111,185,123, 76,221,199,149,182,238,111, 30, 62,199,143, 36,145,179, 44,249, 18,135,200,126,133,229, 42,154,109,240,253, + 53,206,247, 95,106,109, 27,111,124,226,108, 88,172,248, 88, 89,171,137, 44,216,211, 56,121,112,219, 37, 85,164,198,119,241,100, +191, 51, 81,201, 70, 46, 79,130, 85,126,194,168,185, 53, 21,197,186, 47,105,244,243,247,175,102,223,135,113,109,150,255, 0,206, +227,255, 0,241, 43, 3, 47,184,251, 64,203, 44,171,220, 91,113, 44,197,128, 25,112, 30,102,255, 0,167, 95, 62,119, 22,199,183, + 67,180,101,230,197,181,205,179, 77,131,150,184,176,137,164,103, 25, 72,218,174,192, 73,249,203,166,228,175, 10,235,251, 91,177, +123,123, 51,107,237,216, 39,216,178,183,111,243, 12, 82,201,157,220, 48, 78,233, 30,220,200,204,154, 2, 32, 49,254,239, 77,223, +169,207,195,202,179,106,252,111, 67,116, 83, 84,116,214,159,149, 81,210,237,169, 90,146,139,105,213, 87, 74,254,116,103,176,109, +187,158,217,188, 66, 78,221,155, 14,100, 80,217,100, 24,242,164,182, 99,196,106, 49,179, 90,174, 44, 96, 46,168,238, 9,240, 53, +228,223,114, 30,159, 15, 27,184, 33,235,163,198,153,113,199, 28,215, 0, 56, 85,113,168, 95,204,113,175, 93, 86, 89, 34, 12,140, + 24, 56,186,176, 55, 4, 30, 68, 17, 90, 57,150, 47,254, 11,249,221, 31,254, 98,149, 63, 76,250,109, 54, 23,232, 91,255, 0,127, +122, 84, 3,184,225, 31,252, 56,255, 0, 97,106, 53, 39,252,207,248,113,254,194,212, 43, 64,171,147,243,143,119,227, 52, 3,123, +209,242, 71,198, 61,223,140,208,173, 64,121,172,189,227,191, 71,129,157,153,143, 42,100, 60, 9,185,180,177,250,118, 9,139,233, + 37,146, 60,118, 50,143,129,181,232, 0,169,226,124, 57, 26,233, 7,121,224, 54,254,251, 2,160,121,213,228,129, 2, 74,141, 51, + 75, 20, 30,169,191,195,223, 88, 77, 32,168,115,192,176,183,182,175, 55,109, 96,182,195,149,219,198, 73,189, 38, 95,169,234, 73, +169,122,131,213,203, 36,242,105, 58,116,240,105, 14,159,135,151,157, 55,249,115, 28,103,228,229,250,188,149,131, 37,164,150, 76, + 37,101, 17,117,166,136, 99,201, 37,194,235, 55, 65,193, 75, 88, 30, 54,160, 50, 35,239,188,118,193,204,202,108, 80,178, 97,201, +141, 20,138, 39,141,162, 79, 85,193, 90,121,210,235, 31, 76,220, 73,192,233, 35,198,164, 59,247, 1,115,240,176, 39,128, 67, 54, + 95,167, 86,141,230,143,168, 31, 45,218, 40,186, 81,131,121, 86,224, 22,101,224, 20,131,238,177,135,217,177, 96,227,188, 88,219, +158, 98, 72, 83, 30, 49, 40, 48,143,135, 16, 50, 68,165, 22, 32,140,165, 31, 75,171, 2, 15, 62,124,104,152, 93,157,133,183, 75, +142,216, 89,121, 81, 69, 16,135,173, 2,188, 97,103,108,119,121, 34,105, 72,140, 17,241, 72,110,168, 85, 79, 1,107, 80, 22, 55, +109,246, 77,191, 54, 44, 28, 92, 9,115,230, 48,190, 92,233, 17, 1,146, 24,221, 35, 37, 20,143,222, 57, 47,193, 71,151, 58,197, +219,251,226, 72,177,114, 95,119,198, 32, 65, 22,225,149, 30, 68,108,160, 73, 30, 22,105,196,233,232, 54,210,126, 36, 23, 39,143, + 19,194,183,119,110,223,139,117,200,139, 40,101, 79,135, 42,196,216,211, 54, 51, 42,153, 32,118, 73, 26, 50, 89, 88,175,197, 24, +179, 37,143, 62, 53, 83,252,151,180,180, 47, 11, 73, 59, 35,193,155,140,126, 53,184, 92,252,129,155, 35, 2, 19,230, 73, 20,104, +246,115,189, 70, 0, 99,247,180, 89,216,209, 29,183, 16,102,230,201,149, 46, 24,134, 9,209,225, 45, 12, 3, 41,221, 50, 20, 21, +101,233,176,181,135,204,109,230,106, 59, 23,118, 62,233,188,230,108,239, 11,122,136,230, 50, 8, 88, 8,223, 27, 19,211,227, 72, + 12,224,220,235, 50,204, 80, 1,237,242,171,179,118,183, 90, 8,245,110,121,126,190, 41,228,200, 93,194,241,117, 3, 75, 17,199, +145, 21, 58,125, 37, 77, 7,128, 11,192,241,231, 75, 11,179,182,220, 12,184,243,241,164,156,101, 71, 55, 95,174,204,172,236,167, + 30, 60, 70,134, 70,100, 37,163,101,137, 88,223,142,174, 55,168, 12,221,255, 0,185,247,173,187,125,109,179, 19, 25, 27, 29, 70, +214, 81,137, 26,156,230,102, 54, 52,139,196,240,212,171,164,121, 17,127, 26,108,159,188,109,187, 7, 11, 27, 43, 50, 1, 11, 74, + 50, 94,120, 94,120,212,168,196,156,226, 74,176,235,211,214,114,234, 74,170,142, 32,120, 86,206,229,219, 24,155,158,233, 30,235, + 52,243,199, 44, 99, 20, 52, 81,148, 17,191,163,200,245,144,150,215, 27, 55, 7, 36, 27, 48,184, 62,227, 85,207,102,226, 34, 66, +184,217,153, 88,197, 61, 74,202,241, 50, 7,150, 44,188,131,153, 44, 76,198, 63,132, 9, 15,194,201,102, 3,133,252,104, 5,221, +123,190, 78,215, 46,211, 20, 25, 30,150, 44,204,137, 34,200,157, 96,108,150, 85, 76,121,102, 93, 49, 32, 36,221,163, 28,135, 42, +198,237,238,231,221,183,109,199, 27, 31, 43, 37,162, 71,198,195,157,125, 38, 12,153, 41, 33,200,146,116, 45, 52,145, 44,139,142, + 25, 98, 83,241,145,166,231,244, 77,187, 28,189,186, 12,204,220, 12,217, 89,196,155,116,175, 52, 1, 72, 10, 90, 72,100,198, 33, +238, 9, 35, 76,167,149,184,214, 94,217,218, 16,237,121,103, 39,109,221, 51,113,117,170, 36,241, 47,166,116,149, 82, 89,167, 85, +110,174, 51,176, 23,157,199,192, 71, 15,111, 26, 3, 11, 59,189,247, 40, 36,238, 70,133,160,232, 99,227,101,203,178,141, 23, 33, +246,230, 92,124,141,102,255, 0, 22,169, 30,227,217, 70,238, 14,226,238, 77,166, 13,215,109,198,150, 28,157,207, 22, 93,183,209, +100,152, 66,134, 77,194, 87,131, 68,145,134, 32,178,180, 71,136,183, 2, 43, 78,127,187,174,221,155,111,135, 4, 52,176,180, 81, +207, 12,185,145,116, 87, 34,117,201, 70,142, 83,145, 39, 72,235, 39, 86,174, 95, 48, 30,234,186, 59, 87, 1,153,164,203,205,200, +202,203,151, 43, 23, 50, 92,201,154, 33, 35, 54, 11,137, 96,143, 76, 49, 71, 26,198, 8,226, 21, 1,226,120,223,141, 1,202,103, +119,254,231, 46, 78,235,145,181,152,142,221,143,178, 62,126, 33, 41,168,250,164, 76, 73,238, 91,243,148, 38, 98,139,121,215,111, +178,229, 73, 62, 20,249, 18,205,147,150, 81,155, 72,159, 10, 76, 25,126, 21, 13,165, 33,200, 72,153,175,126, 13,107, 95,133,248, + 86, 34,125,223,246,236, 24,147, 97, 69, 60,201, 20,248,217,152,110, 21,227,191, 79, 54, 88,231,144,143,221,218,233,210, 85, 79, + 37, 28, 65,231, 91,240, 98, 52,120,115,226,229,238, 83,238, 61,112,202,210,228, 12,116,117, 86, 93, 37, 87,210, 67, 2,253, 96, +154, 3, 11, 27,191, 49,242,113,167,145,112, 73,201,131, 39, 11, 19,211,197, 60, 82,141,121,238,177, 68,173, 34,252, 42,232,196, +135, 95,205, 35,153,170, 59,183,127,101,166,201, 54, 94,217,129,167, 62, 60, 76,252,169, 67,186,178, 64,112,167, 56,108,120,129, +213,188,163,128,225,240,143,162,180,112,251, 47,109,196,133, 34,108,220,169,250,109,128,234, 91,164, 5,246,199,234, 99, 11, 71, + 10,240,224, 3,249,251, 15, 26,108,174,197,218,242,241, 91, 9, 51,114,241,226,146, 60,200, 50, 26, 35, 25,121, 33,206,156,230, + 75, 17, 47, 11,129,166, 83,240,144, 47,110, 28,104, 13,173,243,121,147,107,108, 60,108, 92, 54,205,205,206,145,210, 8, 21,196, + 98,209, 70,211,200,204,236, 26,223, 10, 88, 11,113, 36,123,235, 25,123,214, 57,242,227,137,246,217,161,196,121, 78, 26,228, 76, + 85, 92,101, 12, 95, 92,208,188, 63, 50,217, 84,173,255, 0, 72,121,113,173,125,235,106,135,119,244,210, 46, 84,248, 89, 88,142, +207,143,149,140,171,173,122,145,180, 18, 45,165, 71, 82, 25, 28,248,112, 54, 34,178,143,104,224,199, 56,150, 12,137,218, 40,201, +154, 28, 89,152, 52,126,171,211,122, 47, 82,204, 83,168, 88,199,206,237,107,146,214,189, 16, 42,225,247,196, 19,166, 43, 79,183, +190, 63,172, 27,124,209,221,213,237,143,185,179,197, 4,204, 87,149,164, 77, 44,190,209, 84,230,239,163,149,182,103,229,225,224, +203, 12, 88,184, 3,112,124,176,209, 18,145,203,215,232, 20, 71, 31, 27, 63, 66,252,173,198,130,123, 31, 54, 46,215,147,109, 89, +198, 86,237,147,131,133,183, 25,165,147, 76, 88,235,136, 53, 43, 64, 99,137, 88,172,114,179, 58,234, 26,143, 14, 60, 43,117,251, + 59,106,124, 60,236, 29,114,164, 57,248, 56,251,100,161, 25, 70,136,113,150, 68,140,197,116, 54,107, 74,111,123,142, 92, 42,130, +182, 95,119,180, 91,131,225,197,130,254,156,101, 62,220,153,165,214,222,165, 49,219, 45,135, 75,230,210, 21,109,127, 63,195,141, + 23,124,110,242,118,252,121, 35, 5,127,137, 36, 91, 60,210,177,117,233,201, 30,231, 34,198, 93, 84, 91, 73, 37, 88, 1,126, 23, + 7,204, 85,236,142,212,205,201,238, 65,150, 36, 17,109, 75,148,115,217, 22,107,234,145,177, 95, 17,173, 1,135,225,114, 90,229, +186,165,108, 56, 40, 36,213,225,217, 59, 96,194,124, 20,200,201, 69,124,109,191, 16, 74, 26, 61,106,187, 91,153, 49,164, 91,198, + 87, 94,163,118,186,144,124,133, 64, 55,113,119, 72,216,100, 43,232,155, 36,174, 36,187,132,218,100, 84, 9, 14, 59,196,146,124, +192,234,111,222,240, 30, 52,231,186, 72,220,223, 1, 48, 93,225, 57, 79,183,195,148,100, 85, 15,150,152,231, 47,165,160,241, 10, + 85, 74,235,243,240,183, 26, 62,239,219, 88, 91,211,202,114,229,152, 25,112,167,219, 92,198, 80,126,235, 33,163,119,126, 40,126, + 59,194, 45,225,207,133, 77, 59,111, 16,110,131,115,235, 74, 80,100, 28,213,195, 58, 58, 35, 41,161,244,166,113,240,235,191, 78, +252, 53, 90,230,246,189, 1,204,236,221,239,157,147,135, 30, 86,102, 57,151, 54,108,125,180,197,137, 25, 68,137,165,206,121,163, + 86, 87,248,153, 65,233,234,109, 87,176, 28, 56,213,249, 59,251, 26, 45,195, 23,107,203,197,108, 92,169,158, 24,101,130,105, 81, +102, 89,114, 37,104, 35, 17, 68,126, 41, 83, 82, 92,184,252,210, 15,184,216,157,143,183, 97, 64,216,184,249,121, 90,213,113, 23, + 26,119, 49, 51,195,232, 36,146,108,125, 0, 68,170,109,213, 42,117,131,117,246,241,171, 49,118,172, 24,121, 17,100,166,225,152, + 77,226,108,181,103, 67,234,100,133,228,154, 55,153,180,106, 31, 20,166,234,133, 84,139, 11, 88, 85, 0,119,174,226, 93,147, 50, + 73, 37, 89, 36,138, 13,183, 43,112,120, 16, 32, 13,208,146, 4,249,155,226, 13,251,206, 30, 20, 55,238,217,220,156, 72,246,198, +125,201,115,101,193, 24,157, 85,177,233, 99,174, 99, 73,213,211,111,236,220, 11, 91,230,225,203,141, 94,221,187,111, 7,123,121, +159, 46, 73, 80,205,133, 62,220,221, 34,162,209,100, 52,114, 59, 13, 72,223, 24, 49, 11,120,123, 40, 25, 29,173,139,145, 60,249, + 24,249,121, 24,153, 82,229, 62,112,201,136,198, 89, 30, 76,117,194,145, 16, 58, 50,233, 49,160,230, 9, 13,198,245,158,101, 41, +109,221,217, 36,153, 19, 69,151, 3,175, 91, 62, 76, 92, 88,217, 68,111, 18, 71,183, 71,184,149,153, 79,231, 95, 82,159,109, 85, +159,188,167,203, 27,123,109,184,165, 99,201,125,165,242,102,148,169,233,166,231, 42,129, 16, 95,206, 61, 59,221,135, 34, 71,209, +122, 94,206,194,137, 19,211,229,228,197, 34,228,156,181,155, 82, 59,134,108, 81,183,186,222, 88,222,225,162, 94,102,231, 87, 27, +211, 99,246, 94, 0, 56,125, 44,172,152,225,195, 92, 21,104,129,140,137,155,109, 96,248,207, 41,104,201,191,131,104,211,127,162, +168, 41,167,127,109,110,251,138,164,125, 67,131, 12,249, 9, 28, 82,163,200,235,143, 40,199, 43, 34, 41,188, 76,238,203,160, 55, + 53, 55,173, 94,222,220, 51,183, 39,221, 87, 62, 37,133,240,243,142, 50, 68,164, 54,148, 24,240, 75,109, 99,230,248,165, 60,124, +170, 43,217,216,102, 28,220, 71,202,201,124, 60,148,154, 40,241,181,170,164, 11,145, 33,157,250, 90, 80, 18,193,248,169,125, 86, + 28, 60,239,123,104,218, 27,106, 25,102, 41,229,203,151, 50,127, 85,149, 52,253, 48, 76,166, 56,225, 58, 68, 73, 26,133,180, 67, +133,168, 11,250, 62, 43, 90,160,192, 95,135, 10,180,139,212, 66,246,179, 14, 98,128,192, 88,154, 1,163,224, 40,209, 99, 54, 82, +158, 33,109,226,104, 42,132,130,193,180,210, 65,144, 5,226,189,189,149, 72, 89, 27,116,177,126,244,176, 33, 56,154, 48, 49,222, +169,151,203, 11,102,213,164,240, 55,171, 0, 95,151, 15,109, 1, 97, 76,124,111, 77,170, 62,116, 61, 26, 69,175,168,243,167,183, + 10, 0,182,140,243, 63, 77, 79, 76,119,231,202,171,155,159,163,149, 49, 60,239, 64, 88,233, 71,111, 10, 70, 4,229,122, 5,200, + 60,233,245,155,208, 19,120,213, 69,129,170, 89,145,252, 33,188, 69, 29,174, 90,194,155,166, 39,117, 67,242,243,111,112,162, 5, + 65,143, 43, 8,200, 70, 32,248,128,106, 93, 9,255, 0,217, 63,234,154,218, 80, 0, 10, 5,128,224, 0,169, 0, 60,171,123, 60, + 73, 83, 34, 44, 89, 73,212,209, 53,135,134,147, 86, 96,134,101,184,233, 48, 23,241, 83, 90, 72, 42,194, 11,123,106, 40, 42,241, + 27,151, 3,231,174,221,142, 5,239, 14,240,204,155,107, 66,112,247, 44,131, 54,251,145,187, 79,180, 69,140,178, 76,232,176, 51, +227,130, 88,200,195,149,113, 61,241,180,207, 63,121,166,209,183,236,141,183,102,228,116,145, 49, 83, 50, 76,255, 0, 83, 44,204, + 89, 50, 19, 38,110, 44, 37, 14,191,233,122,214,220,251,159, 31,102,238, 94,243,218,183,173,167,248,190,195,185,110,217, 15, 52, + 29, 87,199,101,158, 9,229,104,222, 41,208, 53,141,155,136,183, 17, 84,167,222,247,253,207,239, 3,104,220,253, 60, 29,191,147, +142, 49,134,211, 6,121,120,113, 96,198,199, 95,220, 44,146, 74, 3, 24,202,169,187,120,222,178, 82,175,117,246,119,115,237, 27, +122,110, 27,150,229,143,187, 98, 98,202, 49, 50, 27, 19, 44,229,122, 73,200,191, 66, 96,126, 67,195,195,133,119,253,157,133,143, + 47,105, 98,192,157,183, 30,173,198, 35,211,194,147,184, 50,176,166,221, 90, 33,166, 89, 97,195, 65,160,220,175, 35,252,149,159, +223,145,227, 98,246,174,225, 22,200,219, 14, 36, 25,217, 49,102,111, 17,109,251,169,207,201,200,148, 49, 8,176,198,200,154, 35, + 70,144,181,133, 98,118,255, 0,125,190, 60, 91, 54, 44,253,179,252, 91,184,182,104,204,125,189,152, 36,153, 89, 81,181, 75, 31, + 83, 26, 53, 61,109, 26,139, 39, 17,248,234, 36,146,162, 84, 94, 5,109,183, 86,235,230,110,253,216,174, 44,184, 27,208,108, 73, + 98,134, 77,202, 52,131, 18, 55, 5,163,102, 73,116, 66, 76,162,238, 71,203,202,247,175,114,195,195,200, 76, 88, 16,227,202,154, + 99, 81,161,193, 44, 44, 7, 6, 35,129, 53,227,191,115, 83,228, 28, 13,218, 76,150,101,203,147,119,197,105, 99, 42,218,158, 75, + 72,204,140,170, 87, 79,197,250, 92, 1,175,161,198,166, 85,102, 5, 88,128, 89, 46, 13,143,149,197, 90, 16,202,232,203,209,183, + 77,175,210,181,172,121,245,111,111,170,149,106,248,125, 31,142,149, 90, 16,195,127,204,255, 0,135, 31,236, 45, 70,164,255, 0, +221,255, 0,195,143,246, 22,163,227, 66,149,178, 71,198, 61,223,142,131,236,163,100,124,227,221,248,232, 39,137,225, 64,121,179, +247,150,253, 30, 83,224,234,136,200,174,219,102,173, 2,255, 0,196, 31, 53,225,132,219,135, 15, 78,129,237,252,235,248, 86, 94, +249,157,184,190,212,147,195,148,113, 99, 56,125,199,170, 8, 65, 69, 45,143,152, 35, 87,190,171,234,226, 13,252, 56,219,157,122, +151,240,173,183,168,100, 56,112,117, 12,195, 40,191, 73, 53,117,194,232, 19,222,215,234, 5,225,171,157,170, 19,108,155, 54, 76, + 41, 22, 70,221,141, 44,113, 25, 90, 52,120, 35,101, 83, 57, 38, 98,170, 84,216,201,168,234,243,191, 26, 3, 59, 97,204,220,114, +198,245,137,149,146, 36,155, 11, 53,241, 96,201, 17,170,144,167, 30, 9,212,148, 28, 14,150,152,253, 28,235,131,237,173,215,123, +199, 76, 28,175, 94,211, 9, 33,216, 34,200, 73, 84, 62,181,204,200,200,129,190, 38, 36,134, 85,111,152,113, 36, 11,215,170,199, +143, 4, 45, 35,195, 18,198,211, 63, 82,102, 69, 10, 93,244,132,214,228,124,205,165, 64,185,240, 21, 86, 29,151,102,198, 5,113, +246,236,104,148,178, 72, 66, 67, 26,141,113, 57,150, 54,248, 87,154, 59, 22, 83,224, 77,232, 14, 33,119,253,219, 27, 11, 22,108, +105, 34,199,196, 89,243,142, 87, 73, 18, 70, 66,187,140,144, 70,243,196,205,213, 16,176, 12, 11,198, 47,175,217, 87,190,240, 55, + 29,198, 60,108,253,191, 19, 39,210,194,155, 78, 86,108,140, 20, 23,145,149,227,137, 80, 55, 2,182,214, 77,215,141,200,250,122, +134,216,182,105,154, 23,147,111,198,118,199,102,146, 2, 98, 75,163, 59,245, 93,151,225,224, 75,252,103,249,220,121,209,115,246, +157,175,116, 17,255, 0, 18,194,131, 48, 69,171,166, 50, 35, 89, 2,234, 22, 96, 3,131,206,220,104, 14, 55, 59,122,221,113,100, +221,255, 0,135, 50, 69,209,221, 37, 89,250, 43, 27,228,180, 49,224,227,203,212, 72,167, 96, 36, 10,238, 58,154,126, 45, 28,184, +213,125,191,117,223,101,238, 9,113,113,247, 53, 41,185,231,195, 31, 83,165,169, 35,140,237, 43,157,251,132,144,252, 32,144, 0, +191,188,241, 38,187,140,173,143,102,205, 12,185,120, 24,243,171,201,215,113, 36, 72,218,165,210, 35, 50, 53,199, 22, 40,161, 73, + 62, 28, 57, 84,198,211,182,174, 88,207, 92, 40, 6, 96,181,178, 68, 73,213, 26, 81,162, 95,222, 91, 87, 4, 98,163,143, 35,106, +203, 7,157,190,239,185, 64,159,196,176,178, 19, 14, 76, 61,187,127,202, 17,132, 13, 20,135, 19,113, 93, 40, 81,205,174,250,120, +183, 62, 38,214,189,116, 49,247, 30,235,149,187, 38,222,174,144,164,187,164,248, 11,116, 5,146, 36,218,215, 57, 57,243,101,153, +184,251, 56, 87, 65, 46,197,178, 76, 34,235,237,184,178,116, 89,158, 29, 80,198,116, 52,143,214,114,191, 15, 13, 79,241, 55,153, +226,104,135,106,218,198,121,221, 6, 12, 30,188,144,125,103, 73, 58,183,208, 98,191, 82,218,175,160,233,247,112,160, 60,223,182, +247,157,222, 61,182, 8,211, 33, 91, 43, 39, 27, 98,132,238, 18, 38,185, 16,102, 77,147, 27, 23,212, 72,114,160,105, 93, 95,156, +120,223,149, 92,205,238,174,224,139, 14,118,143, 34, 53,151, 3, 19,118,200,121,186, 42, 70, 67,109,185,177,226,198, 64,110, 10, +178, 41, 58,173,244, 90,187,116,217,118, 72,160,155, 26, 45,183, 22, 56, 50, 0, 89,226, 72, 99, 85,112,172,206,161,194,168,189, +153,217,135,180,147, 86, 97,217,246,134,128, 64,112, 49,204, 75, 11, 98,172,102, 36, 42, 32,114, 25,225,177, 31, 35, 21, 4,175, + 35,106, 2,250,116, 27, 88, 66,173,160,233,112,182, 54,107, 3, 99,110, 70,198,166, 16, 30, 0,112, 34,135, 28, 24,240,180,173, + 4, 73, 19, 78,253, 89,202, 40, 82,242,105, 84,214,246,249,155, 74, 1,115,224, 40,129,213,121,159,101, 64, 62,149,224, 45,248, + 41,149, 53, 49,191,135,141, 57,146, 51,205,135,215, 81, 89, 82,236,117, 80, 4,211,196,143, 10, 69,120, 89, 71,190,134,211,131, +123, 15,166,198,152, 76, 8,191, 27,242,181,141, 0, 69, 3,199,137,170,206,151, 99, 98, 64,240, 21, 62,175,144, 55,247, 90,135, +169,136,251,106,160, 71, 73, 28, 53, 84,149, 47,196,154,111,140,139,242, 6,144,103, 94, 95, 93, 80, 71,197,170, 66,162, 46, 73, + 62,116,224,219,157, 64, 10,247, 55,243,162, 45, 12, 84,193,181, 0,148,113, 39,218,105,228,177, 20,232, 56,123,233, 63, 35, 84, +133,102,123, 41, 3,153,166,135,196,212, 31,230, 52, 72,121, 26,134,145, 25,248,145,122,120, 13,151,235,167,100, 46,252, 8, 22, + 30, 52,163, 22, 95,164,211,144, 45, 42, 90, 53, 30, 44, 73,185,242, 2,171,160,144,131,161,244,132, 55, 31, 79, 26, 52,173,253, +154, 15,209,185,250,120, 84, 5,244,185, 3,230, 28, 62,138,133, 37,139,123,177,111, 30,126,250, 28,138, 5,192,243,167, 89, 5, +248,120,219,133, 69,219,135, 31, 19, 64, 66,195, 65, 31,233,194,167, 14,107,192,186, 20, 2, 9,168,115, 67,244,209,177,206, 30, +128, 37, 7, 87,190,213,163, 36,223,113, 50, 71,210, 40, 1,126, 23,181, 58,248,159,109, 74,100,193, 49,134,136,254,242,227, 72, +250,105,172, 45,106, 2, 68,249,126, 10,112, 1, 81,226,124,106, 54,243,172, 77,191,187,118,188,253,255, 0, 51,183, 34, 18,199, +157,134, 9, 99, 34,168,142, 77, 58,117,116,152, 51, 19,109, 67,152, 20, 6,239, 58, 96, 46,125,158, 85,159, 14,243,139, 54,241, +147,177,170,200, 50,177, 97, 76,137, 36, 32,116,202,200, 72, 80,167, 86,171,240,242,173, 27,125, 38,128, 68,112, 20,214,177, 53, + 82,125,219, 11, 31,114,196,218,101,114, 50,243, 86, 71,199,143, 73, 32,172, 67, 83,146,220,133,170,233, 4,208, 3,183,198, 15, +149,207,224,171, 88,209, 21, 95,139,230, 60, 77, 10, 37,187,223,192, 81,167,157, 49,113,229,200,112, 74, 66,141, 35, 5,231,101, + 26,141,175,106,212,122,145,176,225,125,181, 48, 24,114,172, 14,216,238,189,179,187,112, 95, 63,109, 18, 34,199, 33,138, 72,103, + 85, 89, 20,216, 48, 36, 35, 56,179, 3,192,222,174,108, 91,238, 38,253,136,249,152,139, 34, 71, 28,210,227,178,204, 20, 54,168, + 91, 67, 17,165,152, 90,227,133,111,113, 30,188, 13, 80,214,240,162, 35,159, 1, 80, 12,181, 53,101,168,186,150,157, 79, 17,192, +201,237,220,108, 31,188,137,123,171, 12,230,237, 45,220, 38, 57,213, 45,212,139,171, 52,145,137,226,241, 12,154,175,194,185,175, +188, 73,182, 92,255, 0,188, 78,221,124, 45,199, 31,248, 65,195,219,210, 61,199, 33, 86,120, 22, 52,119, 93,115,198,108, 26,214, +248,149,173,237,181,123,148,223,118,221,139,184,101,100,102,102,108,208,205, 62, 84,141, 54, 67,147, 32,215, 35,177,118,118, 1, +192,185, 38,245,207,102,118, 47, 97,227,119,142,221,219,139,219, 88,103, 27, 55, 18,124,167,152,180,221, 64,208,176, 80,163,247, +154,108,111, 88,106,140, 86,135,153,125,230, 54,199,153,218,184, 45,137,159,183,229,238,155,126,116,240, 77, 52, 50,225,156,153, +177,207, 8,159, 70, 12,113, 38,131,243, 5,177,210, 56, 94,247,174,219,183,247, 30,203,194,198,251,186, 94,225,143,210,238,131, + 5, 38,219, 55,123,133, 80,194,241,122,105,219,244, 27, 95, 13, 92, 1,242,241,210,143,238,187, 99, 76,227, 14, 87,109, 97,140, + 78,188,142,185, 1,141,250, 55, 61, 56,244,137,111,123, 91,195,236,161, 31,187,141,157,230,195,145,123, 87, 22, 72,244,204,185, + 88,102, 94, 32,134,253,203, 35,153,109,242,139,145,122,187, 93, 42, 42,115, 95,118,168,141, 63,112,201,165,117,142,224,132, 44, +165, 85,172, 11,203,113,196,142, 6,190,130, 32,158, 66,188,247,105,237,121,246, 65, 38, 46,215,219,216,248,152,249, 15, 28,178, +250,121,202, 40,120,203,233,123,180,165,239,102,175, 65,141,116, 34,173,201,210, 0,185, 36,158, 3,196,158, 38,161, 71,227,229, +198,212,169,252,105, 80, 24, 15,202, 63,248,113,254,194,212,125,183,169,191,230, 15,247,113,254,194,212, 56,242,160, 43,100, 31, +140,123,191, 29, 10,244, 76,144,117,142, 30, 31,109, 6,128,157,197,193, 52,193,128, 53,207,193,221, 24,211,166,220,230, 35, 26, +110, 25, 89,152,106,206,194,209,156, 47, 81,173,220,254,139,122, 99,111,125, 30, 62,230,216,101,197,124,212,205,140,227,196,241, +198,238, 67, 15,138,107,116,172, 8, 4,137, 53, 13, 36,112, 62, 20, 33,176, 88,113, 21, 30, 99,149,100, 73,221, 27, 12, 49,193, + 52,153,209,172,121, 10,207, 19, 16,223, 44,110, 35,145,152, 90,234, 17,141,155, 85,180,248,213,184,183,125,182, 89,215, 22, 60, +149,105,158, 89,113,214, 49,123,153, 96, 26,165, 78, 95,154, 40, 82,240, 22,250,105, 15,109, 98, 67,221, 91,108,185,217,187, 91, + 49,139, 51, 18,103,129, 34,111,239, 76,112, 38, 83, 20, 54,210, 62, 23, 60, 9,191,194,106,120, 93,205,181,102,193,182,179,204, + 32,200,220,241,224,201,135, 25,248,178,174, 66,235,141, 93,128,210, 11,113, 11,115,241, 16,109, 66, 27, 32,212,197,171, 21, 59, +155, 96,118,201, 85,206,140,156, 72,229,159, 33,142,160, 22, 56, 27,167, 43,106, 34,199, 67,112,107,114,170,216, 93,215,133,184, + 76, 83, 28, 5,137,115, 36,193, 50, 72,218, 11, 24,177, 70,107, 58, 70,203,168,240,107, 21, 54, 34,196,212,101, 58, 35,106, 86, +184,172, 56,251,175, 96,151, 26,124,200,243,227,104, 49,196, 70, 87, 1,185,100,112,135, 72,211,119,234, 30, 11,166,247, 60, 57, +212,241,187,151,111,204,204,193,196,193,111, 82,153,209,229, 72,153, 8,126, 21, 56,109, 20,114, 35, 3, 99,125, 83,126, 10,128, +215, 34,139, 20,105,109, 77,196,154, 29,197, 89, 3, 74,139, 0, 5, 64, 50,199, 16, 60, 64,246, 81, 34, 72,236, 78,145,206,163, +194,215,242,229, 83,140, 0,160,223,219,198,128,154,170,234,228, 5, 49,190,160, 0, 26,124, 77, 56,117,183, 23, 11,244,212, 94, + 88, 7, 39, 31, 93, 1, 34,160, 14,124, 64,170,234, 84,131,194,246, 53, 51, 50, 88,233, 55, 63, 93, 15,170,160,124,166,227,216, +104, 9, 18, 57, 80, 15, 17,193, 77,249, 84,154, 80,109,112,109, 81, 46, 61,191, 85, 84, 4, 11, 15, 14, 94,218, 98, 90,214, 20, +218,133,143, 3, 76, 91,200,112,170, 6, 6,156,159,132,251,170, 36,240,166, 98,116,212, 3, 10,151,133, 48,169, 91,133, 1, 49, +192, 10,140,166,200, 77, 78,212, 57,133,210,198,169, 10,128, 23,110, 30, 53, 97, 84, 11,138,132, 41,198,255, 0, 85, 61,200,144, +159,109,103,139, 52, 72,175, 27,208,211,151, 26,152, 36,177,191,209, 80,242,170, 3,201, 98, 75,121, 34,255, 0, 45, 17, 37,141, + 88, 70,124, 77,175,237,242,161,147,101, 18, 17,240,145,161,168, 68,190,128, 21, 69,143,197,175,202,161, 73, 50,168, 44,202, 45, +103,210, 8,246, 11,154, 27,157, 86,162,130,166,202,156, 86, 53, 36,183,155, 55, 58, 19, 90,213, 72, 34, 14,142, 92,232,108,156, + 65,181, 94, 55, 8, 1, 0,139, 84, 78,147,111,134,169, 10,128, 1, 42, 91,151, 15,229,171,160,253,126,117, 80,155,206, 60, 60, +170,218,113,176,160, 37,113, 94,103, 38,213,145,153,147,220, 59,166,212, 63,250,214,207,186,156,172, 32, 7, 23, 94,132, 98, 88, + 15,243,101, 81,107,120,154,244,221, 35,128,241,172,253,187,102,197,219, 50,247, 12,184, 30, 70,147,114,152,100, 78, 28,130,161, +130,132,178,105, 85,176,176,241,189, 3, 56,188,110,224,139, 55,115,222,123,139,109,248,173,176, 71,147, 18, 27, 18,178, 70,103, + 99, 27,123, 85,151, 73,170,242,108,145, 67,216,203,221, 73,151,145,252,120, 98, 38,227,252, 72,207, 38,190,163, 1, 41,143, 78, +189, 26,120,232,211,166,213,213,224,118,174,201,178,238,123,142,227,141,175, 86,232, 8,200,197,114,166, 21, 12, 75, 48,141,116, +130, 3, 18,120, 92,213, 21,236,141,180,227,174,220,119, 60,227,179, 6,213,252, 36,202,189, 27, 6,215,211, 47,163,170, 99,191, +230,234,161, 12, 93,207,106,195,223, 59,187,182,178, 51, 4,200,219,166, 12,179,100,172,115, 73, 29,157, 33, 66, 2,105, 97,163, +219,110,126, 53,232,123,142, 86, 62,223,129,147,155,150,229, 49,224,137,229,149,151,152, 85, 4,157, 54,241,242,172,173,227,183, + 54,237,230,124, 28,166,200,200,194,200,192,214, 49,231,194,147,162,225, 36, 1, 94, 59,233,111,132,129, 91, 25, 88,120,251,142, + 44,248, 89, 75,212,198,201,141,162,149, 15, 11,163,130,172, 46, 61,134,136,167,150,178,228, 98,102,118,198,245,183,109,115,237, + 88,217,155,158, 46, 48,204,200,206,146,108,140,152,114,111,194,104, 9,117, 80,200, 47,197,174, 43,213, 55,111,255, 0, 44,205, +255, 0,129, 47,236, 26,231, 96,251,189,194,140,109,227, 35,118,220,178, 97,218,178, 34,202,192,130, 89,144,198,134, 3,116, 66, +189, 47,136,120,121,219,128, 35,141,117,115, 99,166, 78, 60,176, 72, 72, 89,145,163, 98,188,192, 97,164,218,247,243,173,197, 25, + 60,187,102, 31,229,140, 30,220,238,232, 56,109,153,216,152,216, 59,248, 91,105, 94, 1, 32,203,111,232, 49,208,199,202,162,243, +205, 15,103, 76,248,242,180,101,187,137,212,180,108, 86,234,217,134,226,235,224,107,209, 49,187,115,109,198,237,245,237,166, 86, +159,111, 88, 14, 49, 19, 16, 93,144,130, 56,149, 10, 47,199,152, 21,155,141,216,187, 44, 29,179, 47,106,117, 50, 36,193,145,204, +189,103,117,235,171,151, 18, 7, 87, 68, 80, 10,176,225,240,213,163,248, 0, 29,209, 60,241,247, 87,103,198,146, 50, 36,185, 25, + 66, 68, 82, 64, 96, 32,184,212, 7, 58,202,219, 59,127, 23,185,119,190,235,139,118,200,203,150, 40, 51, 4, 88,208,174, 76,201, + 28,122,162, 13,173, 81, 29, 65, 32,158, 0,220, 15, 42,222,197,236,124,100,220,118,253,215, 55,117,220, 55, 12,205,181,157,177, +219, 38,100,100,179,174,130,165, 4, 96,114,241, 28, 79,137,173,173,175, 97,196,218,243, 55, 44,220,119,145,228,221, 38, 25, 25, + 11, 33, 82,170,225, 66, 90, 61, 42,164, 11, 15, 18,106,237,174,180, 7,150, 97,237, 75,159,247, 89,254,111,202,207,206,125,247, + 26, 41, 37,196,203,245, 83, 14,151,166,157,225, 68,141, 21,194, 1,161, 56,155, 94,252,111, 93, 86,239,129,141,220,125,233,218, +240,110,109, 43, 69, 62,209, 52,179,136,101,146, 2,231,247,108, 67, 52, 12,141,164,147,200, 26,232,112,251, 43,108,199,237, 38, +236,212,150,115,183, 52,114, 68,102, 44,157,125, 50,200,211, 55,197,211,209,125, 77,195,224,163,110, 93,149,135,185,101,109,249, +209,110, 57,219,126, 86,219,140,112,224,155, 14, 72,145,140,109,107,235,234, 67, 39, 19,167,194,213,134,137,161,201, 99,203, 63, +105,111, 61,215,179,109, 83, 77,149,182,109,219, 95,241, 92, 92,105,228,105,142, 52,193, 93,186, 8,210, 22,109, 47,109, 86, 38, +176, 48,182,158,239,204,217, 48, 55,221,147,103,206,126,226,149, 97,204, 77,242, 77,198, 13, 19,107, 34, 71, 71,129,178, 0,233, + 50, 18,161, 52,139,120,248,215,173,108,189,171,180,236,112,229, 38, 50, 60,242,231,157, 89,249,121,110,103,159, 32,219, 79,239, +164,126, 96, 3,192,114,172,124,127,187,140, 92, 47,240,216, 59,214,233,139,180,106,214, 54,136,178, 20, 64, 46,218,140,106,197, + 12,130, 51,226,186,190,154,149,210,131, 83, 22, 93,171,252,195,247,147,155, 6,229,145,147, 30, 46, 22, 22, 14, 88,192,138, 98, + 34,105,131,146, 4,128,112,101, 22, 55, 3,157,122, 70,182,240,172,200,182, 28, 76,125,251, 47,184, 81,228, 57,121,144, 69,141, + 44,108, 87,164, 18, 18, 74,149, 26,117, 95,143, 31,138,180,109,230,106,161, 73,114, 39,169,191, 5,255, 0, 13, 42,107, 11,115, +240,252,116,170,151, 95,129,140,246,248, 15,251,184,255, 0, 97,106, 53, 39,254,236,127,187,143,246, 22,154,226,178,104,169,147, +243,142, 30, 31,140,208, 69,175,225, 71,201, 63, 24,247,125,180, 2, 46,104, 14, 39, 23,177,219, 22, 77,191, 50, 24,176,163,220, +177,242,247, 28,140,188,197, 65,212,146, 60,181,203, 88, 20,185,143, 83,233,235,199,169, 91,135, 14, 23,225, 89,159,229,190,225, +219,240,250,178,196,153, 57, 83,229,236,204, 81, 38,154,115,175, 19, 33,122,178, 57,104,190, 8,191, 59,225, 22, 69,240,225, 94, +147,107,114,166,225,122, 3,205,178,123,107,126, 50,182, 20,112, 68,102,220,246,253,225, 50,165,102,147,211,227,182,229,153, 20, +186, 22, 65, 25,212,200,175,112,164, 13, 90, 77,107,108,219, 75,167,122,238,121,136, 31,248,126, 44, 96, 66,206,140,128,229,228, + 36, 49,100, 50, 22, 0, 53,147, 17, 46, 71, 15,140,215,103,111, 42, 86, 60,232, 14, 61,251, 99,118,151,119,154, 70,104, 23, 1, +247, 25, 55, 88,229, 87,115, 53,219, 3,248,122,194,200, 99, 10, 62, 35,168,144,199,133, 84,195,236,141,195, 31, 39,106,235,116, +167,143, 26, 13,173, 50, 31,212,228,198,145,203,182,143,136,166, 60,122, 35,159, 89, 10, 81,164,249,120,240,240,174,238,230,149, +248,222,128,225,228,236,125,206, 76, 89, 32,105,177,213,155, 19,116,129, 77,220,142,166,110,122,103,193,113,160,124, 33, 82,207, +228,121, 94,143, 7,108,239, 18,230,141,195, 47,211, 66,242,110, 89, 25,239, 12,114,188,154, 99,155,109,254, 30,137,168,196,151, + 97, 39, 19,194,214,250,171,178,189,205, 33,199,202,128,243,233,123,103,114,217,182,216,243, 28,197, 52,152, 24,219, 28,107, 28, + 66,105, 3, 75,182, 52,130,109, 66, 56,154, 65, 25,234,220, 50,163, 17,204,175, 10,211,237, 45,175, 48, 38, 62,233,153,140,145, +200,102,221,100,187,107,141,213,115,114,214,100, 41, 12,137,170,206,177,223,226, 42, 64,183, 14, 60, 58,238, 32, 82,191, 10,200, + 17,249,111, 69,211,230,205,238,185,161,139, 16, 7,186,138, 71, 30, 21, 0,221, 53, 60,248,251, 9,169,136,208,240,211,206,152, + 3,206,214,246,212,137,241,160, 25,180, 40,181,169, 88,105, 30, 3,149, 68,217,128,185,191, 26,147, 58,175, 34, 47,229,194,128, +152, 3,199,133, 34,109, 80, 50,165,129,213,115,229, 80,234, 3,204, 31,168,213, 4,139,112,183,133,234, 55, 94, 28,106, 46,117, + 15,148,129,230,105,172, 60,168, 7,186,249,211, 93, 88,219,198,155,147, 10,151, 11,131,227, 84, 8,129, 80,147,130,123,205, 72, +158, 53, 9, 57, 1,237,168, 6, 28,234, 71,203,253, 57,212, 71, 58,152, 63, 16, 30,234, 16, 37, 6,126, 86,162,147,106,175, 33, +185, 21, 65, 36,224, 40, 90,198,187, 31, 26, 33, 54, 91, 80,209, 65,226, 69,234, 36,105,146,184,248,136,168,120, 11,212, 3, 5, +186,129, 97, 83,101,248,109, 70, 17,114, 54, 1, 89, 27,136, 54,189, 60,145, 33,143, 72,190,159, 10,174,178, 88, 90,223,232, 5, + 46,185,228, 9,169, 66,146,109, 42,186, 19,128,160,147,115,238,169, 22, 5,121,211, 53,128,184,242, 53, 72, 78, 57, 68,192,240, +181,185,210,195,139,170, 95, 81, 54,240,227,239,168, 99, 13, 40,215,241,251, 42,222, 26,162, 6,208, 15, 16, 47,127, 58,164, 34, +216, 54,117,117,107,219,207,221, 68, 48, 56,240,189, 29,154,203,195,194,160,146, 92,106, 34,215,240,160,168, 34,172,188,233,151, +217,198,157,231, 13,164, 41,224,198,198,157,108, 57, 80, 25,217,127,219, 26, 0,231, 71,201, 23,157,173,202,153, 80,222,244, 3, +172, 78, 92, 39, 16,120,114,242,173,104, 80, 40, 0,120, 80, 21, 65,148,191,184,125, 85,110, 49, 85, 2,100,120, 83,211,129,115, +106,153, 90,218, 48,217, 14, 38,156, 45, 61,173,227, 83, 75,214,144,173, 72,128, 71, 42, 42,147,227, 82, 0,159, 10, 34,160,241, +164,171,200, 86,132,144,120,222,138, 13,169,130,139, 84,128,227, 88, 13, 18, 13, 76,204,223,155, 82,181, 43, 53, 77, 13, 32,101, +143,136,168, 27,115,163,105,191, 58,137, 65, 85, 52, 82, 28, 52,255, 0, 87,255, 0,210,165, 83,210, 45,244,126, 58, 85,107,248, +131, 18, 75,254,239,254, 28,127,176,181, 31, 42,155,142, 9,255, 0, 14, 63,216, 90,137,229, 88, 5, 92,159,237, 71,187,241,208, +173,111,101, 23, 38,218,199,186,133,244,125, 52, 3, 16, 77, 59, 88,114,165, 81, 55,160, 21,248,211,241,166, 21, 48, 46, 47,206, +132, 35,203,133, 55,190,166, 71, 27,218,151,143, 33, 64, 53,189,180,220, 69, 61,128,241,165,204,243,225, 64, 56,226, 56,211,216, + 83, 15, 31,101, 58,155,222,178,202, 36,143, 89,211,123, 88, 94,137,209, 55,226,231,240, 83,195,249,223, 71, 27, 81, 77,219,159, +133, 64, 0,162,150, 85, 4,159, 49,122, 39, 70, 34,109, 98,125,132,211,105,180,156,128,246,209, 9,241, 22,184, 52, 3,172, 17, +219,130,129, 80,101, 80,108, 0,162,107,241,189,234, 5,148,113, 54,227, 64, 70,192,178,219,223, 68, 35, 87, 11, 80, 68,137,175, +230, 22,169,180,209,240,170, 8,206,188, 21,110,126,138, 14,149,189,174,104,142,198, 78, 35,151,180, 84,116, 30,122,184,208, 13, +161,120, 27, 84,108, 1, 22,169,219,249,199,133, 68,128, 8,181, 0,205, 80,127, 10, 39, 51, 67,127,155,232,160, 24,124,213, 63, +239, 42, 11,206,157,141,158,254,195, 66, 4,115,194,171,155,106, 30,218,176,167, 82,131, 65,144, 89,253,213, 64,143,141, 50,158, + 22,165,122, 19,135, 82,116,242, 53, 13, 18,176,107,240, 30,195, 83,107,145,244, 10, 4,114, 53,194,249,154,181, 25, 64, 73,115, + 97,192,113,163, 8, 21,248,125, 6,162,120, 30, 62, 68, 85,187, 66,234,218,124, 15,242,212, 27, 28, 31,101,234, 20,174, 45,126, + 60,170,109,109, 60, 60,173, 83,120, 8, 28, 15,250,127,161,168, 48,178,123,121, 80, 19, 28, 35, 39,253, 57, 81, 54,246, 99, 27, + 19,199,226,252, 85, 3,194, 22,191, 59, 31,228,169,224,112,137,189,173, 90, 70, 89,104,248, 83, 26, 95, 77, 42, 16,173, 42,133, +120,192,229,123,154, 32,185, 62,202,132,255, 0,219, 70,190,250, 40, 6,220, 57,208,165, 9,173,214,111, 43,254, 42,156,107,168, +219,220, 77, 66, 75,153, 91,223, 86, 34, 91,113,241,160, 44, 70, 42,218, 11, 10,173, 16,171,106, 57, 10,210, 68, 36, 56, 11,248, +211, 92,249,211,146, 41, 90,252,171,113, 70,120,139,135,137,169,163,133,229, 67, 43, 72, 10,172,195, 77, 58,150, 67,147,227, 68, + 83,237,170,235, 97, 82, 13,198,175, 35, 73,174,101,144,198,136, 13, 5,120,142,117, 45, 44, 56,214, 90, 69,221, 80,234,194,165, +172,120, 85,109, 70,164, 24,214, 92, 74,131, 94,252,233,190, 17, 81, 6,153,143,149, 40,105,164, 75,133,190,143,199, 74,163,115, +167,250,191,142,149, 41,248,146,136,198,115,193, 63,225,199,251, 11, 81,189, 73,199,201,255, 0, 14, 59, 31,234, 45, 68, 14,126, + 85,146,149,178, 15,198, 56,248, 80, 79, 17, 86,222, 30,161,190,171,120, 91,159,227,168,140, 95,231,223,232,160, 42,216,211,219, +133,175, 86,125, 40,183,205,244,218,144,197,254,119,224,252,180, 5, 96, 61,180,133, 89,244,196, 31,159,240,126, 90, 94,152,126, +159,224,160, 43,150, 4,121,154, 97,126,118,171, 3, 23,143,207,248, 63, 45, 56,199, 28,139,126, 10, 0, 31, 64,166,227,110,116, +127, 79,252,239,193,249,105,122, 99,127,155,240,126, 90, 0, 3,143, 26,149,133,175, 70,244,246,252,255, 0,193, 79,233,255, 0, +157,248, 42, 48, 9, 3,128, 66,218,220,248,212,254, 50, 69,216, 95,198,194,141, 30, 57, 10, 70,174,102,252,191, 45, 75,211,255, + 0, 59,143,186,178, 0,116,248,234,103, 55,250, 57, 83,136,173,127,136,241,246,209,250, 90, 71,205,127,120,167, 17, 17,205,175, +229,194,168, 43, 24,215, 87, 30, 86,228, 77, 57, 68, 0, 88, 15,170,140, 34, 3, 85,219,159,179,242,211,244, 1,225,171,219,202, +128, 6,145,123, 88, 82, 96,188,141,168,205, 18,248,184,191,187,242,212, 58,105,195,226,213,229,195,141, 1, 92,189,152,240,189, + 71, 89,110, 0,125,116,115, 0, 36,157,127,130,162, 32, 0,124,223,131,242,208, 1, 1,184,139,142, 53, 30, 58,188,234,208,199, + 39,147,126, 15,203, 77,233,184,159,139,240, 80, 21,238, 65,168, 49, 36,241,171,126,154,255, 0,157,248, 63, 45, 65,177,174, 79, +197,248, 63, 45, 1, 93,121,212, 38, 36, 48,176,225,111,229,171,131, 26,223,157,248, 63, 45, 56,128, 6,177,110, 99,202,128,163, + 28,186, 65, 20,153,245,113,243,171,237,135, 17,226, 79,224,170,205,134, 53,217, 95,135,187,242,208, 1, 0,145,244,212,159,138, + 53,188, 1,171, 62,146,192,124,126, 62, 95,150,154, 76, 95,129,190, 59, 92,121,126, 90, 20,205,139,139,139,209,220,124, 36,251, +104,209,225,105,144,124,126, 23,229,236,247,209, 91, 15, 82,155, 53,133,252,191, 45, 24, 69,108,102,179, 16,121, 17,252,149,104, +147,106,120,112,180,139,151,227,238,252,180, 95, 77,199,231,191,209,249,106, 50,149,100, 39,194,131, 39, 5,183,187,249,106,251, +227,255, 0, 58,215,225,203,242,213,121, 49, 47, 97,175,199,203,242,208, 2, 63, 18,104, 28,207,141, 22, 1,209,129,139,113,177, +228, 42, 99, 22,223,159,248, 63, 45, 51,193,112, 84, 63, 63,103,229,173, 25, 34, 51, 96, 60, 44, 65,246,212,142, 86, 57, 82, 9, + 34,254, 53, 87,209,155,155, 63,224,252,180,189, 27,126,159,224,252,180, 3,163,135,153, 5,245, 88, 27,154,186,167,237,160, 98, +225, 16,250,245,114,246,126, 90,185,233,248,223, 87,224,161, 76,226,159,190,107,248, 31,229,163,168,229, 70,108,125, 76, 88,183, + 63,103,229,169,199,141,199,230,252, 20, 33, 40,215,133, 28,112, 90,116,128, 1,197,184, 14,116,197,146,246,226, 64,246, 15,182, +180,154, 92, 73, 71,200, 86,225, 72, 27, 83,130,190,223,168,125,180,172,167,207,234, 31,109, 93,235,169,143,175,161, 32,194,164, + 56,242,168,133, 30,223,168,125,180, 64, 84,120, 31,168,125,181,119,199,170, 45, 37,208,107, 53, 56, 94, 60,169,195, 1,224,126, +161,246,212,132,163,244, 79,212, 62,218,187,227,212, 56,190,129, 18,194,142, 31,133,170,168,145,127, 69,190,161,246,212,196,232, + 63, 53,190,161,246,212,114,143, 82,168,248, 7,226,124, 41,194,154, 15,170, 79,209,111,168,125,180,189, 90,254,139,125, 67,237, +172,238, 93, 68, 84,151, 20, 30,215,166,211, 66, 25,104, 63, 53,190,161,246,210, 57,113,254,131,125, 67,237,169,185,117, 44,147, +124, 3,105,254, 79,199, 74,133,234, 23, 78,171, 55,203,171,195,244,180,249,210,171,185,117, 37, 31,192,203,112, 62, 11,243, 49, +199,251, 11, 80,226, 15, 10, 41,137,216, 70,192,173,186,113,243,117, 7,228, 95, 2, 69, 55, 69,255, 0,153,250,233,254,181, 67, + 64,249,241,165,113,199,249, 40,157, 23,191, 52,253,116,251,105,250, 15,127,153, 57,113,248,215,253,106, 3,204, 54, 21,203,203, +222,251,109,166,202,103,133, 31,184,100, 16,184,213,241,195,184,116,149,181, 19,207, 68,154, 87,244, 64,225,206,141,187,247,126, +255, 0,129,157,188,109,208,152,204,219, 90,230,101,179, 58, 93, 70, 41,139, 24,225,179,123,159, 37,175,231,211, 53,219,226,195, +177,245,160,244, 71, 7,171,254, 43,210,116, 95, 31, 95,246,163,214,244,180, 53,255, 0,181,183, 86,223,157,243,113,170,144,109, + 91, 78, 62,241,188,103,100,230,193,145,157,149, 4, 67, 47, 30,121,113,237, 14, 26, 9, 52, 43, 70, 44, 68,100,179,221,159,159, +209, 64,115,171,220,123,222, 38,230, 54,140,137,211, 40, 67,184, 77,136,249,134, 37, 78,172,107,181, 29,201, 69,147,225, 12,146, + 88, 27,120, 85,217, 55,205,210, 94,209,237,253,198, 57, 82, 28,237,227,248,100,115,100, 4, 5, 99, 57,157, 62,171,162, 55,195, +127,136,133, 7,196,213,246,198,236,145,181, 64,174,118,159,225, 2,114,113,139, 75,138,113,253, 69,152,157, 5,159, 71, 82,218, +175,227,107,213,236,136, 54, 54,216,213,114, 61, 15,240, 19, 20, 97, 11,203,142, 49, 58, 39, 79, 71, 73,213,211, 11,242,232,183, +178,213, 1,231,152,187,254,253,133,177,177,197,205, 85,108, 44,109,239,116,146, 89, 99, 18,122,151,196,220, 36,141, 32, 26,219, +225, 75, 27,124, 38,226,235,111,110,222, 39,113,111, 83,247, 52, 88,210, 74,171,131, 38,231, 54,220,113, 58, 67, 80, 68,219, 23, +113, 12,100,249,181, 9, 56,123,171,105,224,236,230,195,219,238, 54,129,130, 37,115,182,126,247, 20, 67,214,234, 30,167,167,179, + 5,213,212,249,180,254,119, 62, 53,120, 67,179,156,209,163,208, 12,239, 82,246,210,248,253,111, 87,208, 26,255, 0, 59, 87, 87, +211,243,252,237, 31,205,160, 57,205,131, 19,112,219,123,168,237, 51,238, 47,151, 6, 22,199,183,166,151, 91, 7,117,147, 34, 6, +154,197,154,204,198, 45, 68,220,158, 54,191, 1, 88,143,222,221,194,153,111,129,170, 35, 34,187,109, 65,180, 11,255, 0, 17,147, + 58, 72, 32, 54,225,195,211, 34,189,191,157,126, 66,189, 5,224,219,142,237, 31, 80,225,255, 0, 25,232, 55, 74,239, 0,202,244, +250,190, 45, 63, 23, 83,167,175,159,133,234,161,199,237,223, 80,117, 29,183,212,122,213,213,121, 49,181,250,254,153,209,127,138, +254,163,167,123,126,118,159,101, 1,198, 75,222,123,228, 48,239,147,164,171, 50, 99,237,249,121,216, 82,180, 40,145, 9, 49,178, + 27, 28, 8,148, 57,145,163,240, 61, 80, 9, 96,109,194,143, 62,227,189,228,110, 56, 56,179,110, 95,247, 62,228, 56, 45, 34, 70, +169,213,132,237,199, 44, 43,170,155, 16, 11,178,219,220,121,138,223, 76,110,200, 86,203,208,219, 54,162,179,156,239,222,225,147, +163, 80,245, 61,111,139,229,213,110,165,248, 95,157, 93,201,199,237,219, 63,172, 59,109,189, 98,117, 58,178, 99,127,223,244, 39, + 79, 86,166,254,223, 70,157, 63,157,107, 80, 28,206,247,185,239,120, 93,223, 60, 56, 25,166, 56,178,113,182,172,116, 70, 64,233, + 7,170,205,158, 6,148, 41, 54, 47,240,216, 19,204,176, 7,144, 21,177,139,188,111,115,118,142,126,106,201,142, 55, 60, 73,179, + 48,224,202,156,172, 48,202,248,249, 50, 98,199, 39,196, 66, 13,122, 7,142,157, 94,202,185,186, 99,118,217,200, 97,188,157,183, +213, 28,114, 27,213, 75,140, 37,244,218,197,255, 0,180,109, 93, 61,118,246,106,246,213,197,143,105, 93,144,171, 12, 22,216,122, + 36, 92,201, 7,164,232,123,245,116,244,126, 10,128,224, 50, 59,211,186, 22, 35,143,136, 30,124,140, 56,242,231,200, 89,163,197, +129,193,199,146, 40,214, 28,214,154,120,162, 85, 94,161,212,208, 22,230,164,120,214,230, 23,112,111,217, 61,222,251,127, 76,141, +172,102,207,128, 89,253, 58,160, 16,226, 12,144,201,121,125, 67,202, 95,152,233,233,208,125,151,173, 95, 79,216, 99, 23,111,234, + 29,159,211,164,175,252, 59, 84,184,157, 62,182,165, 18,116,126, 43, 51,235,211,170,220,117, 90,252,107, 70, 56,123,112,111,238, +241,157,191,252,193,162,210, 0,240, 28,205, 1, 87,230, 23,234, 91, 70,159,162,222, 22,160, 56, 62,238,125,205,123,181,160,131, +113,146, 40, 88,108, 61, 56, 64,248, 81,165,220,228,137,154,193,133,254, 79,139,244,129,177,224, 41,241,247,237,226, 85,138,113, + 38, 43,238,107,182,239, 9, 22, 94, 78,152,149,165,197,220,225,193,135, 81, 37, 99, 93, 98,220, 57, 22,183,133,119, 91,140, 93, +179,252, 79, 31,248,169,219,191,139, 90, 63, 73,234, 91, 31,212,219,172,189, 46,151, 80,235,183, 95, 78,155,126,125,173,198,135, + 36, 93,165,208,113, 33,218,250, 6, 28,174,166,167,198,209,208,235, 15, 91,170,230,218, 58,246,234,248,107,249,184,208, 28,240, +238, 29,202, 30,199,222,247,142,161,109,199,108, 25, 33, 6, 68, 43, 28,177,188, 43,169, 99,200, 72,201,136,176,191, 19, 25,210, + 69,168, 9,188,247, 12,217,178,108,158,189, 34,151,248,182, 70, 23,241, 35, 2, 92, 67, 14, 2,110, 10,130, 51,240, 92,187,145, +115,249,163,207,141,117, 56,208,118,210,236, 82,174, 57,219,191,128, 5,144,100,105,124,115,137,166,231,171,213, 58,140,124,239, +171, 87,211, 80,220, 96,237, 86,197,203, 27,161,219,125, 55,169, 30,183,175, 38, 56, 79, 85,211, 91,117,139,181,186,189, 45, 63, + 55,197,166,222, 20, 7,158, 13,243,118,206,220,246,205,207, 42, 65,163, 63, 19,183,103,124, 6, 67,210, 71,202,207,120,222, 72, +197,248, 30, 5,129,246,143, 33, 87,229,238,174,224, 76, 72,179, 35,203,138,105, 55, 60,135,131, 31,110,137, 34,245, 56,234,185, +254,136, 24,122,205, 28,111,240,124, 36,202,214,234, 17,225,194,187, 44,168,123, 91,214,226,122,211,182,122,253, 17,122, 14,179, +227,117,186,125, 85,232,244, 53,182,173, 61,109, 58, 52,254,117,173,198,171, 62, 47,100, 22,221, 58,141,180,235,114, 63,140, 94, + 92, 91,223,169, 97,234,126, 47,132,245,127, 75,243,253,181, 65, 82, 13,251,113, 94,201,159,121,206,120,177, 51,225, 76,128,210, + 50,172,234,166, 25,158, 4,118, 76, 87,116, 46, 66,130, 85, 94,193,184, 86, 10,238,219,230,227, 38,204, 39,202,147, 26, 76,126, +225,147, 2, 96,201, 18,201, 36,107,137, 52,202,179,136, 29,162,184,226,164, 41,183, 35,204, 87,113,233,246, 19,177,145,171, 7, +248, 15, 68,131,105, 32,244,125, 11,113,227,171,167,162,223, 69, 81,139, 31,179, 23, 21, 68, 71,104,244,131, 38, 32,182,147, 16, +199,234,244,142,143, 29, 86,235,105,182,159,206,183, 42, 3, 47,119,222, 55,156,126,229,139, 6, 28,164,131,111,149,160,198, 71, + 72,227,157, 86,105,132,132,166, 80,213,214,142, 70,248, 76, 92, 52, 31,206,174, 95,182,187,155,123,135, 23,183,113,206, 99,102, + 71, 34,109,209,101,134,141, 78,145,155,212, 31,191,154, 71,234, 52,159, 15,193,160, 31,148,235,231, 94,139, 54, 63,109,127, 27, +133,178, 91,110,254, 58, 0, 16,117, 36,199,245,118, 33,180,232, 12,221, 78, 90,173,111, 11,251,107, 51, 27, 27,238,251,175, 27, + 99, 54,199,215,186,136,186,114, 97,106,213,214, 58, 52,133,110,125,107,218,223,157,127, 26, 3,154,201,220,251,131, 47, 31,101, +221,100,220,186,107, 46,247,151,140,152,241, 68, 21, 68,120,171,184, 70,170,237,170,239,168, 65,196, 30, 28,143, 49, 83,131,187, +247,188,156, 76,118, 19, 69, 20,179,227,246,227,153,122, 96,132,125,218, 87,139, 37,180,147,110, 64, 21, 30, 21,218, 79, 7,109, +122, 24,125, 65,219,125, 7,170, 62,155,168,248,221, 31, 89,213,123,244,245, 54,158,183, 87, 95, 47,139, 85,252,107, 21,246,206, +195,202,193,120,241,114, 54,168, 48, 99,159, 14,124,150,196,159, 13, 81,140, 83, 25,113,163,156,130, 84,163,184,101, 10,121,241, + 11, 64,105,118,222,233, 62,229,183, 48,205,149,100,202,135, 39, 51, 23,168,160, 47, 89, 49, 50,100,198, 19, 4, 30, 97, 69,237, +194,245,197,205,222, 59,254, 46, 14,102,119, 94, 57,153,241, 55,153,224,143,164, 0,129,246,204,181,198,136,181,141,216, 58,191, +197,127, 27, 90,187,172, 12, 29,131,175,131, 54,211, 38, 29,227,197,154, 44, 24,241,102,131, 73,198,105, 98, 51, 52, 98, 54,248, +148, 72,137,114, 56, 3,237, 53,153,181,237,125,149,131, 14,225, 12,121, 27,110, 73, 35, 33,247, 57,102,159, 18, 71,233, 73, 60, +147, 76,185, 36, 17,251,180,145,202,252, 67,133,128, 60,170, 48,140,204,157,247,185, 48,251,130, 29,168, 55,170,131, 26, 76, 8, +242,231, 43,143, 12, 76, 51,165,145, 93,155,169, 50,202, 10,160,180, 75, 26,181,202,157, 87,189, 81,126,228,238,102,124,172, 81, +147, 19,100,202,234,248,177, 70, 49,200,150, 3,146, 99,213,182, 76,100,233, 74,221, 33,109, 19, 29, 90,239,225, 93,190, 94, 63, +111,157,235, 17,179,206,223,252, 96, 45,176,186,210, 99,250,157, 36,181,186, 65,219, 95, 61, 86,183,183,219, 89,210, 98,118, 25, +143, 48,106,217,180, 60,168,119, 15,222,226, 11, 62,182,211,213, 58,248, 55, 82,246,191,231, 95,198,244, 69, 50,115,119, 9, 55, + 62,215,217,230,200,200,234, 71,159,155,135,143,155, 42, 43, 99,234,137,178,132, 79, 27,173,238,154,180,132,112, 13,184,144, 56, + 85,109,199,105,216,213,240, 49,176, 30, 89, 82, 61,233,112,242, 35,103,149, 86, 32,241, 60,239,137, 29,180, 3, 24, 44, 24, 90, +246, 60, 47,194,195,175,124,125,136,236,214,156,224,127, 1, 48,168, 23,147, 28, 97,244,127, 54,223, 23, 79, 69,237,111, 10,124, + 12,110,218, 76, 28, 68,219,219,110, 56, 34,123, 97, 24,100,199, 49,122,159,139,251, 18,173,110,175,205,203,226,231, 64,121,190, +233,234,113,247, 29,211, 34, 52,120,224,131,120, 24,139,184,166, 67,235,141, 14,223, 14,156, 95, 79,193, 76,110,205, 98,218,184, +106,189,171,175,151,126,159, 99,236, 44,109,210, 24, 36,202,201,139,106, 19,161,208,100, 65, 36,120,194, 64,211,217,149,130,106, + 28, 77,235,107, 38, 14,222, 49, 79,234,142,223,210,245, 43,234,186,143,143,167,214,104, 77, 29, 93, 77,110,182,141, 22,191,197, +107,123, 42,134,217,143,216,222,147,113,254, 6,219, 41,193,233,255, 0,245, 99,135, 38, 31, 75,165,165,255, 0,239, 93, 38,211, +163, 78,191,159,133,175,237,160, 50,247, 77,202, 76,157,241,101,209, 62, 36, 71, 99,220,219,163, 56, 49,157,113,203,137,103,211, +114, 46, 3, 27, 26,165,186,101,110, 56,219, 31,101,100,227,228, 58, 55, 82, 14,188, 64, 92,204, 70,223, 60,186, 28,243, 55, 41, +107,121,155,243, 2,186,173,255, 0, 23,183, 26, 56, 7,115, 54,221,211, 12,199, 27,248,132,184,224, 92, 15,143, 71, 93,188,190, +107,120,115,163,238,120,251, 79,167,199,254, 42,112,189, 63, 90, 63, 75,234,164,131, 71, 95,251,158,151, 85,173,175,244,109,199, +202,128,231,251, 75,123,221,115,103,108,125,207, 33, 51, 4,187,118, 14,230,147, 71, 24,140, 70,217,157, 96,240,124, 36,130,163, +164, 10,147,198,222,117,133,145,222,123,212,120, 25, 57, 40,209,117, 98,219,247,172,181,186,112,234, 96,103,174, 36, 28, 47,203, +166,120,249,154,237,182,124, 77,140, 46, 71,240, 22,192,210,100,190, 79,162,151, 28,142,161, 31,222,116,155,157,188,235, 35, 55, +106,236,204,216,119,124, 49,147,182, 99, 79,145, 14, 66,110,121, 24,217, 24,105,145, 28,108,202, 50, 90, 71,212, 74,217,244,235, +212, 45,170,215,227, 84,134,100,251,206,246,185,217, 29,191,235, 99, 13, 30,108,208, 54,228, 34, 95,142, 36,219, 70,226, 35, 9, +125, 32,235,123, 18, 13,244,143, 62, 53, 87,105,238, 61,214, 8, 59, 95, 22, 41,186,208, 62, 46,205, 22,100,102, 53, 32,122,216, +136,102,158,105, 28, 72,210, 54,157, 73,211, 4,112, 58,185,215, 88,184,221,151,252, 40,137,142,209,252, 47,212,150,227, 46, 47, +167,245, 86, 44,120,234,209,212,181,248,115,183, 14, 84, 70,199,236,143, 81,138,204,118,127, 81,209,198, 24, 55,147, 19, 87, 67, + 80,244,157, 17,171,228,213,110,150,158, 31,163, 64,112,112,247, 39,116,109,139,155,141,135, 43,103, 60, 25, 27,190, 83, 51,250, +116, 91, 99,103,122,117,142, 87,202,154, 45, 16,241, 55,209,118, 23, 80, 56, 14, 61,143,123,247, 6,119,109, 98,227,110, 48,105, + 56,173,234, 97,153, 10,234, 99, 57,198,146, 92, 75,123,229,136, 39,245,133, 90,200,199,236, 67,147,254, 44,236,222,169,114,152, +183, 82, 76, 65, 39,171,248, 3,234,187, 92,203,242, 94,252,126, 95,101, 89,238, 77,171, 7, 62, 12, 63,226,217,177,226,225, 99, +229, 67, 51, 35,203, 2, 71, 52,168,225,160,141,222, 83,227, 32, 28, 20,141, 92,168, 14, 86, 30,224,238, 56,115,163,245, 83,199, + 34,140,231,218,101,194, 88,128, 33,162,219,142,105,202,214, 62, 46, 50, 45,237,242,233, 35,223, 66,199,239, 13,255, 0, 39, 11, + 31,165, 44, 49,228,100, 99,246,219, 9, 12, 65,130,201,187,202,241,100,182,157, 66,226,192,105, 23,225, 93,154,227,236, 31,198, +217,181, 96,127, 28,233,217,255, 0,121, 7,170,233,216,115, 26,186,154,116,219,232,170,251,100, 61,138,177, 48,218, 78,206, 99, +234, 99, 22,244,207,136, 71, 84,200,222,142,250, 27,230,234,223,165,252,239,150,128,109,251,117,207,218,103,216,176,163,149,100, + 57,143, 60, 89,146,186, 0, 95,163,133, 62, 64, 96, 7, 5,188,145, 2,109,238,174, 78, 30,239,223,180,236,251,132,243, 70,113, +114,176,176,101,149, 33, 68,145, 14, 78, 70, 59, 79, 44, 57, 1, 91,173, 11,191,195,209, 33,116,121,215,117,189,193,177, 60, 17, +127,153, 27, 4, 99,245, 84,195,235,222, 16,157, 96,173,167, 71, 89,173,171, 78,175,162,245, 78, 28,126,205,254, 33,130,216,237, +181,127, 16, 16,198, 54,222,156,152,189, 94,129, 67,209,244,225, 91, 86,142,157,244,105,252,219,219,133,101,186,190, 5, 71, 35, +129,221,125,213, 62,216, 30, 98,144, 79,147, 54,204, 49,167,153,113,216,133,221, 38,233, 75,104,113,103,147,247,106, 44, 99, 50, + 16,198,252,121, 87, 81,220,185,155,158, 26,237, 27,102, 54, 98,195, 38,111, 93,114,179, 90, 53, 37,134, 62, 36,147,144,169,193, + 87,168,201,115,110, 66,246,243,171, 59,116, 29,152,184,204, 54,179,181,122, 99,147, 9,111, 78,248,198, 63, 86, 93, 78, 63,200, +214,234,235,211,211,241,189,180,213,253,246, 29,141,176,208,119, 25,194,244,125, 85, 49,250,247,132, 71,213, 1,138,233,235, 29, + 58,180,234,250, 47,225, 79, 96, 60,247,100,238,205,250, 40,251,119, 15, 30, 51, 46, 36, 88, 59, 26,101,201, 33,128, 35,250,228, +209, 44,146,201, 60,201, 49,112, 5,227, 17,163, 93,129,191, 58,206,131,185, 55,157,130, 13,198, 76,108,207, 83,145,235,247, 44, +172,148,232, 33, 46,176,103,140, 64,211,201, 35,174,152,180,252, 33, 99,248,193, 32, 15,132, 87,124,248,253,166,217,155, 99, 33, +218,253, 88,134, 49,179,218, 76, 81, 39,167, 32,244,189, 40,213,125, 22,190,141, 28, 45,123, 80, 51, 49,187, 32,176, 59,147,108, +250,131,100,219,175, 46, 39,205,175,252,101,195,183, 19,212,254,215,249,223, 55, 26,190,192, 80,159,187,247, 22,221,102,219,137, + 65, 1,221,114,240, 56, 45,155,161, 22,210, 51,146,198,255, 0, 55, 88,243,242,225, 92,214,221,189,119, 6, 56,219,159, 3, 61, +157,229,237,237,136,140, 87, 49,153, 24,200,211, 9,206, 55,169,101,141,242, 10,198,196,106,249,185, 30, 66,187,191, 77,218, 63, +197,201, 45,181,127, 25, 60,239, 38, 47,170,225, 9,240,213,175,251, 11,255, 0, 83,217, 64,205,198,236,102,143, 25,115,219,102, +208,113, 99, 24, 93, 89, 49, 7,248, 77, 75,210,232, 22,111,236,181,105,211,167,225,189,173, 83,216, 13, 46,218,223,151,115,217, +241,114,102,153, 50, 50, 89, 47, 51, 42, 24,143,204,200, 11,196, 73, 40,126, 2, 15,133,193,183, 10,215,245,177,249, 86, 70,217, +143,177,220,255, 0, 6,108, 27,244, 97,191,164,146, 15,251,191,199,233,255, 0,178,111,236,254,125, 30, 28,237,227, 90, 62,156, +254,146,127,237, 19,253,106, 83,192, 84, 55,173,143,202,151,173,139,202,129,233,207,233, 39,254,209, 63,214,165,233,207,233, 39, +254,209, 63,214,165, 5, 75, 30,182, 63,209,165,235, 35,242,160,116, 15,233, 39,235,167,250,213, 33, 7,243,147,245,211,237,165, + 60, 1,107,212, 39, 79, 85,191,187,191,209,212,211, 74,135,160,105,233,220, 95,163,206,227, 79,246,191,165,202,149, 1,255,217, +}; +#endif diff --git a/source/blender/src/pub/windows_publisher_splash.jpg.c b/source/blender/src/pub/windows_publisher_splash.jpg.c new file mode 100644 index 00000000000..520c58bc9f2 --- /dev/null +++ b/source/blender/src/pub/windows_publisher_splash.jpg.c @@ -0,0 +1,1002 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +/* DataToC output of file <splash_jpg> */ +#ifdef _WIN32 + +int datatoc_tonize= 30796; +char datatoc_ton[]= { +255,216,255,224, 0, 16, 74, 70, 73, 70, 0, 1, + 2, 0, 0,100, 0,100, 0, 0,255,236, 0, 17, 68,117, 99,107,121, 0, 1, 0, 4, 0, 0, 0, 50, 0, 0,255,238, 0, 14, 65, +100,111, 98,101, 0,100,192, 0, 0, 0, 1,255,219, 0,132, 0, 8, 6, 6, 6, 6, 6, 8, 6, 6, 8, 12, 8, 7, 8, 12, 14, + 10, 8, 8, 10, 14, 16, 13, 13, 14, 13, 13, 16, 17, 12, 14, 13, 13, 14, 12, 17, 15, 18, 19, 20, 19, 18, 15, 24, 24, 26, 26, 24, + 24, 35, 34, 34, 34, 35, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 1, 9, 8, 8, 9, 10, 9, 11, 9, 9, 11, 14, 11, 13, 11, 14, + 17, 14, 14, 14, 14, 17, 19, 13, 13, 14, 13, 13, 19, 24, 17, 15, 15, 15, 15, 17, 24, 22, 23, 20, 20, 20, 23, 22, 26, 26, 24, 24, + 26, 26, 33, 33, 32, 33, 33, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,255,192, 0, 17, 8, 1, 15, 1,244, 3, 1, 34, 0, 2, 17, + 1, 3, 17, 1,255,196, 0,196, 0, 0, 1, 5, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2, 4, 5, 6, 0, + 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 16, 0, 2, 1, 3, + 2, 4, 2, 5, 7, 7, 8, 6, 7, 5, 6, 7, 1, 2, 3, 0, 17, 4, 18, 5, 33, 49, 19, 6, 65, 20, 81, 97,113, 34, 50,129, +145,209, 66, 35, 21, 7,161,193,225, 82,146,178, 51,177, 98,114,130, 67,115, 36, 22,240,210, 83, 99,131, 54,162,179,195,211, 52, + 84,116,147,163,196, 37, 23,241,194,226, 68,100, 53,132,148,164, 69,133, 38, 71, 17, 0, 2, 2, 1, 2, 4, 4, 3, 5, 7, 4, + 3, 0, 0, 0, 0, 0, 1, 17, 2, 3, 33, 4, 49, 65, 81, 18, 97,113, 19, 5,129,145, 34,161,177,193,209, 50,240,225, 66, 82, + 98,146, 20,114, 35, 51, 21,241,147, 52,255,218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0,244,254,224,238, 9, 59,127,111, +143, 51, 67,204,154, 98, 78,154,190,139, 94, 48,111,227, 84,189,187,248,157,181,111,121,203,182, 74,211, 97,102,202,116,192,147, + 54,164,144,254,170, 72,167,226,245, 16, 42,195,187, 50, 59,119, 27,111,129,187,154, 24,230,194, 99, 18,162, 76,130, 69,234,116, +174, 13,155,135, 32,107,198, 59,154, 93,139,117,238, 13,167, 19,177, 96, 16,100, 52,145,170, 24, 87, 66, 9,117,130,140, 20,114, +211,109, 71,217,122, 3,232,137, 38,156, 48,180,141,107,126,177,166, 28,153,129,254, 35,254,209,174,146,247, 30,155, 80,154,246, +185,161, 3,121,137,173,113, 35,126,209,166, 25,242, 9,183, 85,199,245,143,211, 76, 91,218,246,227, 78, 3,244,208, 4, 19, 79, +200,202,255, 0,180,126,154, 78,164,222, 19, 73,251, 70,147,133,119, 1, 64, 41,151, 35,152,149,255, 0,104,211,124,198, 77,175, +213,111,218, 53,220,111,127, 10,105,225,236,160, 7,145,149,148,161, 71, 85,214,230,247, 12,104, 77,153,149,107, 9,228,191,244, +219,233,166,101,177, 50, 42,223,128, 23, 31, 41,253, 20, 11,240,189, 70, 80,227, 47, 44,243,200,147,246,219,233,167,121,188,171, +127, 30, 79,219,111,166,128,183, 34,194,151, 79,166,128,120,204,204, 60,167,147,246,219,233,167, 12,172,195,195,204, 73,251,109, +244,208,208, 0,107,181, 11,147, 64, 72, 25, 57, 64, 15,183,147,246,219,233,174,108,188,145,253,188,159,180,126,154,142, 90,246, +181,112,227,196,208, 18, 35,205,159, 81,213, 59,143, 69,216,253, 52, 81,149, 59,114,157,173,233,214,126,154, 28, 43,238, 18, 64, + 34,231,232,174,233,196, 73, 58, 7, 14,103,133, 64, 20,229,100, 40, 7,168,228,122,117, 31,166,156, 50,167,241,149,253, 94,241, +250,106, 40, 68, 38,195, 81, 83,114, 45,123, 11,123, 41, 86, 38, 23, 1,143,203,232,160, 36, 12,156,130, 47,214,126, 62, 26,143, +211, 93,230, 50,120,253,171,254,209,250,106, 54,151, 22, 42,192,129,234,167, 19, 34, 47,188,160,251, 15, 30, 63, 37, 0,127, 49, + 61,191,140,255, 0,180,126,154, 11,228,228, 37,137,158, 79,219, 99,249,233,133,207, 61, 36,122,233,132,135,176, 2,214,231,194, +168, 10,115, 50, 45,168, 78,224, 90,228,234,111,166,163, 54,118, 99,177, 34,121, 64,240, 1,219,233,164,200, 4, 21, 31, 84,211, + 81,108, 11, 55, 1,206,254,129, 84, 6,243,153,104,183,108,137, 15,160,107,110, 39,231,166,249,220,213,248,178, 36, 36,241, 62, +251, 88,126, 90, 1,144, 22, 4,242,228,130,154,225,152,220, 27, 15, 77, 0, 99,153,154, 13,206, 84,160,122, 3,183,211, 78, 25, +217,108, 46,185, 18,254,219,125, 53, 28,105, 34,199,222,181, 32, 38,246, 2,194,128, 56,204,206,191,189,147, 32,254,187,125, 52, +158,127, 49, 28, 95, 38, 82, 15,134,182,250,104, 18, 0, 56,147, 78,134, 61,103, 83,142, 20, 4,207, 63,148,120, 9,228, 55,254, +123,125, 52, 63, 53,158,183, 45,145, 47, 30, 67,168,223, 77,112, 0, 27,129, 72,195, 81,246, 80, 13,108,220,255, 0, 9,229,253, +182,250,105, 70, 86,224,194,254, 98, 85,254,187,125, 53,192, 0,220,254, 74,105,148, 51,149, 81,192, 80, 5, 89,243, 56, 95, 38, + 99,255, 0, 17,128,254, 90,123,103,100, 71,192,228, 73,127,233,183,211, 80,220,189,248,181,133, 35,105,248,173,115, 64, 73,108, +236,203,123,179,200,111,252,246,250,105,135, 63, 48, 45,142, 68,154,189, 78,223, 77, 7, 81, 43,199,129, 52,208,128, 27,243, 52, + 1,151, 51, 56,113, 57, 50,252,178, 55,211, 69,251,195, 44, 11,117,228, 39,210, 93,190,154,141, 93,106,146, 88, 13,231,179, 79, +255, 0,152,151,246,219,233,174,243,185,191,249,153,127,109,190,154, 13,253, 20,156,104, 9, 30,119, 51,255, 0, 51, 47,237,183, +211, 93,231,115,127,243, 18,254,219,125, 52, 21,141,155,225, 82,109,206,194,137,229,220,124, 86, 95, 89, 35,243, 80,163,188,230, +111,254,102, 95,219,111,166,151,206,102,127,230, 37,253,182,250,105, 4, 81,142,108, 91,211, 97,249,205, 56, 34,168,184, 78, 63, +206, 52,130, 74, 59,206,102,255, 0,230, 37,253,182,250,105,235, 62,224,198,194,105,126, 87, 97,252,166,144, 22,191,186,109,202, +250, 69,169,194, 61, 94, 36,250,111, 65, 35,196,217, 96,217,242,220,122, 64,118, 39,249,104,131, 38, 64, 1,235,206,231,159,198, + 64, 63,203, 65, 17,251,197, 72,245,222,140, 34,186,240,229,200,250,232, 7,121,236,149, 33, 81,216, 92,253,102,102,253,227, 72, +217, 25,108,120,205, 32,246, 49, 3,135,178,185,186, 8,190,251, 45,239,233,166, 75,149,140,138,160, 18, 64, 30, 3,157, 8, 56, +100,100,145,113, 60,156,191, 89,185,252,244,238,182,101,237,213,146,220, 46,117, 55,211, 80,159,115, 65,194, 56,190, 82,105,158, +126, 99,198,194,222,138,165, 44,203,229, 90,226,121, 7,245,207,211, 72,114,164,140,141, 89, 45,242,185, 63,158,169,100,154,103, +182,167, 38,254,186, 72,161,103,112, 61, 52, 16, 93,156,225, 99,108,153, 15,139, 16, 88,216,126,106, 99,110,202,163,132,210, 49, +181,175,114, 63, 61, 87,121,115,203,199,198,135, 44, 36, 88, 1,206,128,184,251,193,122, 61, 93, 79,171,161,171, 93,205,237,215, +209,207,157,117, 66,209,254, 22,223,254,150,223,255, 0, 85, 93, 80,106, 86,247,175,107,127,155,118,204,125,187,205,156, 62,147, + 69, 63, 80, 71,212,189,162, 41,166,218,147,245,189, 52,189,175,216,219, 15,107,162, 75,133,142, 36,220, 58,106,147,103, 73,169, +164, 98, 5,156,160,118,110,152, 99,196,133,173, 19,113, 49,255, 0, 66, 63,220, 90, 40,225, 84,128,100, 82, 8,227,225, 76, 55, + 62, 23,181, 18, 98, 53, 15,101, 12, 53, 8, 40, 39,149, 34,179, 92,223,149, 40, 34,184,219,149,232, 7, 3, 92, 77, 39, 0, 56, +215, 92, 80, 10, 24, 48, 32,120, 83, 26,220,169,111,111, 10,105, 6,244, 4, 25,134,169,152, 3,234,249,133, 32, 81,122,226,215, +114,222,158, 52,151, 63, 61, 66,132,184, 6,152, 88,154,225,206,148,248, 80, 28, 1,174, 35,133,118,175, 10, 67,114,104, 14, 98, +168, 9, 60, 0, 28,106,150, 77,246, 93,127, 99, 26,232, 28,181, 92,147,243, 17, 87,122, 1, 6,252,106,143, 63,104,104,245, 79, +138, 53, 39, 54,143,196,123, 61, 85,243,253,201,238,150, 58,219,108,218, 85,151,120,253, 94, 31, 3,221,176, 91,103,119, 93,194, +151,104, 85,159,210, 93,109,155,174, 46, 84, 98, 51,238, 76, 46, 89, 15, 27,255, 0, 70,213, 44, 73, 25,185,184, 7,215,194,176, +170,204,140, 25, 73, 86, 28, 65, 28, 8, 53,125,129,188,137, 10,195,150, 64,123,105, 89,121, 3,253, 47, 93,112,217,123,165,114, + 70, 61,195, 85,183, 5,110, 21,183,159, 70,118,222,123,107,164,228,193, 54,175, 58,243,175,151, 84, 93, 35, 92, 13, 46, 0, 38, +231,143,135,170,140,173,199,153,229, 65, 17,234,176,224, 69,189,211, 77, 10, 44, 15, 1, 99,110, 28, 56, 31,101,125, 99,229,135, +247, 73,224,120,158, 52,146,125, 95, 2, 15, 31,146,185, 99, 28,195, 21, 83,196,241,189,190, 74, 99, 33,189,217,201,245,144, 60, +104, 7, 49, 7,143, 42, 66, 1,185, 28,169,132, 75,126, 96,252,148,229,224, 46,220,207, 58,168, 2,153, 75, 21,191, 27, 27, 90, +163,201, 32,115,167,234, 41,226,125, 38,151, 34,109,108, 85,121, 14, 23,160, 51, 1,109, 34,168, 30,250,143,194, 41, 7, 17, 98, +222,218, 64,206,203,107, 87, 44, 71,153, 63, 53, 0,154,213, 77,148,123,105, 88, 51,252, 34,194,156, 20, 47, 31,229,165,214,164, +216,113, 52, 3, 58, 55, 23, 38,244, 68, 54,249, 41,154,158,252,120, 10, 70, 11,241, 31,154,128, 61,238, 41, 7, 62, 60, 40, 87, + 37,120, 2, 13, 42,181,151,143, 58, 1,236,234, 27, 72,226, 79, 51, 67, 36,131, 97,238,138,226, 73, 62,138,224,140,220,129, 52, +146,192,140, 67,120, 94,151,141, 21, 96, 99,241, 50,175,180,253, 23,167,172, 49, 11,106,102,107,248, 40,183,229, 53, 1, 30,187, +137,224, 56,212,144,138, 62, 20, 6,222, 44,111,244, 10, 80, 24,240, 83,111, 18, 0,181, 4,128, 17, 72,124, 45,237,225,252,180, +229,133,126,179,129,236,226,104,193, 47,225,198,246, 36,209, 4, 64, 3,126, 22,170, 36, 10, 71, 16,250,172,199,214,108, 15,231, +162, 11, 33, 26, 35, 85,177,185,184,212, 71,202,215,167, 3, 10,129,173,197,253,102,154,217,152,177,139, 11,177,240,176,168, 7, + 48,145,189,230, 36,173, 51,167,232, 28,249, 94,154,119, 0,192, 4,143,128,244,154,143, 46,108,231,128,178,251, 5, 82, 19, 68, + 36,142, 63, 45,115,244,144, 93,220,122,238,106,188, 60,210, 11,150, 39,229,166, 52,108, 90,199,194,133,130,120,200,199, 64,108, +111,236, 20,199,220, 2,216, 36,127, 61, 6, 40,125,205, 84,178, 65,166,205,225,202,128, 79, 57, 59, 92,139, 47,178,135, 36,179, +191,196,228,252,180,240,129, 22,231,199,141, 72,138, 37,156, 5, 91, 15, 18,106, 26,141, 8, 73, 27, 22, 30,186,147,229,143,207, +198,164,152, 70, 61,217,200, 60, 56, 90,163, 12,171,191, 46, 28,133, 83, 36,115, 29,184, 91,141, 28, 71,165, 64, 53, 32,105,190, +178, 61,227,196, 26,137, 49,102,114,163,144,168,105,105,168, 97, 7, 82,197,124, 42, 66, 66,208, 27,183, 6,240, 30,170, 14, 27, + 16,116,183,133, 74,157,137,141,152, 11, 26, 17,185,114, 71,121,225, 67,164, 53,143,170,154,230, 55, 0, 6,189,254,181, 69,100, + 0, 95,196,211,161, 4, 95,209, 70, 43,199, 82,195,165,254, 23,226, 22,242,214,241,255, 0,204,222,186,159, 97,229,180,248,121, +127,254, 34,186,161,189, 62,210, 72,248,163,191,132,113,254,226,209, 46, 41, 17,111,164,255, 0,187,143,247, 22,158, 98, 7,194, +180,114, 35,205,109, 67,217, 64, 53, 34,104,174,223, 37, 4,196,109, 66, 13, 6,151, 87,141, 33,132,143, 19, 78, 17,112,231, 64, + 37,252,111, 93,171,198,148, 66, 71,141,113, 70,183, 10, 1, 46,105, 93,136, 70, 32,241, 0,145,243, 82, 89,135,133, 10,107,244, +200,244,218,212, 4,113,192, 82, 18, 47,236,174,211,233,165, 2,161, 68,227, 80, 39,221,241, 34,125, 3, 84,164,115, 43,107,124, +230,167,202,186,209,144, 27, 22, 5, 65,244, 92, 86,101,246,236,200,216,169,136,155,120,175, 17, 95, 63,220, 55, 27,156, 74,139, +111, 70,251,166,108,151,116,120, 30,237,142, 13,190, 87,111, 94,241, 17, 21,158,217,241, 44,198,251,142, 63,178,127,201, 75,247, +238, 63,251, 39,252,149, 83,228, 51, 63,216, 63,205, 92,112,114,192, 36,194,192, 14, 36,145,202,190,103,249,254,227,252,175,255, + 0, 95,238, 62,135,248, 91, 15,230, 95,223,251,203,127,191,160,183,240,159,242, 82, 13,254, 17,253,147,254, 74,161,174,174,127, +246,219,191,230, 95,218,142,159,245,155, 95,229,127,220,201,153,179,226,100, 30,164, 17, 52, 82,125,110, 90, 79,175,219, 80,234, + 70, 62, 14,102, 87,254, 27, 30, 73, 71,165, 20,145,243,138, 59,236,187,180,107,169,240,166, 3,210, 16,159,228,175, 45,214, 92, +173,229,244,222,186,183, 90,197,126,195,211, 71,139, 18, 88,251,214,156, 21,173, 47,237, 11,182,239, 50,225,145, 20,215,146, 14, + 67,245,151,217, 90, 40,178,160,153, 82, 72,220, 50, 30, 55,172, 83, 43, 41, 42,192,171, 14, 4, 30, 4, 84,140, 44,233,240,100, +215, 17,186,159,138, 51,240,154,246,236,189,206,248, 99, 30,105,181, 56, 79,241, 87,243, 71,143,121,237,212,203, 57, 49, 69,111, +198, 63,134,223,188,218,222, 51,240,181,239, 77, 22,191, 19,236, 30, 20, 12, 44,204,109,198, 46,164, 99,223, 31, 28,102,215, 83, + 71, 72,162,109, 94,237,171,244, 52,189,111, 85,122, 53,106,189, 83, 71,194,189, 45, 75, 58, 93, 58,181,197, 49,108, 71, 16,106, + 28,242,158, 49,169,254,145,170,205,195,187,123,123,106,221, 27,106,207,158, 76,121,144, 43,107,101, 99, 29,156,106, 28, 87, 87, +229, 21, 35, 31, 51, 15, 61, 90,124, 28,132,200,132,177, 2, 72,216, 48,225,225,195,198,186,250,119, 73, 89,213,164,245, 78, 52, + 57, 87, 37, 44,221,107,100,218,226,167, 85,240, 8, 21, 79, 3,198,157,211, 69,227, 75, 98, 56,240, 2,152,196, 49,245, 14, 85, + 13,138,206,170, 61, 53,197,152,175,187,195,211, 65,154,104,160, 67, 52,238,177, 70,191, 20,142, 66,168,191, 14,102,163,199,186, +237,178,184,138, 28,216, 36,145,205,149, 22, 84, 98, 79,160, 0,111, 85, 38,245, 73,145,180,156, 54,145, 44, 91,147, 53,205,119, + 16,108,171, 97,226,105, 0,241, 28,232,168,186,172, 88,123, 5, 66,140, 96, 26,220, 79,176, 83,214, 57, 72,176, 75,123,127, 77, + 29, 85,185, 14, 22,167,232, 60, 9, 54,160, 35,116, 79,214, 97,252,180,162, 52, 30,186, 43,152,150,228,176,181, 51,175, 8,229, +118,160, 56, 40, 6,192,123, 40,129, 9, 31,203, 81,252,221,219,221, 90,108,153, 51,242, 83,167,217, 64, 76,142, 62, 23,229,195, +228,165,251, 21,211,169,197,253,181, 92, 76,172, 13,216,154,116, 80,146,120,242,168, 86, 75,124,172,101, 39,155, 31, 0, 7,211, + 76, 57,163,154, 39, 31, 11,208, 36,134,196, 88, 94,252,169,147,205,139,133, 17,155, 50,100,134, 36,248,164,145,130,168,240,230, +106,248, 32,185,183,162, 93, 66,121,188,137, 13,129,176,245, 10, 73, 76,196, 93,152,154,167,195,238,238,223,159,113,135,108,196, +200, 57, 19,204, 74,171, 70,135, 64, 32, 22, 55,118,211,224, 60, 42,249,157, 36, 4, 3, 86,245,181, 99,190,174,178,167, 93, 12, +210,244,188,246, 89, 90, 28,104,228,136,136, 73, 52,246,132,130, 47, 79,123, 70, 6,158, 38,137, 27,135, 23,101,191, 26,201,183, + 11, 65,177,196,170,156,124, 79, 10,233, 99, 37,184, 11,240,166,204,238,205, 96,108, 7, 27, 83,145,207, 79,143, 59,209,138,169, +103, 92, 68,186, 79, 58, 50,162, 56,212, 77,189,149, 25,148,179,146,124, 40,209,157, 8, 56, 80, 55,200,100,178, 50, 16,171,200, +114,246, 81, 34,145,157,110,124, 56, 90,155, 50,181,239,110,124,169, 99, 70, 81,107,123,104,203, 94,172,100,224,177, 0,112, 6, +157,143,116, 44, 61, 95,158,142, 33,234,122,136,228, 77, 24, 66,136,160, 22, 5,173,198,136,150,114,192,207,115, 25, 3,143, 10, +134, 19, 81, 0, 85,130,172, 99,131, 53,201,225, 77, 34, 20,224,139,207,198,132, 2,199,234,223,143, 42,227,142,230,238,162,224, +250, 40,190, 60, 23,143, 58, 80,242,216,216,219,244,208, 54, 36,105,210, 83,126, 44,105,225,195, 45,136, 30,195, 76,210,215,247, +141,174,109,122,238,152, 99,166,247,185,231, 86, 9, 32,155, 24, 18, 62,209,109,227,115,202,138, 32,141, 80, 1, 42,223,196,241, +227, 92, 99, 65,194,231, 95, 38, 30, 30,170,120,129,116,139,145,195,137,168, 89, 15,165,124,189,186,131,255, 0, 15,107,216,242, +235,243,174,174,176,242,247,208,109,229,237,255, 0,191,255, 0, 67, 93, 65, 36,232,192, 8,135,210,145,254,226,211,152,138, 96, +224,137,127,246,105,251,162,148, 16, 69,234,153, 3, 41, 32,252,148, 59,222,151, 33,189,241,225,194,133,123, 80, 4,225, 74, 8, + 20, 16,192,248,211,239, 64, 59, 80, 62,170,234,101, 40, 32, 80, 11,227,114, 42, 62, 83, 13, 1, 71,166,255, 0, 53, 25,154,161, +228,146, 93, 87,194,212, 97, 2, 4,218,194,184, 92,241,165, 28, 5, 40, 32, 10,133, 18,222, 52,150,187, 82,220,218,161,102,103, +197,134, 52,223, 92,199,146, 15, 15,233, 87, 60,185,105,138,142,249, 44,171, 85,205,155,199,142,249, 44,169,142,174,205,242, 68, +169,178, 33,197,143, 92,173, 97,224, 60, 79,168, 10,207,102,238, 50,229,146,163,220,138,252, 16,120,255, 0, 74,163,207,145, 46, + 75,245, 37,107,159, 1,224, 7,170,133, 95,157,222,251,149,243,205, 49,205, 49,244,231,111,245,126, 71,222,217,251,125, 48,197, +239, 23,191,217, 95, 47,204,234,218,236, 61,169, 18,198,153,155,162,107,145,172,201,142,126, 21, 30, 26,253, 39,213, 84,125,175, +132,153,187,188, 66, 65,120,225, 6,102, 30,157, 54,211,255, 0, 72,138,208,254, 32,119, 20,189,181,219, 89, 25,184,164, 12,185, +153,113,241, 88,253, 87,146,254,255, 0,245, 85, 73, 30,186,245,123, 54,194,185,159,171,116,173,245,118,210,175,132,243,179, 60, +222,237,190,120,106,241,213,186,197,123,174,215, 24,232,135,239,189,239,219, 29,174, 70, 54,110, 72,243, 10, 56, 98, 99,174,183, + 81,252,229, 94, 11,253, 98, 42,135, 31,241,151,180,166,147, 68,177,229,227,173,255, 0,137, 36, 74, 87,229,233,187,183,228,175, + 5,150, 89, 38,145,230,153,218, 73,100, 37,157,216,146,204,199,137, 36,158,100,211, 43,246,117,246,252, 74,177,102,219,234,180, +249, 35,241,215,247, 44,206,211, 85, 84,186, 61,126,108,250,159,165,176,247, 86, 16,202,198,146, 60,168,159,132,121, 80,145,169, + 79,162,252,193, 31,170,213,133,221,246,153,246,140,163, 4,190,242, 55,189, 20,163,147, 47,210, 60,107,207,127, 15,251,159, 43, +183, 55,252,107, 72,124,142,100,137, 6,100, 36,251,165, 92,233, 18, 91,245,144,155,223,228,175,123,238,156, 37,203,218, 37,123, +125,166, 63,218,161,246,124, 67,246,107,243,254,247,237, 84, 85,181,234,190,164,157,149,150,142,201,113,173,143,208,123, 55,186, + 90,206,180,183,233,109, 86,213,226,170,223, 11, 84,243,236, 60,169, 48,231, 89,227, 60,190, 37,240, 97,226, 13,109, 49,178, 99, +150, 37,153, 88,105,147,222, 4,240,172, 37,105,123,118,118,124,121, 32, 63,217, 48,101,246, 55,233, 21,241,253,159,112,235,149, +224,111,233,186,109,120, 89,126,104,250,190,235,129, 91, 26,204,151,213, 70,147,241,171,252,153,229, 95,137, 68, 30,235,200, 42, + 65, 29, 40,120,143,232, 10,210,254, 31,102, 98, 96,246,220,211,229,204,144, 70,185, 47,119,145,130,143,129, 60, 77,102,191, 18, +133,187,175, 32,127,186,135,247, 5, 81,237, 91, 94,231,190, 72, 48,112,129,116,142,238,218,154,209,199,170,192,177,246,219,219, + 95,185,244,235,147,105,142,182,183,106, 85,171,111,193, 35,241, 11, 45,177,239, 50, 90,181,239,179,181,146, 94, 45,158,175, 39, +123,246,193,126,153,220, 7,172,136,228, 43,243,132,181, 89,224,238, 91,118,230,133,240, 50, 35,200, 11,204, 35, 2, 71,180,115, + 21,231, 18,254, 26,239, 11, 1,146, 28,136, 38,144, 11,244,129,101, 39,212, 11, 11,124,245,149, 73, 51,246,124,210, 81,159, 23, + 51, 29,136, 54,247, 89, 88,115, 6,184,173,166, 12,137,250, 57, 91,107,175,236,143, 67,222,238, 49, 53,235,226, 73, 62,154,126, +103,172,247,176, 35,182,115,245,122, 35,225,255, 0, 21, 43,204,251, 87,254, 98,219,173,254,216,126,122,218,238, 27,210,239,221, +135,151,152,192, 46, 74,116,226,201, 81,200, 56,146, 62, 32,122, 24, 27,214, 47,181, 5,251,139,110, 31,239,135,242, 26,233,182, +171,174,223, 53,109,163, 78,201,255, 0,105,207,117,122,223,115,130,245,114,172,168,215,247, 30,217,117, 85, 44,238, 21, 84, 93, +137, 32, 0, 7,164,154,163,204,239,206,220,193,144,198, 50,122,238, 56, 30,138,151, 3,250,223, 15,229,172, 87,126,119, 12,249, + 57,210,108,216,206, 83, 19, 24,233,156, 3,110,164,131,158,175, 82,242,183,166,162,246,175,103, 54,255, 0, 19,230,100,204,113, +240,209,186,106, 84, 93,221,128,185,211,126, 0, 11,243,174, 20,218, 99,174, 53,151, 61,157, 83,213, 37,227,192,239,147,121,146, +217, 94, 29,189, 85,154,209,183,225,196,219, 71,248,141,177, 76,250, 76,210, 66, 15, 13, 79, 25,183,253, 29, 85,123,141,157, 14, +227, 24,159, 15, 33,103,136,253,120,216, 48,191,160,218,176,251,191,225,180, 48,226,188,251, 86, 76,143, 50, 2,194, 9,180,157, +118, 23,178,178,133,177,244,112,172,126,195,190,101,236, 57,233,151, 3, 19, 29,192,200,134,254,235,167,136, 35,211,232, 62, 21, + 86,215, 14, 90, 59,109,236,229,114,176,123,188,248,110,169,185,162,139,127, 21, 79,113,120,236,180,129, 81, 16,151, 32, 0, 9, + 36,240, 0, 10,243,127,196, 60,249, 30, 77,178,108,105,157, 99,154, 23,145, 74, 49, 91,134, 42, 65,225,234,172,190,220,219,222, +233, 33,218,112,165,150, 83,148, 71, 82, 50,230,196, 37,205,220,147,193, 69,248,214, 49,236,157,241,172,142,234,169,241,149,194, + 30,166,242,111,213, 50,188, 75, 27,179, 92, 33,241,149,166,135,169,228,119,167,108,224,202, 98,124,193, 43,142, 7,162,173, 32, + 31,214, 81,167,242,212,189,187,185,182, 13,225,196,120, 89,138,102, 60,161,144, 24,220,255, 0, 68, 56, 23,249, 43, 10,223,134, + 59,170,195,175,206, 64,101,183,240,236,246,191,163, 85,191, 53, 99, 39,131, 35, 7, 38, 76,121,129,139, 34, 7, 42,195,197, 89, + 79,129, 21,214,155, 77,182, 68,214, 60,141,217,126,220, 14, 55,222,238,177, 53,108,184,146,171,229,251,228,250, 18, 7, 83, 38, +150, 23, 67, 66,221, 55, 28, 29,182, 48,249, 19,199,140,141,227, 35, 0, 79,178,252,235, 51,129,220,167, 31,178,163,223,242,135, + 83, 34, 48, 96, 80,127,180,152, 49, 69,191,180, 13, 70,188,183, 55, 59,112,222,179,142, 70, 83,190, 70, 84,236, 21, 71, 62, 36, +217, 81, 23,192,122, 0,174, 56, 54, 86,189,173,220,251,107, 70,234,223, 86,186, 29,247, 27,250,210,180,236, 93,214,186, 86, 75, +162,125, 79, 95, 78,251,237,128, 66, 54,120,213,202,253, 57, 45,243,232,181, 85,247,150,110, 30,227,218,217, 89, 24, 83,166, 68, +122,226, 26,163, 96,214,251, 69,224,109,202,179,184,159,134, 91,220,240, 9,114, 39,131, 25,216, 95,164,197,153,135,244,180, 2, + 63, 45, 80,239, 59, 30,239,219,146, 28,108,206, 16,228, 11, 9, 34, 98, 98,148, 41,191,171,145,227, 98, 43,190, 61,190,223,212, +175,165,150,109, 86,156, 61,102, 58, 30,124,187,173,215,165,101,151, 12, 86,213,106, 86,145, 61,120,134,236,223,249,155,111,254, +155,127,213,181,123, 64, 41, 18,188,210, 48, 72,212, 93,157,141,148, 1,233, 38,188, 99,178,191,230,157,183,133,253,246,225,255, + 0, 13,170,207,191,123,146,125,195,113,151,105,199,110,158, 6, 27,104,100, 83,110,164,171,241, 51,250,116,158, 0, 85,221, 96, +182,109,197,106,156, 37, 73,111,194, 89,157,166,226,184, 54,215,187, 82,221,225, 46,174, 17,179,205,239,158,219,197,144,167,154, + 51,176,189,250, 40, 92,126,215, 5, 63, 33,166, 98,254, 32,246,204,140, 17,230,146, 29, 71,226,146, 51, 97,127,232,106,172,127, +104,246, 43,119, 14, 59,110, 25,147,156,108, 48,197, 35,208, 1,121, 10,252, 68, 22,224, 5,248, 85,190,251,248, 99, 22, 46, 20, +185,123, 70, 76,146, 73, 10,151, 56,243, 5, 37,192, 23, 33, 89, 2,241,244,112,174,111, 14,206,182,244,237,123,119,112,111,148, +252,142,171, 62,250,245,245,107, 74,118,241, 75,155, 95, 51,125,143, 46, 46,225, 18,229, 97, 79, 28,240,183, 39,141,131, 11,252, +149, 32,196,163,134,174, 21,225, 61,181,220, 25, 61,191,184,199,146,132,182, 51, 16,185, 80, 95,131,167,143, 15,214, 30, 6,180, +255, 0,137,153, 82,166,229,129, 38, 44,206,145, 75,138, 29, 74, 49, 80,192,187, 89,184,122,171, 22,216,181,154,184,251,180,178, +109, 90, 58,114, 55, 79,112, 79, 13,178,118,253, 85,105, 58,207, 94,105,158,153,145,147,135,137,142,211,228,186,197, 12, 98,239, + 43,144,160, 15, 89, 53, 71,131,222,123, 14,233,184,166,217,130,239, 36,210, 22,233,182,130, 16,232, 82,231,139, 88,242, 95, 69, +121, 14, 18,111, 59,212,169,180,226, 60,185, 45, 51, 7, 16,151, 37,110,160,251,237,168,216, 0, 15, 51, 94,131,219, 31,135,251, +142,201,187,226,238,153,185,120,229, 97, 15,174, 24,203, 51,123,241,180,124, 14,144, 56, 22,173, 95,107,135, 21, 45,234,100,155, + 67,117, 75, 79, 35, 56,247,153,179, 94,190,158, 56,164,165,118,245,243,215, 67,125,170, 75,240,255, 0, 75, 83,130,185,241,244, +126, 90, 85,147, 29,120,117, 47,110,118, 23,174,243, 24,232,120, 43, 55,228,175, 9,244, 14,210, 77,198,175,120,120, 82,136,248, +123,220,205,128, 52,207, 52, 1, 58, 99, 31, 41,174,243,147,114, 80,170, 61,149, 10, 24, 66,110, 24, 11,158, 96, 81, 76, 4, 11, +233, 55, 35,159,133, 66, 57, 89, 7,251, 66, 7,160,112,160,201, 36,172, 9, 46, 79,203, 66, 22, 38, 38,183,190,202, 7, 1,123, +142, 66,155,254, 29, 78,166,148, 27,120, 10,173, 13,195,143, 62, 20, 80, 56, 80, 19, 12,248,160,113, 37,207,178,132,114,224, 65, +238,196, 77,189, 38,163, 61,128, 62,170, 17,109, 95,146,172,130,112,205, 65,109, 48, 1,237, 98,105, 78,107, 19,113, 18, 2,124, +120,159,207, 80, 75, 16,120, 11,220, 88, 83,212,240, 23,231,227, 80, 22,190,102, 79, 47,125, 43,252, 13, 86,183, 11,249,141, 62, +154,234, 13,255, 0,195,127,252, 55,255, 0, 19, 93, 64, 90, 17,193, 63,160,159,186, 43,171,137,248, 63,160,159,186, 43,175, 84, +132,124,143,136, 95,209, 64, 34,252, 40,211,183,190, 7,170,134, 47,126, 2,128, 96, 85, 82,125, 38,157,164,248, 26,112,181, 37, +184,208, 8, 1,177, 6,147, 65, 6,247,231,225, 69, 2,244,164, 80, 2,227,227, 80,166, 26,165, 98, 57,125, 2,167,176,181, 87, + 23, 5,139,122,120,218,140,168, 80,163,145,167, 16, 7,168, 10,104,106,160,221,115,228,146, 87,198, 67,166, 52, 58, 90,223, 88, +142,119,175, 46,239,117, 77,182, 62,251, 41,109,197, 82,230,207, 70,219,109,125,198, 78,202,232,150,173,190, 72,145,159,187,133, +188, 88,134,231,145,151,192,127, 70,169, 73, 44, 75, 49,185, 60, 73, 60,233, 42,199,111,218,164,202, 34, 89,110,144,248,122, 91, +217, 95,157,190, 77,206,251, 50, 95,169,242,170,253, 53, 95,183, 51,239, 86,155,125,158, 38,248, 46,118,127,170,204,141,141,135, + 46, 86,162,130,209,160, 37,156,242, 22,168,245,178, 88, 99,142, 62,138, 40, 84,181,128, 30,186,200, 75, 25,138, 71,141,185,161, + 42,126, 74,233,190,216,173,181, 49,107,220,237, 61,207,148,233, 9, 28,246,123,199,184,190, 93, 59, 85, 99,181,115,141,101,179, + 67,217, 82,170,110,178, 70,121,201, 11, 5,246,130,173,252,130,157,248,185,182, 79,184,118,147, 77, 2,151,108, 25,211, 37,212, +115,233,128,209,185,249, 53,222,168, 48,242,165,193,202,139, 46, 31,142, 38, 12, 61,126,144,125,162,189, 63, 7, 59, 19,118,195, + 19, 69,103,142, 65,166, 88,154,198,196,143,121, 28, 87,211,246, 45,213,107, 95, 79,248,177,219,185, 46,181,103,206,247,173,171, +187,118,254, 28,149,237,111,165,145,242, 93,117,123, 71,114,254, 13, 69,147, 59,229,246,222, 74, 99, 7, 37,142, 22, 69,250,106, + 79,251, 55, 80,196, 15, 81, 7,219, 89,220,127,193,158,233,146, 80,185, 19, 98, 65, 31,140,157, 70,115,111, 82,170, 87,236, 43, +187,193,106,207,122, 94, 15,137,248,251,108,183, 21,183,111, 99,126, 43,129,141,237,205,178,125,227,125,192,219,177,212,179, 77, + 50, 6, 35,234,160, 58,157,207,244, 84, 19, 95, 78,111,178,172, 59, 62,107,185,176, 49, 50, 15,107,141, 3,242,154,165,236,254, +196,218,187, 66, 54,146, 2,114,115,229, 93, 51,102, 72, 0, 58,121,232,141,120,233, 90,131,221,219,220,121, 76, 54,220, 86,213, + 28,109,170,119, 28,139, 14, 74, 61,158, 53,241, 61,231,127,141, 98,179, 79, 78,215, 90, 79, 27, 90,199,221,246,109,134, 69,116, +159, 23,101,107,199, 10,214,166, 86,174,187,117,152, 77, 56, 0,144, 84, 92, 15,109, 82,214,143,183, 32, 43, 12,179,145,252, 70, + 10,190,197,253, 38,191, 41,237,149,118,221,227,143,225,150,252,160,253, 55,184,217, 87,107,146,121,194, 94,114,121, 95,226, 65, +191,117,100, 27, 17,246, 80,243,254,128,173, 39,225,162,194, 54,140,146,162,243, 54, 65, 18, 31, 29, 33, 23, 79,242,154,206,126, + 36,241,238,188,143,238,226,253,193, 85, 27, 22,255, 0,159,219,243,180,248,160, 52, 83, 13, 50,194,247,210,250,125,158, 34,252, +235,250, 19,197,108,155, 58, 82,188,123,106,252,224,252, 13,114,215, 22,246,247,178,211,186,201,248, 79, 51,219,129, 40,223,205, + 53,228,255, 0,136,171, 8,238, 50, 98,182,182,130, 51, 53,191, 95,136,253,208, 42,198,111,196,201,154, 43, 67,183,170,203,111, +137,228, 44,160,255, 0, 68, 42,147,243,214, 50,105,179,119,124,230,150, 77, 89, 25,121, 47,201, 69,203, 49,224, 21, 64,252,149, +207,103,182,201,142,238,249, 23,106,134,184,157,119,187,172, 89,113,172,120,223,115,109, 62, 31,153,119,179, 23,255, 0, 42,119, + 16,254,204,121, 91,127, 75,169,198,161,246,159,252,201,182,255, 0,124, 63, 61,108,114,246, 35,176,246, 6,108, 19, 91,205, 77, +211,155, 38,222, 12,100, 64, 19,250,163,242,214, 55,180,255, 0,230, 77,183,251,225,252,134,187, 86,234,248,247, 22,175, 6,237, +246, 85, 35,133,233,106,100,219, 82,220, 82,172,252,110,217, 19,121,215,247,190,225,212,248,252,204,218,175,233,214,213, 59,108, +217,123,159, 51, 17,103,218,226,153,177, 88,176, 83, 28,161, 86,224,217,184,107, 21,117,223,221,185, 62, 46,116,155,206, 50, 23, +196,201, 58,167, 32, 95,167, 39, 35,171,212,220,239,233,168,125,169,222,115,118,234, 62, 36,176,249,140, 57, 27, 94,144,116,186, + 49, 22, 37,111,192,131,110, 85,175, 82,215,193, 91,225, 85,179,133,163,251, 87,153,151,142,180,220, 90,153,221,168,165,253, 75, +236,126, 66, 14,217,239,163,253,134, 73,255, 0,142, 63,239, 42, 49,236,142,234,230,118,231,253,184,255, 0,215,173, 30,239,248, +152,211,226, 73,143,180,227, 60, 18,202, 10,156,137, 88, 93, 1,225,116, 84,191, 31, 65,189, 73,236, 94,233,223,119, 44,149,219, +114,161, 57,176, 40,247,243, 73,210,209, 15, 3, 35,114,111,229,174, 94,166,234,184,222, 71, 76,117,142, 43,131,143,153,215,210, +218, 91, 34,198,178,100,180,240,107, 85, 63, 34,131,188, 49,178,112,246,253,131, 31, 49, 74,100, 71,138,201, 34, 18, 9, 5, 89, + 64, 28, 47,225, 86,159,133,145, 35,101,110, 82,145,119, 88,227, 85, 62,128,197,137,253,209, 78,252, 86, 10, 50,246,219, 27,253, +148,159,188,180,239,194,166, 69,151,116, 45,250,176,219,231,146,179,107, 78,197,219,132,235,243,185,170,213, 47,112, 85,227, 26, +107,225, 67,210, 7, 43, 90,245,226,125,242,161, 59,167,112, 0, 91,222, 66,125,166, 52,189,123,104,158, 48,108, 22,254,154,241, + 78,250, 33,187,171, 60,129, 97,120,248,127,194, 74,225,237,223,243, 91,253, 15,239, 71,163,220,255, 0,225,175,250,215,220,195, +230, 25,127,200, 59,104, 4,244,142,116,183, 30, 23,210,214,252,244, 62,193,138, 9,123,167, 9,103,181,135, 81,163,191,235,136, +216,173,105,118, 45,168,239,189,130,118,208, 66,201,214,146, 88, 24,248, 72,173,194,231,208,121, 87,159, 21,206,218, 51,134,160, +248,185,184,174, 24, 95,131, 43, 41,184, 53,236,163, 87,174,124, 73,197,187,174,191,187,153,225,200,158, 59, 96,204,212,215,182, +143,251,121, 31, 69,244, 91,245,109,111, 19, 89, 15,196,152,161,255, 0, 44, 59, 77,167,170,179, 68, 97,226, 47,168,155, 27,127, + 86,245,153,198,252, 80,202, 88, 66,230, 96,137,165, 3,248,137, 33, 64, 79,164,169, 87,254, 90,206,119, 15,115,110, 29,198,234, +103, 81, 22, 52, 62,244,112, 71,114, 1, 60, 53, 49, 60,207,133,121, 48,108,243, 87, 45,109,101,218,170,230,103,140, 30,205,198, +247, 5,176,218,180,110,206,202, 34, 56, 79, 81,253,146, 64,238,157,180,177,176,214,215, 63,240,222,169,243,245,121,236,157,127, + 31, 86, 77, 87,231,125, 70,245,107,217,223,243, 46,223,253, 54,253,198,171, 62,249,237,220,140, 28,249,119, 88, 35, 45,133,150, +218,220,168,254, 28,141,241, 6,245, 49,226, 13,123,158, 74,215,115,218,244,238,162,143, 52,222,135,129, 99,181,182,189,235, 85, + 76,142,124,154, 90,149,187,118,205,221, 89, 88,113,207,182,164,231, 17,239,211, 49,202, 21,120, 18, 13,151, 88,241, 21, 43,252, +191,222,230,227,167,146,125, 63,110, 63,239, 41,221,177,222,115,108, 48,156, 41,226, 57, 24,133,139, 32, 83,103, 66,126, 45, 55, +224, 65,244, 85,142,241,248,138,249, 56,175,141,181, 64,248,237, 40, 42,217, 14,195, 82,131,250,129,124,125,119,174,119,182,231, +212,117,174, 58, 58,206,150,125, 60,117, 58,210,187, 95, 73, 90,217,114, 43, 37,173, 87, 95, 13, 10, 63,242, 95,115,159,255, 0, +183,191,237,199,254,189, 77,239,100,202,137, 54, 56, 51, 65, 92,136,118,248,227,145, 73,185, 5, 9, 91, 92, 95,209, 90, 30,200, +238,109,251,116,155,200,228,192,114,225,140,123,249,163,221,100,244, 7, 60,154,255, 0, 61, 85,126, 38,234, 59,166, 17, 97,111, +240,230,223,182,213,154,229,202,247, 53,199,145, 87,233, 77,253, 62, 70,173,139, 18,218,219, 46, 39,127,169,164,213,188, 25, 55, +240,183, 30, 50,219,142, 89, 31,106,162, 56,149,189, 10,218,153,190,114,162,189, 9,205,143, 63,101, 96,191, 11, 17,158, 13,207, + 77,184, 60, 87,191,177,235,208, 78, 49,250,206, 62, 65, 94, 29,239,255, 0, 69,254, 31,113,239,216,194,219, 83,227,247,176, 73, +195,143,164,209,173,122, 98, 39,128,227, 82, 22, 50,107,204,122,129,105,174, 34,212,101,135, 72,211,242,210,180, 87, 4, 3, 66, + 1,210, 10,220, 83, 28, 88, 26,146,168, 21,109,126, 84, 9, 52,145,192,241, 55,189, 10, 9, 97,149,136, 33, 15,203, 68, 88,165, +111, 64,249,104,137, 32, 80, 7,143, 0, 7,182,145, 92, 39,188, 71, 11,241,160, 56, 98,187, 94,238, 7,201, 92, 49, 71,139,159, +144, 84,152,110, 80, 19,192,154,118,154, 16,141,229, 80,115,103,255, 0, 79,146,151,203, 69,233,115,242,212,146, 41, 45, 64, 19, +161, 31,150,181,143,254, 30,215,191, 27,121,141, 85,212,107,127,135,245,116,127,237,171,170,128,204, 88, 20, 22,250,137,251,162, +151, 81,244, 83,143,213, 63,204, 79,221, 20,221, 84, 4,121,254, 48,108,121, 80,140,150,240, 53, 34, 83,198,227,209, 65,182,163, +198,128,110,163,110, 95, 53, 34,200, 73,226, 45, 70, 2,222,202,234, 1,186,172, 41,117, 3,227, 74, 64,228,105,186, 64, 38,244, + 3, 36,107, 41, 42,111, 96, 79,205, 80,128,169, 83,128, 34, 98, 56, 30, 0,124,245, 23, 73,183, 58,140,168,227,106,163,206,218, +167,121,222, 88, 44,235, 33,212, 69,236, 65, 60,249,213,209, 30, 53,220,128,175, 62,231,107,143,113, 69, 76,147,163,148,214,141, + 29,246,251,156,152, 44,237,142, 53, 80,211,213, 21, 56, 91, 64, 70,234,101, 89,136,229, 24,226, 63,173, 87, 60, 64,224, 45,110, + 84,128,113,162,242, 21,118,251,108, 88, 43,217,138,177,213,190, 47,205,147, 62,227, 38,107,119,100,115,209,114, 94, 72, 17, 44, +106,147,120,195, 33,188,210, 11,131,194, 79,204,106,242,154, 66,176, 33,133,193,224, 65,169,186,219,215,113,138,216,237,167, 52, +250, 91,147, 46,219, 61,176,101, 89, 43,175, 38,186,174,134, 58,165, 96,238, 25,123,116,221,108, 73, 76,109,201,135, 53, 97,232, + 96,120, 26,147,157,181, 60, 68,203,140, 53,199,204,167,138,253, 34,171, 43,242,249,112,230,219,100,139, 39, 75, 46, 22, 95,125, + 89,250, 60,121,113,110, 49,205, 98,213,124, 83,251,154, 54, 88,189,242, 52,129,155,138,117,120,188, 71,129,254,171,125, 53, 33, +251,227, 0, 15,179,198,153,155,208,218, 84,124,247,106,194,215, 87,162,190,235,188, 74, 59,211,241,117, 82,112,126,219,181,110, +123, 26,240, 77,193,123,185,247, 86,227,158,166, 24,237,141, 11,112,101,140,221,136,244, 23,250, 42,138,186,143,141,135, 62, 91, +232,133,110, 60, 92,240, 81,237, 53,230,190, 76,251,140,139,185,219, 37,158,137,113,249, 35,209, 90, 97,193, 71,218,171,142,171, + 86,255, 0, 54, 55, 27, 30, 76,169,150, 8,133,217,143, 63, 0, 60, 73,173,140, 49, 54, 52, 9, 4, 86,210,130,195,210,125, 38, +133,129,183,197,183,199,101,247,164, 97,239,200,121,159, 80,245, 84,146,121,219,198,191, 65,237,219, 47,241,232,237,127,249, 47, +199,250, 87, 79,204,248, 91,253,231,175,101, 90,126,138,112,254,167,212,160,221,251,111,103,220,178,188,222,118, 10, 73,144,224, + 6,144,179,220,133, 0, 14, 68, 84, 97,218,219, 25,195, 56, 13,134,158, 91, 81,144, 39, 30, 14, 64, 5,149,137,212, 56, 15, 3, + 87,185, 46,193,213, 64,189,133, 0,251,195,159,182,213,245, 86, 76,144,151,125,161,112,213,232,124,239, 75, 28,183,217, 89,124, +116, 90,153,102,252, 61,237,176,250,180, 76, 23,245, 68,134,223, 77, 92,237, 91, 22,205,180,123,219,126, 42,196,228, 88,202,110, +206, 71,244,222,230,167,143, 69,184,122, 77, 33,247, 79, 50,125, 66,173,179,101,178,139, 94,205,116,108,149,193,138,174,107,142, +169,245, 72,102,102, 38, 38,227,142,248,121,104, 38,130, 75,107,140,220, 3, 98, 24,114,177,230, 42,191, 23,181,123,127, 15, 38, + 60,172, 92, 20,142,104,142,168,220, 51,146, 15,167,139, 85,153,186,157, 67,135,166,136, 13,248,250,107, 42,247, 74, 21,154, 79, +138, 79, 67, 79, 29, 44,213,173, 84,218,224,218,150, 43, 42,178,149,112, 25, 72,177, 83,196, 16,107, 55,153,217, 93,183,153, 35, + 57,196,232,177,230, 97,102, 65,251, 32,233,252,149,164,174,232, 92,222,252,248,210,185, 47, 77,105,103, 95, 39, 2,248,233,125, + 47, 85,111, 53, 38, 82, 62,193,237,184, 88, 51, 67, 36,182,240,146, 70,183,253, 29, 53,161,194,198,197,193,132, 99,225,196,144, + 68,188,145, 0, 81,249, 43, 17,220,157,225,186,109, 27,254, 70,221, 10,196,113,161, 49, 88,178, 18,214,120,210, 70,226, 24,126, +181, 2,126,234,238,205,200,190, 78,203,183,186, 96,130, 68,110,176,153, 73, 3,210,196, 21, 39,210, 23,149, 91,228,201,127,215, +103,111, 54, 74, 98,199, 79,209, 74,215,201, 27,125,199,101,218,119,102,141,247, 28,101,157,162, 4, 70, 88,176,176, 60,254, 18, + 41, 54,253,155,107,218,122,135,109,198, 88, 12,182, 18, 21, 44,111,166,246,248,137,244,214, 51,101,252, 67,200,143, 41,113,119, +232, 16, 68,205,161,167,141, 74, 60,102,246,187,161,230, 7,141,172,125,181,123,222,253,201,157,219,235,183,182,218, 34,101,202, + 18,151, 50, 41,113,100,233,233,211,102, 31,175, 83,190,253,189,189,207,183,164,233,242, 29,148,238,239,237, 93,221, 99, 95,153, +164, 64, 73,170,236,206,215,216,119, 12,151,203,204,194, 89,114, 37,177,121, 9,112, 78,144, 20,114, 96, 57, 10,238,215,220,166, +221,182,108, 92,252,192,162,121,250,154,194, 11, 47,185, 35,160,225,115,224,181, 75,222,189,217,185,118,254,118, 62, 54,222, 33, + 49,203, 15, 81,250,138, 88,223, 81, 94, 22, 97,232,169, 91, 90,174,106,221, 95,131,130,218,149,178,139, 85, 89,113,213, 73, 97, +186,230, 96,118, 86,213, 19,226, 97,223, 29,166,233,136, 81,202,217,157, 89,203, 93,181,126,165, 3, 1,182,126,248,219,223, 55, + 55,110, 85,233, 74,208, 46,166,187,139, 42,189,195,166,146, 62, 62, 85, 81,222,155,131,238, 93,153,181,101,204, 7, 94,105,161, +146, 77, 34,203,115, 12,183,183, 58,160,237,206,228,221,118,237,185,246,141,155, 19,204,101, 77, 51,204,207,165,164,178,149,141, + 6,148, 79, 90,241, 39,133, 59,172,159,114,111,187,172,235,243, 29,149,117,237,117, 93,189, 35, 79,145,178, 31,135, 61,186,126, +208,137,109,250,157, 67,111,166,167,228,246,231,111,237,123, 46,104, 92, 32,248,209, 68,211,205, 16, 36, 52,157, 16,100, 0,201, +197,185,173, 98,219,189,123,187,105,157, 83,117,199, 26, 79, 17, 20,240,152,174, 56, 95, 67, 46,159,159,141,109, 62,248,197,223, +123, 63,116,207,198, 36, 3,137,146,146, 68,214,212,140,177, 53,212,219,219,122,219,205,150,209, 55,179,143, 19, 11, 6, 26,207, +110, 58,169,211,130, 40, 59, 62,126,217,221,183, 99, 30, 14,205,228,242, 49,162,108,132,152,204,207,201,150, 59, 91,135,251, 74, +156,221,239,132,251,217,216, 31,109, 45,171, 47,200,180,140,224,169,188,157, 29, 69, 74,242,241,181,103,127, 11,127,230, 12,159, +253, 27,255, 0,214,195, 83,127,205,185,255, 0,230,239,186,188,182, 39, 71,239, 47, 45,212,232,253,166,158,191, 79, 86,187,252, + 86,241,244,214, 45,107, 89,205,172,219,241,114,110,180,173, 83, 85,170,170,232,148, 26,124,190,192,237,140,183, 47,228,250, 12, +121,152, 29,144,126,205,202,254, 74, 28, 31,135, 93,175, 11,135, 56,242, 77,111, 9, 36, 98, 62,101,211, 65,239, 46,246,110,222, +153, 54,252, 24, 86,108,199, 65, 35,188,151,208,138,110, 7,186,164, 18,198,222,154,168,139,115,252, 79,202,199, 92,248, 49,151, +203,186,137, 16, 4,132, 18,164,106, 4, 35, 55, 80,220, 87, 79, 95, 52, 71,169,104,243,103, 63,241,240,204,250,116,249, 35,121, + 14, 62, 46, 12, 75,137,137, 18,193, 18,143,114, 56,212, 42,250,249, 86, 35,188,183, 77,139, 15,112,131, 31,117,218,124,252,189, + 5,116,151,170, 83, 74,180,142, 52,216,127, 70,133,219,255, 0,136, 57,121, 91,140, 91,110,247, 2, 35, 74,253, 21,158, 48, 80, +172,135,221, 11, 34, 49, 60,219,135,133,170,163,241, 44, 91,124,197,255, 0,209,167,253,108,213,205, 90,201,247, 38,211,234,158, +167, 71, 74,181,218,234,154,232,214,135,164,118,222,221,181, 99,109,208,230,109,120,131, 13,115,226,138,119,140, 51, 55,196,154, +212, 18,196,242,213, 87, 5,111, 94, 91,139,221,221,207,145,182,226, 97,118,230,218,237, 14, 22, 60, 80, 75,146, 34,105,152,188, +113,170,155, 91,220, 28, 71, 46, 38,155,181,126, 36,238,248,217,171,143,191, 70,178, 65,171, 68,204, 19,167, 44,124,109,123, 11, + 14, 30, 34,212,109,183, 54,109,183,205,133, 85, 85, 21, 73, 37,201,104,122, 67, 22, 66, 64,225,126, 6,139,230, 20, 85,103,115, +119, 30,221,219,152,105,147,145, 8,159, 38, 98, 70, 60, 32,216,185, 28,201, 60,108,163,196,214, 51, 7,185,187,251,124,234, 79, +178, 97, 68,176, 6,248,150, 52, 9,195,234,135,201,107, 19,233,181, 66,158,138,114, 73, 60, 20,159,101, 15, 94, 83,159,117, 90, +222,139, 86, 10, 63,196, 30,230,216,179,151, 19,185,112, 80,169,177,109, 40, 35,147, 79, 45,104, 84,152,216,127,165,235, 99,191, +247, 36,152,157,175, 54,253,180,200,146,251,177, 62, 59, 56, 37, 72,146, 68, 67,117,184, 60,152,252,180, 4,195, 6,107,241,208, +212,169,135,145,123,178,216, 14,119, 53,231,184,191,138,123,144,192,200,108,184,163,155, 61,157, 87, 18, 52, 86, 84, 0,131,169, +228,247,141,248,218,192, 84,254,208,238,126,229,221,247,150,196,221,198,140,119,133,228, 69, 48,244,248,169, 91,105, 36, 92,243, +168, 83,118,177, 11,222,215, 32,115,166,194,161,129, 4,120,212,129,193, 79,205, 65,199,224, 73, 30, 6,132, 14,163, 72,165,181, +112,244,210,131,224,106,129,182,227, 75,106,227,225, 92, 61, 84, 4,159,236, 63,224,255, 0,219, 87, 87,127, 99,127,247, 63,246, +213,212, 1,216,240, 91,126,162,126,232,166, 53,248, 27, 82,146,214, 75,243,208,151,253,145, 72,120,248, 80, 1,150,247,229,198, +212,128,124,158,154, 89, 73,214, 7,160, 80,213,154,230,252,168, 2, 94,254, 21,199,135,133, 52, 31, 77, 41, 60, 40, 14,231,196, +210, 19,122,224,199, 81, 4, 88, 82, 49,183, 42, 2, 54, 75,130,170, 61,119, 31, 37, 8,176, 2,157,148,110,234,190, 0, 94,254, +223,254,202, 15,174,163, 41,196,220, 87,113,244, 82,168,225,122, 95, 10, 1, 3,113,167, 22, 39,128,161,131,204,211,129, 0, 80, + 28, 5,233, 66,138,229, 34,150,252,104, 5, 68, 5,192,240,191, 16,125, 20,220,157,175, 11, 35,222,120,128,254,114,240, 63,146, +137, 25, 26,193, 38,214,227, 69, 12,182,231,250, 43, 23,165, 46,187,111, 85,101,209,169, 53, 75,222,143,186,150,117,125, 83,130, +142, 94,223,135, 94,152,166,101,191,131, 40,111,203,238,210,142,218, 91,219,205, 31,216,255, 0,241, 85,211, 1,173,120,252,130, +137,170,255, 0, 9,226, 43,200,253,183,102,220,250, 75,225,107, 47,196,244,175,112,221,165, 30,171,249, 85,254, 5,108, 29,189, +131, 29,139,234,149,191,156,108, 62, 97, 83, 4, 9, 24, 9, 31,186,163,192, 90,194,164,107,241,231, 76, 33,124,121,215,163, 22, + 12, 88,148, 99,165,107,228,181,249,156, 50,102,203,145,206, 75,187,121,189, 62, 64,250,108,205,160,185,176, 30,170,227, 19,143, +174, 72,246, 10,122, 31,120,211,197,129,244,138,234,115, 43,114, 56, 74, 81,141,237,110, 63, 37,232, 23,210,120,114,241, 52,108, +150,213, 51,176,229,123,113,245,112,160,131,126, 85,160, 41,177,227,207,213, 74, 13,197,143, 3, 76, 38,198,151,219, 64,119, 1, +195,159,164,154, 32,231,106, 8, 32,155, 15, 26, 58,142, 55,163, 2,170,220,138,145,106, 26, 14, 34,141, 80,135,138,119,222,145, +221,217,250,175,166,240,106,183, 59,116, 35,229, 94,195,141,229, 31, 10, 3,131,164,226,116,215,161,163,225,209,111,118,223, 37, +120,239,126,255, 0,205,155,135,252, 31,250,136,235, 65,149,216,189,207,183,179,195,178,110,108,112, 88,146,177, 9,164,132,216, +248, 58,175,184,125,181, 65, 75,248,130,113, 15,112,183,150,211,172, 66,131, 39, 79,251, 91,183, 63, 94,141, 53, 55,190, 22,100, +216,187, 89,114, 47,213, 24,207,174,252,239,163, 31,129,191,143,166,172,182, 31,195,105, 23, 37, 50,247,217,146, 68, 82, 28, 99, + 68, 75,107, 55,191,218, 59, 1,195,210, 7, 63, 77,106,187,171,182, 98,238, 76, 20,131,169,209,200,128,151,199,146,215, 81,113, +102, 86, 30,131, 64, 67,236, 69,137,251, 79, 9,131, 18,203,214, 86, 0,242, 61,103, 54, 63, 33,172,119,226,116,152,231,123,199, +134, 22,187,195,142,162, 81,123,217,153,153,128, 62,187, 88,209, 49,187, 19,188,176, 93,162,196,205, 76,104,156,128,239, 14, 68, +136,173,225,114, 17, 65, 63, 53, 73,206,252, 47,220,157, 98,124, 92,216,166,157,181, 54, 84,185, 5,214,236, 79, 13, 1, 82, 66, +125,164,208, 11,221, 11, 24,252, 60,216,138,168, 14, 95, 30,237,226,126,194, 90,176,252, 46,108, 47,186,243, 21, 2,156,222,189, +230,189,139,116,244,142,159,245,111,171,229,189, 78,222,123, 83,113,220,123, 87,109,216,224,150, 5,201,195,104,154, 87,118,113, + 25, 9, 27,198,116,144,133,185,183,136,170, 24,191, 13,247,172, 76, 84,200,195,207, 72, 55, 68,102, 7,165, 36,138,133, 13,180, +233,144, 42,178,183, 63, 11, 80, 23,255, 0,136,231, 13,123,105,214,125, 61,118,150, 63, 43,127,139, 88,111,123, 79,245, 53, 86, + 83,178,122,223,229,238,234,255, 0, 97,228,218,215,229,175,165, 55, 47,147,159,201, 79,255, 0,233,247,116,238, 57, 8,219,182, +106,122, 12,210,202,243,184, 31,205, 7,253, 97, 91,172,126,217,199,219,187,115, 51, 99,219,136,234,100,193, 44,102,121,120,107, +150, 84, 41,173,202,131, 97,199,192,112, 20, 6, 7,240,183,254, 96,201,255, 0,209,191,253,108, 53, 91,255, 0,253, 3,255, 0, +243, 63,252, 85,109,123, 51,178,247, 78,220,221, 38,205,206,155, 30, 72,164,199,104, 64,133,157,155, 83, 60,111,115,174, 52, 22, +178, 84, 79,242, 14,240,123,163,239,190,190, 55,150,243,254,115, 70,185, 58,157, 62,183, 90,214,233,219, 85,189,116, 1,251,223, +182,176,183,156,209,151, 6,231,141,139,157, 26, 8,230,199,201,145, 80, 48, 30,242,159, 22, 83,102,244, 85, 84, 91, 63,226, 86, +221,142,137,129,146,211, 99,162,142,152,142,104,221, 66,248,105, 19, 91,133,185, 90,180, 61,221,216,171,191,206, 55, 28, 41,215, + 31, 55, 72, 73, 22, 64, 76,114, 5,224,164,149,185, 82, 7, 14, 70,169,177,187,127,241, 35, 2, 5,195,196,207, 69,199, 64, 21, + 0,148, 48, 10, 57, 5,214,154,128, 20, 5,110, 23,125,111, 59,118,225,229,119,236,120,166, 10,250, 50,117, 68,177,204,134,252, + 88,116,194,139,142,124,184,211,127, 19,191,253,247, 23,255, 0, 69, 31,253,108,213,103,183,126, 29,103, 73,157,247,135,112,102, + 36,190,255, 0, 82, 72,227, 45, 35,200,223, 21,157,220, 45,175,227,206,172, 59,191,178,247, 78,227,220, 96,206,194,155, 30, 56, +163,199, 72, 74,204,206,173,168, 59,191, 13, 17,184,183,191,233,161, 77, 63,107,193, 20, 29,185,181,164, 42, 21, 91, 22, 25, 8, + 30, 45, 34, 9, 28,252,172,198,188,167,241, 17, 85,123,175, 46,192, 13, 73, 9, 54,241, 61, 53,175, 97,218,113,164,193,218,176, +112,102, 42,210,227, 99,197, 11,178,220,169,104,209, 80,149,184, 6,220, 43, 15,221, 93,137,187,239,219,212,219,150, 36,248,201, + 12,139, 26,133,149,164, 13,116, 80,166,225, 99, 97,225,233,161, 10, 95,196,193, 40,220, 54,194,223,193,242, 75,163,209,171, 91, +107,252,154,106, 94,193,143,248,131, 38,211,140,219, 54,100, 9,128, 87,236, 22,208, 92, 11,241, 7, 84, 68,222,252,238,107,109, +191,246,198, 31,112,237,209, 97,229,183, 78,120, 0,232,100,160,185, 70,176, 13,192,218,234,109,196, 86, 51, 15,180, 59,227,102, +214,155, 46,227, 31, 65,155,225, 87, 32, 19,250,198, 57, 16,168, 62,202, 0, 59,231,111,119,190,234,176,166,249,151,136,226, 34, +198, 13,111, 12, 68, 94,218,172, 81, 16,158, 66,167,101, 96,102,109,159,134,121,184, 89,143, 27,180,114, 39, 77,162,113, 34,232, +108,136,155,226, 31,206, 38,135, 31,225,239,112,239, 57,139,149,220,187,138,149, 22, 7, 75, 25, 36,210, 56,233, 91,133, 68, 30, +207,154,181,219,215,110, 46, 71,107, 75,219,187, 72,142, 1,166, 36,131,168, 72, 80, 18, 84,149,139, 21, 86, 55, 58, 79,135, 58, + 3, 19,248, 85,131,141, 62,102,225,155, 42, 7,155, 21, 98, 88, 11, 11,233,234,151,212,195,215,238, 87,169,214, 71,177,251, 87, +112,237,159, 63,231,228,134, 79, 53,209,233,244, 25,218,221, 62,165,245,107, 68,253,113, 90,242, 61, 20, 7,120, 90,135, 0,224, +222,211, 69,183, 10, 20, 2,225,189,166,128, 50,220,120,210,248, 83, 47, 78, 7,194,128,239, 93, 45,248, 90,146,220,125,117,214, + 28,168, 9, 86,251, 15,248, 63,246,213,212,150,251, 11,127,185,255, 0,182,174,160, 12,231,225,254,130,126,232,164, 7,242,215, + 61,253,223,232, 39,238,138,101,254,122, 1,146,219, 80,246,113, 52,194, 7,167,157, 36,199,223, 30,202,102,174, 55,160, 9,123, + 10,237, 66,178, 57,127,137, 29,147,131,151, 62, 30, 94,241, 28, 89, 56,210, 60, 51,198, 82, 82, 86, 72,201, 71, 94, 8, 71, 2, + 41,119,175,196, 30,218,217, 54,140,125,246, 76,131,153,131,149, 33,139, 30, 76, 48, 37,212,224, 18, 87,226, 80, 8,177,230,104, + 13,101,205, 37,175,204,212, 76, 28,200,247, 12, 44,108,248, 67, 44, 89, 81, 36,232,174, 0, 96,178, 40,117, 13, 98, 69,236,125, + 53, 38,246,160, 33, 79,115, 51, 1,198,214, 3,230,166, 89,185, 83,201, 13, 33,111, 2,111, 85, 93,193,220, 59,119,108,237,175, +187,110,101,198, 50, 50,161,233, 46,182,212,223, 8, 2,226,161, 75, 64,167,149, 46,159, 10,137,180,110,152,251,198,219,139,186, +227, 43,164, 25,113,172,209, 44,128, 7, 10,194,227, 80, 82,194,255, 0, 45, 75,213, 64, 53, 82,252, 41,116, 11,210,171, 0, 77, + 71,200,220,182,252, 39, 84,204,203,135, 29,228, 35,166,179, 72,168, 90,255, 0,170, 24,139,208, 18,130,129,106, 91, 0, 41, 53, +131, 98, 56,131,196, 26,141,151,185,237,248,110,145,229,229, 67,142,207,240, 44,178, 42, 22,191, 15,116, 49, 23,160, 38, 34,130, +192, 31, 11,154,118,149,253, 81,243, 80, 60,214, 52, 8,102,200,149, 34,140, 91,237, 29,130,175, 30, 92, 91,133,116, 59,150,221, +146,230, 60,124,184,101,107, 95, 76,114, 43, 27, 14,102,192,212, 4,160,145,159,168, 9,174, 17, 39,163,157, 33,113,162,234,226, +145,100, 95, 3,199,198,128, 82,137,171,228,229, 92, 99, 78, 22,254, 83, 93,212, 3, 87,172,211,131, 41, 62,206, 32,208, 12, 17, +139,158, 99,229,164,104,255, 0,156,223, 57,167,146, 56,144, 64,166,177, 22, 36,159, 14, 94, 20, 5, 99, 31,125,141,184, 18, 77, +205, 52,144, 56,222,254,170,127, 76,145,239,154,239,113,121, 14, 53,160, 55,222, 35,221, 22,245,210,132, 31, 88,222,149,157,189, +130,152,196, 30, 60,205, 0,225,164, 48, 85, 28,234, 66,138,141, 29,203, 2,124, 42, 72, 53, 24, 8,190, 20,241, 76, 94,116,250, +164, 49,187,239,225,252, 59,222,235, 62,232,249,205, 11, 79,162,241,136,195, 1,161, 22, 62,122,135,234,214,186, 86,181,135,166, +136,105,174, 5,175, 64, 42,240, 81, 78, 7,141, 48,176, 22, 4,210,223,198,244, 7, 73,224, 61, 44, 40,130,130,238, 3, 45,207, +141,205, 47, 93, 60, 56,208, 4, 39,194,186,154, 92, 91,141, 53,165, 69, 62, 63, 61, 73, 16, 57,190, 52, 30,218,125, 71, 51, 13, + 64,143, 11,254, 90, 40,122, 72,128,156,233, 64,160,153, 84, 11,216, 80,219, 36, 1,202,168,130, 93,141,185, 83, 73,183, 62, 20, + 8,242, 75,181,173, 97,233,162, 23,176,189, 70,209, 97,131,146, 62, 44,247,246, 81,146,193, 84, 95,194,129, 52,224, 13, 35,141, +249,211, 60,211, 0, 5,185, 81, 2, 95, 1, 92, 8,191,232,160,195, 43, 63, 19,202,139,126, 23, 28,234, 59, 36, 59, 88,242,104, +112,219, 73, 32,223,137,166, 73, 56, 81,111, 19, 66, 89,138,139, 45, 84,228,144, 76, 23,191, 35,249, 41, 88,130,106, 44, 89, 5, +136, 13, 71, 6,245, 64,245,183,167,242, 82, 30,124, 43,133,113,160, 23,194,133, 3, 11, 55, 11,113,163,120, 94,131,143,196, 48, +245,208, 5, 23,165,183,166,187,145,174, 54, 2,230,132, 20,138,224,104,125, 85,181,175,202,187,170,180, 41, 54,255, 0, 97,203, +251, 31,251,106,234,103, 84,116, 47,254,230,255, 0,251,235, 87, 80, 8,242,201,100,227,253,156,100,240, 30, 40,180,206,163,250, +107,156,127, 15,251,184,255, 0,113,105,148, 40, 44,137, 36,214, 0,110, 22,244, 10, 16,150, 75, 30, 55, 62,177, 93,146, 78,177, +236,252,230,129,198,168, 62,106,205,200,154, 46,236,239, 97, 22,212, 55, 83, 63,222,113, 61,215, 87,149, 86,201,185,204, 3, 75, +113,138,220, 15, 11, 95,157, 38,108,187,127,255, 0, 76,112,113,176,231,121,102, 93,217,229,204, 73, 23, 73,142, 71,199, 42, 21, + 56,181,211, 74, 11, 31, 77,235,109,147,248,107,222,209,239,187,238,233,180,110, 24, 24,241,111, 47,149, 27,235,105, 12,158, 91, + 42, 94,169, 66, 58, 12, 21,172, 7, 35,236, 52,185, 63,131,155,138,118,196, 91, 78, 6,110, 60,155,131,229,140,188,185,166, 47, + 28, 90, 86, 54,141, 99,143, 66, 72,198,218,175,114, 5, 64, 7,185,123,239,117,192,126,221,237,188, 61,211,238, 76, 33,183, 98, +203,155,184,172, 70,103, 5,226,247, 70,149, 12,218, 70,145,240,250,106,157,255, 0, 20,123,198,110,207, 89, 23,112, 49,231, 99, +230,174, 60,153, 75, 28, 90,228,134, 72,154, 68, 12, 74, 27, 50,180,103,136,177, 53,177,238, 47,195,141,235, 38,125,155,121,216, +114,224,135,120,219, 49, 96,198,153, 38,185,137,204, 11,167, 90, 18,141,126,101,108,203, 98, 40, 91,247, 98,119,175,115,108, 17, +225,238, 89, 59,114,231,166, 96,200, 2, 32,209, 66,144,136,140,122, 47, 28, 36,151,214,196,241, 31, 45, 1, 77,219,221,225,221, +216, 93,235,129,182,239,219,136,202,195,201,197, 73,101,137, 20,104, 17,190, 47,154, 70, 30,234,182,181,176,185,241,227, 89,174, +226,238,110,234,238,237,147,112,221,178,242,146, 45,150, 44,200,160,143,110, 85, 81,102,112,242, 39,188, 23, 81,208, 23,137, 39, +141,235,208,163,252, 55,222, 63,205,251,118,249, 60,216,173,129,141,139, 6, 46, 68, 65,228,234,183, 79, 23,202,190,129,210,211, +107,242,187,114,172,255, 0,255, 0, 72,123,194, 60, 28,237,155, 27,114,195, 27,108,185, 9,145, 18, 72, 94,242, 52,122,145, 25, +200,137,138, 29, 15,196, 11,241,249,232, 8,217,189,235,184,224, 97,118,191,110, 98,110,159,114, 97,125,221,143, 54,110,226,177, + 25,156, 23, 82, 84,104, 80,205,164,105, 31, 15,167,213, 81, 91,241, 51,187, 37,236,225, 42,231,152,243,160,205, 92,121, 50,150, + 56,181, 73, 12,145, 59,168,107,161,179, 43, 70,125,225, 99, 90,189,211,240,203,125, 9,176,238,123, 38,102, 60, 59,214,211,139, + 14, 44,235, 38,163, 12,134, 16,108,232, 90, 54,191, 6, 42, 67, 45,136,162,239,253,139,222,221,205,176, 69,133,185,228,237,203, +158,185,131, 33, 68, 65,226,133, 33, 17, 24,244, 94, 56, 73, 47,173,137,226, 62, 90,128,208,246, 7,249,187, 41,114,247, 94,230, +147,252, 54,116,120,210,237,112, 43, 43, 8,227, 42,229,181, 5,227,168,174,130,111, 89,159,197, 14,204,237,188, 77,187,119,238, +172,236,137,134,231,148,241,140, 69, 46, 2,117, 44,168,177, 34,105,227,117, 82, 77,205,122,110,211,143, 38, 6,215,131,131, 49, + 13, 38, 54, 60, 80,200,201,114,165,163, 69, 66, 84,144, 13,174, 61, 21,231, 95,136, 29,141,222, 93,227,187, 71, 52, 25, 88, 48, +237,152,130,216, 88,242,201, 45,238,108, 94, 73, 20, 64,203,169,136,229,196, 91,229,160, 52, 63,133,203,185, 47,100,109,191,121, + 22, 46, 67,156,113, 37,245, 8, 11,158,149,239,225,167,225,254,109,171, 45,248,161,217,157,183,139,183,110,221,215,157,145, 48, +221, 50,158, 49,136,165,192, 78,165,149, 22, 36, 77, 60,110,170, 73,185,171,105,123,127,241, 41,187,106, 12, 8,183,188,116,222, + 35,202,105, 36,202, 86,101,140,227,116,244,164, 75,167, 31,193,184,219, 71,203, 85,253,245,216,157,237,222, 27,132, 18, 38,102, + 4,120, 24,104, 23, 22, 9, 36,152,146,246, 29, 73,100, 81,142,203,169,136,249,190, 90, 2, 11,237,253,193,159,248, 39,133,130, + 49,103,204,205,201,157, 6, 52, 72,141, 36,190, 88, 74,210, 71,112, 1, 33, 66,167, 2,120,105,181,119,224,254, 71,107,227,239, +175,183, 29,175, 39,110,238, 88,241, 91, 30,115,145, 33,145, 36, 40, 80,207,104,217, 80,196,250,146,250,108,108, 46, 47, 91, 8, + 54, 95,196,136, 59, 78, 28, 72, 55,188, 63,243, 4, 25,157,110,185,254, 3, 98,116,140, 99, 28,131, 0,227,169,175,240,120,115, +168, 61,141,248,125,187,109,125,195,149,221,253,213,157, 6, 86,235, 56,125, 9, 1,247, 67, 75,193,221,142,152,197,244,251,160, + 40,181, 1,233, 0, 2,250,145, 5,137,177,191,160, 83,132, 74, 79, 21, 28,104, 64,169, 7,237, 2,130,127, 39,162,139,212,142, +252,197,189,162,160, 16,198,151,211,160, 91,211, 74, 98,140, 46,173, 3,230,164, 50,169, 58, 65, 95, 93,207,135,170,185,229, 64, +190,235, 3,113,202,226,128,106,196,133, 67, 88,122,248, 83, 94, 36, 17,179,105, 0,128,127, 37, 59,168,128, 11,176,246, 94,133, + 59,163, 68, 64, 96,111,110, 31, 45, 80, 66, 99,115,126,116,132,223,219,234,174, 60, 15,166,144,240,227,252,149, 65,215,181, 42, + 33,115,194,154, 1,118, 0, 11,147,200, 84,228,141, 99, 26, 71,202,104, 1,232,208,163,215,206,184, 83,229, 60, 20,124,180,209, + 80, 11,114, 57, 11,215, 6,145,185, 45, 53,216,175, 47, 69, 18, 54,109, 4,213, 32,168, 90,246, 97,106, 89, 13,150,134,146,113, +187,115,166,188,154,137, 3,151,133, 1,194,236,218,168,172, 66,169, 39,149, 48,123,170, 7,141, 53,216, 17, 99,198,177,197,154, +224, 3, 83, 49, 38,137, 18,146, 75, 26,229, 0,211,238, 1,225,202,180,248, 4, 61,136, 84, 36,138,139,168,155,154, 44,132, 48, + 3,143,174,134, 20, 84, 74, 3, 31, 18,234, 55,110, 66,164,167, 43,208,151, 74,128, 45, 92,204, 2,112,190,163,244, 84,114,217, + 65, 75, 33, 47,195,144,166,146,199,135,166,152,104,209, 42,143,120,252,149,174, 8,129, 99, 93, 10, 41,238,218, 22,230,212, 61, + 67,244, 80,166,117,102,210, 57, 15,229,172, 68,178,140,190,162, 73,165, 85,212,193,105,130,164,192,160, 2,196,113, 39,133,109, +184, 68, 12,160, 40, 1,124, 40,172,218, 22,228,240, 2,131,117,244,112,227, 67,200,145, 79,184,191, 41,174,105, 75, 40, 23, 98, +238, 88,215,114, 3,141, 52,250,133, 26, 20, 82, 67, 48,224, 43,167, 4,100, 36, 17, 88, 92,243, 52,101, 54, 54,166,234, 95, 14, + 3,198,185,138, 0, 88,243, 2,176,155,159, 51, 77,104, 29, 72,225, 78,107, 90,228,242,168,169,144,128, 27,241, 62,138, 27,204, +210, 30, 60, 23,209, 93, 12, 64,117,201, 13,117, 97, 97,224,106,195, 27,109,251, 21,151,171,252, 64, 30,218,121, 92, 95,211, 84, +165,198,146,150,248,136,227, 90,200, 20,199, 4, 81, 55, 52, 69, 83,110, 92, 5,169, 93, 67,209, 16, 91, 6,220,122,159,244,127, + 77, 87,205,171,166,214,241,225, 87,179,113, 28, 43, 59, 46, 66, 94, 72,126,178,177, 95,152,218,171, 81, 4, 92, 16,134, 21, 17, +235,235, 49, 58,110,170, 57,222,153,246, 58, 46, 36,144,191,138,240,250, 41, 4,141, 27, 44,134, 63,117, 70,155,158, 70,153, 19, + 22,185,183, 18,111, 89,147, 80, 88,244,215,200,117, 53,182,190,133,173,234,235,234,189,117, 45,207,146,211,127,236, 57,255, 0, +199,181,117, 89, 16, 58, 65,252, 63,238,227,253,197,161,211,228,254,207,251,184,255, 0,113,105,148, 4, 92,155,107, 30,207,206, +104, 7,149, 31, 39,248,131,217,249,205, 7,149, 80,100, 71,127,109,202,136,210, 64,234, 91, 7, 43,112,126, 32,133,242,141, 34, + 60, 36,254,177, 48,189,189,149,117, 30,255, 0,183, 72,254, 84,202, 23, 57, 98,234,201,137,198,234,194, 49, 51, 71,170,193, 75, +133,107,149,231,110, 54,181, 99,242,255, 0, 15,183, 9,229,205,100,200,129, 83, 35,113, 19, 68,164,191,187,129, 33,201,108,140, +118, 1, 62, 34,217,146, 21, 81,195,151, 26,179, 94,212,204, 29,195,145,184, 16,143,142,243,207,151, 12,207,145,145,117,105,241, +188,175, 76, 98, 3,208, 86, 4,181,228,226, 74,240,183,160, 11,140, 46,233,218, 50, 98,219,140,147,174, 62, 70,229,143, 6, 84, + 56,239,123,170,228, 46,168,213,216, 13, 32,183, 16,183, 62,241, 28, 40,144,247, 71,111,207,143, 38, 92, 91,132,109, 4, 77, 26, + 60,158,240, 23,156,233,134,215, 23, 34, 67,240,145,192,248, 86,119, 15,181, 55,140, 56, 96,192,255, 0, 9, 46, 60,248, 91,118, + 46,116,238, 89,154, 38,193,141,163,144,192,140,158,249,107,142,155, 18,186, 79, 27, 87, 67,218,123,188,131, 26, 76,150,199,138, + 92, 65,180, 99,170,198,238,200,240,237,121, 7, 34, 73, 77,227, 4, 60,129,136, 84,240,241,106, 3, 67,141,221, 27, 6, 87, 80, +193,158,140,176,194,249, 50,150, 12,129, 98,140,233,145,201,117, 95,128,240, 97,205,124,106,110, 46,231,183,230, 98, 73,157,141, + 48,124,120,181, 9, 90,204, 10, 20, 23,101,100, 96, 24, 16, 56,216,138,199, 73,217, 59,148,184,178, 99,153,224, 82,248,155,166, + 58,176,105, 63,137,155,158,153,208,114, 80,116,133, 75, 57, 28, 65,229,122,209,118,206,213, 62,213,141,149,230, 35, 88,101,203, +201,108,150,140,100, 79,150,194,233, 28, 67,169, 62, 81, 46,237,104,199,160,120,122,234, 48, 15,108,239, 45,131,116,135,111,145, +114, 4, 19,110, 41, 28,144,227,202, 8,113,213, 98,136,174, 64, 42, 11, 50,149, 94, 62,241,229,122, 94,228,238,237,191,182,228, + 16,100,198,242,204,216,153, 25,170,168, 56, 21,198,211,117,185,241,109, 70,222,206, 62, 21,157,219, 59, 51,122,196,196,199,219, +167,108, 99, 11,141,181, 50,167,142, 87, 44,131,107,159,172,166, 53,104,151, 87, 89, 66,142, 36,105, 55,248,170,215,189,123,123, +114,238, 14,159,221,207, 2,255, 0,130,207,194,147,204, 59,165,188,216,135, 67,174,136,228,190,150,135,136,225,192,252,149, 1, +108,157,197,182,100, 73,142, 49, 39,142, 72,165,158, 92,105,100,102, 49,148,120, 97,108,150, 26, 93, 70,175,117, 65,240,247, 78, +174, 85, 35,111,222,118,189,210, 41,103,192,201, 89,163,134,198, 83,102, 82,161,151, 90,181,156, 3,165,151,138,158, 68,114,172, +252,157,177,185, 54,229, 38,114, 62, 59, 35,110, 89, 25,234,146,107, 96, 99,155,108,251,189, 85,212, 40,185,234,113, 97,127,135, +198,252, 40,221,183,178,110, 91,110, 30,126, 62, 80,142, 36,157, 82, 60, 92,100,154, 76,133,136, 44,101, 24, 9,166, 69,147,167, +171,224, 67,125, 43,243, 80, 22, 43,221, 93,186,240, 67, 58,231,198, 98,200, 36, 67, 32, 13,165,128,209,169,175,110, 8, 58,139, +118, 62,232, 38,215,174, 78,229,219, 34,243,231, 49,252,178,225,102, 28, 11,181,216,201, 32,130, 60,162, 81, 80, 22,176, 73, 56, +240,225, 98,121, 86,103, 63,178,115,242, 54,237,159, 8,244,167, 56,219, 82,109, 57,137,230,114,113,226, 4, 8,181, 75,254, 27, + 67, 78,158,227,125,155,218,252, 42, 70,229,218, 91,148,243,101,102, 68,209,202,100,220,165,205,142, 1,149, 62, 33,104,166,194, +139, 10,207, 62, 48, 14,172,175, 30,162,162,225,151,133,252, 40, 13, 72,223,118, 84,202,199,193, 57,145,249,172,149, 70,137, 84, +150, 4, 74, 11, 69,119, 80, 84,117, 2,157, 55, 62,247,133, 71, 61,209,219,250,178, 45,155, 31,248,107, 44,182, 13,196,153, 58, + 63,103,238,253,167,218,123,158,229,253,238, 28,235, 61, 39,105,238,235,153,181,136, 95, 31,200,237,171,182,244,144, 79, 52, 74, +167, 10,235, 50,244,130, 73,212, 44,182,208,210, 49, 34,214,225,123,212,105,123, 55,120,153,167,107,227, 65, 26,203, 22, 68,120, +152,249, 83,162, 75, 34,100,249,137, 26, 25, 52,245,112,196,136,126, 24,216,141,124,125,116, 6,229, 55, 29,189,182,255, 0,189, + 70, 68,127,119,172,109, 51,101, 19,238, 42, 37,245,150, 39,150,155, 27,250, 42,155, 51,188,182,152, 83,111,242,108, 51, 27,112, +204, 24, 49, 1,170, 62,155,132, 50, 72,210, 6, 77, 67, 74,219,221, 34,230,227,195,141, 53, 59,117,191,201,179,118,222,184,160, +200,153, 39, 35, 76,146,205, 18,203, 52,175,144, 53, 73, 57, 50,184,212,222,243, 30, 39,137,176,229, 81,211, 96,220, 39,207,139, +118,201,104, 33,200,147,120, 77,207, 35, 25, 36,105, 17, 34,139, 1,182,245, 68,126,154,106,114,108,198,224, 15,155,136, 19,119, + 94,245,218,182,141,205,246,156,148,115, 60, 67, 12,200,225,108,161,115, 39,242,192,159,232,124, 71,212,120,113,169,239,220,253, +187,208,198,203, 25,136,144,230, 23,242,238, 67, 11,136,216, 69, 33, 96, 69,208, 43,251,172, 90,214, 60, 13, 83,239,221,189,159, +185,119, 4, 91,158, 44,152,227, 22,219,103, 88, 72,238,178, 41,219,243,155, 53,180,170,198,234,218,210, 66, 5,216,113, 30,187, +138,108,206,197,207,154, 8, 96,102,135, 32, 58,238, 16, 79, 31,154,202,199,141, 83, 55, 53,179, 35,145,134, 54,134,152, 8,219, + 75, 70,214, 26,173,199,198,128,216,111, 91,195,109,146, 96, 99, 67,136,114,178,119, 25, 94, 8, 81, 93, 99, 0,199, 12,153, 12, + 89,159,135,195, 25,170,140,126,243,219,115,224,150,103,141,241, 35,199,135, 22,121, 26, 82, 15, 28,151,158, 21,137, 4,122,181, + 29,112, 16, 52,223, 85,197,170, 79,117,236,210,111,111,181, 75, 14, 38, 30,225, 30, 6, 68,147,100, 96,238, 12,201, 12,170,240, + 75, 2,241, 16,100,139,171, 72, 27,138,120, 86,105,123, 11,115,143, 18,104,206, 68,114,145,228, 30, 8, 99,154,104, 63,240,153, + 57, 83,182, 58,204,171,212,141, 86, 60,133,142, 39, 94, 62,239, 16, 40, 13, 4,253,207,176,227, 65, 14, 68,249,177,172, 83,163, + 75, 19,123,198,232,140, 17,219,221, 4,128,172,192, 53,249,120,208,231,238, 45,190, 61,227, 27,100,141,250,185, 83,202,240,200, +171,202, 34,152,239,151,239,146, 45,240, 40,224, 15, 11,139,213, 52,253,139,159, 38,218,112,225,108,120, 93,246,189,199, 8,169, +150,121, 20,100,103,100,199,148,167,169, 42,188,142,163, 75,106, 99,196,159,171,232,153, 47,106,110, 82,111, 38, 69,108,117,219, + 78,110, 78,113,159, 91,245,255, 0,197, 96,190, 23, 76, 69,163, 77,209,219, 85,245,241, 30,186,160,184,199,238, 62,222, 24,146, +103, 46,124, 93, 8,217, 18, 73,141,192, 6, 83,104,173,112, 9, 87,250,172, 56, 55,133, 31,112,222, 27, 26, 44, 73, 48,177, 37, +206,124,211,246, 41, 29,163, 80,154, 12,165,229,121,116,170, 13, 34,220,120,220,218,178,187,103,101,238, 56,248,177,197, 40,134, + 57,210,125,165,157,206, 86, 78, 81,146, 45,182,110,171,182,172,128,116,106,187,116,227, 85, 0,120,159, 70,135,186, 48, 55,125, +203, 18, 44, 61,179,164, 96,146, 79,254, 99, 20,179,201,140,210,193,164,222, 20,154, 24,167,101,214,214,212, 64,190,155,128,120, +212, 3,155,184, 34,159,102,195,222,112,113,166,202, 92,229,133,177,177,213, 64,144,156,130,186,117,146,116,160, 91,221,152,155, + 1,233,167,224,111,184,121, 91, 92,219,180,255, 0,224,225,198,105,162,202, 19, 17,246,111,143, 35, 67, 40,212,164,171, 13, 72, +108, 71, 58,135,184,226,247, 36,155, 99,225,109,113,225,224, 73,210,199,142, 17, 28,210, 1, 26,134, 35, 34, 56,223,203,251,182, +140, 5,137,186,126,187, 11, 10,112,218, 39,255, 0, 43,203,179,199,129,135, 11,244,204, 73,132,210,203, 62, 49, 91,220,235,155, +167, 12,165,156, 92,150,211,125, 92,120,208, 7,110,230,216, 52, 67, 43,103, 34,172,197,209, 67, 6, 86, 12,133, 85,250,138,202, + 26, 61, 37,214,229,192,181,199,166,159, 47,113,237,144,206,216, 49, 79, 28,185,113,207, 14, 60,240,150, 41,160,207, 36,113,139, +182,146, 53,125,168, 42,191, 90,177,249, 61,141,188,100,170,140,150,142,113, 52,121, 24,239, 4,185,185, 75,210,138,105, 35,116, +235, 77, 0,137,242,244,170, 48,101,146,215,225,199,133,234,254,110,218,206,127, 61,166, 72, 71,153,223, 48,247,100,185,110, 16, + 99,249, 77,104,222,231,198,124,187, 88,114,229,198,169, 11, 47,243, 22,197,124,192,217,145,223, 8, 51,100, 18, 72, 10,177,182, +135, 32,145,102,210,195, 73,211,123, 30, 28,232,219,126,126, 38,229, 9,202,194,144, 75, 16, 98,135,129, 82,174,191, 18,186,184, + 12,164,122, 8,172,110, 63,102,231,227,156,244,104,113,178, 75,195,147,143,142,217, 57, 57, 82,164,201,147,146, 50,116,180, 55, + 9,142, 52,168, 7,166, 9,213,239,123,111,251,127, 3,121,218,177,188,190,113,137,224,145,166,151,140,175, 52,232, 89,147,163, + 27, 74,241,167, 86,201,171, 83,183,189,123, 14, 35,141, 71,208,168,184,146, 70,191, 10, 17,145,253, 52,101, 94, 28,104,110,151, +114, 47, 96, 40, 81,162, 87, 30, 53,221, 87,244,210,244,199,235, 10, 94,136,253,113, 84,131, 58,143,233,165, 18, 56,241,167,244, + 1, 36,106, 30,170,105,136,143, 17,243,208, 29,214,147,211, 92, 37,114,108, 79, 10,111, 77,169, 10,145,204, 80, 4,118, 11,109, + 47,170,252,248, 90,147,172,252,189, 20,145,128,206, 1,228,106, 72,199,140,208, 17,186,175, 73,173,141, 75,242,169,111, 93,119, +148, 95, 77, 1, 23, 91, 83,196,242, 90,194,164,156, 52, 28,141, 39,148, 30,154,128, 7, 94, 79, 85, 55,168,231,152, 20, 97, 8, + 42, 71,162,230,245,221, 1,107,250, 41, 0, 30,182,167,137,156, 13, 32, 10, 89, 49,201,226,166,222, 21, 29,195,163,105,110,116, +128, 79, 86,212, 5,255, 0,211,213, 64,150, 66, 78,145,200, 80,210, 66,139, 98,126, 46, 85,213, 21,117, 44,135,199, 68,149,172, +236, 87,209,106,150, 48, 33, 60,122,205,243, 10,174, 70, 42,194,198,172,161,125, 75,235,173, 25,101, 76,219,207,105, 99, 79, 38, + 62, 71,112,224,195, 60, 76, 99,146, 41, 50, 96, 70, 87, 83,102, 87, 86,112, 84,131,206,245,118,123,215,178,236, 63,255, 0, 99, +218,255, 0,254,119, 31,254,242,190,126,198,237,253,175, 59,122,239,173,247, 47,105,155,184,242,182,221,205,227,199,216,241,228, +146, 54,101,159, 34, 80,249, 15,208,188,165, 83, 77,189,223,150,179,189,215,218,155, 70,219,223, 56,155, 22, 43, 62, 22, 22,106, +226, 75, 54, 52,206, 30, 92, 54,201, 85,105, 49,157,252, 89, 47,204,212,118, 85,171,179,224,148,191,129, 85, 93,154,170,226,220, + 47,137,244,243,247,175,102,223,135,113,109,150,255, 0,214,227,255, 0,222, 85, 6, 95,113,246,129,150, 89, 87,184,182,226, 89, +139, 0, 50,224, 60,205,255, 0, 94,190,124,238, 45,143,110,135,104,203,205,139,107,155,102,155, 7, 45,113, 97, 19, 72,206, 50, +145,181, 93,128,147,235, 46,155,146,188, 43, 95,218,221,139,219,217,155, 95,110,193, 62,197,149,187,127,152, 98,150, 76,238,225, +130,119, 72,246,230, 70,100,208, 17, 1,143,236,244,221,250,156,252, 61, 21,156, 89,235,154,157,213, 77, 67,141, 99,240,148,116, +203,138,216,172,170,218,114,167, 73,252, 97,158,193,182,238,123,102,241, 9, 59,118,108, 57,145, 67,101,144, 99,202,146,217,143, + 17,168,198,205,106,152,177,128,186,163,184, 39,192,215,147,126, 8,121,124, 60,110,224,135,174,143, 26,101,199, 28,115, 92, 0, +225, 85,198,161,127, 72,227, 94,186,172,178, 68, 25, 24, 48,113,117, 96,110, 8, 60,136, 34,180,115, 36, 95,252, 23,243,186, 63, +252, 69,117, 47, 76,249,109, 54, 23,232, 91,255, 0,127,122,234, 1, 92,112,143,251,184,255, 0,113,105,180,231,250,159,221,199, +251,139, 76,173, 2, 46, 79,198, 61,159,156,208, 13,239, 71,201, 30,248,246,126,115, 66,181, 1,230,178,247,142,253, 30, 6,118, +102, 60,169,144,240, 38,230,210,199,229,216, 38, 47,148,150, 72,241,216,202, 61,198,215,160, 2,167,137,240,228,107, 72, 59,207, + 1,183,247,216, 21, 3,206,175, 36, 8, 18, 84,105,154, 88,160,243, 77,254, 30,250,194,105, 5, 67,158, 5,133,189,117, 57,187, +107, 5,182, 28,174,222, 50, 77,229, 50,252,207, 82, 77, 75,212, 30,110, 89, 39,147, 73,211,167,131, 72,116,251,188,189, 52,159, +229,204,113,159,147,151,230,242, 86, 12,150,146, 89, 48,149,148, 69,214,154, 33,143, 36,151, 11,172,221, 7, 5, 45, 96,120,218, +128,168,143,190,241,219, 7, 51, 41,177, 66,201,135, 38, 52, 82, 40,158, 54,137, 60,215, 5,105,231, 75,172,125, 51,113, 39, 3, +164,143, 26,112,239,220, 5,207,194,192,158, 1, 12,217,126, 93, 90, 55,154, 62,160,124,183,104,162,233, 70, 13,229, 91,128, 89, +151,128, 82, 15,178, 70, 31,102,197,131,142,241, 99,110,121,137, 33, 76,120,196,160,194, 61,220, 64,201, 18,148, 88,130, 50,148, +125, 46,172, 8, 60,249,241,162, 97,118,118, 22,221, 46, 59, 97,101,229, 69, 20, 66, 30,180, 10,241,133,157,177,221,228,137,165, + 34, 48, 71,189, 33,186,161, 85, 60, 5,173, 64, 72,221,183,217, 54,252,216,176,113,112, 37,207,152,194,249,115,164, 68, 6, 72, + 99,116,140,148, 82, 62,209,201,126, 10, 61, 28,234,151,111,239,137, 34,197,201,125,223, 24,129, 4, 91,134, 84,121, 17,178,129, + 36,120, 89,167, 19,167,160,219, 73,247,144, 92,158, 60, 79, 10,189,221,187,126, 45,215, 34, 44,161,149, 62, 28,171, 19, 99, 76, +216,204,170,100,129,217, 36,104,201,101, 98,190,244, 98,204,150, 60,248,212, 79,242, 94,210,208,188, 45, 36,236,143, 6,110, 49, +247,214,225,115,242, 6,108,140, 8, 79,137, 36, 81,163,213,206,245, 24, 1,143,222,209,103, 99, 68,118,220, 65,155,155, 38, 84, +184, 98, 24, 39, 71,132,180, 48, 12,167,116,200, 80, 85,151,166,194,214, 31, 17,183,164,211,118, 46,236,125,211,121,204,217,222, + 22,243, 17,204,100, 16,176, 17,190, 54, 39,151,198,144, 25,193,185,214,101,152,160, 3,215,232,169,179,118,183, 90, 8,245,110, +121,126,126, 41,228,200, 93,194,241,117, 3, 75, 17,199,145, 21, 58,125, 37, 77, 7,128, 11,192,241,231, 93,133,217,219,110, 6, + 92,121,248,210, 78, 50,163,155,175,215,102, 86,118, 83,143, 30, 35, 67, 35, 50, 18,209,178,196,172,111,199, 87, 27,212, 5,110, +255, 0,220,251,214,221,190,182,217,137,140,141,142,163,107, 40,196,141, 78,115, 51, 27, 26, 69,226,120,106, 85,210, 61, 4, 95, +198,147, 39,241, 27,110,193,194,198,202,204,128, 66,210,140,151,158, 23,158, 53, 42, 49, 39, 56,146,172, 58,244,245,156,186,146, +170,163,136, 30, 21,115,185,118,198, 38,231,186, 71,186,205, 60,241,203, 24,197, 13, 20,101, 4,111,228,242, 60,228, 37,181,198, +205,193,201, 6,204, 46, 15,176,212,115,217,184,136,144,174, 54,102, 86, 49, 79, 50,178,188, 76,129,229,139, 47, 32,230, 75, 19, + 49,143,221, 2, 67,238,178, 89,128,225,127, 26, 3,187,175,119,201,218,229,218, 98,131, 35,202,197,153,145, 36, 89, 19,172, 13, +146,202,169,143, 44,203,166, 36, 4,155,180, 99,144,229, 84,221,189,220,251,182,237,184,227, 99,229,100,180, 72,248,216,115,175, +148,193,147, 37, 36, 57, 18, 78,133,166,146, 37,145,113,195, 44, 74,125,242, 52,220,254,169,182,199, 47,110,131, 51, 55, 3, 54, + 86,113, 38,221, 43,205, 0, 82, 2,150,146, 25, 49,136,123,130, 72,211, 41,229,110, 53, 87,182,118,132, 59, 94, 89,201,219,119, + 76,220, 93,106,137, 60, 75,229,157, 37, 84,150,105,213, 91,171,140,236, 5,231,113,238, 17,195,215,198,128,162,206,239,125,202, + 9, 59,145,161,104, 58, 24,248,217,114,236,163, 69,200,125,185,151, 31, 35, 89,191,189,170, 71,184,245, 81,187,131,184,187,147, +105,131,117,219,113,165,135, 39,115,197,151,109,242, 89, 38, 16,161,147,112,149,224,209, 36, 97,136, 44,173, 17,226, 45,192,138, +179,159,240,235,183,102,219,225,193, 13, 44, 45, 20,115,195, 46,100, 93, 21,200,157,114, 81,163,148,228, 73,210, 58,201,213,171, +151,196, 7,178,166,142,213,192,102,105, 50,243,114, 50,178,229,202,197,204,151, 50,102,136, 72,205,130,226, 88, 35,211, 12, 81, +198,177,130, 56,133, 64,120,158, 55,227, 64,101, 51,187,255, 0,115,151, 39,117,200,218,204, 71,110,199,217, 31, 63, 16,148,212, +124,210, 38, 36,247, 45,245,148, 38, 98,139,122,107,111,178,229, 73, 62, 20,249, 18,205,147,150, 81,155, 72,159, 10, 76, 25,125, +213, 13,165, 33,200, 72,153,175,126, 13,107, 95,133,248, 85, 34,126, 31,246,236, 24,147, 97, 69, 60,201, 20,248,217,152,110, 21, +227,191, 79, 54, 88,231,144,143,179,181,211,164,170,158,133, 28, 65,231, 87,240, 98, 52,120,115,226,229,238, 83,238, 61,112,202, +210,228, 12,116,117, 86, 93, 37, 87,202, 67, 2,252,224,154, 2,139, 27,191, 49,242,113,167,145,112, 73,201,131, 39, 11, 19,203, +197, 60, 82,141,121,238,177, 68,173, 34,251,170,232,196,135, 95,170, 71, 51, 80,119,110,254,203, 77,146,108,189,179, 3, 78,124, +120,153,249, 82,135,117,100,128,225, 78,112,216,241, 3,171,121, 71, 1,195,221, 31, 37, 88,225,246, 94,219,137, 10, 68,217,185, + 83,244,219, 1,212,183, 72, 11,237,143,212,198, 22,142, 21,225,192, 7,244,250,143, 26, 76,174,197,218,242,241, 91, 9, 51,114, +241,226,146, 60,200, 50, 26, 35, 25,121, 33,206,156,230, 75, 17, 47, 11,129,166, 83,238,144, 47,110, 28,104, 11,173,243,121,147, +107,108, 60,108, 92, 54,205,205,206,145,210, 8, 21,196, 98,209, 70,211,200,204,236, 26,222,234, 88, 11,113, 36,123,106,153,123, +214, 57,242,227,137,246,217,161,196,121, 78, 26,228, 76, 85, 92,101, 12, 95, 60,208,188, 63, 18,217, 84,173,255, 0, 88,122, 56, +213,190,245,181, 67,187,249,105, 23, 42,124, 44,172, 71,103,199,202,198, 85,214,189, 72,218, 9, 22,210,163,169, 12,142,124, 56, + 27, 17, 85, 71,180,112, 99,156, 75, 6, 68,237, 20,100,205, 14, 44,204, 26, 63, 53,229,188,151,153,102, 41,212, 44, 99,231,118, +181,201,107, 94,136, 17,112,251,226, 9,211, 21,167,219,223, 31,206, 13,190,104,238,234,246,199,220,217,226,130,102, 43,202,210, + 38,150, 95, 88,168,115,119,209,202,219, 51,242,240,240,101,134, 44, 92, 1,184, 62, 88,104,137, 72,229,235,244, 10, 35,143,125, +159,161,126, 86,227, 65, 61,143,155, 23,107,201,182,172,227, 43,118,201,193,194,219,140,210,201,166, 44,117,196, 26,149,160, 49, +196,172, 86, 57, 89,157,117, 13, 71,135, 30, 21,122,253,157,181, 62, 30,118, 14,185, 82, 28,252, 28,125,178, 80,140,163, 68, 56, +203, 34, 70, 98,186, 27, 53,165, 55,189,199, 46, 21, 65, 27, 47,187,218, 45,193,240,226,193,127, 46, 50,159,110, 76,210,235,111, + 50,152,237,150,195,165,241,105, 10,182,191,167,242,211, 69,223, 27,188,157,191, 30, 72,193, 95,188,146, 45,158,105, 88,186,244, +228,143,115,145, 99, 46,170, 45,164,146,172, 0,191, 11,131,233, 21, 59, 35,181, 51,114,123,144,101,137, 4, 91, 82,229, 28,246, + 69,154,250,164,108, 87,196,107, 64, 97,247, 92,150,185,110,169, 91, 14, 10, 9, 53, 56,118, 78,216, 48,159, 5, 50, 50, 81, 95, + 27,111,196, 18,134,143, 90,174,214,230, 76,105, 22,241,149,215,168,221,174,164, 31, 64,168, 4,238, 46,233, 27, 12,133,124,147, +100,149,196,151,112,155, 76,138,129, 33,199,120,146, 79,136, 29, 77,246,188, 7,141, 41,238,146, 55, 55,192, 76, 23,120, 78, 83, +237,240,229, 25, 21, 67,229,166, 57,203,233,104, 60, 66,149, 82,186,253, 62, 22,227, 71,221,251,107, 11,122,121, 78, 92,179, 3, + 46, 20,251,107,152,202, 15,178,200,104,221,223,138, 31,126,240,139,120,115,225, 79, 78,219,196, 27,160,220,250,210,148, 25, 7, + 53,112,206,142,136,202,104,124,169,156,123,186,239,211,191, 13, 86,185,189,175, 64,102,118,110,247,206,201,195,143, 43, 51, 28, +203,155, 54, 62,218, 98,196,140,162, 68,210,231, 60,209,171, 43,251,204,160,244,245, 54,171,216, 14, 28,106,124,157,253,141, 22, +225,139,181,229,226,182, 46, 84,207, 12, 50,193, 52,168,179, 44,185, 18,180, 17,136,162, 62,244,169,169, 46, 92,125, 82, 15,176, +216,157,143,183, 97, 64,216,184,249,121, 90,213,113, 23, 26,119, 49, 51,195,228, 36,146,108,125, 0, 68,170,109,213, 42,117,131, +117,245,241,169, 49,118,172, 24,121, 17,100,166,225,152, 77,226,108,181,103, 67,230,100,133,228,154, 55,153,180,106, 30,244,166, +234,133, 84,139, 11, 88, 85, 0,119,174,226, 93,147, 50, 73, 37, 89, 36,138, 13,183, 43,112,120, 16, 32, 13,208,146, 4,248,155, +222, 13,246,156, 60, 40,111,221,179,185, 56,145,237,140,251,146,230,203,130, 49, 58,171, 99,210,199, 92,198,147,171,166,223,195, +112, 45,111,139,135, 46, 53, 59,118,237,188, 29,237,230,124,185, 37, 67, 54, 20,251,115,116,138,139, 69,144,209,200,236, 53, 35, +123,224,196, 45,225,234,160,100,118,182, 46, 68,243,228, 99,229,228, 98,101, 75,148,249,195, 38, 35, 25,100,121, 49,215, 10, 68, + 64,232,203,164,198,131,152, 36, 55, 27,214,121,148,133,183,119,100,146,100, 77, 22, 92, 14,189,108,249, 49,113, 99,101, 17,188, + 73, 30,221, 30,226, 86,101, 63, 90,250,148,250,234, 44,253,229, 62, 88,219,219,109,197, 43, 30, 75,237, 47,147, 52,165, 79, 77, + 55, 57, 84, 8,130,253, 99,211,189,216,114, 36,124,147,165,236,236, 40,145, 60,190, 94, 76, 82, 46, 73,203, 89,181, 35,184,102, +197, 27,123,173,229,141,238, 26, 37,230,110,117,113,189, 38, 63,101,224, 3,135,210,202,201,142, 28, 53,193, 86,136, 24,200,153, +182,214, 15,140,242,150,140,155,248, 54,141, 55,249, 42,130, 26,119,246,214,239,184,170, 71,212, 56, 48,207,144,145,197, 42, 60, +142,184,242,140,114,178, 34,155,196,206,236,186, 3,115, 83,122,181,237,237,195, 59,114,125,213,115,226, 88, 95, 15, 56,227, 36, + 74, 67,105, 65,143, 4,182,214, 62, 47,122, 83,199,209, 77, 94,206,195, 48,230,226, 62, 86, 75,225,228,164,209, 71,141,173, 85, + 32, 92,137, 12,239,210,210,128,150, 15,197, 75,234,176,225,233,188,237,163,104,109,168,101,152,167,151, 46, 92,201,252,214, 84, +211,244,193, 50,152,227,132,233, 17, 36,106, 22,209, 14, 22,160, 39,232,247,173,106, 99, 1,126, 28, 42, 82, 47, 81, 11,218,204, + 57,138, 3, 1, 98,104, 4,143,128,163, 69,140,217, 74,120,133,183,137,160,170, 18, 11, 6,211, 92,131, 32, 11,197,123,122,170, +144,146, 54,233, 98,251, 82,192,132,226,104,192,199,122,134, 95, 44, 45,155, 86,147,192,222,164, 1,126, 92, 61,116, 4,133, 49, +241,189, 38,168,249,208,244,105, 22,190,163,206,150,220, 40, 2,218, 51,204,252,180,253, 49,223,159, 42,142,110,126, 78, 84,132, +243,189, 1, 35,165, 29,188, 43,140, 9,202,244, 11,144,121,210,235, 55,160, 30,241,170,139, 3, 80,179, 35,247, 67,120,138, 59, + 92,181,133, 39, 76, 78,234,135,225,230,222,193, 68, 8,131, 30, 86, 17,144,140, 65,241, 0,211,186, 19,255, 0,178,127,217, 53, +116,160, 0, 20, 11, 1,192, 1, 78, 0,122, 43,125,158, 36,146,162, 44, 89, 73,212,209, 53,135,134,147, 82, 96,134,101,184,233, + 48, 23,241, 83, 86, 72, 42, 66, 11,122,234, 42, 41,226, 59,151, 3,231,174,221,142, 5,239, 14,240,204,155,107, 66,112,247, 44, +131, 54,251,145,187, 79,180, 69,140,178, 76,232,176, 51,227,130, 88,200,195,149, 98,123,227,105,158,126,243, 77,163,111,217, 27, +110,205,200,233, 34, 98,166,100,153,254,102, 89,152,178,100, 38, 76,220, 88, 74, 29,127,210,245,109,185,247, 62, 62,205,220,189, +231,181,111, 91, 79,222,251, 14,229,187,100, 60,208,117, 95, 29,150,120, 39,149,163,120,167, 64,214, 54,110, 34,220, 69, 66,159, +123,223,247, 63,196, 13,163,115,242,240,118,254, 78, 56,198, 27, 76, 25,229,225,197,131, 27, 29,126,193,100,146, 80, 24,198, 85, + 77,219,198,245,146,145,123,175,179,187,159,104,219,211,112,220,183, 44,125,219, 19, 22, 81,137,144,216,153,103, 43,202, 78, 69, +250, 19, 3,240, 30, 30, 28, 43,127,217,216, 88,242,246,150, 44, 9,219,113,234,220, 98, 61, 60, 41, 59,131, 43, 10,109,213,162, + 26,101,150, 28, 52, 26, 13,202,242, 63,201, 85,253,249, 30, 54, 47,106,238, 17,108,141,176,226, 65,157,147, 22,102,241, 22,223, +186,156,252,156,137, 67, 16,139, 12,108,137,162, 52,105, 11, 88, 85, 39,111,247,219,227,197,179, 98,207,219, 63,123,119, 22,205, + 25,143,183,179, 4,147, 43, 42, 54,169, 99,234, 99, 70,167,173,163, 81,100,226, 63, 61, 68,146, 80,148, 47, 2,182,219,150,231, +204,189,252, 49, 92, 89,112, 55,160,216,146,197, 12,155,148,105, 6, 36,110, 11, 70,204,146,232,132,153, 69,220,143,135,149,239, + 94,229,135,135,144,152,176, 33,199,149, 52,198,163, 67,130, 88, 88, 14, 12, 71, 2,107,199,127, 6,167,200, 56, 27,180,153, 44, +203,151, 38,239,138,210,198, 85,181, 60,150,145,153, 25, 84,174,159,123,245,184, 3, 95, 67,141, 76,170,204, 10,177, 0,178, 92, + 27, 31, 69,197, 88, 33, 85,209,151,163,110,155, 95,165,107, 88,243,234,222,223, 53,117, 90,248,124,159,158,186,172, 16,163,127, +169,253,220,127,184,180,218,115,255, 0,103,253,220,127,184,180,223, 26, 20,141,146, 61,241,236,252,244, 31, 85, 27, 35,227, 30, +207,207, 65, 60, 79, 10, 3,205,159,188,183,232,242,159, 7, 84, 70, 69,118,219, 53,104, 23,251,193,243, 94, 24, 77,184,112,242, +232, 30,223,206,191,133, 85,239,153,219,139,237, 73, 60, 57, 71, 22, 51,135,220,122,160,132, 20, 82,216,249,130, 53,123,234,190, +174, 32,223,195,141,185,215,169,125,213,182,245, 12,135, 14, 14,161,152,101, 23,233, 38,174,184, 93, 2,123,218,253, 64,188, 53, +115,181, 50,109,147,102,201,133, 34,200,219,177,165,142, 35, 43, 70,143, 4,108,170,103, 36,204, 85, 74,155, 25, 53, 29, 94,155, +241,160, 43,182, 28,205,199, 44,111, 88,153, 89, 34, 73,176,179, 95, 22, 12,145, 26,169, 10,113,224,157, 73, 65,192,233,105,143, +201,206,176,125,181,186,239,120,233,131,149,231,218, 97, 36, 59, 4, 89, 9, 42,135,214,185,153, 25, 16, 55,188,196,144,202,173, +241, 14, 36,129,122,245, 88,241,224,133,164,120, 98, 88,218,103,234, 76,200,161, 75,190,144,154,220,143,137,180,168, 23, 62, 2, +162,195,178,236,216,192,174, 62,221,141, 18,150, 73, 8, 72, 99, 81,174, 39, 50,198,222,234,243, 71, 98,202,124, 9,189, 1,136, + 93,255, 0,118,198,194,197,155, 26, 72,177,241, 22,124,227,149,210, 68,145,144,174,227, 36, 17,188,241, 51,117, 68, 44, 3, 2, +241,139,235,245, 84,239,196, 13,199,113,143, 27, 63,111,196,201,242,176,166,211,149,155, 35, 5, 5,228,101,120,226, 84, 13,192, +173,181,147,117,227,114, 62, 93, 67,108, 91, 52,205, 11,201,183,227, 59, 99,179, 73, 1, 49, 37,209,157,250,174,203,238,240, 37, +253,243,252,238, 60,232,185,251, 78,215,186, 8,254,242,194,131, 48, 69,171,166, 50, 35, 89, 2,234, 22, 96, 3,131,206,220,104, + 12,110,118,245,186,226,201,187,253,220,201, 23, 71,116,149,103,232,172,111,146,208,199,131,143, 47, 81, 34,157,128,144, 43,184, +234,105,247,180,114,227, 81,246,253,215,125,151,184, 37,197,199,220,212,166,231,159, 12,125, 78,150,164,142, 51,180,174,119,216, + 36,135,221, 4,128, 5,253,167,137, 53,184,202,216,246,108,208,203,151,129,143, 58,188,157,119, 18, 68,141,170, 93, 34, 51, 35, + 92,113, 98,138, 20,147,225,195,149, 60,109, 59,106,229,140,245,194,128,102, 11, 91, 36, 68,157, 81,165, 26, 37,251, 75,106,224, +140, 84,113,228,109, 89, 96,243,183,221,247, 40, 19,239, 44, 44,132,195,147, 15,110,223,242,132, 97, 3, 69, 33,196,220, 87, 74, + 20,115,107,190,158, 45,207,137,181,175, 90, 24,251,143,117,202,221,147,111, 87, 72, 82, 93,210,124, 5,186, 2,201, 18,109,107, +156,156,249,178,204,220,125, 92, 43, 65, 46,197,178, 76, 34,235,237,184,178,116, 89,158, 29, 80,198,116, 52,143,214,114,190,239, + 13, 79,239, 55,164,241, 52, 67,181,109, 99, 60,238,131, 6, 15, 62, 72, 62,115,164,157, 91,232, 49, 95,169,109, 87,208,116,251, + 56, 80, 30,111,219,123,206,239, 30,219, 4,105,144,173,149,147,141,177, 66,119, 9, 19, 92,136, 51, 38,201,141,139,234, 36, 57, + 80, 52,174,175,172,120,223,149, 76,205,238,174,224,139, 14,118,143, 34, 53,151, 3, 19,118,200,121,186, 42, 70, 67,109,185,177, +226,198, 64,110, 10,178, 41, 58,173,242, 90,182,233,178,236,145, 65, 54, 52, 91,110, 44,112,100, 0,179,196,144,198,170,225, 89, +157, 67,133, 81,123, 51,179, 15, 89, 38,164,195,179,237, 13, 0,128,224, 99,152,150, 22,197, 88,204, 72, 84, 64,228, 51,195, 98, + 62, 6, 42, 9, 94, 70,212, 4,244,232, 54,176,133, 91, 65,210,225,108,108,214, 6,198,220,141,141, 60, 32, 60, 0,224, 69, 14, + 56, 49,225,105, 90, 8,146, 38,157,250,179,148, 80,165,228,210,169,173,237,241, 54,148, 2,231,192, 81, 3,170,243, 62,170,128, + 93, 43,192, 91,242, 82, 42,106, 99,127, 15, 26, 83, 36,103,155, 15,158,154,178,165,216,234,160, 9,167,137, 30, 21,197,120, 89, + 71,182,134,211,131,123, 15,150,198,144, 76, 8,191, 27,242,181,141, 0, 69, 3,199,137,168,206,151, 99, 98, 64,240, 20,254,175, +160, 27,251, 45, 67,212,196,125, 53, 80, 27,164,142, 26,169,202,151,226, 77, 39,190, 69,249, 3, 92, 25,215,151,207, 84, 13,241, +106,112,166,139,146, 79,166,148, 27,115,168, 1, 94,230,254,154, 34,208,197, 60, 27, 80, 28,163,137, 62,179, 75, 37,136,165, 65, +195,219, 92,252,141, 82, 17,153,236,164, 14,102,146, 31, 19, 76,127,136,209, 33,228,106, 26, 67,103,226, 69,233, 96, 54, 95,158, +149,144,187,240, 32, 88,120,215, 70, 44,191, 41,167, 32, 74, 84,180,106, 60, 88,147,115,232, 2,163,160,144,131,161,244,132, 55, + 31, 47, 26, 52,173,252, 52, 31,171,115,242,240,166, 11,233,114, 7,196, 56,124,149, 10, 59, 22,247, 98,222, 60,253,180, 57, 20, + 11,129,233,165, 89, 5,248,120,219,133, 53,219,135, 31, 19, 64, 50,195, 65, 31,233,194,159, 14,107,192,186, 20, 2, 9,166,115, + 67,242,209,177,206, 30,128, 37, 7, 87,182,213,163, 35,223,113, 50, 71,210, 40, 1,126, 23,181, 42,248,159, 93, 58,100,193, 49, +134,136,253,165,198,145,242,210, 88, 90,212, 3,137,244,126, 74, 80, 1, 81,226,124,105,182,244,213, 38,223,221,187, 94,126,255, + 0,153,219,145, 9, 99,206,195, 4,177,145, 84, 71, 38,157, 58,186, 76, 25,137,182,161,204, 10, 2,247,157, 32, 23, 62,175, 69, + 87,195,188,226,205,188,100,236,106,178, 12,172, 88, 83, 34, 73, 8, 29, 50,178, 18, 20, 41,213,170,252, 61, 21, 99,111,148,208, + 28, 71, 1, 73,107, 19, 81, 39,221,176,177,247, 44, 77,166, 87, 35, 47, 53,100,124,120,244,146, 10,196, 53, 57, 45,200, 90,166, +144, 77, 0, 59,123,224,250, 46,127, 37, 74,198,136,170,251,223, 17,226,104, 81, 45,222,254, 2,141, 60,233,139,143, 46, 67,130, + 82, 20,105, 24, 47, 59, 40,212,109,123, 86,171,212,141,135, 11,235,167,128,195,149, 80,118,199,117,237,157,219,130,249,251,104, +145, 22, 57, 12, 82, 67, 58,170,200,166,193,129, 33, 25,197,152, 30, 6,245, 51, 98,223,113, 55,236, 71,204,196, 89, 18, 56,230, +151, 29,150, 96,161,181, 66,218, 24,141, 44,194,215, 28, 43,125,196,122,240, 45, 67, 91,194,136,142,124, 5, 48, 50,211,213,150, +162,234, 88,234,120,142, 6, 79,110,227, 96,254, 36, 75,221, 88,103, 55,105,110,225, 49,206,169,110,164, 93, 89,164,140, 79, 23, +136,100,213,126, 21,154,252, 68,155,101,207,252, 68,237,215,194,220,113,254,232, 56,123,122, 71,184,228, 42,207, 2,198,142,235, +174,120,205,131, 90,222,242,181,189,118,175,114,155,240,219,177,119, 12,172,140,204,205,154, 25,167,202,145,166,200,114,100, 26, +228,118, 46,206,192, 56, 23, 36,222,179,217,157,139,216,120,221,227,183,118,226,246,214, 25,198,205,196,159, 41,230, 45, 55, 80, + 52, 44, 20, 40,251, 77, 54, 55,172, 53, 12, 76, 30,101,248,152,219, 30,103,106,224,182, 38,126,223,151,186,109,249,211,193, 52, +208,203,134,114,102,199, 60, 34,125, 24, 49,196,154, 15,196, 22,199, 72,225,123,222,182,221,191,184,246, 94, 22, 55,225,210,247, + 12,126, 87,116, 24, 41, 54,217,187,220, 42,134, 23,139,203, 78,223,168,218,248,106,224, 15,163,198,202, 63,194,237,141, 51,140, + 57, 93,181,134, 49, 58,242, 58,228, 6, 55,232,220,244,227,210, 37,189,237,111, 15,162,132,127, 14, 54,119,155, 14, 69,237, 92, + 89, 35,211, 50,229, 97,153,120,130, 27,236, 89, 28,203,111,132, 92,139,213,237,113, 34, 76,215,225,170, 35, 79,220, 50,105, 93, + 99,184, 33, 11, 41, 85,107, 2,242,220,113, 35,129,175,160,136, 39,144,175, 61,218,123, 94,125,144, 73,139,181,246,246, 62, 38, + 62, 67,199, 44,190, 94,114,138, 30, 50,250, 94,237, 41,123,217,171,208, 99, 93, 8,171,114,116,128, 46, 73, 39,128,241, 39,137, +168, 81,120,250, 56,218,186,151,198,186,128,160,126, 81,255, 0,119, 31,238, 45, 55,215,122,123,253, 65,254,238, 63,220, 90,103, + 30, 84, 4,108,131,239,143,103,231,161, 94,137,146, 14,177,195,195,233,160,208, 15,184,184, 38,144, 48, 6,179,240,119, 70, 52, +233,183, 57,136,198,155,134, 86,102, 26,179,176,180,103, 11,204,107,119, 63,170,222, 88,219,219, 71,143,185,182, 25,113, 95, 53, + 51, 99, 56,241, 60,113,187,144,195,222,154,221, 43, 2, 1, 34, 77, 67, 73, 28, 15,133, 8, 92, 22, 28, 69, 55,152,229, 85, 18, +119, 70,195, 12,112, 77, 38,116,107, 30, 66,179,196,196, 55,195, 27,136,228,102, 22,186,132, 99,102,213,109, 62, 53, 46, 45,223, +109,150,117,197,143, 37, 90,103,150, 92,117,140, 94,230, 88, 6,169, 83,151,213, 20, 41, 56, 11,124,181,195,215, 84,144,247, 86, +219, 46,118,110,214,204, 98,204,196,153,224, 72,155,251, 83, 28, 9,148,197, 13,180,143,117,207, 2,111,238,154,126, 23,115,109, + 89,176,109,172,243, 8, 50, 55, 60,120, 50, 97,198,126, 44,171,144,186,227, 87, 96, 52,130,220, 66,220,251,196, 27, 80,133,200, + 52,241,106,165, 78,230,216, 29,178, 85,115,163, 39, 18, 57,103,200, 99,168, 5,142, 6,233,202,218,136,177,208,220, 26,220,170, + 54, 23,117,225,110, 19, 20,199, 1, 98, 92,201, 48, 76,146, 54,130,198, 44, 81,154,206,145,178,234, 60, 26,197, 77,136,177, 53, + 25, 77, 17,181,117,174, 42,142, 62,235,216, 37,198,159, 50, 60,248,218, 12,113, 17,149,192,110, 89, 28, 33,210, 52,221,250,135, +130,233,189,207, 14,116,252,110,229,219,243, 51, 48,113, 48, 91,204,166,116,121, 82, 38, 66, 31,117, 78, 27, 69, 28,136,192,216, +223, 84,223,146,160, 45,200,162,197, 26, 91, 83,113, 38,135,113, 82, 64,210,162,192, 1, 80, 8,177,196, 15, 16, 61, 84, 72,146, + 59, 19,164,115,166,240,181,253, 28,169,241,128, 20, 27,250,248,208, 15, 85, 93, 92,128,164, 55,212, 0, 3, 79,137,165, 14,182, +226,225,126, 90,107,203, 0,228,227,231,160, 28, 84, 1,207,136, 21, 29, 74,144,120, 94,198,158,102, 75, 29, 38,231,231,161,245, + 84, 15,132,220,122,141, 0,226, 71, 42, 1,226, 56, 41,191, 42,115, 74, 13,174, 13,169,165,199,175,230,170,129,192,176,240,229, +235,164, 37,173, 97, 73,168, 88,240, 52,133,189, 3,133, 80, 32, 52,164,251,167,217, 77, 39,133, 35, 19,166,160, 16, 83,188, 41, + 5, 58,220, 40, 7,142, 0, 83,101, 54, 66,105,246,161,204, 46,150, 53, 72, 68, 0,187,112,241,169, 10,160, 92, 83, 33, 78, 55, +249,169,110, 68,132,250,235, 60, 89,161,197,120,222,134,156,184,211,193, 37,141,254, 74,103,162,168, 15, 37,137, 45,232, 69,254, + 90, 34, 75, 26,176,140,248,155, 95,215,232,161,147,101, 18, 17,238,145,161,168, 68,190,128, 21, 69,143,189,175,209, 80,163,153, + 84, 22,101, 22,179,233, 4,122,133,205, 13,206,171, 81, 65, 83,101, 78, 43, 26,146, 91,210,205,206,132,214,181, 82, 28, 65,209, +203,157, 13,147,136, 54,169,198,225, 0, 32, 17,106,105,210,109,238,213, 33, 16, 0, 37, 75,114,225,252,181, 52, 31,159,211, 81, + 9,188,227,195,209, 82,211,141,133, 0,235,138,243, 57, 54,172,140,204,158,225,221, 54,161,255, 0,206,182,125,212,229, 97, 0, + 56,186,244, 35, 18,192,127,155, 42,139, 91,196,215,166,233, 28, 7,141, 87,237,219, 54, 46,217,151,184,101,192,242, 52,155,148, +195, 34,112,228, 21, 12, 20, 37,147, 74,173,133,135,141,232, 25,139,198,238, 8,179,119, 61,231,184,182,223,122,219, 4,121, 49, + 33,177, 43, 36,102,118, 49,183,173, 89,116,154,143, 38,201, 20, 61,140,189,212,153,121, 31,127, 12, 68,220,126,242, 51,201,175, +168,192, 74, 99,211,175, 70,158, 58, 52,233,181,106,240, 59, 87,100,217,119, 61,199,113,198,215,171,116, 4,100, 98,185, 83, 10, +134, 37,152, 70,186, 65, 1,137, 60, 46,106, 10,246, 70,218,113,215,110, 59,158,113,217,131,106,251,164,202,189, 27, 6,215,211, + 47,163,170, 99,191,213,213, 66, 20,187,158,213,135,190,119,119,109,100,102, 9,145,183, 76, 25,102,201, 88,230,146, 59, 58, 66, +132, 4,210,195, 71,174,220,252,107,208,247, 28,172,125,191, 3, 39, 55, 45,202, 99,193, 19,203, 43, 47, 48,170, 9, 58,109,227, +232,170,173,227,183, 54,237,230,124, 28,166,200,200,194,200,192,214, 49,231,194,147,162,225, 36, 1, 94, 59,233,111,116,129, 87, + 25, 88,120,251,142, 44,248, 89, 75,212,198,201,141,162,149, 15, 11,163,130,172, 46, 61, 70,136,167,150,178,228, 98,102,118,198, +245,183,109,115,237, 88,217,155,158, 46, 48,204,200,206,146,108,140,152,114,111,194,104, 9,117, 80,200, 47,197,174, 43,213, 55, +111,255, 0,108,205,254,226, 95,220, 53,157,131,240,247, 10, 49,183,140,141,219,114,201,135,106,200,139, 43, 2, 9,102, 67, 26, + 24, 13,209, 10,244,189,225,225,233,183, 0, 71, 26,213,205,142,153, 56,242,193, 33, 33,102, 70,141,138,243, 1,134,147,107,223, +211, 91,170, 50,121,118,204, 63,203, 24, 61,185,221,208,112,219, 51,177, 49,176,119,240,182,210,188, 2, 65,150,223,208, 99,161, +143,162,154,243,205, 15,103, 76,248,242,180,101,187,137,212,180,108, 86,234,217,134,226,235,224,107,209, 49,187,115,109,198,237, +245,237,166, 86,159,111, 88, 14, 49, 19, 16, 93,144,130, 56,149, 10, 47,199,152, 21, 91,141,216,187, 44, 29,179, 47,106,117, 50, + 36,193,145,204,189,103,117,235,171,151, 18, 7, 87, 68, 80, 10,176,225,238,213,135,246, 0, 29,209, 60,241,247, 87,103,198,146, + 50, 36,185, 25, 66, 68, 82, 64, 96, 32,184,212, 7, 58,170,219, 59,127, 23,185,119,190,235,139,118,200,203,150, 40, 51, 4, 88, +208,174, 76,201, 28,122,162, 13,173, 81, 29, 65, 32,158, 0,220, 15, 69, 95, 98,246, 62, 50,110, 59,126,235,155,186,238, 27,134, +102,218,206,216,237,147, 50, 50, 89,215, 65, 82,130, 48, 57,120,142, 39,196,213,214,215,176,226,109,121,155,150,110, 59,200,242, +110,147, 12,140,133,144,169, 85,112,161, 45, 30,149, 82, 5,135,137, 53,123,103, 88, 7,150, 97,237, 75,159,248, 89,254,111,202, +207,206,125,247, 26, 41, 37,196,203,243, 83, 14,151,150,157,225, 68,141, 21,194, 1,161, 56,155, 94,252,111, 90,173,223, 3, 27, +184,251,211,181,224,220,218, 86,138,125,162,105,103, 16,203, 36, 5,207,217,177, 12,208, 50, 54,146, 79, 32,107, 67,135,217, 91, +102, 63,105, 55,102,164,179,157,185,163,146, 35, 49,100,235,233,150, 70,153,189,238,158,139,234,110, 30,229, 27,114,236,172, 61, +203, 43,111,206,139,113,206,219,242,182,220, 99,135, 4,216,114, 68,140, 99,107, 95, 95, 82, 25, 56,157, 62, 22,172, 52, 77, 12, +150, 60,179,246,150,243,221,123, 54,213, 52,217, 91,102,221,181,253,235,139,141, 60,141, 49,198,152, 43,183, 65, 26, 66,205,165, +237,170,196,213, 6, 22,211,221,249,155, 38, 6,251,178,108,249,207,220, 82,172, 57,137,190, 73,184,193,162,109,100, 72,232,240, + 54, 64, 29, 38, 66, 84, 38,145,111, 31, 26,245,173,151,181,118,157,142, 28,164,198, 71,158, 92,243,171, 63, 47, 45,204,243,228, + 27,105,251,105, 31,152, 0,240, 28,170,159, 31,240,227, 23, 11,252, 54, 14,245,186, 98,237, 26,181,141,162, 44,133, 16, 11,182, +163, 26,177, 67, 32,140,248,174,175,150,164,233, 3, 82,150, 93,171,252,195,248,147,155, 6,229,145,147, 30, 46, 22, 22, 14, 88, +192,138, 98, 34,105,131,146, 4,128,112,101, 22, 55, 3,157,122, 70,182,240,170,200,182, 28, 76,125,251, 47,184, 81,228, 57,121, +144, 69,141, 44,108, 87,164, 18, 18, 74,149, 26,117, 95,143, 31,122,172,109,233, 53, 80,139,114, 31,169,191, 37,255, 0, 45,117, + 37,133,185,248,126,122,234,165,215,236, 41,158,222,225,255, 0,119, 31,238, 45, 54,156,255, 0,217,143,247,113,254,226,210, 92, + 86, 77, 17, 50,126, 49,195,195,243,154, 8,181,252, 40,249, 39,223, 30,207,166,128, 69,205, 1,137,197,236,118,197,147,111,204, +134, 44, 40,247, 44,124,189,199, 35, 47, 49, 80,117, 36,143, 45,114,214, 5, 46, 99,212,250,122,241,234, 86,225,195,133,248, 85, +103,249,111,184,118,252, 62,172,177, 38, 78, 84,249,123, 51, 20, 73,166,156,235,196,200, 94,172,142, 90, 47,114, 47,173,238,139, + 34,248,112,175, 73,181,185, 82,112,189, 1,230,217, 61,181,191, 25, 91, 10, 56, 34, 51,110,123,126,240,153, 82,179, 73,229,241, +219,114,204,138, 93, 11, 32,140,234,100, 87,184, 82, 6,173, 38,173,182,109,165,211,189,119, 60,196, 15,247,126, 44, 96, 66,206, +140,128,229,228, 36, 49,100, 50, 22, 0, 53,147, 17, 46, 71, 15,124,214,206,222,138,235, 30,116, 6, 61,251, 99,118,151,119,154, + 70,104, 23, 1,247, 25, 55, 88,229, 87,115, 53,219, 3,238,245,133,144,198, 20,123,199, 81, 33,143, 10,137,135,217, 27,134, 62, + 78,213,214,233, 79, 30, 52, 27, 90,100, 63,153,201,141, 35,151,109, 30,241, 76,120,244, 71, 62,178, 20,163, 73,240,241,225,225, + 91,187,154,235,241,189, 1,135,147,177,247, 57, 49,100,129,166,199, 86,108, 77,210, 5, 55,114, 58,153,185,233,159, 5,198,129, +238,133, 75, 63,160,242,189, 30, 14,217,222, 37,205, 27,134, 95,150,133,228,220,178, 51,222, 24,229,121, 52,199, 54,219,247,122, + 38,163, 18, 93,132,156, 79, 11, 91,230,173,149,238,107,135, 31, 69, 1,231,210,246,206,229,179,109,177,230, 57,138,105, 48, 49, +182, 56,214, 56,132,210, 6,151,108,105, 4,218,132,113, 52,130, 51,213,184,101, 70, 35,153, 94, 21,103,218, 91, 94, 96, 76,125, +211, 51, 25, 35,144,205,186,201,118,215, 27,170,230,229,172,200, 82, 25, 19, 85,157, 99,191,188, 84,129,110, 28,120,107,184,129, + 93,126, 21,144,113,248,111, 69,211,233,102,246, 92,208,197,136, 3,217, 69, 35,143, 10,128, 78,154,158,124,125, 68,211,196,104, +120,105,231, 72, 1,231,107,122,233,196,248,208, 8,218, 20, 90,213,214, 26, 71,128,229, 77, 54, 96, 46,111,198,156,206,171,200, +139,250, 56, 80, 15, 0,120,240,174, 38,212,195, 42, 88, 29, 87, 62,138,103, 80, 30, 96,252,198,168, 28, 91,133,188, 47, 77,186, +240,227, 77,115,168,124, 36, 15, 73,164,176,244, 80, 11,117,244,210, 93, 88,219,198,147,147, 10,119, 11,131,227, 84, 28, 64,166, + 73,193, 61,166,156, 79, 26,100,156,128,245,212, 2, 14,116,227,232,255, 0, 78,116,209,206,158, 15,188, 7,178,132, 9, 65,159, +149,168,164,218,163,200,110, 69, 80, 57, 56, 10, 22,177,174,199,198,136, 77,150,212, 52, 80,120,145,122,137, 26, 99,174, 61,226, + 41,158, 2,244,192,193,110,160, 88, 83,217,125,219, 81,132, 76,141,128, 86, 70,226, 13,175, 75, 36, 72, 99,210, 47,167,194,163, +172,150, 22,183,250, 1, 93,215, 60,129, 53, 32,163,155, 74,174,132,224, 40, 36,220,251, 41,197,129, 94,116,141, 96, 46, 61, 6, +169, 7,199, 40,152, 30, 22,183, 58,236, 56,186,165,245, 19,111, 14, 62,218,102, 48,210,141,127, 31,162,165,225,170, 32,109, 0, +241, 2,247,244,213, 32,214,193,179,171,171, 94,222,159,101, 16,192,227,194,244,118,107, 47, 15, 10, 98, 73,113,168,139, 95,194, +130, 65, 21,101,231, 72,190,174, 52,175, 56,109, 33, 79, 6, 54, 52,171, 97,202,128,174,203,254, 49,160, 14,116,124,145,121,218, +220,169, 21, 13,239, 64, 42,196,229,194,113, 7,135, 47, 69, 91, 66,129, 64, 3,194,128,170, 12,165,253,131,230,169,113,138,168, + 15, 35,194,150,148, 11,155, 83,202,214,209,134,198,113, 52,161,105,109,111, 26,122, 94,180,132,200,208, 8,229, 69, 82,124,105, +192, 19,225, 68, 84, 30, 52,180,242, 19, 3,144,120,222,138, 13,169, 2,139, 83,128,227, 88, 13, 14, 13, 72,204,223, 86,157,106, +235, 53, 77, 13, 32,101,143,136,166, 27,115,163,105,191, 58,105, 65, 85, 52, 81,156, 52,255, 0, 87,255, 0,189, 93, 79,210, 45, +242,126,122,234,179,247,130,146, 75,253,159,247,113,254,226,211,125, 20,247, 28, 19,251,184,255, 0,113,105,167,149, 96, 17,114, +127,138, 61,159,158,133,107,122,168,185, 54,214, 61,148, 47,147,229,160, 35, 67,157,137,147,145, 62, 44, 19, 44,147, 99, 16, 39, +141, 77,202, 19,224,222,186,146,214, 28,171,207,226,218, 37, 92,183,137, 83, 37, 32,159,123,145,102,211, 36,192, 54, 58,197,169, + 75, 29, 95, 9, 99,197,188,125, 52,237,171, 15,114,198,201,218,230,139,204,245,100,151,112,138, 99, 51,202,201,211,141, 24, 99, + 43,135, 36, 5,186,139,122,107,209,108, 21,134,213,249, 78,171,193,191,192,242,215,113,121, 74,212,231, 26, 63, 20,191, 19,121, +126, 52, 35,149, 0,202,242, 93, 65,230, 76,125, 97, 23,214,233,134,209,171,217,115,106,243,181, 27,175,150,199,251,171,207,125, +241,229,242,190,247,234,245,173,171, 67,105,254, 39,185,175, 95,240,244, 85,183,109,195,140,123,141, 38,193, 76,163,142, 54,205, + 19, 73,146,178,219,174,101,141,153, 67, 79,245,173,204, 14, 30,138, 61,186, 73,183,105,132,249,116,235,231,200, 87,114,237,106, +165, 88,150,150,175,175, 79, 46,125, 13,167, 46, 20,158,218,204,100,109,249, 83,101,100,206,233,146, 73,221, 34,142, 50,175, 42, +143, 42, 98,137,100,208, 20,129,160,221,181, 17,249,168,120,254,115,109,205,110,164,121, 62, 76, 46,124, 56,234,169, 44,190,241, +150, 39,135,128, 12,120,168,109, 4,214, 61, 36,214,150,214, 56,124, 36,223,172,211,214,176,166, 38,124, 96,214,219,215, 67,138, + 88,230,143,169, 11, 7, 75,178,220,122, 85,138, 48,249, 8,172,111, 75, 62, 33,182, 75, 42,228,205,145,229, 48,129,199,101,157, + 92, 72,160,117, 12,115, 70, 74, 43,127,180, 89, 87,229,181, 29, 86,126,156, 31,123,199,150,248,131,207,144,177, 9,139,245, 78, + 75,116,117, 8,189,238, 49,127, 12,158, 31,146,171,194,191,154,117,229,248, 17,103,127,203, 26,115,126, 92, 95, 35, 91, 44,209, + 99,194,249, 25, 14, 35,138, 37, 47, 35,177,176, 10, 57,147, 77,197,202,198,205,135,175,138,226, 72,238, 84,155, 16, 67, 47, 2, +172, 26,196, 17,232, 53, 81,186, 46, 67,246,242,192,177,202,122,201, 20, 89, 38, 69,235, 77, 28, 79,165,100,145,149, 62, 57, 16, +113,225,227,198,129,218, 82,102,167,155,196,203,142, 67, 26,183, 83, 31, 45,226,145, 14, 64,102,109, 83, 59, 73,245,207,186, 52, +240,244,142, 21,135,141,118, 90,243,170,113, 30, 6,253, 87,234, 86,145,163, 83, 62, 38,145, 35,214,116,222,214, 23,162,116, 77, +248,185,252,149,136, 72,247, 88,165,220, 19, 0,100,205,146,209,229, 90,114, 39,137,208,147,169, 21,245,151,130, 70,240,137,144, +143,101,175, 82, 38, 19, 44,189,125,162, 60,212,219,161, 56, 82,101, 36,139, 62,178,201,146,166, 93, 9, 55,218, 49, 17, 95,169, +164,113,246,222,175,161,253, 92,124, 63,111,129,159, 95,250,120,120,253,223,137,174, 40,165,149, 65, 39,210, 47, 68,232,196, 77, +172, 79,168,154,200,199, 14,102,225,185,175, 82, 60,165,193,151,115,148,157, 66,104,129,199, 24, 32, 45,239,164,136,218, 81,227, +192,154,100, 17,207, 18,224,174,236,153,141,133, 16,205,142, 36,140, 78,206, 36, 25, 37,113,250,157, 31,180,254, 0,251, 50,120, +124,182,169,232,240,250,181,142, 9,107,207,242, 47,172,255, 0,151, 73,137,111, 78, 95,102,166,195, 20,226,101, 64,153, 24,197, + 94, 41, 5,209,199, 34, 57, 80,243, 50,113, 48, 99, 18,228,200,177, 33, 96,129,143,139, 49,176, 80, 7, 18,107, 54,145,110, 81, +118,102, 28, 16, 36,177,204,162, 33,147, 19, 43,245,132, 38, 95,181, 5, 99, 43, 33, 58,121,133, 55,181,237, 81, 98,192,155, 38, + 12, 78,184,154, 88, 19,116, 15, 7,187, 52, 33, 33, 49,123,229, 3,200,210,116,245,242, 47,107,120,112,181, 85,138,178,219,182, +138,205,120,232, 71,154,208,146,174,174,169,248, 75, 53,176,101, 98,228,205, 44, 56,242, 43,190, 57,211, 56, 95,170,214,248, 73, +244,212,162, 53,112,181, 96,228,194,201,196,137,196, 41, 34, 98,201,185, 78,217, 97,196,242,222, 33,175,162,197, 35,113, 33,143, + 85,174, 87,159, 11,240,163, 71,214, 92,108, 20,222, 6,100,248, 43, 14, 79, 76, 71, 28,203, 39, 84,202, 4, 29, 69,141,158, 75, +244,184, 70, 92,223,245,172,212,120,107,197, 91,236,212,139, 53,184, 90,186,196,204,233,196,215, 78,241,117, 6, 63, 80,117,130, +235, 49,130, 53,105, 38,193,180,243,181,199, 58,102,149,189,174,107, 41,155,135, 36,185,109, 56, 76,232,164,155,106, 88,210,117, + 18, 75, 42,202,183,212,175,211, 34, 62,166,159, 11,139,159,135,141, 77,237,248,231, 56,217,168, 86, 68, 75,142,148,170, 38, 69, +114, 83,222, 48,197,151,239,165,143, 49,114, 47,227,206,163,196,149,123,149,167,135, 35, 85,202,221,187, 93, 99,143, 63,192,191, +208,188, 13,169,182, 0,139, 86, 30, 8,179,224,194,201,150, 3,144,210, 96, 71, 22, 95, 93,132,240, 9, 30, 7, 45, 36, 83, 69, +144, 88,117, 30, 59,134, 40,196, 31,154,146,120,242,230,197,131,116,145,242, 36,108,225, 62, 76,120,218,114, 25, 2,200, 84,227, +164,111,140, 75, 69, 40,141, 87, 73, 42, 71, 19,227, 91,244, 53,253, 92,227,134,179, 19,192,207,249, 14, 63, 70,177, 60,116,137, +142, 38,219,171, 27,187,198,142,173, 36,118, 18, 40, 32,149, 36,106, 26,135,133,197,115,248, 86, 63, 39, 23, 54, 57, 55, 57, 49, +224,200,142,108,131,137, 36,164,137,164, 6, 18, 16,100, 42,180,100, 6, 96,111,112,135, 85,175,166,157,139,137,153, 59,225,195, + 41,157,240, 91, 54, 82, 64, 73,161, 65, 15,150,114, 7,190,237, 39, 72,203,203, 93,184,240, 28, 45, 89,120, 84, 79,119, 41,225, +225, 37, 89,156,199,103, 56,227,227, 6,180,124, 84,255, 0,237, 43, 29,139,135,145,143, 30, 28,178,174,104, 13, 14,100,121,102, + 54,153,165,208,172, 4, 32,113, 36, 54,145,238, 91,141, 74,238,179,184, 99,237,248,123,150,215,214,121,176,221, 89,161, 26,139, +188,114, 47, 76,235, 81,197,152, 18, 15, 26,122, 75,186,181, 86,253, 77,169,229, 43, 65,235, 62,219, 89,215,244,164,225,113,135, +169,169,115,194,163,155,106, 30,186,193,237, 27,103,112,230, 38,118,223,153, 54, 66,121, 12, 73, 33,197,152,187,175, 82,121,216, +202,143,170,254,246,155,105,245, 84, 76, 15,243, 54,118,126, 33,203, 92,136,160,220,165,142, 73,239,212, 65, 18, 98,106, 14,190, + 26,122,150,249,107,127,227, 47,171,253,202,253, 63,249,251,140, 45,211,250,127,219,183,213,167,199,131,159,142,135,164,159, 26, + 12,217, 48, 98, 65, 38, 70, 76,139, 20, 49, 13, 82, 72,198,192, 15, 93,121,214,119,249,159, 11, 47, 40, 99,140,153, 97,219,100, +148, 65, 99, 35,117, 83, 51, 80,143,211,171,167,113,236,245, 85,182,241, 4,146,118,190, 94,210, 19, 34,108,188, 8,160,234, 49, + 18,125,164,173, 98,197, 27,251, 65,206,252,197, 63,199, 73,210,110,154,179, 75, 78, 73,243,251, 81, 86,229,181,120,163, 78,169, +181, 60,218,229,246, 51, 93, 12,177,101, 68,179,194, 67,197, 32, 13, 27,143, 16,124,104,205,114, 62, 65, 94,125,149,183,228,156, +140,193, 31,155,251, 60,220, 88, 49,202,203, 63, 8, 25, 85,101,210,117,113, 4, 30, 45, 82,122, 89,120,240, 73, 4,254,105,118, +152,183,137, 18,112,134, 83, 32,196,208, 10, 89,150,242, 24,181,158, 54,168,240, 39, 13, 95,143, 40,248,252,202,183, 22, 83, 52, +225,206,116,227, 29, 56,104,109,175,195,228, 52, 12,124,172,124,184, 87, 35, 26, 65, 44, 46, 24, 43,175, 34, 84,149, 63, 49, 21, +137,135, 81,201, 67,184,121,239,242,224,155, 47,201, 91,175,174,214, 78,142,189, 31,107,167,227,233,234,171,158,215,103,198,216, +118,237,189,225,157, 51, 50, 23, 41,161,234,198,214, 82,178,202,235,214,107, 89,111,195,159, 58,151,193,219, 89,153,114,185,105, + 26,207,197, 70,166,169,185,238,188, 58,246,168,124,245,159,166, 62, 14,116,234,104,133,175,199,149, 61,173,167,135,162,213,230, +242, 38,225,228,161,242, 35, 63,239, 79, 47,149,247,200,144, 79,109, 90, 27, 71,197,238,234,215,240,104,171, 60,204, 17,131,247, + 84, 57, 35, 50, 93,189,225,146, 76,129, 11,204,242,182, 83, 42, 89,164,233,157,126,157, 62, 0,213,123,116,154, 93,250,185,210, + 53,250,126, 60,249, 25, 91,166,211,125,154, 40,214,116,250,190, 28,185,155,129,194, 50,127,211,149, 19,111,102, 49,177, 60,125, +239,205, 89,238,205,150, 73,123, 87, 22, 73,157,228,144,245,193,121, 73,103, 32, 77, 32, 26,137,245, 86,135, 3,132, 77,235,106, +229,106,246,222,213,227,218,218,249, 29,169,110,250, 86,241, 29,201, 56,243, 37, 31, 10, 67, 93,242,215, 86, 74, 70,149, 66,188, + 96,114,189,205, 16, 92,159, 85, 50,127,227, 70,190,218, 40, 6,220, 57,208,164, 9,173,214,111, 69,255, 0, 53, 62, 53,212,109, +236, 38,153, 37,204,173,237,169, 17, 45,184,248,208, 18, 35, 21, 45, 5,133, 70,136, 84,181, 28,133,105, 34, 14, 28, 5,252,105, + 46,125, 52,164,138,235, 95,149,110,168,207, 19,184,120,154,122, 56, 94, 84, 50,181,192, 85,102, 26,105,201, 36, 57, 62, 52, 69, + 62,186,142,182, 20,224,220,106,242, 52,154,230, 73, 12,104,128,208, 87,136,231, 78,210,195,141,101,164, 94,233, 14,172, 41,218, +199,133, 70,212,105,193,141,101,212,168, 53,239,206,147,221, 20,208,105, 24,250, 41, 6,154, 67,184, 91,228,252,245,212,219,157, + 63,213,252,245,212,143,188,144,138,103, 60, 19,251,184,255, 0,113,105,183,167, 56,248, 63,187,142,199,250,139, 77, 3,159,162, +178, 82, 54, 65,247,199, 31, 10, 9,226, 42, 91,195,212, 55,213,111, 11,115,252,244,209,139,252,251,252,148, 4, 91, 26, 91,112, +181,234, 79,149, 22,248,190, 91, 87, 12, 95,231,126, 79,211, 64, 70, 3,215, 92, 42, 79,150, 32,252,127,147,244,215,121, 97,250, +255, 0,146,128,142, 88, 17,233, 52,130,252,237, 82, 6, 47, 31,143,242,126,154, 81,142, 57, 22,252,148, 0, 62, 65, 73,198,220, +232,254, 95,249,223,147,244,215,121, 99,127,139,242,126,154, 0, 3,143, 26,117,133,175, 70,242,246,250,255, 0,146,151,203,255, + 0, 59,242, 84, 96, 18, 7, 0,133,181,185,241,167,251,228,139,176,191,141,133, 26, 60,114, 20,141, 92,205,249,126,154,119,151, +254,119, 31,101,100, 0,233,241,212,206,111,242,114,165, 17, 90,254,241,227,235,163,244,180,143,138,254,209, 74, 34, 35,155, 95, +209,194,168, 35, 24,215, 87, 30, 86,228, 77, 41, 68, 0, 88, 15,154,140, 34, 3, 85,219,159,171,244,210,244, 1,225,171,215,202, +128, 6,145,123, 88, 87, 48, 94, 70,212,102,137,124, 92, 95,217,250,105,157, 52,225,239,106,244,112,227, 64, 71, 47,102, 60, 47, + 77,214, 91,128, 31, 61, 28,192, 9, 39, 95,228,166,136, 0, 31, 23,228,253, 52, 4, 60,172, 56,115,160,124, 92,165, 15, 12,159, + 28,119, 32, 17,232, 58, 72,225,234,167,133, 9,100, 64, 2,168, 10, 0, 22, 0, 15, 0, 42, 88,199, 39,147,126, 79,211, 73,229, +184,159,123,242, 85,151, 16, 72, 83, 49,169, 30,228, 26, 99, 18, 79, 26,151,229,175,245,191, 39,233,166, 54, 53,201,247,191, 39, +233,168, 82, 58,243,166, 76, 72, 97, 97,194,223,203, 83, 6, 53,190,183,228,253, 52,162, 0, 26,197,185,143, 69, 1, 6, 57,116, +130, 43,153,245,113,244,212,246,195,136,241, 39,242, 84,102,195, 26,236,175,195,217,250,104, 0,128, 72,249,105,207,197, 26,222, + 0,212,159, 41, 96, 61,255, 0, 31, 71,233,164,147, 23,220,111,126,215, 30,143,211, 66,149,177,113,113,122, 59,143,116,159, 93, + 26, 60, 45, 50, 15,127,194,252,189, 94,218, 43, 97,234, 83,102,176,191,163,244,209,132, 70,198,107, 49, 7,145, 31,201, 82,137, + 54,165,135, 11, 72,185,126, 62,207,211, 69,242,220,126, 59,252,159,166,163, 41, 22, 66,124, 42,179,114,218,176, 55, 46,147,102, + 68, 93,225,191, 74, 69,119,141,151, 85,131, 0,209,178,181,143,141, 94, 62, 63,243,173,126, 28,191, 77, 71,147, 18,246, 26,252, +125, 31,166,173, 91, 78, 83,105,245, 68,178, 86, 81,100,154,232,200,184,248,208, 98,226,166, 22, 36, 98, 40, 99, 26, 99, 69,228, + 5, 74,128,116, 96, 98,220,108,121, 10,120,197,183,215,252,159,166,145,224,184, 42, 31,159,171,244,213,158,108,144,150,139, 72, + 26, 51, 96, 60, 44, 65,245,211,142, 86, 57, 82, 9, 34,254, 53, 23,201,155,155, 63,228,253, 53,222, 77,191, 95,242,126,154, 1, + 81,195,204,130,250,172, 13,205, 77, 83,244,208, 49,112,136,125,122,185,122,191, 77, 76,242,252,111,171,242, 80,165,113, 79,182, +107,248, 31,229,163,168,229, 70,108,125, 76, 88,183, 63, 87,233,167,199,141,199,226,252,148, 32,232,215,133, 28,112, 90, 84,128, + 1,197,184, 14,116,133,146,246,226, 64,245, 15,166,180,154, 92, 73, 15,145,214,225, 92, 13,169, 65, 95, 95,204, 62,154,235, 41, +244,252,195,233,171,222,186,152,250,250, 14, 12, 41,195,143, 42,104, 81,235,249,135,211, 68, 5, 71,129,249,135,211, 87,190,189, + 81, 98,221, 4,179, 82,133,227,202,148, 48, 30, 7,230, 31, 77, 56, 74, 63, 84,252,195,233,171,223, 94,161,213,244, 8,150, 20, +112,252, 45, 81, 68,139,250,173,243, 15,166,158, 39, 65,245, 91,230, 31, 77, 71,106,245, 42,175,128,126, 39,194,148, 41,160,249, +164,253, 86,249,135,211, 93,230,215,245, 91,230, 31, 77,103,185,117, 21, 86, 92, 80,123, 94,147, 77, 8,101,160,250,173,243, 15, +166,184,229,199,250,141,243, 15,166,167,114,234, 91, 38,248, 6,211,252,159,158,186,133,230, 23, 78,171, 55,195,171,195,245,180, +250,107,170,247, 46,164,135,246, 21,110, 7,185,126,102, 56,255, 0,113,105,156, 65,225, 69, 49, 59, 8,216, 21,183, 78, 62,110, +160,252, 11,224, 72,164,232,191,243, 63,109, 63,214,168,104, 31, 62, 53,215, 28,127,146,137,209,123,243, 79,219, 79,166,151,160, +247,248,147,151, 31,125,127,214,160, 60,195, 97, 92,188,189,239,182,218,108,166,120, 81,251,134, 65, 11,141, 94,252, 59,135, 73, + 91, 81, 60,244, 73,165,127, 84, 14, 28,232,219,191,119,239,248, 25,219,198,221, 9,140,205,181,174,102, 91, 51,165,212, 98,152, +177,142, 27, 55,177,242, 90,254,158,153,173,190, 44, 59, 31, 90, 15, 36,112,122,191,226,188,167, 69,241,245,255, 0, 20,121,222, +150,134,191,241,109,213,183,214,248,184,212, 72, 54,173,167, 31,120,222, 51,178,115, 96,200,206,202,130, 33,151,143, 60,184,246, +135, 13, 4,154, 21,163, 22, 34, 50, 89,238,207,207,228,160, 51,171,220,123,222, 38,230, 54,140,137,211, 40, 67,184, 77,136,249, +134, 37, 78,172,107,181, 29,201, 69,147,221, 12,146, 88, 27,120, 84,217, 55,205,210, 94,209,237,253,198, 57, 82, 28,237,227,238, +200,230,200, 8, 10,198,115, 58,125, 87, 68,111,118,254,241, 10, 15,137,169,237,141,217, 35,106,129, 92,237, 63,116, 9,201,198, + 45, 46, 41,199,243, 22, 98,116, 22,125, 29, 75,106,191,141,175, 83,178, 32,216,219, 99, 85,200,242, 63,112,152,163, 8, 94, 92, +113,137,209, 58,122, 58, 78,174,152, 95,135, 69,189, 86,168, 15, 60,197,223,247,236, 45,141,142, 46,106,171, 97, 99,111,123,164, +146,203, 24,147,204,190, 38,225, 36,105, 0,214,222,234, 88,219,221, 55, 23, 91,122,238,241, 59,139,122,159,185,162,198,146, 85, + 92, 25, 55, 57,182,227,137,210, 26,130, 38,216,187,136, 99, 39,197,168, 73,195,217, 87, 79, 7,103, 54, 30,223,113,180, 12, 17, + 43,157,179,237,113, 68, 61,110,161,234,121,123, 48, 93, 93, 79,139, 79,214,231,198,167, 8,118,115,154, 52,121, 1,157,230, 94, +218, 95, 31,173,230,250, 3, 95,214,213,213,242,252,254,182,143,230,208, 25,205,131, 19,112,219,123,168,237, 51,238, 47,151, 6, + 22,199,183,166,151, 91, 7,117,147, 34, 6,154,197,154,204,198, 45, 68,220,158, 54,191, 1, 84,143,222,221,194,153,111,129,170, + 35, 34,187,109, 65,180, 11,253,227, 38,116,144, 64,109,195,135,150, 69,123,127, 58,252,133,122, 11,193,183, 29,218, 62,161,195, +251,231,160,221, 43,188, 3, 43,203,234,247,180,251,221, 78,158,190,126, 23,168,135, 31,183,124,193,212,118,223, 49,231, 87, 85, +228,198,215,231,250,103, 69,253,235,249,142,157,237,245,180,250,168, 12,100,189,231,190, 67, 14,249, 58, 74,179, 38, 62,223,151, +157,133, 43, 66,137, 16,147, 27, 33,177,192,137, 67,153, 26, 63, 3,213, 0,150, 6,220, 40,243,238, 59,222, 70,227,131,139, 54, +229,255, 0,131,238, 67,130,210, 36,106,157, 88, 78,220,114,194,186,169,177, 0,187, 45,189,135,152,171,244,198,236,133,108,189, + 13,179,106, 43, 57,206,251, 92, 50,116,106, 30,103,173,239,124, 58,173,212,191, 11,243,169,185, 56,253,187,103,243,135,109,183, +156, 78,167, 86, 76,111,252,126,132,233,234,212,223,199,209,167, 79,214,181,168, 12,206,247,185,239,120, 93,223, 60, 56, 25,166, + 56,178,113,182,172,116, 70, 64,233, 7,154,205,158, 6,148, 41, 54, 47,238,216, 19,204,176, 7,144, 21,113,139,188,111,115,118, +142,126,106,201,142, 55, 60, 73,179, 48,224,202,156,172, 48,202,248,249, 50, 98,199, 39,188, 66, 13,122, 7,142,157, 94,170,153, +186, 99,118,217,200, 97,188,157,183,205, 28,114, 27,205, 75,140, 37,242,218,197,255, 0,136,218,186,122,237,234,213,235,169,139, + 30,210,187, 33, 86, 24, 45,176,244, 72,185,146, 15, 41,208,246,234,233,232,252,149, 1,128,200,239, 78,232, 88,142, 62, 32,121, +242, 48,227,203,159, 33,102,143, 22, 7, 7, 30, 72,163, 88,115, 90,105,226,137, 85,122,135, 83, 64, 91,154,145,227, 87,152, 93, +193,191,100,247,123,237,253, 50, 54,177,155, 62, 1,103,242,234,128, 67,136, 50, 67, 37,229,243, 15, 41,126, 99,167,167, 65,245, + 94,173,124,191, 97,140, 93,191,168,118,127, 46,146,191,221,218,165,196,233,245,181, 40,147,163,239, 89,159, 94,157, 86,227,170, +215,227, 86, 49,195,219,131,127,119,140,237,255, 0,230, 13, 22,144, 7,128,230,104, 10,191, 16,191, 82,218, 52,252,150,240,181, + 1,131,238,231,220,215,187, 90, 8, 55, 25, 34,133,134,195,211,132, 15,117, 26, 93,206, 72,153,172, 24, 95,224,247,191, 88, 27, + 30, 2,151, 31,126,222, 37, 88,167, 18, 98,190,230,187,110,240,145,101,228,233,137, 90, 92, 93,206, 28, 24,117, 18, 86, 53,214, + 45,195,145,107,120, 86,235,113,139,182,126,243,199,251,212,237,223,123, 90, 63, 41,230, 91, 31,204,219,172,189, 46,151, 80,235, +183, 95, 78,155,125,123, 91,141, 14, 72,187, 75,160,226, 67,181,244, 12, 57, 93, 77, 79,141,163,161,214, 30,119, 85,205,180,117, +237,213,240,215,241,113,160, 51,195,184,119, 40,123, 31,123,222, 58,133,183, 29,176,100,132, 25, 16,172,114,198,240,174,165,143, + 33, 35, 38, 34,194,252, 76,103, 73, 22,160, 38,243,220, 51,102,201,178,121,244,138, 95,189,178, 48,190,242, 48, 37,196, 48,224, + 38,224,168, 35, 62,229,203,185, 23, 63, 84,122,120,214,167, 26, 14,218, 93,138, 85,199, 59,119,220, 1,100, 25, 26, 95, 28,226, +105,185,234,245, 78,163, 31, 59,234,213,242,211, 55, 24, 59, 85,177,114,198,232,118,223, 45,230, 71,157,235,201,142, 19,205,116, +214,221, 98,237,110,175, 75, 79,197,239,105,183,133, 1,231,131,124,221,179,183, 61,179,115,202,144,104,207,196,237,217,223, 1, +144,244,145,242,179,222, 55,146, 49,126, 7,129, 96,125, 99,208, 42,124,189,213,220, 9,137, 22,100,121,113, 77, 38,231,144,240, + 99,237,209, 36, 94,103, 29, 87, 63,201, 3, 15, 89,163,141,253,207,116,153, 90,221, 66, 60, 56, 86,203, 42, 30,214,243,184,158, +116,237,158,127, 68, 94, 67,172,248,221,110,159, 85,122, 61, 13,109,171, 79, 91, 78,141, 63, 90,214,227, 81,159, 23,178, 11,110, +157, 70,218,117,185, 31,124, 94, 92, 91,223,169, 97,230,125,239,116,245,127, 91,235,250,234,130, 36, 27,246,226,189,147, 62,243, +156,241, 98,103,194,153, 1,164,101, 89,213, 76, 51, 60, 8,236,152,174,232, 92,133, 4,170,189,131,112,170, 21,221,183,205,198, + 77,152, 79,149, 38, 52,152,253,195, 38, 4,193,146, 37,146, 72,215, 18,105,149,103, 16, 59, 69,113,197, 72, 83,110, 71,152,173, +199,151,216, 78,198, 70,172, 31,184,122, 36, 27, 73, 7,147,232, 91,143, 29, 93, 61, 22,249, 42, 12, 88,253,152,184,170, 34, 59, + 71,148, 25, 49, 5,180,152,134, 63, 55,164,116,120,234,183, 91, 77,180,253,107,114,160, 42,247,125,227,121,199,238, 88,176, 97, +202, 72, 54,249, 90, 12,100,116,142, 57,213,102,152, 72, 74,101, 13, 93,104,228,111,116,197,195, 65,250,213,151,237,174,230,222, +225,197,237,220,115,152,217,145,200,155,116, 89, 97,163, 83,164,102,245, 7,219,205, 35,245, 26, 79,119,220,208, 15,194,117,243, +175, 69,155, 31,182,190,251,133,178, 91,110,251,244, 0, 32,234, 73,143,230,236, 67,105,208, 25,186,156,181, 90,222, 23,245,213, +102, 54, 55,225,247, 94, 54,198,109,143,175,117, 17,116,228,194,213,171,172,116,105, 10,220,250,215,181,190,181,252,104, 12,214, + 78,231,220, 25,120,251, 46,235, 38,229,211, 89,119,188,188,100,199,138, 32,170, 35,197, 93,194, 53, 87,109, 87,125, 66, 14, 32, +240,228,121,138,124, 29,223,189,228,226, 99,176,154, 40,165,159, 31,183, 28,203,211, 4, 35,238,210,188, 89, 45,164,155,114, 0, +168,240,173,164,240,118,215,145,135,204, 29,183,200,121,163,229,186,143,141,209,243,157, 87,191, 79, 83,105,235,117,117,242,247, +181, 95,198,169, 95,108,236, 60,172, 23,143, 23, 35,106,131, 6, 57,240,231,201,108, 73,240,213, 24,197, 49,151, 26, 57,200, 37, + 74, 59,134, 80,167,159, 16,180, 5,151,109,238,147,238, 91,115, 12,217, 86, 76,168,114,115, 49,122,138, 2,245,147, 19, 38, 76, + 97, 48, 65,233, 10, 47,110, 23,172, 92,221,227,191,226,224,230,103,117,227,153,159, 19,121,158, 8,250, 64, 8, 31,108,203, 92, +104,139, 88,221,131,171,251,215,241,181,171,117,129,131,176,117,240,102,218,100,195,188,120,179, 69,131, 30, 44,208,105, 56,205, + 44, 70,102,140, 70,222,242,137, 17, 46, 71, 0,125,102,171, 54,189,175,178,176, 97,220, 33,143, 35,109,201, 36,100, 62,231, 44, +211,226, 72,253, 41, 39,146,105,151, 36,130, 62,205, 36,114,190,240,225, 96, 15, 42,140, 34,179, 39,125,238, 76, 62,224,135,106, + 13,230,160,198,147, 2, 60,185,202,227,195, 19, 12,233,100, 87,102,234, 76,178,130,168, 45, 18,198,173,114,167, 85,239, 80, 95, +185, 59,153,159, 43, 20,100,196,217, 50,186,190, 44, 81,140,114, 37,128,228,152,245,109,147, 25, 58, 82,183, 72, 91, 68,199, 86, +187,248, 86,223, 47, 31,183,206,245,136,217,231,111,251,224, 45,176,186,210, 99,249,157, 36,181,186, 65,219, 95, 61, 86,183,175, +215, 85,210, 98,118, 25,143, 48,106,217,180, 60,168,119, 15,181,196, 22,125,109,167,170,117,240,110,165,237,127,173,127, 27,209, + 20,169,205,220, 36,220,251, 95,103,155, 35, 35,169, 30,126,110, 30, 62,108,168,173,143,170, 38,202, 17, 60,110,183,186,106,210, + 17,192, 54,226, 64,225, 81,183, 29,167, 99, 87,192,198,192,121,101, 72,247,165,195,200,141,158, 85, 88,131,196,243,190, 36,118, +208, 12, 96,176, 97,107,216,240,191, 11, 13,123,227,236, 71,102,180,231, 3,238, 19, 10,129,121, 49,198, 31, 71,234,219,222,233, +232,189,173,225, 75,129,141,219, 73,131,136,155,123,109,199, 4, 79,108, 35, 12,152,230, 47, 51,239,127, 4,171, 91,171,241,114, +247,185,208, 30,111,186,121,156,125,199,116,200,141, 30, 56, 32,222, 6, 34,238, 41,144,250,227, 67,183,195,167, 23,203,240, 83, + 27,179, 88,182,174, 26,175,106,215,203,191, 79,177,246, 22, 54,233, 12, 18,101,100,197,181, 9,208,232, 50, 32,146, 60, 97, 32, +105,236,202,193, 53, 14, 38,245,117,147, 7,111, 24,167,243, 71,111,233,121,149,243, 93, 71,199,211,231, 52, 38,142,174,166,183, + 91, 70,139, 95,222,181,189, 85, 3,108,199,236,111, 41,184,253,198,219, 41,193,233,255, 0,243, 99,135, 38, 31, 75,165,165,255, + 0,241, 93, 38,211,163, 78,191,143,133,175,235,160, 42,247, 77,202, 76,157,241,101,209, 62, 36, 71, 99,220,219,163, 56, 49,157, +113,203,137,103,211,114, 46, 3, 27, 26,133,186,101,110, 56,219, 31,101,100,227,228, 58, 55, 82, 14,188, 64, 92,204, 70,223, 60, +186, 28,243, 55, 41,107,122, 77,249,129, 90,173,255, 0, 23,183, 26, 56, 7,115, 54,221,211, 12,199, 27,239, 9,113,192,184, 30, +254,142,187,122, 62, 43,120,115,163,238,120,251, 79,151,199,251,212,225,121,126,180,126, 87,205, 73, 6,142,191,246, 61, 46,171, + 91, 95,234,219,143,162,128,207,246,150,247,186,230,206,216,251,158, 66,102, 9,118,236, 29,205, 38,142, 49, 24,141,179, 58,193, +224,247, 73, 5, 71, 72, 21, 39,141,189, 53, 69,145,222,123,212,120, 25, 57, 40,209,117, 98,219,247,172,181,186,112,234, 96,103, +174, 36, 28, 47,203,166,120,250, 77,109,182,124, 77,140, 46, 71,220, 45,129,164,201,124,159, 37, 46, 57, 29, 66, 63,180,233, 55, + 59,122,106,163, 55,106,236,204,216,119,124, 49,147,182, 99, 79,145, 14, 66,110,121, 24,217, 24,105,145, 28,108,202, 50, 90, 71, +212, 74,217,244,235,212, 45,170,215,227, 84,133,100,251,206,246,185,217, 29,191,231, 99, 13, 30,108,208, 54,228, 34, 95,126, 36, +219, 70,226, 35, 9,125, 32,235,123, 18, 13,244,143, 79, 26,139,180,247, 30,235, 4, 29,175,139, 20,221,104, 31, 23,102,139, 50, + 51, 26,144, 60,236, 68, 51, 79, 52,142, 36,105, 27, 78,164,233,130, 56, 29, 92,235, 88,184,221,151,247, 81, 19, 29,163,238,191, + 50, 91,140,184,190, 95,205, 88,177,227,171, 71, 82,215,225,206,220, 57, 81, 27, 31,178, 60,198, 43, 49,217,252,199, 71, 24, 96, +222, 76, 77, 93, 13, 67,202,116, 70,175,131, 85,186, 90,120,126,173, 1,131,135,185, 59,163,108, 92,220,108, 57, 91, 57,224,200, +221,242,153,159,203,162,219, 27, 59,203,172,114,190, 84,209,104,135,137,190,139,176,186,129,192,113,216,247,191,112,103,118,214, + 46, 54,227, 6,147,138,222,102, 25,144,174,166, 51,156,105, 37,196,183,182, 88,130,127, 88, 84,172,140,126,196, 57, 63,226,206, +205,230,151, 41,139,117, 36,196, 18,121,191,112, 62,171,181,204,191, 5,239,199,225,245, 84,158,228,218,176,115,224,195,251,219, + 54, 60, 92, 44,124,168,102,100,121, 96, 72,230,149, 28, 52, 17,187,202,124,100, 3,130,145,171,149, 1,149,135,184, 59,142, 28, +232,252,212,241,200,163, 57,246,153,112,150, 32, 8,104,182,227,154,114,181,143,123,140,139,123,124, 58, 72,246,208,177,251,195, +127,201,194,199,233, 75, 12,121, 25, 24,253,182,194, 67, 16, 96,178,110,242,188, 89, 45,167, 80,184,176, 26, 69,248, 86,205,113, +246, 15,190,217,181, 96,125,249,211,179,253,164, 30,107,167, 97,204,106,234,105,211,111,146,163,237,144,246, 42,196,195,105, 59, + 57,143,169,140, 91,203, 62, 33, 29, 83, 35,121, 59,232,111,139,171,126,151,243,190, 26, 1, 55,237,215, 63,105,159, 98,194,142, + 85,144,230, 60,241,102, 74,232, 1,126,142, 20,249, 1,128, 28, 22,242, 68, 9,183,178,178,112,247,126,253,167,103,220, 39,154, + 51,139,149,133,131, 44,169, 10, 36,136,114,114, 49,218,121, 97,200, 10,221,104, 93,253,222,137, 11,163,211, 91,173,238, 13,137, +224,139,252,200,216, 35, 31,170,166, 31, 62,240,132,235, 5,109, 58, 58,205,109, 90,117,124,151,168,112,227,246,111,222, 24, 45, +142,219, 87,222, 2, 24,198,219,211,147, 23,171,208, 40,122, 62, 92, 43,106,209,211,190,141, 63, 86,246,225, 89,110, 95, 2,163, + 35,129,221,125,213, 62,216, 30, 98,144, 79,147, 54,204, 49,167,153,113,216,133,221, 38,233, 75,104,113,103,147,236,212, 88,198, +100, 33,141,248,242,173, 71,114,230,110,120,107,180,109,152,217,139, 12,153,189,117,202,205,104,212,150, 24,248,146, 78, 66,167, + 5, 94,163, 37,205,185, 11,219,211, 82,118,232, 59, 49,113,152,109,103,106,242,199, 38, 18,222, 93,241,140,126,108,186,156,127, +129,173,213,215,167,167,227,123,105,169,251,236, 59, 27, 97,160,238, 51,133,228,250,170, 99,243,239, 8,143,170, 3, 21,211,214, + 58,117,105,213,242, 95,194,159, 0,121,238,201,221,155,244, 81,246,238, 30, 60,102, 92, 72,176,118, 52,203,146, 67, 0, 71,243, +201,162, 89, 37,146,121,146, 98,224, 11,198, 35, 70,187, 3,126,117, 93, 7,114,111, 59, 4, 27,140,152,217,158,103, 35,207,238, + 89, 89, 41,208, 66, 93, 96,207, 24,129,167,146, 71, 93, 49,105,247, 66,199,239,130, 64, 30,232,173,243,227,246,155,102,109,140, +135,107,243, 98, 24,198,207,105, 49, 68,158, 92,131,210,242,163, 85,244, 90,250, 52,112,181,237, 64,204,198,236,130,192,238, 77, +179,234, 13,147,110,188,184,159, 22,191,241,151, 14,220, 79, 83,248,191,206,248,184,213,248, 2, 4,253,223,184,182,235, 54,220, + 74, 8, 14,235,151,129,193,108,221, 8,182,145,156,150, 55,248,186,199,159,163,133,102,182,237,235,184, 49,198,220,248, 25,236, +239, 47,111,108, 68, 98,185,140,200,198, 70,152, 78,113,188,203, 44,111,144, 86, 54, 35, 87,197,200,242, 21,187,242,221,163,247, +185, 37,182,175,190, 79, 59,201,139,230,184, 66,124, 53,107,254, 5,255, 0,169,234,160,102,227,118, 51, 71,140,185,237,179,104, + 56,177,140, 46,172,152,131,252, 38,165,233,116, 11, 55,240,181,105,211,167,221,189,173, 83,224, 11, 46,218,223,151,115,217,241, +114,102,153, 50, 50, 89, 47, 51, 42, 24,143,196,200, 11,196, 73, 40,125,194, 15,133,193,183, 10,183,243,177,250, 42,163,108,199, +216,238,126,230,108, 27,244, 97,191,148,146, 15,252, 63,191,229,255, 0,132,223,195,248,244,120,115,183,141, 88,249,115,250,201, +255, 0,180, 79,245,169, 30, 2, 67,121,216,253, 21,222,118, 47, 69, 3,203,159,214, 79,253,162,127,173, 93,229,207,235, 39,254, +209, 63,214,164, 9, 36,121,216,255, 0, 86,187,206, 71,232,160,116, 15,235, 39,237,167,250,212,225, 7,243,147,246,211,233,164, +120, 2, 87,152, 78,158,171,127,103,127,147,169,166,186,135,160,105,233,220, 95,163,206,227, 79,241,127, 91,149,117, 1,255,217, +}; + +#endif diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c new file mode 100644 index 00000000000..77252808170 --- /dev/null +++ b/source/blender/src/renderwin.c @@ -0,0 +1,809 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#include <string.h> +#include <stdarg.h> +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "BLI_blenlib.h" + +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "DNA_view3d_types.h" +#include "DNA_screen_types.h" +#include "DNA_vec_types.h" + +#include "BKE_global.h" +#include "BKE_utildefines.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" +#include "BIF_graphics.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_mywindow.h" +#include "BIF_renderwin.h" +#include "BIF_toets.h" + +#include "BDR_editobject.h" + +#include "BSE_view.h" +#include "BSE_drawview.h" +#include "BSE_filesel.h" +#include "BSE_headerbuttons.h" + +#include "blendertimer.h" + +#include "blendef.h" +#include "mydevice.h" +#include "winlay.h" +#include "render.h" + +/***/ + +typedef struct { + Window *win; + + float zoom, zoomofs[2]; + int active; + + int mbut[3]; + int lmouse[2]; + + /* flags escape presses during event handling + * so we can test for user break later. + */ +#define RW_FLAGS_ESCAPE (1<<0) + /* old zoom style (2x, locked to mouse, exits + * when mouse leaves window), to be removed + * at some point. + */ +#define RW_FLAGS_OLDZOOM (1<<1) + /* on when image is being panned with middlemouse + */ +#define RW_FLAGS_PANNING (1<<2) + /* on when the mouse is dragging over the image + * to examine pixel values. + */ +#define RW_FLAGS_PIXEL_EXAMINING (1<<3) + unsigned int flags; + + float pan_mouse_start[2], pan_ofs_start[2]; + + char *info_text; +} RenderWin; + +static RenderWin *renderwin_new(Window *win) +{ + RenderWin *rw= MEM_mallocN(sizeof(*rw), "RenderWin"); + rw->win= win; + rw->zoom= 1.0; + rw->active= 0; + rw->flags= 0; + rw->zoomofs[0]= rw->zoomofs[1]= 0; + rw->info_text= NULL; + + rw->lmouse[0]= rw->lmouse[1]= 0; + rw->mbut[0]= rw->mbut[1]= rw->mbut[2]= 0; + + return rw; +} +static void renderwin_destroy(RenderWin *rw) +{ + if (rw->info_text) MEM_freeN(rw->info_text); + window_destroy(rw->win); + MEM_freeN(rw); +} + +/***/ + +static void close_renderwin(void); + +static RenderWin *render_win= NULL; + +/**/ + +static void renderwin_queue_redraw(RenderWin *rw) +{ + window_queue_redraw(rw->win); +} + +static void renderwin_reshape(RenderWin *rw) +{ + ; +} + +static void renderwin_get_disprect(RenderWin *rw, float disprect_r[2][2]) +{ + float display_w, display_h; + float cent_x, cent_y; + int w, h; + + window_get_size(rw->win, &w, &h); + + display_w= R.rectx*rw->zoom; + display_h= R.recty*rw->zoom; + cent_x= (rw->zoomofs[0] + R.rectx/2)*rw->zoom; + cent_y= (rw->zoomofs[1] + R.recty/2)*rw->zoom; + + disprect_r[0][0]= w/2 - cent_x; + disprect_r[0][1]= h/2 - cent_y; + disprect_r[1][0]= disprect_r[0][0] + display_w; + disprect_r[1][1]= disprect_r[0][1] + display_h; +} + + /** + * Project window coordinate to image pixel coordinate. + * Returns true if resulting coordinate is within image. + */ +static int renderwin_win_to_image_co(RenderWin *rw, int winco[2], int imgco_r[2]) +{ + float disprect[2][2]; + + renderwin_get_disprect(rw, disprect); + + imgco_r[0]= (winco[0]-disprect[0][0])/rw->zoom; + imgco_r[1]= (winco[1]-disprect[0][1])/rw->zoom; + + return (imgco_r[0]>=0 && imgco_r[1]>=0 && imgco_r[0]<R.rectx && imgco_r[1]<R.recty); +} + + /** + * Project window coordinates to normalized device coordinates + * Returns true if resulting coordinate is within window. + */ +static int renderwin_win_to_ndc(RenderWin *rw, int win_co[2], float ndc_r[2]) +{ + int w, h; + + window_get_size(rw->win, &w, &h); + + ndc_r[0]= (float) (win_co[0]*2)/(w-1) - 1.0; + ndc_r[1]= (float) (win_co[1]*2)/(h-1) - 1.0; + + return (fabs(ndc_r[0])<=1.0 && fabs(ndc_r[1])<=1.0); +} + +static void renderwin_set_infotext(RenderWin *rw, char *info_text) +{ + if (rw->info_text) MEM_freeN(rw->info_text); + rw->info_text= info_text?BLI_strdup(info_text):NULL; +} + +static void renderwin_draw(RenderWin *rw, int just_clear) +{ + float disprect[2][2]; + rcti rect; + + rect.xmin= rect.ymin= 0; + window_get_size(rw->win, &rect.xmax, &rect.ymax); + renderwin_get_disprect(rw, disprect); + + window_make_active(rw->win); + + glEnable(GL_SCISSOR_TEST); + glaDefine2DArea(&rect); + + glClearColor(.1875, .1875, .1875, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + if (just_clear || !R.rectot) { + glColor3ub(0, 0, 0); + glRectfv(disprect[0], disprect[1]); + } else { + glPixelZoom(rw->zoom, rw->zoom); + glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, R.rectot); + glPixelZoom(1.0, 1.0); + } + + if (rw->info_text) { + glColor3ub(255, 255, 255); + glRasterPos2i(10, 10); + BMF_DrawString(G.font, rw->info_text); + } + + window_swap_buffers(rw->win); +} + + /* XXX, this is not good, we do this without any regard to state + * ... better is to make this an optimization of a more clear + * implementation. the bug shows up when you do something like + * open the window, then draw part of the progress, then get + * a redraw event. whatever can go wrong will. + */ +static void renderwin_progress(RenderWin *rw, int start_y, int nlines, int rect_w, int rect_h, unsigned char *rect) +{ + float disprect[2][2]; + rcti win_rct; + + win_rct.xmin= win_rct.ymin= 0; + window_get_size(rw->win, &win_rct.xmax, &win_rct.ymax); + renderwin_get_disprect(rw, disprect); + + window_make_active(rw->win); + + glEnable(GL_SCISSOR_TEST); + glaDefine2DArea(&win_rct); + + glDrawBuffer(GL_FRONT); + glPixelZoom(rw->zoom, rw->zoom); + glaDrawPixelsSafe(disprect[0][0], disprect[0][1] + start_y*rw->zoom, rect_w, nlines, &rect[start_y*rect_w*4]); + glPixelZoom(1.0, 1.0); + glFlush(); + glDrawBuffer(GL_BACK); +} + +static void renderwin_mouse_moved(RenderWin *rw) +{ + if (rw->flags&RW_FLAGS_PIXEL_EXAMINING) { + int imgco[2]; + char buf[64]; + + if (R.rectot && renderwin_win_to_image_co(rw, rw->lmouse, imgco)) { + unsigned char *pxl= (char*) &R.rectot[R.rectx*imgco[1] + imgco[0]]; + + sprintf(buf, "R: %d, G: %d, B: %d, A: %d", pxl[0], pxl[1], pxl[2], pxl[3]); + renderwin_set_infotext(rw, buf); + renderwin_queue_redraw(rw); + } else { + renderwin_set_infotext(rw, NULL); + renderwin_queue_redraw(rw); + } + } else if (rw->flags&RW_FLAGS_PANNING) { + int delta_x= rw->lmouse[0] - rw->pan_mouse_start[0]; + int delta_y= rw->lmouse[1] - rw->pan_mouse_start[1]; + + rw->zoomofs[0]= rw->pan_ofs_start[0] - delta_x/rw->zoom; + rw->zoomofs[1]= rw->pan_ofs_start[1] - delta_y/rw->zoom; + rw->zoomofs[0]= CLAMPIS(rw->zoomofs[0], -R.rectx/2, R.rectx/2); + rw->zoomofs[1]= CLAMPIS(rw->zoomofs[1], -R.recty/2, R.recty/2); + + renderwin_queue_redraw(rw); + } else if (rw->flags&RW_FLAGS_OLDZOOM) { + float ndc[2]; + int w, h; + + window_get_size(rw->win, &w, &h); + renderwin_win_to_ndc(rw, rw->lmouse, ndc); + + rw->zoomofs[0]= -0.5*ndc[0]*(w-R.rectx*rw->zoom)/rw->zoom; + rw->zoomofs[1]= -0.5*ndc[1]*(h-R.recty*rw->zoom)/rw->zoom; + + renderwin_queue_redraw(rw); + } +} + +static void renderwin_mousebut_changed(RenderWin *rw) +{ + if (rw->mbut[0]) { + rw->flags|= RW_FLAGS_PIXEL_EXAMINING; + } else if (rw->mbut[1]) { + rw->flags|= RW_FLAGS_PANNING; + rw->pan_mouse_start[0]= rw->lmouse[0]; + rw->pan_mouse_start[1]= rw->lmouse[1]; + rw->pan_ofs_start[0]= rw->zoomofs[0]; + rw->pan_ofs_start[1]= rw->zoomofs[1]; + } else { + if (rw->flags&RW_FLAGS_PANNING) { + rw->flags&= ~RW_FLAGS_PANNING; + renderwin_queue_redraw(rw); + } + if (rw->flags&RW_FLAGS_PIXEL_EXAMINING) { + rw->flags&= ~RW_FLAGS_PIXEL_EXAMINING; + renderwin_set_infotext(rw, NULL); + renderwin_queue_redraw(rw); + } + } +} + +static void renderwin_reset_view(RenderWin *rw) +{ + if (rw->info_text) renderwin_set_infotext(rw, NULL); + + rw->zoom= 1.0; + rw->zoomofs[0]= rw->zoomofs[1]= 0; + renderwin_queue_redraw(rw); +} + +static void renderwin_handler(Window *win, void *user_data, short evt, short val, char ascii) +{ + RenderWin *rw= user_data; + + if (evt==RESHAPE) { + renderwin_reshape(rw); + } else if (evt==REDRAW) { + renderwin_draw(rw, 0); + } else if (evt==WINCLOSE) { + close_renderwin(); + } else if (evt==INPUTCHANGE) { + rw->active= val; + + if (!val && (rw->flags&RW_FLAGS_OLDZOOM)) { + rw->flags&= ~RW_FLAGS_OLDZOOM; + renderwin_reset_view(rw); + } + } else if (ELEM(evt, MOUSEX, MOUSEY)) { + rw->lmouse[evt==MOUSEY]= val; + renderwin_mouse_moved(rw); + } else if (ELEM3(evt, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE)) { + int which= (evt==LEFTMOUSE)?0:(evt==MIDDLEMOUSE)?1:2; + rw->mbut[which]= val; + renderwin_mousebut_changed(rw); + } else if (val) { + if (evt==ESCKEY) { + if (rw->flags&RW_FLAGS_OLDZOOM) { + rw->flags&= ~RW_FLAGS_OLDZOOM; + renderwin_reset_view(rw); + } else { + rw->flags|= RW_FLAGS_ESCAPE; + mainwindow_raise(); + } + } else if (evt==JKEY) { + BIF_swap_render_rects(); + } else if (evt==ZKEY) { + if (rw->flags&RW_FLAGS_OLDZOOM) { + rw->flags&= ~RW_FLAGS_OLDZOOM; + renderwin_reset_view(rw); + } else { + rw->zoom= 2.0; + rw->flags|= RW_FLAGS_OLDZOOM; + renderwin_mouse_moved(rw); + } + } else if (evt==PADPLUSKEY) { + if (rw->zoom<15.9) { + rw->zoom*= 2.0; + renderwin_queue_redraw(rw); + } + } else if (evt==PADMINUS) { + if (rw->zoom>0.26) { + rw->zoom*= 0.5; + renderwin_queue_redraw(rw); + } + } else if (evt==PADENTER || evt==HOMEKEY) { + if (rw->flags&RW_FLAGS_OLDZOOM) { + rw->flags&= ~RW_FLAGS_OLDZOOM; + } + renderwin_reset_view(rw); + } else if (evt==F3KEY) { + mainwindow_raise(); + mainwindow_make_active(); + areawinset(find_biggest_area()->win); + BIF_save_rendered_image(); + } else if (evt==F11KEY) { + BIF_toggle_render_display(); + } else if (evt==F12KEY) { + BIF_do_render(0); + } + } +} + +/**/ + + /* Render window render callbacks */ + +void calc_renderwin_rectangle(int posmask, int renderpos_r[2], int rendersize_r[2]) +{ + int scr_w, scr_h, x, y, div= 0; + float ndc_x= 0.0, ndc_y= 0.0; + + /* XXX, we temporarily hack the screen size and position so + * the window is always 30 pixels away from a side, really need + * a GHOST_GetMaxWindowBounds or so - zr + */ + winlay_get_screensize(&scr_w, &scr_h); + + rendersize_r[0]= (G.scene->r.size*G.scene->r.xsch)/100; + rendersize_r[1]= (G.scene->r.size*G.scene->r.ysch)/100; + if(G.scene->r.mode & R_PANORAMA) { + rendersize_r[0]*= G.scene->r.xparts; + rendersize_r[1]*= G.scene->r.yparts; + } + + rendersize_r[0]= CLAMPIS(rendersize_r[0], 100, scr_w-90); + rendersize_r[1]= CLAMPIS(rendersize_r[1], 100, scr_h-90); + + for (y=-1; y<=1; y++) { + for (x=-1; x<=1; x++) { + if (posmask & (1<<((y+1)*3 + (x+1)))) { + ndc_x+= x; + ndc_y+= y; + div++; + } + } + } + + if (div) { + ndc_x/= div; + ndc_y/= div; + } + + renderpos_r[0]= 60 + (scr_w-90-rendersize_r[0])*(ndc_x*0.5 + 0.5); + renderpos_r[1]= 60 + (scr_h-90-rendersize_r[1])*(ndc_y*0.5 + 0.5); +} + +static void open_renderwin(int winpos[2], int winsize[2]) +{ + Window *win; + + win= window_open("Blender:Render", winpos[0], winpos[1], winsize[0], winsize[1], 0); + + render_win= renderwin_new(win); + + window_set_handler(win, renderwin_handler, render_win); + + winlay_process_events(0); + window_make_active(render_win->win); + winlay_process_events(0); + + renderwin_draw(render_win, 1); + renderwin_draw(render_win, 1); +} + +static void close_renderwin(void) +{ + if (render_win) { + renderwin_destroy(render_win); + render_win= NULL; + } +} + +static void renderwin_init_display_cb(void) +{ + if (G.afbreek == 0) { + int rendersize[2], renderpos[2]; + + calc_renderwin_rectangle(R.winpos, renderpos, rendersize); + + if (!render_win) { + open_renderwin(renderpos, rendersize); + } else { + int win_x, win_y; + int win_w, win_h; + + window_get_position(render_win->win, &win_x, &win_y); + window_get_size(render_win->win, &win_w, &win_h); + + /* XXX, this is nasty and I guess bound to cause problems, + * but to ensure the window is at the user specified position + * and size we reopen the window all the time... we need + * a ghost _set_position to fix this -zr + */ + close_renderwin(); + open_renderwin(renderpos, rendersize); + + renderwin_reset_view(render_win); + render_win->flags&= ~RW_FLAGS_ESCAPE; + } + } +} +static void renderwin_clear_display_cb(short ignore) +{ + if (render_win) { + window_make_active(render_win->win); + renderwin_draw(render_win, 1); + } +} + +static void renderwin_progress_display_cb(int y1, int y2, int w, int h, unsigned int *rect) +{ + if (render_win) { + renderwin_progress(render_win, y1, y2-y1+1, w, h, (unsigned char*) rect); + } +} + + /* Render view render callbacks */ + +static View3D *render_view3d = NULL; + +static void renderview_init_display_cb(void) +{ + ScrArea *sa; + + /* Choose the first view with a persp camera, + * if one doesn't exist we will get the first + * View3D window. + */ + render_view3d= NULL; + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + if (sa->win && sa->spacetype==SPACE_VIEW3D) { + View3D *vd= sa->spacedata.first; + + if (vd->persp==2 && vd->camera==G.scene->camera) { + render_view3d= vd; + break; + } else if (!render_view3d) { + render_view3d= vd; + } + } + } +} + +static void renderview_progress_display_cb(int y1, int y2, int w, int h, unsigned int *rect) +{ + if (render_view3d) { + View3D *v3d= render_view3d; + int nlines= y2-y1+1; + float sx, sy, facx, facy; + rcti win_rct, vb; + + calc_viewborder(v3d, &vb); + + facx= (float) (vb.xmax-vb.xmin)/R.rectx; + facy= (float) (vb.ymax-vb.ymin)/R.recty; + + bwin_get_rect(v3d->area->win, &win_rct); + + glaDefine2DArea(&win_rct); + + glDrawBuffer(GL_FRONT); + + sx= vb.xmin; + sy= vb.ymin + facy*y1; + + glPixelZoom(facx, facy); + glaDrawPixelsSafe(sx, sy, w, nlines, rect+w*y1); + glPixelZoom(1.0, 1.0); + + glFlush(); + glDrawBuffer(GL_BACK); + + v3d->flag |= V3D_DISPIMAGE; + + v3d->area->win_swap= WIN_FRONT_OK; + } +} + + /* Shared render callbacks */ + +static int test_break(void) +{ + if (!G.afbreek) { + if (MISC_test_break()) { + ; + } else if (render_win) { + winlay_process_events(0); + // render_win can be closed in winlay_process_events() + if (render_win == 0 || (render_win->flags & RW_FLAGS_ESCAPE)) + G.afbreek= 1; + } + } + + return G.afbreek; +} + +static void printrenderinfo_cb(double time, int sample) +{ + extern int mem_in_use; + float megs_used_memory= mem_in_use/(1024.0*1024.0); + char str[300], tstr[32], *spos= str; + + timestr(time, tstr); + spos+= sprintf(spos, "RENDER Fra:%d Ve:%d Fa:%d La:%d", (G.scene->r.cfra), R.totvert, R.totvlak, R.totlamp); + spos+= sprintf(spos, "Mem:%.2fM Time:%s ", megs_used_memory, tstr); + + if (R.r.mode & R_FIELDS) { + spos+= sprintf(spos, "Field %c ", (R.flag&R_SEC_FIELD)?'B':'A'); + } + if (sample!=-1) { + spos+= sprintf(spos, "Sample: %d ", sample); + } + + screen_draw_info_text(G.curscreen, str); +} + +/***/ + +void BIF_renderwin_set_custom_cursor(unsigned char mask[16][2], unsigned char bitmap[16][2]) +{ + if (render_win) { + window_set_custom_cursor(render_win->win, mask, bitmap); + } +} + +static void do_crap(int force_dispwin) +{ + if (R.displaymode == R_DISPLAYWIN || force_dispwin) { + RE_set_initrenderdisplay_callback(NULL); + RE_set_clearrenderdisplay_callback(renderwin_clear_display_cb); + RE_set_renderdisplay_callback(renderwin_progress_display_cb); + + renderwin_init_display_cb(); + } else { + BIF_close_render_display(); + + RE_set_initrenderdisplay_callback(renderview_init_display_cb); + RE_set_clearrenderdisplay_callback(NULL); + RE_set_renderdisplay_callback(renderview_progress_display_cb); + } + + RE_set_test_break_callback(test_break); + RE_set_timecursor_callback(set_timecursor); + RE_set_printrenderinfo_callback(printrenderinfo_cb); +} + +static void do_render(View3D *ogl_render_view3d, int anim, int force_dispwin) +{ + do_crap(force_dispwin); + + if (render_win) window_set_cursor(render_win->win, CURSOR_WAIT); + waitcursor(1); + + G.afbreek= 0; + if(G.obedit && !(G.scene->r.scemode & R_OGL)) { + exit_editmode(0); /* 0 = geen freedata */ + } + + if(anim) { + RE_animrender(ogl_render_view3d); + } + else { + RE_initrender(ogl_render_view3d); + } + update_for_newframe(); + R.flag= 0; + + if (render_win) window_set_cursor(render_win->win, CURSOR_STD); + waitcursor(0); + + free_filesel_spec(G.scene->r.pic); + + G.afbreek= 0; + + mainwindow_make_active(); +} + +void BIF_do_render(int anim) +{ + do_render(NULL, anim, 0); +} + +void BIF_do_ogl_render(View3D *ogl_render_view3d, int anim) +{ + G.scene->r.scemode |= R_OGL; + do_render(ogl_render_view3d, anim, 1); + G.scene->r.scemode &= ~R_OGL; +} + +static ScrArea *find_dispimage_v3d(void) +{ + ScrArea *sa; + + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + if (sa->spacetype==SPACE_VIEW3D) { + View3D *vd= sa->spacedata.first; + if (vd->flag & V3D_DISPIMAGE) + return sa; + } + } + + return NULL; +} + +static void redraw_render_display(void) +{ + if (R.displaymode == R_DISPLAYWIN) { + // don't open render_win if rendering has been + // canceled or the render_win has been actively closed + if (render_win) { + renderwin_queue_redraw(render_win); + } + } else { + renderview_init_display_cb(); + renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, R.rectot); + } +} + +static void scalefastrect(unsigned int *recto, unsigned int *rectn, int oldx, int oldy, int newx, int newy) +{ + unsigned int *rect, *newrect; + int x, y; + int ofsx, ofsy, stepx, stepy; + + stepx = (int)((65536.0 * (oldx - 1.0) / (newx - 1.0)) + 0.5); + stepy = (int)((65536.0 * (oldy - 1.0) / (newy - 1.0)) + 0.5); + ofsy = 32768; + newrect= rectn; + + for (y = newy; y > 0 ; y--){ + rect = recto; + rect += (ofsy >> 16) * oldx; + ofsy += stepy; + ofsx = 32768; + for (x = newx ; x>0 ; x--){ + *newrect++ = rect[ofsx >> 16]; + ofsx += stepx; + } + } +} + +void BIF_swap_render_rects(void) +{ + unsigned int *temp; + + if(R.rectspare==0) { + R.rectspare= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + R.sparex= R.rectx; + R.sparey= R.recty; + } + else if(R.sparex!=R.rectx || R.sparey!=R.recty) { + temp= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + + scalefastrect(R.rectspare, temp, R.sparex, R.sparey, R.rectx, R.recty); + MEM_freeN(R.rectspare); + R.rectspare= temp; + + R.sparex= R.rectx; + R.sparey= R.recty; + } + + temp= R.rectot; + R.rectot= R.rectspare; + R.rectspare= temp; + + redraw_render_display(); +} + +void BIF_toggle_render_display(void) +{ + ScrArea *sa= find_dispimage_v3d(); + + if (render_win && render_win->active) { + if (R.displaymode == R_DISPLAYVIEW) { + BIF_close_render_display(); + } + mainwindow_raise(); + } else if (sa) { + View3D *vd= sa->spacedata.first; + vd->flag &= ~V3D_DISPIMAGE; + scrarea_queue_winredraw(sa); + } else { + if (R.displaymode == R_DISPLAYWIN) { + renderwin_init_display_cb(); + } else { + if (render_win) { + BIF_close_render_display(); + } + renderview_init_display_cb(); + renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, R.rectot); + } + } +} + +void BIF_close_render_display(void) +{ + close_renderwin(); +} diff --git a/source/blender/src/resources.c b/source/blender/src/resources.c new file mode 100644 index 00000000000..41645ba126d --- /dev/null +++ b/source/blender/src/resources.c @@ -0,0 +1,304 @@ + + +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> +#include <stdlib.h> +#include <string.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "BIF_gl.h" +#include "BIF_resources.h" + +#include "datatoc.h" + +typedef struct { + unsigned char *data; + int w, h; +} Icon; + +static Icon *icon_from_data(unsigned char *rect, int w, int h, int rowstride) +{ + Icon *icon= MEM_mallocN(sizeof(*icon), "internicon"); + int y; + icon->data= MEM_mallocN(w*h*4, "icon->data"); + icon->w= w; + icon->h= h; + for (y=0; y<h; y++) + memcpy(&icon->data[y*w*4], &rect[y*rowstride], w*4); + return icon; +} +static void icon_draw(Icon *icon) +{ + glDrawPixels(icon->w, icon->h, GL_RGBA, GL_UNSIGNED_BYTE, icon->data); +} +static unsigned char colclamp(int val) +{ + return (val<0)?(0):((val>255)?255:val); +} +static void icon_draw_blended(Icon *icon, unsigned char blendcol[3]) +{ + unsigned char temprect[20*21*4]; /* XXX, not so safe */ + unsigned char *bgcol= icon->data; + int blendfac[3]; + int x, y; + + blendfac[0]= bgcol[0]? (blendcol[0]<<8)/bgcol[0] : 0; + blendfac[1]= bgcol[1]? (blendcol[1]<<8)/bgcol[1] : 0; + blendfac[2]= bgcol[2]? (blendcol[2]<<8)/bgcol[2] : 0; + + for (y=0; y<icon->h; y++) { + unsigned char *row= &icon->data[y*(icon->w*4)]; + unsigned char *orow= &temprect[y*(icon->w*4)]; + + for (x=0; x<icon->w; x++) { + unsigned char *pxl= &row[x*4]; + unsigned char *opxl= &orow[x*4]; + + opxl[0]= colclamp((pxl[0]*blendfac[0])>>8); + opxl[1]= colclamp((pxl[1]*blendfac[1])>>8); + opxl[2]= colclamp((pxl[2]*blendfac[2])>>8); + opxl[3]= pxl[3]; + } + } + + glDrawPixels(icon->w, icon->h, GL_RGBA, GL_UNSIGNED_BYTE, temprect); +} +static void icon_free(Icon *icon) +{ + MEM_freeN(icon->data); + MEM_freeN(icon); +} + +/***/ + +typedef struct { + unsigned char cols[BIFNCOLORSHADES][3]; +} Color; + +static Color *common_colors_arr= NULL; + +static unsigned char *get_color(BIFColorID colorid, BIFColorShade shade) +{ + int coloridx= colorid-BIFCOLORID_FIRST; + int shadeidx= shade-BIFCOLORSHADE_FIRST; + if (coloridx>=0 && coloridx<BIFNCOLORIDS && shadeidx>=0&& shadeidx<BIFNCOLORSHADES) { + return common_colors_arr[coloridx].cols[shadeidx]; + } else { + static unsigned char errorcol[3]= {0xFF, 0x33, 0x33}; + + return errorcol; + } +} + +void BIF_set_color(BIFColorID colorid, BIFColorShade shade) +{ + glColor3ubv(get_color(colorid, shade)); +} + +static void rgbaCCol_addNT(unsigned char *t, unsigned char *a, int N) +{ + t[0]= colclamp(a[0]+N); + t[1]= colclamp(a[1]+N); + t[2]= colclamp(a[2]+N); +} +static void def_col(BIFColorID colorid, unsigned char r, unsigned char g, unsigned char b) +{ + int coloridx= colorid-BIFCOLORID_FIRST; + if (coloridx>=0 && coloridx<BIFNCOLORIDS) { + unsigned char col[3]; + + col[0]= r, col[1]= g, col[2]= b; + rgbaCCol_addNT(get_color(colorid, COLORSHADE_WHITE), col, 60); + rgbaCCol_addNT(get_color(colorid, COLORSHADE_LIGHT), col, 35); + rgbaCCol_addNT(get_color(colorid, COLORSHADE_HILITE), col, 20); + rgbaCCol_addNT(get_color(colorid, COLORSHADE_MEDIUM), col, 0); + rgbaCCol_addNT(get_color(colorid, COLORSHADE_GREY), col, -45); + rgbaCCol_addNT(get_color(colorid, COLORSHADE_DARK), col, -60); + } else { + printf("def_col: Internal error, bad color ID: %d\n", colorid); + } +} + +/***/ + +static Icon **common_icons_arr= NULL; + +static Icon *get_icon(BIFIconID icon) +{ + int iconidx= icon-BIFICONID_FIRST; + if (iconidx>=0 && iconidx<BIFNICONIDS) { + return common_icons_arr[iconidx]; + } else { + return common_icons_arr[ICON_ERROR-BIFICONID_FIRST]; + } +} +static void free_common_icons(void) +{ + int i; + + for (i=0; i<BIFNICONIDS; i++) { + icon_free(common_icons_arr[i+BIFICONID_FIRST]); + } +} + +void BIF_draw_icon(BIFIconID icon) +{ + icon_draw(get_icon(icon)); +} +void BIF_draw_icon_blended(BIFIconID icon, BIFColorID color, BIFColorShade shade) +{ + icon_draw_blended(get_icon(icon), get_color(color, shade)); +} +int BIF_get_icon_width(BIFIconID icon) +{ + return get_icon(icon)->w; +} +int BIF_get_icon_height(BIFIconID icon) +{ + return get_icon(icon)->h; +} + +static void def_icon(ImBuf *bbuf, BIFIconID icon, int xidx, int yidx, int w, int h, int offsx, int offsy) +{ + int iconidx= icon-BIFICONID_FIRST; + if (iconidx>=0 && iconidx<BIFNICONIDS) { + int rowstride= bbuf->x*4; + unsigned char *start= ((char*) bbuf->rect) + (yidx*21 + 3 + offsy)*rowstride + (xidx*20 + 3 + offsx)*4; + common_icons_arr[iconidx]= icon_from_data(start, w, h, rowstride); + } else { + printf("def_icon: Internal error, bad icon ID: %d\n", icon); + } +} + +/***/ + +static void clear_transp_rect(unsigned char *transp, unsigned char *rect, int w, int h, int rowstride) +{ + int x,y; + for (y=0; y<h; y++) { + unsigned char *row= &rect[y*rowstride]; + for (x=0; x<w; x++) { + unsigned char *pxl= &row[x*4]; + if (*((unsigned int*) pxl)==*((unsigned int*) transp)) { + pxl[3]= 0; + } + } + } +} + +void BIF_resources_init(void) +{ + ImBuf *bbuf= IMB_ibImageFromMemory((int *)datatoc_blenderbuttons, datatoc_blenderbuttons_size, IB_rect); + int x, y; + + common_icons_arr= MEM_mallocN(sizeof(*common_icons_arr)*BIFNICONIDS, "common_icons"); + common_colors_arr= MEM_mallocN(sizeof(*common_colors_arr)*BIFNCOLORIDS, "common_colors"); + + for (y=0; y<10; y++) { + for (x=0; x<21; x++) { + int rowstride= bbuf->x*4; + unsigned char *start= ((char*) bbuf->rect) + (y*21 + 3)*rowstride + (x*20 + 3)*4; + unsigned char transp[4]; + transp[0]= start[0]; + transp[1]= start[1]; + transp[2]= start[2]; + transp[3]= start[3]; + clear_transp_rect(transp, start, 20, 21, rowstride); + } + } + + /* hack! */ + for (y=0; y<10; y++) { + for (x=0; x<21; x++) { + if (x==11 && y==6) { + def_icon(bbuf, ICON_BEVELBUT_HLT, x, y, 7, 13, 4, 2); + } else if (x==12 && y==6) { + def_icon(bbuf, ICON_BEVELBUT_DEHLT, x, y, 7, 13, 4, 2); + } else { + def_icon(bbuf, BIFICONID_FIRST + y*21 + x, x, y, 15, 16, 0, 0); + } + } + } + + IMB_freeImBuf(bbuf); + + def_col(BUTGREY, 0xB0,0xB0,0xB0); + def_col(BUTGREEN, 0x88,0xA0,0xA4); + def_col(BUTBLUE, 0xA0,0xA0,0xB0); + def_col(BUTSALMON, 0xB0,0xA0,0x90); + def_col(MIDGREY, 0x90,0x90,0x90); + def_col(BUTPURPLE, 0xA2,0x98,0xA9); + def_col(BUTYELLOW, 0xB2,0xB2,0x99); + def_col(BUTRUST, 0x80,0x70,0x70); + def_col(REDALERT, 0xB0,0x40,0x40); + def_col(BUTWHITE, 0xD0,0xD0,0xD0); + def_col(BUTDBLUE, 0x80,0x80,0xA0); + def_col(BUTDPINK, 0xAA,0x88,0x55); + def_col(BUTPINK, 0xE8,0xBD,0xA7); + def_col(BUTMACTIVE, 0x70,0x70,0xC0); + + def_col(BUTIPO, 0xB0,0xB0,0x99); + def_col(BUTAUDIO, 0xB0,0xA0,0x90); + def_col(BUTCAMERA, 0x99,0xB2,0xA5); + def_col(BUTRANDOM, 0xA9,0x9A,0x98); + def_col(BUTEDITOBJECT, 0xA2,0x98,0xA9); + def_col(BUTPROPERTY, 0xA0,0xA0,0xB0); + def_col(BUTSCENE, 0x99,0x99,0xB2); + def_col(BUTMOTION, 0x98,0xA7,0xA9); + def_col(BUTMESSAGE, 0x88,0xA0,0x94); + def_col(BUTACTION, 0xB2,0xA9,0x99); + def_col(BUTVISIBILITY, 0xB2,0xA9,0x99); + def_col(BUTCD, 0xB0,0x95,0x90); + def_col(BUTGAME, 0x99,0xB2,0x9C); + def_col(BUTYUCK, 0xB0,0x99,0xB0); + def_col(BUTSEASICK, 0x99,0xB0,0xB0); + def_col(BUTCHOKE, 0x88,0x94,0xA0); + def_col(BUTIMPERIAL, 0x94,0x88,0xA0); +} + +void BIF_resources_free(void) +{ + free_common_icons(); + + MEM_freeN(common_colors_arr); + MEM_freeN(common_icons_arr); +} diff --git a/source/blender/src/scrarea.c b/source/blender/src/scrarea.c new file mode 100644 index 00000000000..c1386473f5e --- /dev/null +++ b/source/blender/src/scrarea.c @@ -0,0 +1,66 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#include "DNA_screen_types.h" +#include "DNA_space_types.h" + +#include "BIF_scrarea.h" + +void *scrarea_find_space_of_type(ScrArea *sa, int type) +{ + SpaceLink *sl; + + for (sl= sa->spacedata.first; sl; sl= sl->next) + if (sl->spacetype==type) + return (void*) sl; + + return 0; +} + +int scrarea_get_win_x(ScrArea *sa) +{ + return sa->winrct.xmin; +} + +int scrarea_get_win_y(ScrArea *sa) +{ + return sa->winrct.ymin; +} + +int scrarea_get_win_width(ScrArea *sa) +{ + return sa->winx; +} + +int scrarea_get_win_height(ScrArea *sa) +{ + return sa->winy; +} diff --git a/source/blender/src/screendump.c b/source/blender/src/screendump.c new file mode 100644 index 00000000000..657305930e5 --- /dev/null +++ b/source/blender/src/screendump.c @@ -0,0 +1,150 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * Making screendumps. + */ + +#include <string.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "DNA_screen_types.h" +#include "DNA_space_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_material.h" +#include "BKE_sca.h" + +#include "BIF_gl.h" +#include "BIF_toolbox.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_toets.h" + +#include "BSE_filesel.h" + +#include "render.h" +#include "mydevice.h" + +static unsigned int *dumprect=0; +static int dumpsx, dumpsy; + +void write_screendump(char *name); + +void write_screendump(char *name) +{ + ImBuf *ibuf; + + if(dumprect) { + + strcpy(G.ima, name); + BLI_convertstringcode(name, G.sce, G.scene->r.cfra); + + if(saveover(name)) { + waitcursor(1); + + ibuf= IMB_allocImBuf(dumpsx, dumpsy, 24, 0, 0); + ibuf->rect= dumprect; + + if(G.scene->r.imtype== R_IRIS) ibuf->ftype= IMAGIC; + else if(G.scene->r.imtype==R_IRIZ) ibuf->ftype= IMAGIC; + else if(G.scene->r.imtype==R_TARGA) ibuf->ftype= TGA; + else if(G.scene->r.imtype==R_RAWTGA) ibuf->ftype= RAWTGA; + else if(G.scene->r.imtype==R_PNG) ibuf->ftype= PNG; + else if(G.scene->r.imtype==R_HAMX) ibuf->ftype= AN_hamx; + else if(ELEM5(G.scene->r.imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) { + ibuf->ftype= JPG|G.scene->r.quality; + } + else ibuf->ftype= TGA; + + IMB_saveiff(ibuf, name, IB_rect); + IMB_freeImBuf(ibuf); + + waitcursor(0); + } + MEM_freeN(dumprect); + dumprect= 0; + } +} + + +void BIF_screendump(void) +{ + /* dump pakken van frontbuffer */ + int x=0, y=0; + char imstr[32]; + + dumpsx= 0; + dumpsy= 0; + + if(dumprect) MEM_freeN(dumprect); + dumprect= 0; + + if (G.qual & LR_SHIFTKEY) { + x= 0; + y= 0; + + dumpsx= G.curscreen->sizex; + dumpsy= G.curscreen->sizey; + + } + else { + if(mywin_inmenu()) { + mywin_getmenu_rect(&x, &y, &dumpsx, &dumpsy); + } else { + int win= mywinget(); + + bwin_getsuborigin(win, &x, &y); + bwin_getsize(win, &dumpsx, &dumpsy); + } + } + + if (dumpsx && dumpsy) { + save_image_filesel_str(imstr); + + dumprect= MEM_mallocN(sizeof(int)*dumpsx*dumpsy, "dumprect"); + glReadBuffer(GL_FRONT); + glReadPixels(x, y, dumpsx, dumpsy, GL_RGBA, GL_UNSIGNED_BYTE, dumprect); + + /* filesel openen */ + + activate_fileselect(FILE_SPECIAL, imstr, G.ima, write_screendump); + } +} diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c new file mode 100644 index 00000000000..ec98ed3889b --- /dev/null +++ b/source/blender/src/sequence.c @@ -0,0 +1,1647 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <string.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" +#include "PIL_dynlib.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "DNA_ipo_types.h" +#include "DNA_sequence_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_plugin_types.h" +#include "BKE_global.h" +#include "BKE_texture.h" +#include "BKE_image.h" +#include "BKE_main.h" +#include "BKE_scene.h" +#include "BKE_ipo.h" + +#include "BIF_screen.h" +#include "BIF_interface.h" +#include "BIF_toolbox.h" +#include "BSE_filesel.h" +#include "BSE_headerbuttons.h" +#include "BSE_sequence.h" + +#include "interface.h" /* MAART: for INT and FLO types */ +#include "blendef.h" +#include "render.h" + +Sequence *seq_arr[MAXSEQ+1]; +int seqrectx, seqrecty; + +/* Alle support voor plugin sequences: */ + +void open_plugin_seq(PluginSeq *pis, char *seqname) +{ + int (*version)(); + char *cp; + + /* voor zekerheid: (hier wordt op getest) */ + pis->doit= 0; + pis->pname= 0; + pis->varstr= 0; + pis->cfra= 0; + pis->version= 0; + + /* clear the error list */ + PIL_dynlib_get_error_as_string(NULL); + + /* if(pis->handle) PIL_dynlib_close(pis->handle); */ + /* pis->handle= 0; */ + + /* open the needed object */ + pis->handle= PIL_dynlib_open(pis->name); + if(test_dlerr(pis->name, pis->name)) return; + + if (pis->handle != 0) { + /* find the address of the version function */ + version= (int (*)())PIL_dynlib_find_symbol(pis->handle, "plugin_seq_getversion"); + if (test_dlerr(pis->name, "plugin_seq_getversion")) return; + + if (version != 0) { + pis->version= version(); + if (pis->version==2 || pis->version==3) { + int (*info_func)(PluginInfo *); + PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info");; + + info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pis->handle, "plugin_getinfo"); + + if(info_func == NULL) error("No info func"); + else { + info_func(info); + + pis->pname= info->name; + pis->vars= info->nvars; + pis->cfra= info->cfra; + + pis->varstr= info->varstr; + + pis->doit= (void(*)(void))info->seq_doit; + if (info->init) + info->init(); + } + MEM_freeN(info); + + cp= PIL_dynlib_find_symbol(pis->handle, "seqname"); + if(cp) strcpy(cp, seqname); + } else { + printf ("Plugin returned unrecognized version number\n"); + return; + } + } + } +} + +PluginSeq *add_plugin_seq(char *str, char *seqname) +{ + PluginSeq *pis; + VarStruct *varstr; + int a; + + pis= MEM_callocN(sizeof(PluginSeq), "PluginSeq"); + + strcpy(pis->name, str); + open_plugin_seq(pis, seqname); + + if(pis->doit==0) { + if(pis->handle==0) error("no plugin: %s", str); + else error("in plugin: %s", str); + MEM_freeN(pis); + return 0; + } + + /* default waardes */ + varstr= pis->varstr; + for(a=0; a<pis->vars; a++, varstr++) { + if( (varstr->type & FLO)==FLO) + pis->data[a]= varstr->def; + else if( (varstr->type & INT)==INT) + *((int *)(pis->data+a))= (int) varstr->def; + } + + return pis; +} + +void free_plugin_seq(PluginSeq *pis) +{ + + if(pis==0) return; + + /* geen PIL_dynlib_close: dezelfde plugin kan meerdere keren geopend zijn: 1 handle */ + MEM_freeN(pis); +} + +/* ***************** END PLUGIN ************************ */ + +void free_stripdata(int len, StripElem *se) +{ + StripElem *seo; + int a; + + seo= se; + + for(a=0; a<len; a++, se++) { + if(se->ibuf && se->ok!=2) IMB_freeImBuf(se->ibuf); + } + + MEM_freeN(seo); + +} + +void free_strip(Strip *strip) +{ + strip->us--; + if(strip->us>0) return; + if(strip->us<0) { + printf("error: negative users in strip\n"); + return; + } + + if(strip->stripdata) { + free_stripdata(strip->len, strip->stripdata); + } + MEM_freeN(strip); +} + +void new_stripdata(Sequence *seq) +{ + + if(seq->strip) { + if(seq->strip->stripdata) free_stripdata(seq->strip->len, seq->strip->stripdata); + seq->strip->stripdata= 0; + seq->strip->len= seq->len; + if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelems"); + } +} + +void free_sequence(Sequence *seq) +{ + extern Sequence *last_seq; + + if(seq->strip) free_strip(seq->strip); + + if(seq->anim) IMB_free_anim(seq->anim); + + free_plugin_seq(seq->plugin); + + if(seq==last_seq) last_seq= 0; + + MEM_freeN(seq); +} + +void do_seq_count(ListBase *seqbase, int *totseq) +{ + Sequence *seq; + + seq= seqbase->first; + while(seq) { + (*totseq)++; + if(seq->seqbase.first) do_seq_count(&seq->seqbase, totseq); + seq= seq->next; + } +} + +void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth) +{ + Sequence *seq; + + seq= seqbase->first; + while(seq) { + seq->depth= depth; + if(seq->seqbase.first) do_build_seqar(&seq->seqbase, seqar, depth+1); + **seqar= seq; + (*seqar)++; + seq= seq->next; + } +} + +void build_seqar(ListBase *seqbase, Sequence ***seqar, int *totseq) +{ + Sequence **tseqar; + + *totseq= 0; + do_seq_count(seqbase, totseq); + + if(*totseq==0) { + *seqar= 0; + return; + } + *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar"); + tseqar= *seqar; + + do_build_seqar(seqbase, seqar, 0); + *seqar= tseqar; +} + +void free_editing(Editing *ed) +{ + MetaStack *ms; + Sequence *seq; + + if(ed==0) return; + + WHILE_SEQ(&ed->seqbase) { + free_sequence(seq); + } + END_SEQ + + while( (ms= ed->metastack.first) ) { + BLI_remlink(&ed->metastack, ms); + MEM_freeN(ms); + } + + MEM_freeN(ed); +} + +void calc_sequence(Sequence *seq) +{ + Sequence *seqm; + int min, max; + + /* eerst recursief alle meta's aflopen */ + seqm= seq->seqbase.first; + while(seqm) { + if(seqm->seqbase.first) calc_sequence(seqm); + seqm= seqm->next; + } + + /* effecten: en meta automatische start en end */ + + if(seq->type & SEQ_EFFECT) { + /* pointers */ + if(seq->seq2==0) seq->seq2= seq->seq1; + if(seq->seq3==0) seq->seq3= seq->seq1; + + /* effecten gaan van seq1 -> seq2: testen */ + + /* we nemen de grootste start en de kleinste eind */ + + // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp); + // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp); + + seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp); + seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp); + seq->len= seq->enddisp - seq->startdisp; + + if(seq->strip && seq->len!=seq->strip->len) { + new_stripdata(seq); + } + + } + else { + if(seq->type==SEQ_META) { + seqm= seq->seqbase.first; + if(seqm) { + min= 1000000; + max= -1000000; + while(seqm) { + if(seqm->startdisp < min) min= seqm->startdisp; + if(seqm->enddisp > max) max= seqm->enddisp; + seqm= seqm->next; + } + seq->start= min; + seq->len= max-min; + + if(seq->strip && seq->len!=seq->strip->len) { + new_stripdata(seq); + } + } + } + + + if(seq->startofs && seq->startstill) seq->startstill= 0; + if(seq->endofs && seq->endstill) seq->endstill= 0; + + seq->startdisp= seq->start + seq->startofs - seq->startstill; + seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill; + + seq->handsize= 10.0; /* 10 frames */ + if( seq->enddisp-seq->startdisp < 20 ) { + seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp)); + } + else if(seq->enddisp-seq->startdisp > 250) { + seq->handsize= (float)((seq->enddisp-seq->startdisp)/25); + } + } +} + +void sort_seq() +{ + /* alle strips in soort bij elkaar en op volgorde van machine */ + ListBase seqbase, effbase; + Editing *ed; + Sequence *seq, *seqt; + + ed= G.scene->ed; + if(ed==0) return; + + seqbase.first= seqbase.last= 0; + effbase.first= effbase.last= 0; + + while( (seq= ed->seqbasep->first) ) { + BLI_remlink(ed->seqbasep, seq); + + if(seq->type & SEQ_EFFECT) { + seqt= effbase.first; + while(seqt) { + if(seqt->machine>=seq->machine) { + BLI_insertlinkbefore(&effbase, seqt, seq); + break; + } + seqt= seqt->next; + } + if(seqt==0) BLI_addtail(&effbase, seq); + } + else { + seqt= seqbase.first; + while(seqt) { + if(seqt->machine>=seq->machine) { + BLI_insertlinkbefore(&seqbase, seqt, seq); + break; + } + seqt= seqt->next; + } + if(seqt==0) BLI_addtail(&seqbase, seq); + } + } + + addlisttolist(&seqbase, &effbase); + *(ed->seqbasep)= seqbase; +} + + +void clear_scene_in_allseqs(Scene *sce) +{ + Scene *sce1; + Editing *ed; + Sequence *seq; + + /* als er een scene delete is: alle seqs testen */ + + sce1= G.main->scene.first; + while(sce1) { + if(sce1!=sce && sce1->ed) { + ed= sce1->ed; + + WHILE_SEQ(&ed->seqbase) { + + if(seq->scene==sce) seq->scene= 0; + + } + END_SEQ + } + + sce1= sce1->id.next; + } +} + +/* ***************** DO THE SEQUENCE ***************** */ + +void do_alphaover_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) +{ + int fac2, mfac, fac, fac4; + int xo, tempc; + char *rt1, *rt2, *rt; + + xo= x; + rt1= (char *)rect1; + rt2= (char *)rect2; + rt= (char *)out; + + fac2= (int)(256.0*facf0); + fac4= (int)(256.0*facf1); + + while(y--) { + + x= xo; + while(x--) { + + /* rt = rt1 over rt2 (alpha van rt1) */ + + fac= fac2; + mfac= 256 - ( (fac2*rt1[3])>>8 ); + + if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); + else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1); + else { + tempc= ( fac*rt1[0] + mfac*rt2[0])>>8; + if(tempc>255) rt[0]= 255; else rt[0]= tempc; + tempc= ( fac*rt1[1] + mfac*rt2[1])>>8; + if(tempc>255) rt[1]= 255; else rt[1]= tempc; + tempc= ( fac*rt1[2] + mfac*rt2[2])>>8; + if(tempc>255) rt[2]= 255; else rt[2]= tempc; + tempc= ( fac*rt1[3] + mfac*rt2[3])>>8; + if(tempc>255) rt[3]= 255; else rt[3]= tempc; + } + rt1+= 4; rt2+= 4; rt+= 4; + } + + if(y==0) break; + y--; + + x= xo; + while(x--) { + + fac= fac4; + mfac= 256 - ( (fac4*rt1[3])>>8 ); + + if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); + else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1); + else { + tempc= ( fac*rt1[0] + mfac*rt2[0])>>8; + if(tempc>255) rt[0]= 255; else rt[0]= tempc; + tempc= ( fac*rt1[1] + mfac*rt2[1])>>8; + if(tempc>255) rt[1]= 255; else rt[1]= tempc; + tempc= ( fac*rt1[2] + mfac*rt2[2])>>8; + if(tempc>255) rt[2]= 255; else rt[2]= tempc; + tempc= ( fac*rt1[3] + mfac*rt2[3])>>8; + if(tempc>255) rt[3]= 255; else rt[3]= tempc; + } + rt1+= 4; rt2+= 4; rt+= 4; + } + } +} + +void do_alphaunder_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) +{ + int fac2, mfac, fac, fac4; + int xo; + char *rt1, *rt2, *rt; + + xo= x; + rt1= (char *)rect1; + rt2= (char *)rect2; + rt= (char *)out; + + fac2= (int)(256.0*facf0); + fac4= (int)(256.0*facf1); + + while(y--) { + + x= xo; + while(x--) { + + /* rt = rt1 under rt2 (alpha van rt2) */ + + /* deze ingewikkelde optimalisering is omdat + * de 'skybuf' ingecrosst kan worden + */ + if(rt2[3]==0 && fac2==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1); + else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2); + else { + mfac= rt2[3]; + fac= (fac2*(256-mfac))>>8; + + if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); + else { + rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8; + rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8; + rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8; + rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8; + } + } + rt1+= 4; rt2+= 4; rt+= 4; + } + + if(y==0) break; + y--; + + x= xo; + while(x--) { + + if(rt2[3]==0 && fac4==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1); + else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2); + else { + mfac= rt2[3]; + fac= (fac4*(256-mfac))>>8; + + if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); + else { + rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8; + rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8; + rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8; + rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8; + } + } + rt1+= 4; rt2+= 4; rt+= 4; + } + } +} + + +void do_cross_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) +{ + int fac1, fac2, fac3, fac4; + int xo; + char *rt1, *rt2, *rt; + + xo= x; + rt1= (char *)rect1; + rt2= (char *)rect2; + rt= (char *)out; + + fac2= (int)(256.0*facf0); + fac1= 256-fac2; + fac4= (int)(256.0*facf1); + fac3= 256-fac4; + + while(y--) { + + x= xo; + while(x--) { + + rt[0]= (fac1*rt1[0] + fac2*rt2[0])>>8; + rt[1]= (fac1*rt1[1] + fac2*rt2[1])>>8; + rt[2]= (fac1*rt1[2] + fac2*rt2[2])>>8; + rt[3]= (fac1*rt1[3] + fac2*rt2[3])>>8; + + rt1+= 4; rt2+= 4; rt+= 4; + } + + if(y==0) break; + y--; + + x= xo; + while(x--) { + + rt[0]= (fac3*rt1[0] + fac4*rt2[0])>>8; + rt[1]= (fac3*rt1[1] + fac4*rt2[1])>>8; + rt[2]= (fac3*rt1[2] + fac4*rt2[2])>>8; + rt[3]= (fac3*rt1[3] + fac4*rt2[3])>>8; + + rt1+= 4; rt2+= 4; rt+= 4; + } + + } +} + +void do_gammacross_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) +{ +/* extern unsigned short *igamtab1, *gamtab; render.h */ + int fac1, fac2, col; + int xo; + char *rt1, *rt2, *rt; + + xo= x; + rt1= (char *)rect1; + rt2= (char *)rect2; + rt= (char *)out; + + fac2= (int)(256.0*facf0); + fac1= 256-fac2; + + while(y--) { + + x= xo; + while(x--) { + + col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8; + if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; + col=(fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8; + if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; + col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8; + if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; + col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8; + if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; + + rt1+= 4; rt2+= 4; rt+= 4; + } + + if(y==0) break; + y--; + + x= xo; + while(x--) { + + col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8; + if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; + col= (fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8; + if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; + col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8; + if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; + col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8; + if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; + + rt1+= 4; rt2+= 4; rt+= 4; + } + + } +} + +void do_add_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) +{ + int col, xo, fac1, fac3; + char *rt1, *rt2, *rt; + + xo= x; + rt1= (char *)rect1; + rt2= (char *)rect2; + rt= (char *)out; + + fac1= (int)(256.0*facf0); + fac3= (int)(256.0*facf1); + + while(y--) { + + x= xo; + while(x--) { + + col= rt1[0]+ ((fac1*rt2[0])>>8); + if(col>255) rt[0]= 255; else rt[0]= col; + col= rt1[1]+ ((fac1*rt2[1])>>8); + if(col>255) rt[1]= 255; else rt[1]= col; + col= rt1[2]+ ((fac1*rt2[2])>>8); + if(col>255) rt[2]= 255; else rt[2]= col; + col= rt1[3]+ ((fac1*rt2[3])>>8); + if(col>255) rt[3]= 255; else rt[3]= col; + + rt1+= 4; rt2+= 4; rt+= 4; + } + + if(y==0) break; + y--; + + x= xo; + while(x--) { + + col= rt1[0]+ ((fac3*rt2[0])>>8); + if(col>255) rt[0]= 255; else rt[0]= col; + col= rt1[1]+ ((fac3*rt2[1])>>8); + if(col>255) rt[1]= 255; else rt[1]= col; + col= rt1[2]+ ((fac3*rt2[2])>>8); + if(col>255) rt[2]= 255; else rt[2]= col; + col= rt1[3]+ ((fac3*rt2[3])>>8); + if(col>255) rt[3]= 255; else rt[3]= col; + + rt1+= 4; rt2+= 4; rt+= 4; + } + } +} + +void do_sub_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) +{ + int col, xo, fac1, fac3; + char *rt1, *rt2, *rt; + + xo= x; + rt1= (char *)rect1; + rt2= (char *)rect2; + rt= (char *)out; + + fac1= (int)(256.0*facf0); + fac3= (int)(256.0*facf1); + + while(y--) { + + x= xo; + while(x--) { + + col= rt1[0]- ((fac1*rt2[0])>>8); + if(col<0) rt[0]= 0; else rt[0]= col; + col= rt1[1]- ((fac1*rt2[1])>>8); + if(col<0) rt[1]= 0; else rt[1]= col; + col= rt1[2]- ((fac1*rt2[2])>>8); + if(col<0) rt[2]= 0; else rt[2]= col; + col= rt1[3]- ((fac1*rt2[3])>>8); + if(col<0) rt[3]= 0; else rt[3]= col; + + rt1+= 4; rt2+= 4; rt+= 4; + } + + if(y==0) break; + y--; + + x= xo; + while(x--) { + + col= rt1[0]- ((fac3*rt2[0])>>8); + if(col<0) rt[0]= 0; else rt[0]= col; + col= rt1[1]- ((fac3*rt2[1])>>8); + if(col<0) rt[1]= 0; else rt[1]= col; + col= rt1[2]- ((fac3*rt2[2])>>8); + if(col<0) rt[2]= 0; else rt[2]= col; + col= rt1[3]- ((fac3*rt2[3])>>8); + if(col<0) rt[3]= 0; else rt[3]= col; + + rt1+= 4; rt2+= 4; rt+= 4; + } + } +} + +/* Must be > 0 or add precopy, etc to the function */ +#define XOFF 8 +#define YOFF 8 + +void do_drop_effect(float facf0, float facf1, int x, int y, unsigned int *rect2i, unsigned int *rect1i, unsigned int *outi) +{ + int height, width, temp, fac, fac1, fac2; + char *rt1, *rt2, *out; + int field= 1; + + width= x; + height= y; + + fac1= (int)(70.0*facf0); + fac2= (int)(70.0*facf1); + + rt2= (char*) (rect2i + YOFF*width); + rt1= (char*) rect1i; + out= (char*) outi; + for (y=0; y<height-YOFF; y++) { + if(field) fac= fac1; + else fac= fac2; + field= !field; + + memcpy(out, rt1, sizeof(int)*XOFF); + rt1+= XOFF*4; + out+= XOFF*4; + + for (x=XOFF; x<width; x++) { + temp= ((fac*rt2[3])>>8); + + *(out++)= MAX2(0, *rt1 - temp); rt1++; + *(out++)= MAX2(0, *rt1 - temp); rt1++; + *(out++)= MAX2(0, *rt1 - temp); rt1++; + *(out++)= MAX2(0, *rt1 - temp); rt1++; + rt2+=4; + } + rt2+=XOFF*4; + } + memcpy(out, rt1, sizeof(int)*YOFF*width); +} + + /* L E T O P: rect2 en rect1 omgekeerd */ +void do_drop_effect2(float facf0, float facf1, int x, int y, unsigned int *rect2, unsigned int *rect1, unsigned int *out) +{ + int col, xo, yo, temp, fac1, fac3; + int xofs= -8, yofs= 8; + char *rt1, *rt2, *rt; + + xo= x; + yo= y; + + rt2= (char *)(rect2 + yofs*x + xofs); + + rt1= (char *)rect1; + rt= (char *)out; + + fac1= (int)(70.0*facf0); + fac3= (int)(70.0*facf1); + + while(y-- > 0) { + + temp= y-yofs; + if(temp > 0 && temp < yo) { + + x= xo; + while(x--) { + + temp= x+xofs; + if(temp > 0 && temp < xo) { + + temp= ((fac1*rt2[3])>>8); + + col= rt1[0]- temp; + if(col<0) rt[0]= 0; else rt[0]= col; + col= rt1[1]- temp; + if(col<0) rt[1]= 0; else rt[1]= col; + col= rt1[2]- temp; + if(col<0) rt[2]= 0; else rt[2]= col; + col= rt1[3]- temp; + if(col<0) rt[3]= 0; else rt[3]= col; + } + else *( (unsigned int *)rt) = *( (unsigned int *)rt1); + + rt1+= 4; rt2+= 4; rt+= 4; + } + } + else { + x= xo; + while(x--) { + *( (unsigned int *)rt) = *( (unsigned int *)rt1); + rt1+= 4; rt2+= 4; rt+= 4; + } + } + + if(y==0) break; + y--; + + temp= y-yofs; + if(temp > 0 && temp < yo) { + + x= xo; + while(x--) { + + temp= x+xofs; + if(temp > 0 && temp < xo) { + + temp= ((fac3*rt2[3])>>8); + + col= rt1[0]- temp; + if(col<0) rt[0]= 0; else rt[0]= col; + col= rt1[1]- temp; + if(col<0) rt[1]= 0; else rt[1]= col; + col= rt1[2]- temp; + if(col<0) rt[2]= 0; else rt[2]= col; + col= rt1[3]- temp; + if(col<0) rt[3]= 0; else rt[3]= col; + } + else *( (unsigned int *)rt) = *( (unsigned int *)rt1); + + rt1+= 4; rt2+= 4; rt+= 4; + } + } + else { + x= xo; + while(x--) { + *( (unsigned int *)rt) = *( (unsigned int *)rt1); + rt1+= 4; rt2+= 4; rt+= 4; + } + } + } +} + + +void do_mul_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) +{ + int xo, fac1, fac3; + char *rt1, *rt2, *rt; + + xo= x; + rt1= (char *)rect1; + rt2= (char *)rect2; + rt= (char *)out; + + fac1= (int)(256.0*facf0); + fac3= (int)(256.0*facf1); + + /* formule: + * fac*(a*b) + (1-fac)*a => fac*a*(b-1)+a + */ + + while(y--) { + + x= xo; + while(x--) { + + rt[0]= rt1[0] + ((fac1*rt1[0]*(rt2[0]-256))>>16); + rt[1]= rt1[1] + ((fac1*rt1[1]*(rt2[1]-256))>>16); + rt[2]= rt1[2] + ((fac1*rt1[2]*(rt2[2]-256))>>16); + rt[3]= rt1[3] + ((fac1*rt1[3]*(rt2[3]-256))>>16); + + rt1+= 4; rt2+= 4; rt+= 4; + } + + if(y==0) break; + y--; + + x= xo; + while(x--) { + + rt[0]= rt1[0] + ((fac3*rt1[0]*(rt2[0]-256))>>16); + rt[1]= rt1[1] + ((fac3*rt1[1]*(rt2[1]-256))>>16); + rt[2]= rt1[2] + ((fac3*rt1[2]*(rt2[2]-256))>>16); + rt[3]= rt1[3] + ((fac3*rt1[3]*(rt2[3]-256))>>16); + + rt1+= 4; rt2+= 4; rt+= 4; + } + } +} + +void make_black_ibuf(ImBuf *ibuf) +{ + unsigned int *rect; + int tot; + + if(ibuf==0 || ibuf->rect==0) return; + + tot= ibuf->x*ibuf->y; + rect= ibuf->rect; + while(tot--) *(rect++)= 0; + +} + +void multibuf(ImBuf *ibuf, float fmul) +{ + char *rt; + int a, mul, icol; + + mul= (int)(256.0*fmul); + + a= ibuf->x*ibuf->y; + rt= (char *)ibuf->rect; + while(a--) { + + icol= (mul*rt[0])>>8; + if(icol>254) rt[0]= 255; else rt[0]= icol; + icol= (mul*rt[1])>>8; + if(icol>254) rt[1]= 255; else rt[1]= icol; + icol= (mul*rt[2])>>8; + if(icol>254) rt[2]= 255; else rt[2]= icol; + icol= (mul*rt[3])>>8; + if(icol>254) rt[3]= 255; else rt[3]= icol; + + rt+= 4; + } +} + +void do_effect(int cfra, Sequence *seq, StripElem *se) +{ + StripElem *se1, *se2, *se3; + float fac, facf; + int x, y; + char *cp; + + if(se->se1==0 || se->se2==0 || se->se3==0) { + make_black_ibuf(se->ibuf); + return; + } + + /* als metastrip: andere se's */ + if(se->se1->ok==2) se1= se->se1->se1; + else se1= se->se1; + + if(se->se2->ok==2) se2= se->se2->se1; + else se2= se->se2; + + if(se->se3->ok==2) se3= se->se3->se1; + else se3= se->se3; + + if(se1==0 || se2==0 || se3==0 || se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0) { + make_black_ibuf(se->ibuf); + return; + } + + x= se2->ibuf->x; + y= se2->ibuf->y; + + if(seq->ipo && seq->ipo->curve.first) { + do_seq_ipo(seq); + fac= seq->facf0; + facf= seq->facf1; + } + else if ELEM3( seq->type, SEQ_CROSS, SEQ_GAMCROSS, SEQ_PLUGIN) { + fac= (float)(cfra - seq->startdisp); + facf= (float)(fac+0.5); + fac /= seq->len; + facf /= seq->len; + } + else { + fac= facf= 1.0; + } + + if( G.scene->r.mode & R_FIELDS ); else facf= fac; + + switch(seq->type) { + case SEQ_CROSS: + do_cross_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); + break; + case SEQ_GAMCROSS: + do_gammacross_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); + break; + case SEQ_ADD: + do_add_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); + break; + case SEQ_SUB: + do_sub_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); + break; + case SEQ_MUL: + do_mul_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); + break; + case SEQ_ALPHAOVER: + do_alphaover_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); + break; + case SEQ_OVERDROP: + do_drop_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); + do_alphaover_effect(fac, facf, x, y, se1->ibuf->rect, se->ibuf->rect, se->ibuf->rect); + break; + case SEQ_ALPHAUNDER: + do_alphaunder_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); + break; + case SEQ_PLUGIN: + if(seq->plugin && seq->plugin->doit) { + + if((G.f & G_PLAYANIM)==0) waitcursor(1); + + if(seq->plugin->cfra) *(seq->plugin->cfra)= frame_to_float(CFRA); + + cp= PIL_dynlib_find_symbol(seq->plugin->handle, "seqname"); + if(cp) strcpy(cp, seq->name+2); + + if (seq->plugin->version<=2) { + if(se1->ibuf) IMB_convert_rgba_to_abgr(se1->ibuf->x*se1->ibuf->y, se1->ibuf->rect); + if(se2->ibuf) IMB_convert_rgba_to_abgr(se2->ibuf->x*se2->ibuf->y, se2->ibuf->rect); + if(se3->ibuf) IMB_convert_rgba_to_abgr(se3->ibuf->x*se3->ibuf->y, se3->ibuf->rect); + } + + ((SeqDoit)seq->plugin->doit)(seq->plugin->data, fac, facf, x, y, + se1->ibuf, se2->ibuf, se->ibuf, se3->ibuf); + + if (seq->plugin->version<=2) { + if(se1->ibuf) IMB_convert_rgba_to_abgr(se1->ibuf->x*se1->ibuf->y, se1->ibuf->rect); + if(se2->ibuf) IMB_convert_rgba_to_abgr(se2->ibuf->x*se2->ibuf->y, se2->ibuf->rect); + if(se3->ibuf) IMB_convert_rgba_to_abgr(se3->ibuf->x*se3->ibuf->y, se3->ibuf->rect); + IMB_convert_rgba_to_abgr(se->ibuf->x*se->ibuf->y, se->ibuf->rect); + } + + if((G.f & G_PLAYANIM)==0) waitcursor(0); + } + break; + } + +} + +int evaluate_seq_frame(int cfra) +{ + Sequence *seq; + Editing *ed; + int totseq=0; + + memset(seq_arr, 0, 4*MAXSEQ); + + ed= G.scene->ed; + if(ed==0) return 0; + + seq= ed->seqbasep->first; + while(seq) { + if(seq->startdisp <=cfra && seq->enddisp > cfra) { + seq_arr[seq->machine]= seq; + totseq++; + } + seq= seq->next; + } + + return totseq; +} + +StripElem *give_stripelem(Sequence *seq, int cfra) +{ + Strip *strip; + StripElem *se; + int nr; + + strip= seq->strip; + se= strip->stripdata; + + if(se==0) return 0; + if(seq->startdisp >cfra || seq->enddisp <= cfra) return 0; + + if(cfra <= seq->start) nr= 0; + else if(cfra >= seq->start+seq->len-1) nr= seq->len-1; + else nr= cfra-seq->start; + + se+= nr; + se->nr= nr; + + return se; +} + +void set_meta_stripdata(Sequence *seqm) +{ + Sequence *seq, *seqim, *seqeff; + Editing *ed; + ListBase *tempbase; + StripElem *se; + int a, cfra, b; + + /* zet alle ->se1 pointers in stripdata, dan kan daar de ibuf uitgelezen */ + + ed= G.scene->ed; + if(ed==0) return; + + tempbase= ed->seqbasep; + ed->seqbasep= &seqm->seqbase; + + se= seqm->strip->stripdata; + for(a=0; a<seqm->len; a++, se++) { + cfra= a+seqm->start; + if(evaluate_seq_frame(cfra)) { + + /* we nemen de hoogste effectstrip of de laagste imagestrip/metastrip */ + seqim= seqeff= 0; + + for(b=1; b<MAXSEQ; b++) { + if(seq_arr[b]) { + seq= seq_arr[b]; + if(seq->type & SEQ_EFFECT) { + if(seqeff==0) seqeff= seq; + else if(seqeff->machine < seq->machine) seqeff= seq; + } + else { + if(seqim==0) seqim= seq; + else if(seqim->machine > seq->machine) seqim= seq; + } + } + } + if(seqeff) seq= seqeff; + else if(seqim) seq= seqim; + else seq= 0; + + if(seq) { + se->se1= give_stripelem(seq, cfra); + } + else se->se1= 0; + } + } + + ed->seqbasep= tempbase; +} + + + +/* HULPFUNKTIES VOOR GIVE_IBUF_SEQ */ + +void do_seq_count_cfra(ListBase *seqbase, int *totseq, int cfra) +{ + Sequence *seq; + + seq= seqbase->first; + while(seq) { + if(seq->startdisp <=cfra && seq->enddisp > cfra) { + + if(seq->seqbase.first) { + + if(cfra< seq->start) do_seq_count_cfra(&seq->seqbase, totseq, seq->start); + else if(cfra> seq->start+seq->len-1) do_seq_count_cfra(&seq->seqbase, totseq, seq->start+seq->len-1); + else do_seq_count_cfra(&seq->seqbase, totseq, cfra); + } + + (*totseq)++; + } + seq= seq->next; + } +} + +void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra) +{ + Sequence *seq; + StripElem *se; + Scene *oldsce; + unsigned int *rectot; + int oldx, oldy, oldcfra, doseq; + char name[FILE_MAXDIR]; + + seq= seqbase->first; + while(seq) { + + /* op nul zetten ivm free_imbuf_seq... */ + seq->curelem= 0; + + if(seq->startdisp <=cfra && seq->enddisp > cfra) { + + if(seq->seqbase.first) { + if(cfra< seq->start) do_build_seqar_cfra(&seq->seqbase, seqar, seq->start); + else if(cfra> seq->start+seq->len-1) do_build_seqar_cfra(&seq->seqbase, seqar, seq->start+seq->len-1); + else do_build_seqar_cfra(&seq->seqbase, seqar, cfra); + } + + **seqar= seq; + (*seqar)++; + + se=seq->curelem= give_stripelem(seq, cfra); + + if(se) { + if(seq->type == SEQ_META) { + se->ok= 2; + if(se->se1==0) set_meta_stripdata(seq); + if(se->se1) { + se->ibuf= se->se1->ibuf; + } + } + else if(seq->type & SEQ_EFFECT) { + + /* testen of image te klein is: opnieuw maken */ + if(se->ibuf) { + if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty) { + IMB_freeImBuf(se->ibuf); + se->ibuf= 0; + } + } + + /* moet het effect (opnieuw) berekend? */ + + if(se->ibuf==0 || (se->se1 != seq->seq1->curelem) || (se->se2 != seq->seq2->curelem) || (se->se3 != seq->seq3->curelem)) { + se->se1= seq->seq1->curelem; + se->se2= seq->seq2->curelem; + se->se3= seq->seq3->curelem; + + if(se->ibuf==0) se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0); + + do_effect(cfra, seq, se); + } + + /* size testen */ + if(se->ibuf) { + if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) { + if(G.scene->r.mode & R_OSA) + IMB_scaleImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); + else + IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); + } + } + } + else if(seq->type < SEQ_EFFECT) { + + if(se->ibuf) { + /* testen of image te klein is: opnieuw laden */ + if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty) { + IMB_freeImBuf(se->ibuf); + se->ibuf= 0; + se->ok= 1; + } + } + + if(seq->type==SEQ_IMAGE) { + if(se->ok && se->ibuf==0) { + + /* als playanim of render: geen waitcursor doen */ + if((G.f & G_PLAYANIM)==0) waitcursor(1); + + strcpy(name, seq->strip->dir); + strcat(name, se->name); + BLI_convertstringcode(name, G.sce, G.scene->r.cfra); + se->ibuf= IMB_loadiffname(name, IB_rect); + + if((G.f & G_PLAYANIM)==0) waitcursor(0); + + if(se->ibuf==0) se->ok= 0; + else { + if(se->ibuf->depth==32 && se->ibuf->zbuf==0) converttopremul(se->ibuf); + seq->strip->orx= se->ibuf->x; + seq->strip->ory= se->ibuf->y; + } + } + } + else if(seq->type==SEQ_MOVIE) { + if(se->ok && se->ibuf==0) { + + /* als playanim of render: geen waitcursor doen */ + if((G.f & G_PLAYANIM)==0) waitcursor(1); + + if(seq->anim==0) { + strcpy(name, seq->strip->dir); + strcat(name, seq->strip->stripdata->name); + BLI_convertstringcode(name, G.sce, G.scene->r.cfra); + + seq->anim = openanim(name, IB_rect); + } + if(seq->anim) { + se->ibuf = IMB_anim_absolute(seq->anim, se->nr); + } + + if(se->ibuf==0) se->ok= 0; + else { + if(se->ibuf->depth==32) converttopremul(se->ibuf); + seq->strip->orx= se->ibuf->x; + seq->strip->ory= se->ibuf->y; + if(seq->flag & SEQ_FILTERY) IMB_filtery(se->ibuf); + if(seq->mul==0.0) seq->mul= 1.0; + if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul); + } + if((G.f & G_PLAYANIM)==0) waitcursor(0); + } + } + else if(seq->type==SEQ_SCENE && se->ibuf==0) { + View3D *vd; + + oldsce= G.scene; + set_scene_bg(seq->scene); + + /* oneindige lus voorkomen */ + doseq= G.scene->r.scemode & R_DOSEQ; + G.scene->r.scemode &= ~R_DOSEQ; + + /* vanalles bewaren */ + oldcfra= CFRA; CFRA= seq->sfra + se->nr; + waitcursor(1); + + rectot= R.rectot; R.rectot= 0; + oldx= R.rectx; oldy= R.recty; + /* dit is nodig omdat de huidige 3D window niet de layers mag leveren, alsof het background render is */ + vd= G.vd; + G.vd= 0; + + RE_initrender(NULL); + if (!G.background) { + if(R.r.mode & R_FIELDS) update_for_newframe(); + R.flag= 0; + + free_filesel_spec(G.scene->r.pic); + } + + se->ibuf= IMB_allocImBuf(R.rectx, R.recty, 32, IB_rect, 0); + if(R.rectot) memcpy(se->ibuf->rect, R.rectot, 4*R.rectx*R.recty); + if(R.rectz) { + se->ibuf->zbuf= (int *)R.rectz; + /* make sure ibuf frees it */ + se->ibuf->mall |= IB_zbuf; + R.rectz= 0; + } + + /* and restore */ + G.vd= vd; + + if((G.f & G_PLAYANIM)==0) waitcursor(0); + CFRA= oldcfra; + if(R.rectot) MEM_freeN(R.rectot); + R.rectot= rectot; + R.rectx=oldx; R.recty=oldy; + G.scene->r.scemode |= doseq; + set_scene_bg(oldsce); + + /* restore!! */ + R.rectx= seqrectx; + R.recty= seqrecty; + + /* added because this flag is checked for + * movie writing when rendering an anim. + * very convoluted. fix. -zr + */ + R.r.imtype= G.scene->r.imtype; + } + + /* size testen */ + if(se->ibuf) { + if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) { + + if (G.scene->r.mode & R_FIELDS) { + + if (seqrecty > 288) IMB_scalefieldImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); + else { + IMB_de_interlace(se->ibuf); + + if(G.scene->r.mode & R_OSA) + IMB_scaleImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); + else + IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); + } + } + else { + if(G.scene->r.mode & R_OSA) + IMB_scaleImBuf(se->ibuf,(short)seqrectx, (short)seqrecty); + else + IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); + } + } + } + } + } + } + + seq= seq->next; + } +} + +ImBuf *give_ibuf_seq(int cfra) +{ + Sequence **tseqar, **seqar; + Sequence *seq, *seqfirst=0;/* , *effirst=0; */ + Editing *ed; + StripElem *se; + int seqnr, totseq; + + /* we maken recursief een 'stack' van sequences, deze is ook + * gesorteerd en kan gewoon doorlopen worden. + * Deze methode is vooral ontwikkeld voor stills voor en achter meta's + */ + + totseq= 0; + ed= G.scene->ed; + if(ed==0) return 0; + do_seq_count_cfra(ed->seqbasep, &totseq, cfra); + + if(totseq==0) return 0; + + seqrectx= (G.scene->r.size*G.scene->r.xsch)/100; + if(G.scene->r.mode & R_PANORAMA) seqrectx*= G.scene->r.xparts; + seqrecty= (G.scene->r.size*G.scene->r.ysch)/100; + + + /* tseqar is nodig omdat in do_build_... de pointer verandert */ + seqar= tseqar= MEM_callocN(sizeof(void *)*totseq, "seqar"); + + /* deze fie laadt en maakt ook de ibufs */ + do_build_seqar_cfra(ed->seqbasep, &seqar, cfra); + seqar= tseqar; + + for(seqnr=0; seqnr<totseq; seqnr++) { + seq= seqar[seqnr]; + + se= seq->curelem; + if(se) { + if(seq->type==SEQ_META) { + + /* onderste strip! */ + if(seqfirst==0) seqfirst= seq; + else if(seqfirst->depth > seq->depth) seqfirst= seq; + else if(seqfirst->machine > seq->machine) seqfirst= seq; + + } + else if(seq->type & SEQ_EFFECT) { + + /* bovenste strip! */ + if(seqfirst==0) seqfirst= seq; + else if(seqfirst->depth > seq->depth) seqfirst= seq; + else if(seqfirst->machine < seq->machine) seqfirst= seq; + + + } + else if(seq->type < SEQ_EFFECT) { /* images */ + + /* onderste strip! zodat je bovenin altijd hulptroep kan bewaren */ + + if(seqfirst==0) seqfirst= seq; + else if(seqfirst->depth > seq->depth) seqfirst= seq; + else if(seqfirst->machine > seq->machine) seqfirst= seq; + + } + } + } + + MEM_freeN(seqar); + + if(seqfirst->curelem==0) return 0; + return seqfirst->curelem->ibuf; + +} + +void free_imbuf_effect_spec(int cfra) +{ + Sequence *seq; + StripElem *se; + Editing *ed; + int a; + + ed= G.scene->ed; + if(ed==0) return; + + WHILE_SEQ(&ed->seqbase) { + + if(seq->strip) { + + if(seq->type & SEQ_EFFECT) { + se= seq->strip->stripdata; + for(a=0; a<seq->len; a++, se++) { + if(se==seq->curelem && se->ibuf) { + IMB_freeImBuf(se->ibuf); + se->ibuf= 0; + se->ok= 1; + se->se1= se->se2= se->se3= 0; + } + } + } + } + } + END_SEQ +} + +void free_imbuf_seq_except(int cfra) +{ + Sequence *seq; + StripElem *se; + Editing *ed; + int a; + + ed= G.scene->ed; + if(ed==0) return; + + WHILE_SEQ(&ed->seqbase) { + + if(seq->strip) { + + if( seq->type==SEQ_META ) { + ; + } + else { + se= seq->strip->stripdata; + for(a=0; a<seq->len; a++, se++) { + if(se!=seq->curelem && se->ibuf) { + IMB_freeImBuf(se->ibuf); + se->ibuf= 0; + se->ok= 1; + se->se1= se->se2= se->se3= 0; + } + } + } + + if(seq->type==SEQ_MOVIE) { + if(seq->startdisp > cfra || seq->enddisp < cfra) { + if(seq->anim) { + IMB_free_anim(seq->anim); + seq->anim = 0; + } + } + } + } + } + END_SEQ +} + +void free_imbuf_seq() +{ + Sequence *seq; + StripElem *se; + Editing *ed; + int a; + + ed= G.scene->ed; + if(ed==0) return; + + WHILE_SEQ(&ed->seqbase) { + + if(seq->strip) { + + if( seq->type==SEQ_META ) { + ; + } + else { + se= seq->strip->stripdata; + for(a=0; a<seq->len; a++, se++) { + if(se->ibuf) { + IMB_freeImBuf(se->ibuf); + se->ibuf= 0; + se->ok= 1; + se->se1= se->se2= se->se3= 0; + } + } + } + + if(seq->type==SEQ_MOVIE) { + if(seq->anim) { + IMB_free_anim(seq->anim); + seq->anim = 0; + } + } + } + } + END_SEQ +} + +void do_render_seq() +{ +/* static ImBuf *lastibuf=0; */ + ImBuf *ibuf; + + /* plaatje in R.rectot kopieeren */ + + G.f |= G_PLAYANIM; /* waitcursor patch */ + + ibuf= give_ibuf_seq(CFRA); + if(ibuf) { + + memcpy(R.rectot, ibuf->rect, 4*R.rectx*R.recty); + + /* if (ibuf->zbuf) { */ + /* if (R.rectz) freeN(R.rectz); */ + /* R.rectz = BLI_dupallocN(ibuf->zbuf); */ + /* } */ + + free_imbuf_seq_except(CFRA); + } + G.f &= ~G_PLAYANIM; + +} diff --git a/source/blender/src/space.c b/source/blender/src/space.c new file mode 100644 index 00000000000..1ee6cf013ae --- /dev/null +++ b/source/blender/src/space.c @@ -0,0 +1,2974 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * - hier het initialiseren en vrijgeven van SPACE data + */ + +#include <string.h> +#include <stdio.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_linklist.h" + +#include "DNA_action_types.h" +#include "DNA_curve_types.h" +#include "DNA_image_types.h" +#include "DNA_ipo_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_sequence_types.h" +#include "DNA_sound_types.h" +#include "DNA_space_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view2d_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_blender.h" +#include "BKE_curve.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_ipo.h" +#include "BKE_main.h" +#include "BKE_scene.h" +#include "BKE_utildefines.h" + +#include "BIF_buttons.h" +#include "BIF_drawimage.h" +#include "BIF_drawseq.h" +#include "BIF_drawtext.h" +#include "BIF_editarmature.h" +#include "BIF_editfont.h" +#include "BIF_editika.h" +#include "BIF_editkey.h" +#include "BIF_editlattice.h" +#include "BIF_editmesh.h" +#include "BIF_editoops.h" +#include "BIF_editseq.h" +#include "BIF_editsima.h" +#include "BIF_editsound.h" +#include "BIF_editview.h" +#include "BIF_gl.h" +#include "BIF_imasel.h" +#include "BIF_interface.h" +#include "BIF_mywindow.h" +#include "BIF_oops.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_spacetypes.h" +#include "BIF_toets.h" +#include "BIF_toolbox.h" +#include "BIF_usiblender.h" +#include "BIF_previewrender.h" + +#include "BSE_edit.h" +#include "BSE_view.h" +#include "BSE_editipo.h" +#include "BSE_drawipo.h" +#include "BSE_drawview.h" +#include "BSE_drawnla.h" +#include "BSE_filesel.h" +#include "BSE_headerbuttons.h" +#include "BSE_editnla_types.h" + +#include "BDR_vpaint.h" +#include "BDR_editmball.h" +#include "BDR_editobject.h" +#include "BDR_editcurve.h" +#include "BDR_editface.h" +#include "BDR_drawmesh.h" + +#include "BLO_readfile.h" /* for BLO_blendhandle_close */ + +#include "interface.h" +#include "mydevice.h" +#include "blendef.h" +#include "datatoc.h" + +#include "BPY_extern.h" // Blender Python library + +#include "TPT_DependKludge.h" +#ifdef NAN_TPT +#include "BSE_trans_types.h" +#include "../img/IMG_Api.h" +#endif /* NAN_TPT */ + +#include "SYS_System.h" /* for the user def menu ... should move elsewhere. */ + +extern void StartKetsjiShell(ScrArea *area, char* startscenename, struct Main* maggie, int always_use_expand_framing); + +/** + * When the mipmap setting changes, we want to redraw the view right + * away to reflect this setting. + */ +void space_mipmap_button_function(int event); + + +unsigned short convert_for_nonumpad(unsigned short event); +void free_soundspace(SpaceSound *ssound); + +/* ************* SPACE: VIEW3D ************* */ + +/* extern void drawview3d(); BSE_drawview.h */ + + +void copy_view3d_lock(short val) +{ + bScreen *sc; + int bit; + + /* van G.scene naar andere views kopieeren */ + sc= G.main->screen.first; + + while(sc) { + if(sc->scene==G.scene) { + ScrArea *sa= sc->areabase.first; + while(sa) { + SpaceLink *sl= sa->spacedata.first; + while(sl) { + if(sl->spacetype==SPACE_OOPS && val==REDRAW) { + if(sa->win) scrarea_queue_winredraw(sa); + } + else if(sl->spacetype==SPACE_VIEW3D) { + View3D *vd= (View3D*) sl; + if(vd->scenelock && vd->localview==0) { + vd->lay= G.scene->lay; + vd->camera= G.scene->camera; + + if(vd->camera==0 && vd->persp>1) vd->persp= 1; + + if( (vd->lay & vd->layact) == 0) { + bit= 0; + while(bit<32) { + if(vd->lay & (1<<bit)) { + vd->layact= 1<<bit; + break; + } + bit++; + } + } + + if(val==REDRAW && vd==sa->spacedata.first) { + scrarea_queue_redraw(sa); + } + } + } + sl= sl->next; + } + sa= sa->next; + } + } + sc= sc->id.next; + } +} + +void handle_view3d_lock() +{ + if (G.vd != NULL) { + if(G.vd->localview==0 && G.vd->scenelock && curarea->spacetype==SPACE_VIEW3D) { + + /* naar scene kopieeren */ + G.scene->lay= G.vd->lay; + G.scene->camera= G.vd->camera; + + copy_view3d_lock(REDRAW); + } + } +} + +void space_set_commmandline_options(void) { + SYS_SystemHandle syshandle; + int a; + + if ( (syshandle = SYS_GetSystem()) ) { + /* User defined settings */ + a= (U.gameflags & USERDEF_VERTEX_ARRAYS); + SYS_WriteCommandLineInt(syshandle, "vertexarrays", a); + + a= (U.gameflags & USERDEF_DISABLE_SOUND); + SYS_WriteCommandLineInt(syshandle, "noaudio", a); + + a= (U.gameflags & USERDEF_DISABLE_MIPMAP); + set_mipmap(!a); + SYS_WriteCommandLineInt(syshandle, "nomipmap", a); + + /* File specific settings: */ + /* Only test the first one. These two are switched + * simultaneously. */ + a= (G.fileflags & G_FILE_SHOW_FRAMERATE); + SYS_WriteCommandLineInt(syshandle, "show_framerate", a); + SYS_WriteCommandLineInt(syshandle, "show_profile", a); + + /* When in wireframe mode, always draw debug props. */ + if (G.vd) { + a = ( (G.fileflags & G_FILE_SHOW_DEBUG_PROPS) + || (G.vd->drawtype == OB_WIRE) + || (G.vd->drawtype == OB_SOLID) ); + SYS_WriteCommandLineInt(syshandle, "show_properties", a); + } + + a= (G.fileflags & G_FILE_ENABLE_ALL_FRAMES); + SYS_WriteCommandLineInt(syshandle, "fixedtime", a); + } +} + + /** + * These two routines imported from the gameengine, + * I suspect a lot of the resetting stuff is cruft + * and can be removed, but it should be checked. + */ +static void SaveState(void) +{ + glPushAttrib(GL_ALL_ATTRIB_BITS); + + init_realtime_GL(); + init_gl_stuff(); + + if(G.scene->camera==0 || G.scene->camera->type!=OB_CAMERA) + error("no (correct) camera"); + + waitcursor(1); +} + +static void RestoreState(void) +{ + curarea->win_swap = 0; + curarea->head_swap=0; + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSALL, 0); + reset_slowparents(); + waitcursor(0); + G.qual= 0; + glPopAttrib(); +} + +static LinkNode *save_and_reset_all_scene_cfra(void) +{ + LinkNode *storelist= NULL; + Scene *sc; + + for (sc= G.main->scene.first; sc; sc= sc->id.next) { + BLI_linklist_prepend(&storelist, (void*) sc->r.cfra); + sc->r.cfra= 1; + + set_scene_bg(sc); + } + + BLI_linklist_reverse(&storelist); + + return storelist; +} + +static void restore_all_scene_cfra(LinkNode *storelist) { + LinkNode *sc_store= storelist; + Scene *sc; + + for (sc= G.main->scene.first; sc; sc= sc->id.next) { + int stored_cfra= (int) sc_store->link; + + sc->r.cfra= stored_cfra; + set_scene_bg(sc); + + sc_store= sc_store->next; + } + + BLI_linklist_free(storelist, NULL); +} + +void start_game(void) +{ + Scene *sc, *startscene = G.scene; + LinkNode *scene_cfra_store; + + /* XXX, silly code - the game engine can + * access any scene through logic, so we try + * to make sure each scene has a valid camera, + * just in case the game engine tries to use it. + * + * Better would be to make a better routine + * in the game engine for finding the camera. + * - zr + */ + for (sc= G.main->scene.first; sc; sc= sc->id.next) { + if (!sc->camera) { + Base *base; + + for (base= sc->base.first; base; base= base->next) + if (base->object->type==OB_CAMERA) + break; + + sc->camera= base?base->object:NULL; + } + } + + /* these two lines make sure front and backbuffer are equal. for swapbuffers */ + markdirty_all(); + screen_swapbuffers(); + + /* can start from header */ + mywinset(curarea->win); + + scene_cfra_store= save_and_reset_all_scene_cfra(); + + BPY_end_python(); + + sound_stop_all_sounds(); + + /* Before jumping into Ketsji, we configure some settings. */ + space_set_commmandline_options(); + + SaveState(); + StartKetsjiShell(curarea, startscene->id.name+2, G.main, 1); + RestoreState(); + + BPY_start_python(); + + restore_all_scene_cfra(scene_cfra_store); + set_scene_bg(startscene); + + if (G.flags & G_FLAGS_AUTOPLAY) + exit_usiblender(); + + /* groups could have changed ipo */ + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); +} + +void changeview3d() +{ + + setwinmatrixview3d(0); /* 0= geen pick rect */ + +} + + /* Callable from editmode and faceselect mode from the + * moment, would be nice (and is easy) to generalize + * to any mode. + */ +static void align_view_to_selected(View3D *v3d) +{ + int nr= pupmenu("Align view%t|To selection (top)%x2|To selection (front)%x1|To selection (side)%x0"); + + if (nr!=-1) { + int axis= nr; + + if (G.obedit && (G.obedit->type == OB_MESH)) { + editmesh_align_view_to_selected(v3d, axis); + addqueue(v3d->area->win, REDRAW, 1); + } else if (G.f & G_FACESELECT) { + Object *obact= OBACT; + if (obact && obact->type==OB_MESH) { + Mesh *me= obact->data; + + if (me->tface) { + faceselect_align_view_to_selected(v3d, me, axis); + addqueue(v3d->area->win, REDRAW, 1); + } + } + } + } +} + +void winqread3d(unsigned short event, short val, char ascii) +{ + View3D *v3d= curarea->spacedata.first; + Object *ob; + float *curs; + int doredraw= 0, pupval; + + if(curarea->win==0) return; /* hier komtie vanuit sa->headqread() */ + if(event==MOUSEY) return; + + if(val) { + + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + /* TEXTEDITING?? */ + if(G.obedit && G.obedit->type==OB_FONT) { + switch(event) { + + case LEFTMOUSE: + mouse_cursor(); + break; + case MIDDLEMOUSE: + if(U.flag & VIEWMOVE) { + if(G.qual & LR_SHIFTKEY) viewmove(0); + else if(G.qual & LR_CTRLKEY) viewmove(2); + else viewmove(1); + } + else { + if(G.qual & LR_SHIFTKEY) viewmove(1); + else if(G.qual & LR_CTRLKEY) viewmove(2); + else viewmove(0); + } + case UKEY: + if(G.qual & LR_ALTKEY) { + remake_editText(); + doredraw= 1; + } else { + do_textedit(event, val, ascii); + } + break; + case PAD0: case PAD1: case PAD2: case PAD3: case PAD4: + case PAD5: case PAD6: case PAD7: case PAD8: case PAD9: + case PADENTER: + persptoetsen(event); + doredraw= 1; + break; + + default: + do_textedit(event, val, ascii); + break; + } + } + else { + switch(event) { + + case BACKBUFDRAW: + backdrawview3d(1); + break; + + case LEFTMOUSE: + if (G.obedit || !(G.f&(G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT))) { + mouse_cursor(); + } + else if (G.f & G_VERTEXPAINT) { + vertex_paint(); + } + else if (G.f & G_WEIGHTPAINT){ + weight_paint(); + } + else if (G.f & G_TEXTUREPAINT) { + face_draw(); + } + break; + case MIDDLEMOUSE: + if(U.flag & VIEWMOVE) { + if(G.qual & LR_SHIFTKEY) viewmove(0); + else if(G.qual & LR_CTRLKEY) viewmove(2); + else viewmove(1); + } + else { + if(G.qual & LR_SHIFTKEY) viewmove(1); + else if(G.qual & LR_CTRLKEY) viewmove(2); + else viewmove(0); + } + break; + case RIGHTMOUSE: + if(G.obedit && (G.qual & LR_CTRLKEY)==0) { + if(G.obedit->type==OB_MESH) mouse_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) mouse_nurb(); + else if(G.obedit->type==OB_MBALL) mouse_mball(); + else if(G.obedit->type==OB_LATTICE) mouse_lattice(); + else if(G.obedit->type==OB_ARMATURE) mouse_armature(); + } + else if(G.obpose) { + if (G.obpose->type==OB_ARMATURE) mousepose_armature(); + } + else if( G.qual & LR_CTRLKEY ) mouse_select(); + else if(G.f & G_FACESELECT) face_select(); + else if( G.f & (G_VERTEXPAINT|G_TEXTUREPAINT)) sample_vpaint(); + else + mouse_select(); + break; + + case ONEKEY: + do_layer_buttons(0); break; + case TWOKEY: + do_layer_buttons(1); break; + case THREEKEY: + do_layer_buttons(2); break; + case FOURKEY: + do_layer_buttons(3); break; + case FIVEKEY: + do_layer_buttons(4); break; + case SIXKEY: + do_layer_buttons(5); break; + case SEVENKEY: + do_layer_buttons(6); break; + case EIGHTKEY: + do_layer_buttons(7); break; + case NINEKEY: + do_layer_buttons(8); break; + case ZEROKEY: + do_layer_buttons(9); break; + case MINUSKEY: + do_layer_buttons(10); break; + case EQUALKEY: + do_layer_buttons(11); break; + case ACCENTGRAVEKEY: + do_layer_buttons(-1); break; + + case AKEY: + if(G.qual & LR_CTRLKEY) apply_object(); + else if(G.qual & LR_SHIFTKEY) { + tbox_setmain(0); + toolbox(); + } + else { + if(G.obedit) { + if(G.obedit->type==OB_MESH) deselectall_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) deselectall_nurb(); + else if(G.obedit->type==OB_MBALL) deselectall_mball(); + else if(G.obedit->type==OB_LATTICE) deselectall_Latt(); + else if(G.obedit->type==OB_ARMATURE) deselectall_armature(); + } + else if (G.obpose){ + switch (G.obpose->type){ + case OB_ARMATURE: + deselectall_posearmature(1); + break; + } + } + else { + if(G.f & G_FACESELECT) deselectall_tface(); + else deselectall(); + } + } + break; + case BKEY: + if(G.qual & LR_SHIFTKEY) set_render_border(); + else borderselect(); + break; + case CKEY: + if(G.qual & LR_CTRLKEY) { + copymenu(); + } + else if(G.qual & LR_ALTKEY) { + convertmenu(); /* editobject.c */ + } + else if(G.qual & LR_SHIFTKEY) { + view3d_home(1); + curs= give_cursor(); + curs[0]=curs[1]=curs[2]= 0.0; + scrarea_queue_winredraw(curarea); + } + else if(G.obedit!=0 && ELEM(G.obedit->type, OB_CURVE, OB_SURF) ) { + makecyclicNurb(); + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + } + else { + curs= give_cursor(); + G.vd->ofs[0]= -curs[0]; + G.vd->ofs[1]= -curs[1]; + G.vd->ofs[2]= -curs[2]; + scrarea_queue_winredraw(curarea); + } + + break; + case DKEY: + if(G.qual & LR_SHIFTKEY) { + if(G.obedit) { + if(G.obedit->type==OB_MESH) adduplicate_mesh(); + else if(G.obedit->type==OB_ARMATURE) adduplicate_armature(); + else if(G.obedit->type==OB_MBALL) adduplicate_mball(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) adduplicate_nurb(); + } + else if(G.obpose){ + error ("Duplicate not possible in posemode."); + } + else adduplicate(0); + } + else if(G.qual & LR_ALTKEY) { + if(G.obpose) error ("Duplicate not possible in posemode."); + else + if(G.obedit==0) adduplicate(0); + } + else if(G.qual & LR_CTRLKEY) { + imagestodisplist(); + } + else { + pupval= pupmenu("Draw mode%t|BoundBox %x1|Wire %x2|OpenGL Solid %x3|Shaded Solid %x4"); + if(pupval>0) { + G.vd->drawtype= pupval; + doredraw= 1; + + } + } + + break; + case EKEY: + if(G.obedit) { + if(G.obedit->type==OB_MESH) extrude_mesh(); + else if(G.obedit->type==OB_CURVE) addvert_Nurb('e'); + else if(G.obedit->type==OB_SURF) extrude_nurb(); + else if(G.obedit->type==OB_ARMATURE) extrude_armature(); + } + else { + ob= OBACT; + if(ob && ob->type==OB_IKA) if(okee("extrude IKA")) extrude_ika(ob, 1); + } + break; + case FKEY: + if(G.obedit) { + if(G.obedit->type==OB_MESH) { + if(G.qual & LR_SHIFTKEY) fill_mesh(); + else if(G.qual & LR_ALTKEY) beauty_fill(); + else if(G.qual & LR_CTRLKEY) edge_flip(); + else addedgevlak_mesh(); + } + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) addsegment_nurb(); + } + else if(G.qual & LR_CTRLKEY) sort_faces(); + else if(G.qual & LR_SHIFTKEY) fly(); + else { + set_faceselect(); + } + + break; + case GKEY: + /* RMGRP if(G.qual & LR_CTRLKEY) add_selected_to_group(); + else if(G.qual & LR_ALTKEY) rem_selected_from_group(); + else if(G.qual & LR_SHIFTKEY) group_menu(); + else */ + if(G.qual & LR_ALTKEY) clear_object('g'); + else + transform('g'); + break; + case HKEY: + if(G.obedit) { + if(G.obedit->type==OB_MESH) { + if(G.qual & LR_ALTKEY) reveal_mesh(); + else hide_mesh(G.qual & LR_SHIFTKEY); + } + else if(G.obedit->type== OB_SURF) { + if(G.qual & LR_ALTKEY) revealNurb(); + else hideNurb(G.qual & LR_SHIFTKEY); + } + else if(G.obedit->type==OB_CURVE) { + + if(G.qual & LR_CTRLKEY) autocalchandlesNurb_all(1); /* flag=1, selected */ + else if(G.qual & LR_SHIFTKEY) sethandlesNurb(1); + else sethandlesNurb(3); + + makeDispList(G.obedit); + + allqueue(REDRAWVIEW3D, 0); + } + } + else if(G.f & G_FACESELECT) hide_tface(); + + break; + case IKEY: + break; + + case JKEY: + if(G.qual & LR_CTRLKEY) { + if( (ob= OBACT) ) { + if(ob->type == OB_MESH) join_mesh(); + else if(ob->type == OB_CURVE) join_curve(OB_CURVE); + else if(ob->type == OB_SURF) join_curve(OB_SURF); + else if(ob->type == OB_ARMATURE) join_armature (); + } + else if (G.obedit && ELEM(G.obedit->type, OB_CURVE, OB_SURF)) addsegment_nurb(); + } else if(G.obedit) { + if(G.obedit->type==OB_MESH) { + join_triangles(); + } + } + + break; + case KKEY: + if(G.obedit) { + if(G.obedit->type==OB_SURF) printknots(); + } + else { + if(G.qual & LR_SHIFTKEY) { + if(G.f & G_FACESELECT) clear_vpaint_selectedfaces(); + else if(G.f & G_VERTEXPAINT) clear_vpaint(); + else select_select_keys(); + } + else if(G.qual & LR_CTRLKEY) make_skeleton(); +/* else if(G.qual & LR_ALTKEY) delete_skeleton(); */ + else set_ob_ipoflags(); + } + + break; + case LKEY: + if(G.obedit) { + if(G.obedit->type==OB_MESH) selectconnected_mesh(); + if(G.obedit->type==OB_ARMATURE) selectconnected_armature(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) selectconnected_nurb(); + } + else if(G.obpose) { + if(G.obpose->type==OB_ARMATURE) selectconnected_posearmature(); + } + else { + + if(G.qual & LR_SHIFTKEY) selectlinks(); + else if(G.qual & LR_CTRLKEY) linkmenu(); + else if(G.f & G_FACESELECT) select_linked_tfaces(); + else make_local(); + } + break; + case MKEY: + movetolayer(); + break; + case NKEY: + if(G.obedit) { + switch (G.obedit->type){ + case OB_ARMATURE: + if (okee("Recalc bone roll angles")) auto_align_armature(); + break; + case OB_MESH: + if(G.qual & LR_SHIFTKEY) { + if(okee("Recalc normals inside")) righthandfaces(2); + } + else { + if(okee("Recalc normals outside")) righthandfaces(1); + } + break; + } + allqueue(REDRAWVIEW3D, 0); + } + break; + case OKEY: + if(G.qual & LR_ALTKEY) clear_object('o'); + else if(G.obedit) { + extern int prop_mode; + + if (G.qual & LR_SHIFTKEY) prop_mode= !prop_mode; + else G.f ^= G_PROPORTIONAL; + + allqueue(REDRAWHEADERS, 0); + } + break; + case PKEY: + + if(G.obedit) { + if(G.qual) { + if(G.qual & LR_CTRLKEY) make_parent(); + } + else if(G.obedit->type==OB_MESH) separate_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) separate_nurb(); + } + else if(G.qual & LR_CTRLKEY) make_parent(); + else if(G.qual & LR_ALTKEY) clear_parent(); + else { + start_game(); + } + break; + case RKEY: + if(G.obedit==0 && (G.f & G_FACESELECT)) rotate_uv_tface(); + else if(G.qual & LR_ALTKEY) clear_object('r'); + else if(G.qual & LR_SHIFTKEY) selectrow_nurb(); + else transform('r'); + break; + case SKEY: + if(G.qual & LR_ALTKEY) { + if(G.obedit) transform('N'); /* scale by vertex normal */ + else clear_object('s'); + } + else if(G.qual & LR_SHIFTKEY) snapmenu(); + else if(G.qual & LR_CTRLKEY) { + if(G.obedit) transform('S'); + } + else transform('s'); + break; + case TKEY: + if(G.qual & LR_CTRLKEY) { + if(G.obedit) { + if(G.obedit->type==OB_MESH) { + convert_to_triface(0); + allqueue(REDRAWVIEW3D, 0); + countall(); + makeDispList(G.obedit); + } + } + else make_track(); + } + else if(G.qual & LR_ALTKEY) { + if(G.obedit && G.obedit->type==OB_CURVE) clear_tilt(); + else clear_track(); + } + else { + if(G.obedit) transform('t'); + else texspace_edit(); + } + + break; + case UKEY: + if(G.obedit) { + if(G.obedit->type==OB_MESH) remake_editMesh(); + else if(G.obedit->type==OB_ARMATURE) remake_editArmature(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) remake_editNurb(); + else if(G.obedit->type==OB_LATTICE) remake_editLatt(); + } + else if(G.f & G_FACESELECT) uv_autocalc_tface(); + else if(G.f & G_WEIGHTPAINT) wpaint_undo(); + else if(G.f & G_VERTEXPAINT) vpaint_undo(); + else single_user(); + + break; + case VKEY: + if(G.qual==LR_SHIFTKEY) { + if (G.obedit && G.obedit->type==OB_MESH) { + align_view_to_selected(v3d); + } else if (G.f & G_FACESELECT) { + align_view_to_selected(v3d); + } + } else { + if(G.obedit) { + if(G.obedit->type==OB_CURVE) { + sethandlesNurb(2); + makeDispList(G.obedit); + allqueue(REDRAWVIEW3D, 0); + } + } + else if(G.qual & LR_ALTKEY) image_aspect(); + else set_vpaint(); + } + break; + case WKEY: + if(G.qual & LR_SHIFTKEY) { + transform('w'); + } + else if(G.qual & LR_ALTKEY) { + /* if(G.obedit && G.obedit->type==OB_MESH) write_videoscape(); */ + } + else if(G.qual & LR_CTRLKEY) { + if(G.obedit) { + if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + switchdirectionNurb2(); + } + } + } + else special_editmenu(); + + break; + case XKEY: + case DELKEY: + if(G.obedit) { + if(G.obedit->type==OB_MESH) delete_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) delNurb(); + else if(G.obedit->type==OB_MBALL) delete_mball(); + else if (G.obedit->type==OB_ARMATURE) delete_armature(); + } + else delete_obj(0); + break; + case YKEY: + if(G.obedit) { + if(G.obedit->type==OB_MESH) split_mesh(); + } + break; + case ZKEY: + if(G.qual & LR_CTRLKEY) { + reshadeall_displist(); + G.vd->drawtype= OB_SHADED; + } + else if(G.qual & LR_SHIFTKEY) { + if(G.vd->drawtype== OB_SHADED) G.vd->drawtype= OB_WIRE; + else G.vd->drawtype= OB_SHADED; + } + else if(G.qual & LR_ALTKEY) { + if(G.vd->drawtype== OB_TEXTURE) G.vd->drawtype= OB_SOLID; + else G.vd->drawtype= OB_TEXTURE; + } + else { + if(G.vd->drawtype==OB_SOLID || G.vd->drawtype==OB_SHADED) G.vd->drawtype= OB_WIRE; + else G.vd->drawtype= OB_SOLID; + } + + + scrarea_queue_headredraw(curarea); + scrarea_queue_winredraw(curarea); + break; + + + case HOMEKEY: + view3d_home(0); + break; + case COMMAKEY: + G.vd->around= V3D_CENTRE; + scrarea_queue_headredraw(curarea); + break; + + case PERIODKEY: + G.vd->around= V3D_CURSOR; + scrarea_queue_headredraw(curarea); + break; + + case PADSLASHKEY: + if(G.vd->localview) { + G.vd->localview= 0; + endlocalview(curarea); + } + else { + G.vd->localview= 1; + initlocalview(); + } + scrarea_queue_headredraw(curarea); + break; + case PADASTERKEY: /* '*' */ + ob= OBACT; + if(ob) { + obmat_to_viewmat(ob); + if(G.vd->persp==2) G.vd->persp= 1; + scrarea_queue_winredraw(curarea); + } + break; + case PADPERIOD: /* '.' */ + centreview(); + break; + + case PAGEUPKEY: + if(G.qual & LR_CTRLKEY) movekey_obipo(1); + else nextkey_obipo(1); /* in editipo.c */ + break; + + case PAGEDOWNKEY: + if(G.qual & LR_CTRLKEY) movekey_obipo(-1); + else nextkey_obipo(-1); + break; + + case PAD0: case PAD1: case PAD2: case PAD3: case PAD4: + case PAD5: case PAD6: case PAD7: case PAD8: case PAD9: + case PADMINUS: case PADPLUSKEY: case PADENTER: + persptoetsen(event); + doredraw= 1; + break; + + case ESCKEY: + if (G.vd->flag & V3D_DISPIMAGE) { + G.vd->flag &= ~V3D_DISPIMAGE; + doredraw= 1; + } + break; + } + } + } + + if(doredraw) { + scrarea_queue_winredraw(curarea); + scrarea_queue_headredraw(curarea); + } +} + +void initview3d(ScrArea *sa) +{ + View3D *vd; + + vd= MEM_callocN(sizeof(View3D), "initview3d"); + BLI_addhead(&sa->spacedata, vd); /* addhead! niet addtail */ + + vd->spacetype= SPACE_VIEW3D; + vd->viewquat[0]= 1.0; + vd->viewquat[1]= vd->viewquat[2]= vd->viewquat[3]= 0.0; + vd->persp= 1; + vd->drawtype= OB_WIRE; + vd->view= 7; + vd->dist= 10.0; + vd->lens= 35.0; + vd->near= 0.01; + vd->far= 500.0; + vd->grid= 1.0; + vd->gridlines= 16; + vd->lay= vd->layact= 1; + if(G.scene) { + vd->lay= vd->layact= G.scene->lay; + vd->camera= G.scene->camera; + } + vd->scenelock= 1; +} + + +/* ******************** SPACE: IPO ********************** */ + +void changeview2d() +{ + if(G.v2d==0) return; + + test_view2d(G.v2d, curarea->winx, curarea->winy); + myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); +} + +void winqreadipo(unsigned short event, short val, char ascii) +{ + SpaceIpo *sipo= curarea->spacedata.first; + View2D *v2d= &sipo->v2d; + float dx, dy; + int cfra, doredraw= 0; + short mval[2]; + + if(curarea->win==0) return; + + if(val) { + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) { + case UI_BUT_EVENT: + if(val>0) do_ipowin_buts(val-1); + break; + case LEFTMOUSE: + if( in_ipo_buttons() ) { + do_ipo_selectbuttons(); + doredraw= 1; + } + else if(G.qual & LR_CTRLKEY) add_vert_ipo(); + else { + do { + getmouseco_areawin(mval); + areamouseco_to_ipoco(v2d, mval, &dx, &dy); + + cfra= (int)dx; + if(cfra< 1) cfra= 1; + + if( cfra!=CFRA ) { + CFRA= cfra; + update_for_newframe(); + force_draw_plus(SPACE_VIEW3D); + force_draw_plus(SPACE_ACTION); + force_draw_plus(SPACE_BUTS); /* To make constraint sliders redraw */ + } + + } while(get_mbut()&L_MOUSE); + } + + break; + case MIDDLEMOUSE: + if(in_ipo_buttons()) { + scroll_ipobuts(); + } + else view2dmove(); /* in drawipo.c */ + break; + case RIGHTMOUSE: + mouse_select_ipo(); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + break; + case PADPLUSKEY: + + dx= 0.1154*(v2d->cur.xmax-v2d->cur.xmin); + dy= 0.1154*(v2d->cur.ymax-v2d->cur.ymin); + if(val==SPACE_BUTS) { + dx/=2.0; dy/= 2.0; + } + v2d->cur.xmin+= dx; + v2d->cur.xmax-= dx; + v2d->cur.ymin+= dy; + v2d->cur.ymax-= dy; + test_view2d(G.v2d, curarea->winx, curarea->winy); + doredraw= 1; + break; + case PADMINUS: + dx= 0.15*(v2d->cur.xmax-v2d->cur.xmin); + dy= 0.15*(v2d->cur.ymax-v2d->cur.ymin); + if(val==SPACE_BUTS) { + dx/=2.0; dy/= 2.0; + } + v2d->cur.xmin-= dx; + v2d->cur.xmax+= dx; + v2d->cur.ymin-= dy; + v2d->cur.ymax+= dy; + test_view2d(G.v2d, curarea->winx, curarea->winy); + doredraw= 1; + break; + case PAGEUPKEY: + if(G.qual & LR_CTRLKEY) movekey_ipo(1); + else nextkey_ipo(1); + break; + case PAGEDOWNKEY: + if(G.qual & LR_CTRLKEY) movekey_ipo(-1); + else nextkey_ipo(-1); + break; + case HOMEKEY: + do_ipo_buttons(B_IPOHOME); + break; + + case AKEY: + if(in_ipo_buttons()) { + swap_visible_editipo(); + } + else swap_selectall_editipo(); + allspace (REMAKEIPO, 0); + allqueue (REDRAWNLA, 0); + allqueue (REDRAWACTION, 0); + break; + case BKEY: + borderselect_ipo(); + break; + case CKEY: + move_to_frame(); + break; + case DKEY: + if(G.qual & LR_SHIFTKEY) add_duplicate_editipo(); + break; + case GKEY: + transform_ipo('g'); + break; + case HKEY: + if(G.qual & LR_SHIFTKEY) sethandles_ipo(HD_AUTO); + else sethandles_ipo(HD_ALIGN); + break; + case JKEY: + join_ipo(); + break; + case KKEY: + if(G.sipo->showkey) { + G.sipo->showkey= 0; + swap_selectall_editipo(); /* sel all */ + } + else G.sipo->showkey= 1; + free_ipokey(&G.sipo->ipokey); + if(G.sipo->ipo) G.sipo->ipo->showkey= G.sipo->showkey; + + scrarea_queue_headredraw(curarea); + allqueue(REDRAWVIEW3D, 0); + doredraw= 1; + break; + case RKEY: + ipo_record(); + break; + case SKEY: + if(G.qual & LR_SHIFTKEY) ipo_snapmenu(); + else transform_ipo('s'); + break; + case TKEY: + set_ipotype(); + break; + case VKEY: + sethandles_ipo(HD_VECT); + break; + case XKEY: + case DELKEY: + if(G.qual & LR_SHIFTKEY) delete_key(); + else del_ipo(); + break; + } + } + + if(doredraw) scrarea_queue_winredraw(curarea); +} + +void initipo(ScrArea *sa) +{ + SpaceIpo *sipo; + + sipo= MEM_callocN(sizeof(SpaceIpo), "initipo"); + BLI_addhead(&sa->spacedata, sipo); + + sipo->spacetype= SPACE_IPO; + /* sipo space loopt van (0,-?) tot (??,?) */ + sipo->v2d.tot.xmin= 0.0; + sipo->v2d.tot.ymin= -10.0; + sipo->v2d.tot.xmax= G.scene->r.efra; + sipo->v2d.tot.ymax= 10.0; + + sipo->v2d.cur= sipo->v2d.tot; + + sipo->v2d.min[0]= 0.01; + sipo->v2d.min[1]= 0.01; + + sipo->v2d.max[0]= 15000.0; + sipo->v2d.max[1]= 10000.0; + + sipo->v2d.scroll= L_SCROLL+B_SCROLL; + sipo->v2d.keeptot= 0; + + sipo->blocktype= ID_OB; +} + +/* ******************** SPACE: INFO ********************** */ + +void space_mipmap_button_function(int event) { + set_mipmap(!(U.gameflags & USERDEF_DISABLE_MIPMAP)); + + allqueue(REDRAWVIEW3D, 0); +} + +void space_sound_button_function(int event) +{ + int a; + SYS_SystemHandle syshandle; + + if ((syshandle = SYS_GetSystem())) + { + a = (U.gameflags & USERDEF_DISABLE_SOUND); + SYS_WriteCommandLineInt(syshandle, "noaudio", a); + } +} + +void drawinfospace(void) +{ + uiBlock *block; + float fac; + int dx; + char naam[32]; + + if(curarea->win==0) return; + + glClearColor(0.5, 0.5, 0.5, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + fac= ((float)curarea->winx)/1280.0; + myortho2(0.0, 1280.0, 0.0, curarea->winy/fac); + + sprintf(naam, "infowin %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSSX, UI_HELV, curarea->win); + + uiBlockSetCol(block, BUTBLUE); + uiDefButS(block, TOG|BIT|0, B_RESETAUTOSAVE, "Auto Temp Save", 45,32,126,20, &(U.flag), 0, 0, 0, 0, "Enables/Disables the automatic temp. file saving"); + uiBlockSetCol(block, BUTGREY); + uiDefBut(block, TEX, 0, "Dir:", 45,10,127,20, U.tempdir, 1.0, 63.0, 0, 0, "The directory for temp. files"); + uiDefButI(block, NUM, B_RESETAUTOSAVE, "Time:", 174,32,91,20, &(U.savetime), 1.0, 60.0, 0, 0, "The time in minutes to wait between temp. saves"); + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_LOADTEMP, "Load Temp", 174,10,90,20, 0, 0, 0, 0, 0, "Loads the most recently saved temp file"); + + uiBlockSetCol(block, BUTGREY); + uiDefButS(block, NUM, 0, "Versions:", 281,10,86,42, &U.versions, 0.0, 32.0, 0, 0, "The number of old versions to maintain when saving"); + + uiBlockSetCol(block, BUTYELLOW); + uiDefButI(block, TOG|BIT|USERDEF_VERTEX_ARRAYS_BIT, 0, "Vertex arrays", + 389,54,86,20, &(U.gameflags), 0, 0, 0, 0, + "Toggle between vertex arrays on (less reliable) and off (more reliable)"); + uiDefButI(block, TOG|BIT|USERDEF_DISABLE_SOUND_BIT, B_SOUNDTOGGLE, "No sound", + 478,54,86,20, &(U.gameflags), 0, 0, 0, 0, + "Toggle between sound on and sound off"); + + uiDefButI(block, TOG|BIT|USERDEF_DISABLE_MIPMAP_BIT, B_MIPMAPCHANGED, "No Mipmaps", + 569,54,78,20, &(U.gameflags), 0, 0, 0, 0, + "Toggle between Mipmap textures on (beautiful) and off (fast)"); + + uiBlockSetCol(block, BUTGREEN); + uiDefButS(block, TOG|BIT|4, 0, "Scene Global", + 389,32,86,20, &(U.flag), 0, 0, 0, 0, + "Forces the current Scene to be displayed in all Screens"); + uiDefButS(block, TOG|BIT|5, 0, "TrackBall", + 389,10,86,20, &(U.flag), 0, 0, 0, 0, + "Switches between trackball and turntable view rotation methods (MiddleMouse)"); + uiDefButS(block, TOG|BIT|12, 0, "2-Mouse", + 478,10,86,20, &(U.flag), 0, 0, 0, 0, + "Maps ALT+LeftMouse to MiddleMouse button"); + uiDefButS(block, TOG|BIT|8, 0, "Mat on Obj", + 569,9,78,20, &(U.flag), 0, 0, 0, 0, + "Sets whether Material data is linked to Obj or ObjData"); + uiDefButS(block, TOG|BIT|9, B_U_CAPSLOCK, "NoCapsLock", + 478,32,86,20, &(U.flag), 0, 0, 0, 0, + "Deactives the CapsLock button (only applies to text input)"); + uiDefButS(block, TOG|BIT|10, 0, "Viewmove", + 569,32,78,20, &(U.flag), 0, 0, 0, 0, + "Sets the default action for the middle mouse button"); + + uiDefButS(block, TOG|BIT|13, 0, "noNumpad", + 653,10,76,20, &(U.flag), 0, 0, 0, 0, + "For laptops: keys 1 to 0 become numpad keys"); + uiDefButS(block, TOG|BIT|11, 0, "ToolTips", + 653,32,76,20, &(U.flag), 0, 0, 0, 0, + "Enables/Disables tooltips"); + +// uiDefButS(block, ICONTOG|BIT|14, 0, ICON(), 733,10,50,42, &(U.flag), 0, 0, 0, 0, "Automatic keyframe insertion"); + uiDefButS(block, TOG|BIT|14, 0, "KeyAC", 733,32,50,20, &(U.flag), 0, 0, 0, 0, "Automatic keyframe insertion for actions"); + uiDefButS(block, TOG|BIT|15, 0, "KeyOB", 733,10,50,20, &(U.flag), 0, 0, 0, 0, "Automatic keyframe insertion for objects"); + + uiDefButS(block, TOG|BIT|1, 0, "Grab Grid", 788,32,106,20, &(U.flag), 0, 0, 0, 0, "Changes default step mode for grabbing"); + uiDefButS(block, TOG|BIT|2, 0, "Rot", 842,10,52,20, &(U.flag), 0, 0, 0, 0, "Changes default step mode for rotation"); + uiDefButS(block, TOG|BIT|3, 0, "Size", 788,10,52,20, &(U.flag), 0, 0, 0, 0, "Changes default step mode for scaling"); + + uiDefButS(block, TOG|BIT|0, 0, "Dupli Mesh", 902,32,90,20, &(U.dupflag), 0, 0, 0, 0, "Causes Mesh data to be duplicated with Shift+D"); + uiDefButS(block, TOG|BIT|9, 0, "Armature", 902,10,90,20, &(U.dupflag), 0, 0, 0, 0, "Causes Armature data to be duplicated with Shift+D"); + + uiDefButS(block, TOG|BIT|1, 0, "Curve", 995,32,50,20, &(U.dupflag), 0, 0, 0, 0, "Causes Curve data to be duplicated with Shift+D"); + uiDefButS(block, TOG|BIT|2, 0, "Surf", 995,10,50,20, &(U.dupflag), 0, 0, 0, 0, "Causes Surface data to be duplicated with Shift+D"); + uiDefButS(block, TOG|BIT|3, 0, "Text", 1048,32,50,20, &(U.dupflag), 0, 0, 0, 0, "Causes Text data to be duplicated with Shift+D"); + uiDefButS(block, TOG|BIT|4, 0, "MBall", 1048,10,50,20, &(U.dupflag), 0, 0, 0, 0, "Causes Metaball data to be duplicated with Shift+D"); + uiDefButS(block, TOG|BIT|5, 0, "Lamp", 1101,32,50,20, &(U.dupflag), 0, 0, 0, 0, "Causes Lamp data to be duplicated with Shift+D"); + uiDefButS(block, TOG|BIT|6, 0, "Ipo", 1101,10,50,20, &(U.dupflag), 0, 0, 0, 0, "Causes Ipo data to be duplicated with Shift+D"); + uiDefButS(block, TOG|BIT|7, 0, "Material", 1153,32,70,20, &(U.dupflag), 0, 0, 0, 0, "Causes Material data to be duplicated with Shift+D"); + uiDefButS(block, TOG|BIT|8, 0, "Texture", 1153,10,70,20, &(U.dupflag), 0, 0, 0, 0, "Causes Texture data to be duplicated with Shift+D"); + + + + uiBlockSetCol(block, BUTGREY); + dx= (1280-90)/6; + + +#define _XPOS_ 45 +#define _YPOS_ 80 +#define _BUTH_ 20 +#define _RULESPACE_ 2 + uiDefBut(block, TEX, 0, "Python:", + _XPOS_,_YPOS_-_BUTH_-_RULESPACE_,(short)dx,_BUTH_, U.pythondir, 1.0, 63.0, 0, 0, + "The default directory for Python scripts"); + uiDefBut(block, TEX, 0, "Fonts:", + _XPOS_,_YPOS_,(short)dx,_BUTH_, U.fontdir, 1.0, 63.0, 0, 0, + "The default directory to search when loading fonts"); + uiDefBut(block, TEX, 0, "Render:", + (short)(_XPOS_+dx),_YPOS_,(short)dx,_BUTH_, U.renderdir, 1.0, 63.0, 0, 0, + "The default directory to choose for rendering"); + uiDefBut(block, TEX, 0, "Textures:", + (short)(_XPOS_+2*dx),_YPOS_,(short)dx,_BUTH_, U.textudir, 1.0, 63.0, 0, 0, + "The default directory to search when loading textures"); + uiDefBut(block, TEX, 0, "TexPlugin:", + (short)(_XPOS_+3*dx),_YPOS_,(short)dx,_BUTH_, U.plugtexdir, 1.0, 63.0, 0, 0, + "The default directory to search when loading texture plugins"); + uiDefBut(block, TEX, 0, "SeqPlugin:", + (short)(_XPOS_+4*dx),_YPOS_,(short)dx,_BUTH_, U.plugseqdir, 1.0, 63.0, 0, 0, + "The default directory to search when loading sequence plugins"); + uiDefBut(block, TEX, 0, "Sounds:", + (short)(_XPOS_+5*dx),_YPOS_,(short)dx,_BUTH_, U.sounddir, 1.0, 63.0, 0, 0, + "The default directory to search when loading sounds"); +#undef _XPOS_ +#undef _YPOS_ +#undef _BUTH_ +#undef _RULESPACE_ + uiDrawBlock(block); +} + +void winqreadinfospace(unsigned short event, short val, char ascii) +{ + if(val) { + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) { + case UI_BUT_EVENT: + do_global_buttons(val); + + break; + } + } +} + +void init_infospace(ScrArea *sa) +{ + SpaceInfo *sinfo; + + sinfo= MEM_callocN(sizeof(SpaceInfo), "initinfo"); + BLI_addhead(&sa->spacedata, sinfo); +} + +/* ******************** SPACE: BUTS ********************** */ + +extern void drawbutspace(void); /* buttons.c */ + +void changebutspace(void) +{ + if(G.v2d==0) return; + + test_view2d(G.v2d, curarea->winx, curarea->winy); + myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); +} + +void winqreadbutspace(unsigned short event, short val, char ascii) +{ + SpaceButs *sbuts= curarea->spacedata.first; + ScrArea *sa, *sa3d; + int doredraw= 0; + + if(val) { + + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) { + case UI_BUT_EVENT: + do_blenderbuttons(val); + break; + + case MIDDLEMOUSE: + view2dmove(); /* in drawipo.c */ + break; + case PADPLUSKEY: + case PADMINUS: + val= SPACE_BUTS; + winqreadipo(event, val, 0); + break; + case RENDERPREVIEW: + BIF_previewrender(sbuts); + break; + + case HOMEKEY: + do_buts_buttons(B_BUTSHOME); + break; + + + /* if only 1 view, also de persp, excluding arrowkeys */ + case PAD0: case PAD1: case PAD3: + case PAD5: case PAD7: case PAD9: + case PADENTER: case ZKEY: case PKEY: + sa3d= 0; + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==SPACE_VIEW3D) { + if(sa3d) return; + sa3d= sa; + } + sa= sa->next; + } + if(sa3d) { + sa= curarea; + areawinset(sa3d->win); + + if(event==PKEY) start_game(); + else if(event==ZKEY) winqread3d(event, val, 0); + else persptoetsen(event); + + scrarea_queue_winredraw(sa3d); + scrarea_queue_headredraw(sa3d); + areawinset(sa->win); + } + } + } + + if(doredraw) scrarea_queue_winredraw(curarea); +} + +void set_rects_butspace(SpaceButs *buts) +{ + /* buts space loopt van (0,0) tot (1280, 228) */ + + buts->v2d.tot.xmin= 0.0; + buts->v2d.tot.ymin= 0.0; + buts->v2d.tot.xmax= 1279.0; + buts->v2d.tot.ymax= 228.0; + + buts->v2d.min[0]= 256.0; + buts->v2d.min[1]= 42.0; + + buts->v2d.max[0]= 1600.0; + buts->v2d.max[1]= 450.0; + + buts->v2d.minzoom= 0.5; + buts->v2d.maxzoom= 1.41; + + buts->v2d.scroll= 0; + buts->v2d.keepaspect= 1; + buts->v2d.keepzoom= 1; + buts->v2d.keeptot= 1; + +} + +void test_butspace(void) +{ + ScrArea *area= curarea; + int blocksmin= uiBlocksGetYMin(&area->uiblocks)-10.0; + + G.buts->v2d.tot.ymin= MIN2(0.0, blocksmin-10.0); +} + +void init_butspace(ScrArea *sa) +{ + SpaceButs *buts; + + buts= MEM_callocN(sizeof(SpaceButs), "initbuts"); + BLI_addhead(&sa->spacedata, buts); + + buts->spacetype= SPACE_BUTS; + buts->scaflag= BUTS_SENS_LINK|BUTS_SENS_ACT|BUTS_CONT_ACT|BUTS_ACT_ACT|BUTS_ACT_LINK; + + /* set_rects doet alleen defaults, zodat na het filezen de cur niet verandert */ + set_rects_butspace(buts); + buts->v2d.cur= buts->v2d.tot; +} + +void extern_set_butspace(int fkey) +{ + ScrArea *sa; + SpaceButs *sbuts; + + /* als een ftoets ingedrukt: de dichtsbijzijnde buttonwindow wordt gezet */ + if(curarea->spacetype==SPACE_BUTS) sa= curarea; + else { + /* area vinden */ + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==SPACE_BUTS) break; + sa= sa->next; + } + } + + if(sa==0) return; + + if(sa!=curarea) areawinset(sa->win); + + sbuts= sa->spacedata.first; + + if(fkey==F4KEY) sbuts->mainb= BUTS_LAMP; + else if(fkey==F5KEY) sbuts->mainb= BUTS_MAT; + else if(fkey==F6KEY) sbuts->mainb= BUTS_TEX; + else if(fkey==F7KEY) sbuts->mainb= BUTS_ANIM; + else if(fkey==F8KEY) sbuts->mainb= BUTS_GAME; + else if(fkey==F9KEY) sbuts->mainb= BUTS_EDIT; + else if(fkey==F10KEY) sbuts->mainb= BUTS_RENDER; + + scrarea_queue_headredraw(sa); + scrarea_queue_winredraw(sa); + BIF_preview_changed(sbuts); +} + +/* ******************** SPACE: SEQUENCE ********************** */ + +/* extern void drawseqspace(); BIF_drawseq.h */ + +void winqreadsequence(unsigned short event, short val, char ascii) +{ + SpaceSeq *sseq= curarea->spacedata.first; + View2D *v2d= &sseq->v2d; + extern Sequence *last_seq; + float dx, dy; + int doredraw= 0, cfra, first; + short mval[2]; + + if(curarea->win==0) return; + + if(val) { + + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) { + case LEFTMOUSE: + if(sseq->mainb || view2dmove()==0) { + + first= 1; + set_special_seq_update(1); + + do { + getmouseco_areawin(mval); + areamouseco_to_ipoco(v2d, mval, &dx, &dy); + + cfra= (int)dx; + if(cfra< 1) cfra= 1; + /* else if(cfra> EFRA) cfra= EFRA; */ + + if( cfra!=CFRA || first ) { + first= 0; + + CFRA= cfra; + force_draw(); + } + + } while(get_mbut()&L_MOUSE); + + set_special_seq_update(0); + + update_for_newframe(); + } + break; + case MIDDLEMOUSE: + if(sseq->mainb) break; + view2dmove(); /* in drawipo.c */ + break; + case RIGHTMOUSE: + if(sseq->mainb) break; + mouse_select_seq(); + break; + case PADPLUSKEY: + if(sseq->mainb) { + sseq->zoom++; + if(sseq->zoom>8) sseq->zoom= 8; + } + else { + if(G.qual) { + if(G.qual & LR_SHIFTKEY) insert_gap(25, CFRA); + else if(G.qual & LR_ALTKEY) insert_gap(250, CFRA); + allqueue(REDRAWSEQ, 0); + } + else { + dx= 0.1154*(v2d->cur.xmax-v2d->cur.xmin); + v2d->cur.xmin+= dx; + v2d->cur.xmax-= dx; + test_view2d(G.v2d, curarea->winx, curarea->winy); + } + } + doredraw= 1; + break; + case PADMINUS: + if(sseq->mainb) { + sseq->zoom--; + if(sseq->zoom<1) sseq->zoom= 1; + } + else { + if(G.qual) { + if(G.qual & LR_SHIFTKEY) no_gaps(); + } + else { + dx= 0.15*(v2d->cur.xmax-v2d->cur.xmin); + v2d->cur.xmin-= dx; + v2d->cur.xmax+= dx; + test_view2d(G.v2d, curarea->winx, curarea->winy); + } + } + doredraw= 1; + break; + case HOMEKEY: + do_seq_buttons(B_SEQHOME); + break; + case PADPERIOD: + if(last_seq) { + CFRA= last_seq->startdisp; + v2d->cur.xmin= last_seq->startdisp- (last_seq->len/20); + v2d->cur.xmax= last_seq->enddisp+ (last_seq->len/20); + update_for_newframe(); + } + break; + + case AKEY: + if(sseq->mainb) break; + if(G.qual & LR_SHIFTKEY) { + add_sequence(0); + } + else swap_select_seq(); + break; + case BKEY: + if(sseq->mainb) break; + borderselect_seq(); + break; + case CKEY: + if(last_seq && (last_seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))) { + if(last_seq->flag & SEQ_LEFTSEL) CFRA= last_seq->startdisp; + else CFRA= last_seq->enddisp-1; + + dx= CFRA-(v2d->cur.xmax+v2d->cur.xmin)/2; + v2d->cur.xmax+= dx; + v2d->cur.xmin+= dx; + update_for_newframe(); + } + else change_sequence(); + break; + case DKEY: + if(sseq->mainb) break; + if(G.qual & LR_SHIFTKEY) add_duplicate_seq(); + break; + case EKEY: + break; + case FKEY: + set_filter_seq(); + break; + case GKEY: + if(sseq->mainb) break; + transform_seq('g'); + break; + case MKEY: + if(G.qual & LR_ALTKEY) un_meta(); + else make_meta(); + break; + case SKEY: + if(G.qual & LR_SHIFTKEY) seq_snapmenu(); + break; + case TKEY: + touch_seq_files(); + break; + case XKEY: + case DELKEY: + if(sseq->mainb) break; + del_seq(); + break; + } + } + + if(doredraw) scrarea_queue_winredraw(curarea); +} + + +void init_seqspace(ScrArea *sa) +{ + SpaceSeq *sseq; + + sseq= MEM_callocN(sizeof(SpaceSeq), "initseqspace"); + BLI_addhead(&sa->spacedata, sseq); + + sseq->spacetype= SPACE_SEQ; + sseq->zoom= 1; + + /* seq space loopt van (0,8) tot (250, 0) */ + + sseq->v2d.tot.xmin= 0.0; + sseq->v2d.tot.ymin= 0.0; + sseq->v2d.tot.xmax= 250.0; + sseq->v2d.tot.ymax= 8.0; + + sseq->v2d.cur= sseq->v2d.tot; + + sseq->v2d.min[0]= 10.0; + sseq->v2d.min[1]= 4.0; + + sseq->v2d.max[0]= 32000.0; + sseq->v2d.max[1]= MAXSEQ; + + sseq->v2d.minzoom= 0.1; + sseq->v2d.maxzoom= 10.0; + + sseq->v2d.scroll= L_SCROLL+B_SCROLL; + sseq->v2d.keepaspect= 0; + sseq->v2d.keepzoom= 0; + sseq->v2d.keeptot= 0; +} + +/* ******************** SPACE: ACTION ********************** */ +extern void drawactionspace(void); +extern void winqreadactionspace(unsigned short, short, char ascii); + +void init_actionspace(ScrArea *sa) +{ + SpaceAction *saction; + + saction= MEM_callocN(sizeof(SpaceAction), "initactionspace"); + BLI_addhead(&sa->spacedata, saction); + + saction->spacetype= SPACE_ACTION; + + saction->v2d.tot.xmin= 1.0; + saction->v2d.tot.ymin= 0.0; + saction->v2d.tot.xmax= 1000.0; + saction->v2d.tot.ymax= 1000.0; + + saction->v2d.cur.xmin= -5.0; + saction->v2d.cur.ymin= 0.0; + saction->v2d.cur.xmax= 65.0; + saction->v2d.cur.ymax= 1000.0; + + + saction->v2d.min[0]= 0.0; + saction->v2d.min[1]= 0.0; + + saction->v2d.max[0]= 1000.0; + saction->v2d.max[1]= 1000.0; + + saction->v2d.minzoom= 0.1; + saction->v2d.maxzoom= 10; + + saction->v2d.scroll= R_SCROLL+B_SCROLL; + saction->v2d.keepaspect= 0; + saction->v2d.keepzoom= V2D_LOCKZOOM_Y; + saction->v2d.keeptot= 0; + +} + +void free_actionspace(SpaceAction *saction) +{ + /* don't free saction itself */ + + /* __PINFAKE */ +/* if (saction->flag & SACTION_PIN) + if (saction->action) + saction->action->id.us --; + +*/ /* end PINFAKE */ +} + + +/* ******************** SPACE: FILE ********************** */ + +void init_filespace(ScrArea *sa) +{ + SpaceFile *sfile; + + sfile= MEM_callocN(sizeof(SpaceFile), "initfilespace"); + BLI_addhead(&sa->spacedata, sfile); + + sfile->dir[0]= '/'; + sfile->type= FILE_UNIX; + + sfile->spacetype= SPACE_FILE; +} + +void init_textspace(ScrArea *sa) +{ + SpaceText *st; + + st= MEM_callocN(sizeof(SpaceText), "inittextspace"); + BLI_addhead(&sa->spacedata, st); + + st->spacetype= SPACE_TEXT; + + st->text= NULL; + st->flags= 0; + + st->font_id= 5; + st->lheight= 12; + + st->top= 0; +} + +void init_imaselspace(ScrArea *sa) +{ + SpaceImaSel *simasel; + + simasel= MEM_callocN(sizeof(SpaceImaSel), "initimaselspace"); + BLI_addhead(&sa->spacedata, simasel); + + simasel->spacetype= SPACE_IMASEL; + + simasel->mode = 7; + strcpy (simasel->dir, U.textudir); /* TON */ + strcpy (simasel->file, ""); + strcpy(simasel->fole, simasel->file); + strcpy(simasel->dor, simasel->dir); + + simasel->first_sel_ima = 0; + simasel->hilite_ima = 0; + simasel->firstdir = 0; + simasel->firstfile = 0; + simasel->cmap = 0; + simasel->returnfunc = 0; + + simasel->title[0] = 0; + + clear_ima_dir(simasel); + + // simasel->cmap= IMB_loadiffmem((int*)datatoc_cmap_tga, IB_rect|IB_cmap); + simasel->cmap= IMB_ibImageFromMemory((int *)datatoc_cmap_tga, datatoc_cmap_tga_size, IB_rect|IB_cmap); + if (!simasel->cmap) { + error("in console"); + printf("Image select cmap file not found \n"); + } +} + +/* ******************** SPACE: SOUND ********************** */ + +extern void drawsoundspace(void); +extern void winqreadsoundspace(unsigned short, short, char ascii); + +void init_soundspace(ScrArea *sa) +{ + SpaceSound *ssound; + + ssound= MEM_callocN(sizeof(SpaceSound), "initsoundspace"); + BLI_addhead(&sa->spacedata, ssound); + + ssound->spacetype= SPACE_SOUND; + + /* sound space loopt van (0,8) tot (250, 0) */ + + ssound->v2d.tot.xmin= -4.0; + ssound->v2d.tot.ymin= -4.0; + ssound->v2d.tot.xmax= 250.0; + ssound->v2d.tot.ymax= 255.0; + + ssound->v2d.cur.xmin= -4.0; + ssound->v2d.cur.ymin= -4.0; + ssound->v2d.cur.xmax= 50.0; + ssound->v2d.cur.ymax= 255.0; + + ssound->v2d.min[0]= 1.0; + ssound->v2d.min[1]= 259.0; + + ssound->v2d.max[0]= 32000.0; + ssound->v2d.max[1]= 259; + + ssound->v2d.minzoom= 0.1; + ssound->v2d.maxzoom= 10.0; + + ssound->v2d.scroll= B_SCROLL; + ssound->v2d.keepaspect= 0; + ssound->v2d.keepzoom= 0; + ssound->v2d.keeptot= 0; + +} + +void free_soundspace(SpaceSound *ssound) +{ + /* don't free ssound itself */ + + +} + +/* ******************** SPACE: IMAGE ********************** */ + +/* extern void drawimagespace(); BIF_drawimage.h */ + +void winqreadimagespace(unsigned short event, short val, char ascii) +{ + SpaceImage *sima= curarea->spacedata.first; + View2D *v2d= &sima->v2d; + int width, height; +#ifdef NAN_TPT + IMG_BrushPtr brush; + IMG_CanvasPtr canvas; + int rowBytes; + short xy_prev[2], xy_curr[2]; + float uv_prev[2], uv_curr[2]; + extern VPaint Gvp; +#endif /* NAN_TPT */ + if(val==0) return; + + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + if (sima->flag & SI_DRAWTOOL) { +#ifdef NAN_TPT + /* Draw tool is active */ + switch(event) { + case LEFTMOUSE: + /* Paranoia checks */ + if (!sima) break; + if (!sima->image) break; + if (!sima->image->ibuf) break; + if (sima->image->packedfile) { + error("Painting in packed images not supported"); + break; + } + + brush = IMG_BrushCreate(Gvp.size, Gvp.size, Gvp.r, Gvp.g, Gvp.b, Gvp.a); + /* MAART: skipx is not set most of the times. Make a guess. */ + rowBytes = sima->image->ibuf->skipx ? sima->image->ibuf->skipx : sima->image->ibuf->x * 4; + canvas = IMG_CanvasCreateFromPtr(sima->image->ibuf->rect, sima->image->ibuf->x, sima->image->ibuf->y, rowBytes); + + getmouseco_areawin(xy_prev); + while (get_mbut() & L_MOUSE) { + getmouseco_areawin(xy_curr); + /* Check if mouse position changed */ + if ((xy_prev[0] != xy_curr[0]) || (xy_prev[1] != xy_curr[1])) { + /* Convert mouse coordinates to u,v and draw */ + areamouseco_to_ipoco(v2d, xy_prev, &uv_prev[0], &uv_prev[1]); + areamouseco_to_ipoco(v2d, xy_curr, &uv_curr[0], &uv_curr[1]); + IMG_CanvasDrawLineUV(canvas, brush, uv_prev[0], uv_prev[1], uv_curr[0], uv_curr[1]); + if (G.sima->lock) { + /* Make OpenGL aware of a changed texture */ + free_realtime_image(sima->image); + /* Redraw this view and the 3D view */ + force_draw_plus(SPACE_VIEW3D); + } + else { + /* Redraw only this view */ + force_draw(); + } + xy_prev[0] = xy_curr[0]; + xy_prev[1] = xy_curr[1]; + } + } + /* Set the dirty bit in the image so that it is clear that it has been modified. */ + sima->image->ibuf->userflags |= IB_BITMAPDIRTY; + if (!G.sima->lock) { + /* Make OpenGL aware of a changed texture */ + free_realtime_image(sima->image); + /* Redraw this view and the 3D view */ + force_draw_plus(SPACE_VIEW3D); + } + IMG_BrushDispose(brush); + IMG_CanvasDispose(canvas); + allqueue(REDRAWHEADERS, 0); + break; + } +#endif /* NAN_TPT */ + } + else { + /* Draw tool is inactive */ + switch(event) { + case LEFTMOUSE: + if(G.qual & LR_SHIFTKEY) mouseco_to_curtile(); + else gesture(); + break; + case MIDDLEMOUSE: + image_viewmove(); + break; + case RIGHTMOUSE: + mouse_select_sima(); + break; + case AKEY: + select_swap_tface_uv(); + break; + case BKEY: + borderselect_sima(); + break; + case GKEY: + transform_tface_uv('g'); + break; + case NKEY: + if(G.qual & LR_CTRLKEY) replace_names_but(); + break; + case RKEY: + transform_tface_uv('r'); + break; + case SKEY: + transform_tface_uv('s'); + break; + } + } + + /* Events handled always (whether the draw tool is active or not) */ + switch (event) { + case MIDDLEMOUSE: + image_viewmove(); + break; + case PADPLUSKEY: + sima->zoom *= 2; + scrarea_queue_winredraw(curarea); + break; + case HOMEKEY: + image_home(); + break; + case PADMINUS: + sima->zoom /= 2; + /* Check if the image will still be visible after zooming out */ + if (sima->zoom < 1) { + calc_image_view(G.sima, 'p'); + if (sima->image) { + if (sima->image->ibuf) { + width = sima->image->ibuf->x * sima->zoom; + height = sima->image->ibuf->y * sima->zoom; + if ((width < 4) && (height < 4)) { + /* Image will become too small, reset value */ + sima->zoom *= 2; + } + } + } + } + scrarea_queue_winredraw(curarea); + break; + } +} + + +void init_imagespace(ScrArea *sa) +{ + SpaceImage *sima; + + sima= MEM_callocN(sizeof(SpaceImage), "initimaspace"); + BLI_addhead(&sa->spacedata, sima); + + sima->spacetype= SPACE_IMAGE; + sima->zoom= 1; +} + + +/* ******************** SPACE: IMASEL ********************** */ + +extern void drawimasel(void); +extern void winqreadimasel(unsigned short, short, char ascii); + + +/* alles naar imasel.c */ + + +/* ******************** SPACE: OOPS ********************** */ + +extern void drawoopsspace(void); + +void winqreadoopsspace(unsigned short event, short val, char ascii) +{ + SpaceOops *soops= curarea->spacedata.first; + View2D *v2d= &soops->v2d; + float dx, dy; + + if(val==0) return; + + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) { + case LEFTMOUSE: + gesture(); + break; + case MIDDLEMOUSE: + view2dmove(); /* in drawipo.c */ + break; + case RIGHTMOUSE: + mouse_select_oops(); + break; + case PADPLUSKEY: + + dx= 0.1154*(v2d->cur.xmax-v2d->cur.xmin); + dy= 0.1154*(v2d->cur.ymax-v2d->cur.ymin); + v2d->cur.xmin+= dx; + v2d->cur.xmax-= dx; + v2d->cur.ymin+= dy; + v2d->cur.ymax-= dy; + test_view2d(G.v2d, curarea->winx, curarea->winy); + scrarea_queue_winredraw(curarea); + break; + + case PADMINUS: + + dx= 0.15*(v2d->cur.xmax-v2d->cur.xmin); + dy= 0.15*(v2d->cur.ymax-v2d->cur.ymin); + v2d->cur.xmin-= dx; + v2d->cur.xmax+= dx; + v2d->cur.ymin-= dy; + v2d->cur.ymax+= dy; + test_view2d(G.v2d, curarea->winx, curarea->winy); + scrarea_queue_winredraw(curarea); + break; + + case HOMEKEY: + do_oops_buttons(B_OOPSHOME); + break; + + case AKEY: + swap_select_all_oops(); + scrarea_queue_winredraw(curarea); + break; + case BKEY: + borderselect_oops(); + break; + case GKEY: + transform_oops('g'); + break; + case LKEY: + if(G.qual & LR_SHIFTKEY) select_backlinked_oops(); + else select_linked_oops(); + break; + case SKEY: + + if(G.qual & LR_ALTKEY) shrink_oops(); + else if(G.qual & LR_SHIFTKEY) shuffle_oops(); + else transform_oops('s'); + break; + + case ONEKEY: + do_layer_buttons(0); break; + case TWOKEY: + do_layer_buttons(1); break; + case THREEKEY: + do_layer_buttons(2); break; + case FOURKEY: + do_layer_buttons(3); break; + case FIVEKEY: + do_layer_buttons(4); break; + case SIXKEY: + do_layer_buttons(5); break; + case SEVENKEY: + do_layer_buttons(6); break; + case EIGHTKEY: + do_layer_buttons(7); break; + case NINEKEY: + do_layer_buttons(8); break; + case ZEROKEY: + do_layer_buttons(9); break; + case MINUSKEY: + do_layer_buttons(10); break; + case EQUALKEY: + do_layer_buttons(11); break; + case ACCENTGRAVEKEY: + do_layer_buttons(-1); break; + + } +} + +void init_v2d_oops(View2D *v2d) +{ + v2d->tot.xmin= -28.0; + v2d->tot.xmax= 28.0; + v2d->tot.ymin= -28.0; + v2d->tot.ymax= 28.0; + + v2d->cur= v2d->tot; + + v2d->min[0]= 10.0; + v2d->min[1]= 4.0; + + v2d->max[0]= 320.0; + v2d->max[1]= 320.0; + + v2d->minzoom= 0.01; + v2d->maxzoom= 2.0; + + /* v2d->scroll= L_SCROLL+B_SCROLL; */ + v2d->scroll= 0; + v2d->keepaspect= 1; + v2d->keepzoom= 0; + v2d->keeptot= 0; + +} + +void init_oopsspace(ScrArea *sa) +{ + SpaceOops *soops; + + soops= MEM_callocN(sizeof(SpaceOops), "initoopsspace"); + BLI_addhead(&sa->spacedata, soops); + + soops->visiflag= OOPS_OB+OOPS_MA+OOPS_ME+OOPS_TE+OOPS_CU+OOPS_IP; + + soops->spacetype= SPACE_OOPS; + init_v2d_oops(&soops->v2d); +} + +/* ******************** SPACE: PAINT ********************** */ + + +/* ******************** SPACE: Text ********************** */ + +extern void drawtextspace(void); +extern void winqreadtextspace(unsigned short, short, char ascii); + +/* ******************** SPACE: ALGEMEEN ********************** */ + +void newspace(ScrArea *sa, int type) +{ + if(type>=0) { + if(sa->spacetype != type) { + SpaceLink *sl; + + sa->spacetype= type; + sa->headbutofs= 0; + + uiFreeBlocks(&sa->uiblocks); + wich_cursor(sa); + + if (sa->headwin) addqueue(sa->headwin, CHANGED, 1); + scrarea_queue_headredraw(sa); + + addqueue(sa->win, CHANGED, 1); + scrarea_queue_winredraw(sa); + + areawinset(sa->win); + + bwin_clear_viewmat(sa->win); + + for (sl= sa->spacedata.first; sl; sl= sl->next) + if(sl->spacetype==type) + break; + + if (sl) { + BLI_remlink(&sa->spacedata, sl); + BLI_addhead(&sa->spacedata, sl); + } else { + if(type==SPACE_VIEW3D) + initview3d(sa); + else if(type==SPACE_IPO) + initipo(sa); + else if(type==SPACE_INFO) + init_infospace(sa); + else if(type==SPACE_BUTS) + init_butspace(sa); + else if(type==SPACE_FILE) + init_filespace(sa); + else if(type==SPACE_SEQ) + init_seqspace(sa); + else if(type==SPACE_IMAGE) + init_imagespace(sa); + else if(type==SPACE_IMASEL) + init_imaselspace(sa); + else if(type==SPACE_OOPS) + init_oopsspace(sa); + else if(type==SPACE_ACTION) + init_actionspace(sa); + else if(type==SPACE_TEXT) + init_textspace(sa); + else if(type==SPACE_SOUND) + init_soundspace(sa); + else if(type==SPACE_NLA) + init_nlaspace(sa); + + sl= sa->spacedata.first; + sl->area= sa; + } + } + } + + + /* uitzondering: filespace */ + if(curarea->spacetype==SPACE_FILE) { + SpaceFile *sfile= curarea->spacedata.first; + + if(sfile->type==FILE_MAIN) { + freefilelist(sfile); + } else { + sfile->type= FILE_UNIX; + } + + sfile->returnfunc= 0; + sfile->title[0]= 0; + if(sfile->filelist) test_flags_file(sfile); + } + /* uitzondering: imasel space */ + else if(curarea->spacetype==SPACE_IMASEL) { + SpaceImaSel *simasel= curarea->spacedata.first; + simasel->returnfunc= 0; + simasel->title[0]= 0; + } +} + +void freespacelist(ListBase *lb) +{ + SpaceLink *sl; + + for (sl= lb->first; sl; sl= sl->next) { + if(sl->spacetype==SPACE_FILE) { + SpaceFile *sfile= (SpaceFile*) sl; + if(sfile->libfiledata) + BLO_blendhandle_close(sfile->libfiledata); + } + else if(sl->spacetype==SPACE_BUTS) { + SpaceButs *buts= (SpaceButs*) sl; + if(buts->rect) MEM_freeN(buts->rect); + if(G.buts==buts) G.buts= 0; + } + else if(sl->spacetype==SPACE_IPO) { + SpaceIpo *si= (SpaceIpo*) sl; + if(si->editipo) MEM_freeN(si->editipo); + free_ipokey(&si->ipokey); + if(G.sipo==si) G.sipo= 0; + } + else if(sl->spacetype==SPACE_VIEW3D) { + View3D *vd= (View3D*) sl; + if(vd->bgpic) { + if(vd->bgpic->rect) MEM_freeN(vd->bgpic->rect); + if(vd->bgpic->ima) vd->bgpic->ima->id.us--; + MEM_freeN(vd->bgpic); + } + if(vd->localvd) MEM_freeN(vd->localvd); + if(G.vd==vd) G.vd= 0; + } + else if(sl->spacetype==SPACE_OOPS) { + free_oopspace((SpaceOops *)sl); + } + else if(sl->spacetype==SPACE_IMASEL) { + free_imasel((SpaceImaSel *)sl); + } + else if(sl->spacetype==SPACE_ACTION) { + free_actionspace((SpaceAction*)sl); + } + else if(sl->spacetype==SPACE_NLA){ +/* free_nlaspace((SpaceNla*)sl); */ + } + else if(sl->spacetype==SPACE_TEXT) { + free_textspace((SpaceText *)sl); + } + else if(sl->spacetype==SPACE_SOUND) { + free_soundspace((SpaceSound *)sl); + } + } + + BLI_freelistN(lb); +} + +void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2) +{ + SpaceLink *sl; + + duplicatelist(lb1, lb2); + + /* lb1 is kopie van lb2, van lb2 geven we de filelist vrij */ + + sl= lb2->first; + while(sl) { + if(sl->spacetype==SPACE_FILE) { + SpaceFile *sfile= (SpaceFile*) sl; + sfile->libfiledata= 0; + sfile->filelist= 0; + } + else if(sl->spacetype==SPACE_OOPS) { + SpaceOops *so= (SpaceOops *)sl; + so->oops.first= so->oops.last= 0; + } + else if(sl->spacetype==SPACE_IMASEL) { + check_imasel_copy((SpaceImaSel *) sl); + } + else if(sl->spacetype==SPACE_TEXT) { + } + /* __PINFAKE */ +/* else if(sfile->spacetype==SPACE_ACTION) { + SpaceAction *sa= (SpaceAction *)sfile; + if (sa->flag & SACTION_PIN) + if (sa->action) + sa->action->id.us++; + + } +*/ /* end PINFAKE */ + + sl= sl->next; + } + + sl= lb1->first; + while(sl) { + sl->area= newarea; + + if(sl->spacetype==SPACE_BUTS) { + SpaceButs *buts= (SpaceButs *)sl; + buts->rect= 0; + } + else if(sl->spacetype==SPACE_IPO) { + SpaceIpo *si= (SpaceIpo *)sl; + si->editipo= 0; + si->ipokey.first= si->ipokey.last= 0; + } + else if(sl->spacetype==SPACE_VIEW3D) { + View3D *vd= (View3D *)sl; + if(vd->bgpic) { + vd->bgpic= MEM_dupallocN(vd->bgpic); + vd->bgpic->rect= 0; + if(vd->bgpic->ima) vd->bgpic->ima->id.us++; + } + } + sl= sl->next; + } + + /* nog een keer: van oude View3D de localview restoren (ivm full) */ + sl= lb2->first; + while(sl) { + if(sl->spacetype==SPACE_VIEW3D) { + View3D *v3d= (View3D*) sl; + if(v3d->localvd) { + restore_localviewdata(v3d); + v3d->localvd= 0; + v3d->localview= 0; + v3d->lay &= 0xFFFFFF; + } + } + sl= sl->next; + } +} + +/* wordt overal aangeroepen */ +void allqueue(unsigned short event, short val) +{ + ScrArea *sa; + View3D *v3d; + SpaceButs *buts; + SpaceFile *sfile; + + sa= G.curscreen->areabase.first; + while(sa) { + if(event==REDRAWALL) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + else if(sa->win != val) { + switch(event) { + + case REDRAWHEADERS: + scrarea_queue_headredraw(sa); + break; + case REDRAWVIEW3D: + if(sa->spacetype==SPACE_VIEW3D) { + scrarea_queue_winredraw(sa); + if(val) scrarea_queue_headredraw(sa); + } + break; + case REDRAWVIEW3D_Z: + if(sa->spacetype==SPACE_VIEW3D) { + v3d= sa->spacedata.first; + if(v3d->drawtype==OB_SOLID) { + scrarea_queue_winredraw(sa); + if(val) scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWVIEWCAM: + if(sa->spacetype==SPACE_VIEW3D) { + v3d= sa->spacedata.first; + if(v3d->persp>1) scrarea_queue_winredraw(sa); + } + break; + case REDRAWINFO: + if(sa->spacetype==SPACE_INFO) { + scrarea_queue_headredraw(sa); + } + break; + case REDRAWIMAGE: + if(sa->spacetype==SPACE_IMAGE) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + break; + case REDRAWIPO: + if(sa->spacetype==SPACE_IPO) { + SpaceIpo *si; + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + if(val) { + si= sa->spacedata.first; + if (!G.sipo->pin) + si->blocktype= val; + } + } + else if(sa->spacetype==SPACE_OOPS) { + scrarea_queue_winredraw(sa); + } + + break; + + case REDRAWBUTSALL: + if(sa->spacetype==SPACE_BUTS) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + break; + case REDRAWBUTSHEAD: + if(sa->spacetype==SPACE_BUTS) { + scrarea_queue_headredraw(sa); + } + break; + case REDRAWBUTSVIEW: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_VIEW) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSLAMP: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_LAMP) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSMAT: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_MAT) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSTEX: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_TEX) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSANIM: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_ANIM) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSWORLD: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_WORLD) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSRENDER: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_RENDER) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSEDIT: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_EDIT) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSGAME: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if ELEM(buts->mainb, BUTS_GAME, BUTS_FPAINT) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSRADIO: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_RADIO) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSSCRIPT: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_SCRIPT) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSSOUND: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_SOUND) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWBUTSCONSTRAINT: + if(sa->spacetype==SPACE_BUTS) { + buts= sa->spacedata.first; + if(buts->mainb==BUTS_CONSTRAINT) { + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + } + break; + case REDRAWDATASELECT: + if(sa->spacetype==SPACE_FILE) { + sfile= sa->spacedata.first; + if(sfile->type==FILE_MAIN) { + freefilelist(sfile); + scrarea_queue_winredraw(sa); + } + } + else if(sa->spacetype==SPACE_OOPS) { + scrarea_queue_winredraw(sa); + } + break; + case REDRAWSEQ: + if(sa->spacetype==SPACE_SEQ) { + addqueue(sa->win, CHANGED, 1); + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + break; + case REDRAWOOPS: + if(sa->spacetype==SPACE_OOPS) { + scrarea_queue_winredraw(sa); + } + break; + case REDRAWNLA: + if(sa->spacetype==SPACE_NLA) { + scrarea_queue_headredraw(sa); + scrarea_queue_winredraw(sa); + } + case REDRAWACTION: + if(sa->spacetype==SPACE_ACTION) { + scrarea_queue_headredraw(sa); + scrarea_queue_winredraw(sa); + } + break; + case REDRAWTEXT: + if(sa->spacetype==SPACE_TEXT) { + scrarea_queue_winredraw(sa); + } + break; + case REDRAWSOUND: + if(sa->spacetype==SPACE_SOUND) { + scrarea_queue_headredraw(sa); + scrarea_queue_winredraw(sa); + } + break; + } + } + sa= sa->next; + } +} + +void allspace(unsigned short event, short val) +{ + bScreen *sc; + + sc= G.main->screen.first; + while(sc) { + ScrArea *sa= sc->areabase.first; + while(sa) { + SpaceLink *sl= sa->spacedata.first; + while(sl) { + switch(event) { + case REMAKEALLIPO: + { + Ipo *ipo; + IpoCurve *icu; + + /* Go to each ipo */ + for (ipo=G.main->ipo.first; ipo; ipo=ipo->id.next){ + for (icu = ipo->curve.first; icu; icu=icu->next){ + sort_time_ipocurve(icu); + testhandles_ipocurve(icu); + } + } + } + break; + case REMAKEIPO: + if(sl->spacetype==SPACE_IPO) { + SpaceIpo *si= (SpaceIpo *)sl; + { + if(si->editipo) MEM_freeN(si->editipo); + si->editipo= 0; + free_ipokey(&si->ipokey); + } + } + break; + + case OOPS_TEST: + if(sl->spacetype==SPACE_OOPS) { + SpaceOops *so= (SpaceOops *)sl; + so->flag |= SO_TESTBLOCKS; + } + break; + } + + sl= sl->next; + } + sa= sa->next; + } + sc= sc->id.next; + } +} + + +void force_draw() +{ + /* alle area's die (ongeveer) zelfde laten zien als curarea */ + ScrArea *tempsa, *sa; + + scrarea_do_windraw(curarea); + + tempsa= curarea; + sa= G.curscreen->areabase.first; + while(sa) { + if(sa!=tempsa && sa->spacetype==tempsa->spacetype) { + if(sa->spacetype==SPACE_VIEW3D) { + if( ((View3D *)sa->spacedata.first)->lay & ((View3D *)tempsa->spacedata.first)->lay) { + areawinset(sa->win); + scrarea_do_windraw(sa); + } + } + else if(sa->spacetype==SPACE_IPO) { + areawinset(sa->win); + scrarea_do_windraw(sa); + } + else if(sa->spacetype==SPACE_SEQ) { + areawinset(sa->win); + scrarea_do_windraw(sa); + } + else if(sa->spacetype==SPACE_ACTION) { + areawinset(sa->win); + scrarea_do_windraw(sa); + } + } + sa= sa->next; + } + if(curarea!=tempsa) areawinset(tempsa->win); + + screen_swapbuffers(); + +} + +void force_draw_plus(int type) +{ + /* alle area's die (ongeveer) zelfde laten zien als curarea EN areas van 'type' */ + ScrArea *tempsa, *sa; + + scrarea_do_windraw(curarea); + + tempsa= curarea; + sa= G.curscreen->areabase.first; + while(sa) { + if(sa!=tempsa && (sa->spacetype==tempsa->spacetype || sa->spacetype==type)) { + if(ELEM5(sa->spacetype, SPACE_VIEW3D, SPACE_IPO, SPACE_SEQ, SPACE_BUTS, SPACE_ACTION)) { + areawinset(sa->win); + scrarea_do_windraw(sa); + } + } + sa= sa->next; + } + if(curarea!=tempsa) areawinset(tempsa->win); + + screen_swapbuffers(); +} + +void force_draw_all(void) +{ + /* alle area's die (ongeveer) zelfde laten zien als curarea EN areas van 'type' */ + ScrArea *tempsa, *sa; + + drawscreen(); + + tempsa= curarea; + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->headwin) { + scrarea_do_headdraw(sa); + scrarea_do_headchange(sa); + } + if(sa->win) { + scrarea_do_windraw(sa); + } + sa= sa->next; + } + if(curarea!=tempsa) areawinset(tempsa->win); + + screen_swapbuffers(); +} + +/***/ + +SpaceType *spaceaction_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Action"); + spacetype_set_winfuncs(st, drawactionspace, changeview2d, winqreadactionspace); + } + + return st; +} +SpaceType *spacebuts_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Buts"); + spacetype_set_winfuncs(st, drawbutspace, changebutspace, winqreadbutspace); + } + + return st; +} +SpaceType *spacefile_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("File"); + spacetype_set_winfuncs(st, drawfilespace, NULL, winqreadfilespace); + } + + return st; +} +SpaceType *spaceimage_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Image"); + spacetype_set_winfuncs(st, drawimagespace, NULL, winqreadimagespace); + } + + return st; +} +SpaceType *spaceimasel_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Imasel"); + spacetype_set_winfuncs(st, drawimasel, NULL, winqreadimasel); + } + + return st; +} +SpaceType *spaceinfo_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Info"); + spacetype_set_winfuncs(st, drawinfospace, NULL, winqreadinfospace); + } + + return st; +} +SpaceType *spaceipo_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Ipo"); + spacetype_set_winfuncs(st, drawipo, changeview2d, winqreadipo); + } + + return st; +} +SpaceType *spacenla_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Nla"); + spacetype_set_winfuncs(st, drawnlaspace, changeview2d, winqreadnlaspace); + } + + return st; +} +SpaceType *spaceoops_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Oops"); + spacetype_set_winfuncs(st, drawoopsspace, changeview2d, winqreadoopsspace); + } + + return st; +} +SpaceType *spaceseq_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Sequence"); + spacetype_set_winfuncs(st, drawseqspace, changeview2d, winqreadsequence); + } + + return st; +} +SpaceType *spacesound_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Sound"); + spacetype_set_winfuncs(st, drawsoundspace, NULL, winqreadsoundspace); + } + + return st; +} +SpaceType *spacetext_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Text"); + spacetype_set_winfuncs(st, drawtextspace, NULL, winqreadtextspace); + } + + return st; +} +SpaceType *spaceview3d_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("View3D"); + spacetype_set_winfuncs(st, drawview3d, changeview3d, winqread3d); + } + + return st; +} diff --git a/source/blender/src/spacetypes.c b/source/blender/src/spacetypes.c new file mode 100644 index 00000000000..4a756e5924f --- /dev/null +++ b/source/blender/src/spacetypes.c @@ -0,0 +1,137 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "BLI_blenlib.h" + +#include "DNA_screen_types.h" + +#include "BIF_gl.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_spacetypes.h" + +/***/ + +struct _SpaceType { + char name[32]; + + SpaceDrawFP windraw; + SpaceChangeFP winchange; + SpaceHandleFP winhandle; +}; + + +SpaceType *spacetype_new(char *name) +{ + SpaceType *st= calloc(1, sizeof(*st)); + BLI_strncpy(st->name, name, sizeof(st->name)); + + return st; +} + +void spacetype_set_winfuncs(SpaceType *st, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle) +{ + st->windraw= draw; + st->winchange= change; + st->winhandle= handle; +} + + /***/ + +SpaceType *spacetype_from_code(int spacecode) +{ + switch (spacecode) { + case SPACE_ACTION: return spaceaction_get_type(); + case SPACE_BUTS: return spacebuts_get_type(); + case SPACE_FILE: return spacefile_get_type(); + case SPACE_IMAGE: return spaceimage_get_type(); + case SPACE_IMASEL: return spaceimasel_get_type(); + case SPACE_INFO: return spaceinfo_get_type(); + case SPACE_IPO: return spaceipo_get_type(); + case SPACE_NLA: return spacenla_get_type(); + case SPACE_OOPS: return spaceoops_get_type(); + case SPACE_SEQ: return spaceseq_get_type(); + case SPACE_SOUND: return spacesound_get_type(); + case SPACE_TEXT: return spacetext_get_type(); + case SPACE_VIEW3D: return spaceview3d_get_type(); + default: + return NULL; + } +} + +void scrarea_do_windraw(ScrArea *area) +{ + SpaceType *st= spacetype_from_code(area->spacetype); + + areawinset(area->win); + + if(area->win && st->windraw) { + st->windraw(); + } + else { + glClearColor(0.4375, 0.4375, 0.4375, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + } + + area->win_swap= WIN_BACK_OK; +} +void scrarea_do_winchange(ScrArea *area) +{ + SpaceType *st= spacetype_from_code(area->spacetype); + + areawinset(area->win); + + if (st->winchange) { + st->winchange(); + } else { + if (!BLI_rcti_is_empty(&area->winrct)) { + bwin_ortho2(area->win, -0.5, area->winrct.xmax-area->winrct.xmin-0.5, -0.5, area->winrct.ymax-area->winrct.ymin-0.5); + glLoadIdentity(); + } + } +} +void scrarea_do_winhandle(ScrArea *area, unsigned short event, short val, char ascii) +{ + SpaceType *st= spacetype_from_code(area->spacetype); + + areawinset(area->win); + + if (st->winhandle) { + st->winhandle(event, val, ascii); + } +} diff --git a/source/blender/src/swapbuffers.c b/source/blender/src/swapbuffers.c new file mode 100644 index 00000000000..5d90392b145 --- /dev/null +++ b/source/blender/src/swapbuffers.c @@ -0,0 +1,280 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "DNA_space_types.h" +#include "DNA_screen_types.h" + +#include "BKE_global.h" + +#include "BIF_gl.h" +#include "BIF_interface.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_space.h" + +#include "winlay.h" + +#if 0 +static void copy_back_to_front(void) +{ + int actually_swap= 0; + int winx, winy; + char *data; + + winlay_get_winsize(&winx, &winy); + + if (actually_swap) { + data= malloc(4*winx*winy); + glReadPixels(0, 0, winx, winy, GL_RGBA, GL_UNSIGNED_BYTE, data); + } + + mywinset(1); + glRasterPos2f(-0.5,-0.5); + glReadBuffer(GL_BACK); + glDrawBuffer(GL_FRONT); + glCopyPixels(0, 0, winx, winy, GL_COLOR); + glDrawBuffer(GL_BACK); + glFinish(); + + if (actually_swap) { + glRasterPos2f(-0.5,-0.5); + glDrawPixels(winx, winy, GL_RGBA, GL_UNSIGNED_BYTE, data); + glFinish(); + free(data); + } +} +#endif + +static void screen_swapbuffers_REDRAW(bScreen *sc) +{ + ScrArea *sa; + int doswap= 0, swap; + + /* dit is een nieuwe implementatie: uitsluitend met redraws en normale swapbuffer */ + + /* allemaal front ok? */ + sa= sc->areabase.first; + while(sa) { + if(sa->win && (sa->win_swap & WIN_FRONT_OK)==0) break; + if(!sa->headertype) sa->head_swap= WIN_EQUAL; + if((sa->head_swap & WIN_FRONT_OK)==0) break; + sa= sa->next; + } + if(sa==0) return; + + sa= sc->areabase.first; + while(sa) { + + swap= sa->win_swap; + if( (swap & WIN_BACK_OK) == 0) { + scrarea_do_windraw(sa); + doswap= 1; + sa->win_swap= swap | WIN_BACK_OK; + } + else if( sa->win_swap==WIN_BACK_OK) doswap= 1; + + swap= sa->head_swap; + if( (swap & WIN_BACK_OK) == 0) { + if (sa->headertype) scrarea_do_headdraw(sa); + doswap= 1; + sa->head_swap = swap | WIN_BACK_OK; + } + else if( sa->head_swap==WIN_BACK_OK) doswap= 1; + + sa= sa->next; + } + + /* de hele backbuffer moet nu OK zijn */ + if(doswap) { + myswapbuffers(); + } +} + +#include "BMF_Api.h" +#include <stdio.h> + +static void draw_debug_win(int win) +{ + static int drawcounter= 0; + char buf[64]; + int x, y; + int w, h; + + bwin_getsuborigin(win, &x, &y); + bwin_getsize(win, &w, &h); + + mywinset(win); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, w, 0, h, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(0.8, 0.8, 0.8); + glRecti(0, 0, w, h); + + glColor3f(0.6, 0.6, 0.6); + glRecti(2, 2, w-4, h-4); + + glColor3ub(0, 0, 0); + glRasterPos2i(5, 5); + + sprintf(buf, "win: %d - (%d, %d, %d, %d) %d\n", win, x, y, w, h, drawcounter++); + BMF_DrawString(G.font, buf); +} + +static void screen_swapbuffers_DEBUG(bScreen *sc) +{ + ScrArea *sa; + + for (sa= sc->areabase.first; sa; sa= sa->next) { + draw_debug_win(sa->win); + if (sa->headwin) draw_debug_win(sa->headwin); + } + + myswapbuffers(); +} + +static void screen_swapbuffers_DEBUG_SWAP(bScreen *sc) +{ + ScrArea *sa; + int doswap= 0, swap; + + /* dit is een nieuwe implementatie: uitsluitend met redraws en normale swapbuffer */ + + /* allemaal front ok? */ + sa= sc->areabase.first; + while(sa) { + if(sa->win && (sa->win_swap & WIN_FRONT_OK)==0) break; + if(!sa->headertype) sa->head_swap= WIN_EQUAL; + if((sa->head_swap & WIN_FRONT_OK)==0) break; + sa= sa->next; + } + if(sa==0) return; + + sa= sc->areabase.first; + while(sa) { + + swap= sa->win_swap; + if( (swap & WIN_BACK_OK) == 0) { + scrarea_do_windraw(sa); + draw_debug_win(sa->win); + + doswap= 1; + sa->win_swap= swap | WIN_BACK_OK; + } + else if( sa->win_swap==WIN_BACK_OK) doswap= 1; + + swap= sa->head_swap; + if( (swap & WIN_BACK_OK) == 0) { + if (sa->headertype) { + scrarea_do_headdraw(sa); + draw_debug_win(sa->headwin); + } + doswap= 1; + sa->head_swap = swap | WIN_BACK_OK; + } + else if( sa->head_swap==WIN_BACK_OK) doswap= 1; + + sa= sa->next; + } + + /* de hele backbuffer moet nu OK zijn */ + if(doswap) { + myswapbuffers(); + } +} + +static void screen_swapbuffers_SIMPLE(bScreen *sc) +{ + ScrArea *sa; + + mywinset(1); + glClearColor(0.8, 0.6, 0.7, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + for (sa= sc->areabase.first; sa; sa= sa->next) { + scrarea_do_windraw(sa); + if (sa->headertype) scrarea_do_headdraw(sa); + } + + myswapbuffers(); +} + +static int drawmode_default= 'r'; +int debug_swapbuffers_override= 0; + +void set_debug_swapbuffers_ovveride(bScreen *sc, int mode) +{ + ScrArea *sa; + for (sa= sc->areabase.first; sa; sa= sa->next) { + sa->win_swap= 0; + sa->head_swap= 0; + } + debug_swapbuffers_override= mode; +} + +void screen_swapbuffers(void) +{ + ScrArea *tempsa; + + bScreen *sc= G.curscreen; + int drawmode; + + if (debug_swapbuffers_override) { + drawmode= debug_swapbuffers_override; + } else { + drawmode= drawmode_default; + } + + tempsa= curarea; + areawinset(1); + + if (drawmode=='s') { + screen_swapbuffers_SIMPLE(sc); + } else if (drawmode=='d') { + screen_swapbuffers_DEBUG(sc); + } else if (drawmode=='f') { + screen_swapbuffers_DEBUG_SWAP(sc); + } else { + screen_swapbuffers_REDRAW(sc); + } + + areawinset(tempsa->win); +}
\ No newline at end of file diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c new file mode 100644 index 00000000000..cde64754df8 --- /dev/null +++ b/source/blender/src/toets.c @@ -0,0 +1,874 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * Algemene toetsen, bijzondere in de space.c + */ + +#include <string.h> +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "PIL_time.h" + +#include "nla.h" /* Only for the #ifdef flag - To be removed later */ + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_anim.h" +#include "BKE_scene.h" +#include "BKE_ipo.h" +#include "BKE_action.h" +#include "BKE_ika.h" +#include "BKE_key.h" + +#include "BIF_interface.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_buttons.h" +#include "BIF_renderwin.h" +#include "BIF_toolbox.h" +#include "BIF_toets.h" +#include "BIF_editseq.h" +#include "BIF_editsound.h" +#include "BIF_poseobject.h" +#include "BIF_usiblender.h" + +#include "BDR_vpaint.h" +#include "BDR_editobject.h" +#include "BDR_editface.h" + +#include "BSE_filesel.h" /* For activate_fileselect */ +#include "BSE_drawview.h" /* For play_anim */ +#include "BSE_view.h" +#include "BSE_edit.h" +#include "BSE_editipo.h" +#include "BSE_headerbuttons.h" + +#include "blendef.h" +#include "interface.h" +#include "render.h" +#include "blendertimer.h" /* timer functions */ + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "mydevice.h" +#include "license_key.h" + +#include "BIF_poseobject.h" + +/* only used in toets.c */ +/* this function doesn't really belong here */ +/* ripped from render module */ +void schrijfplaatje(char *name); + + +void write_imag(char *name) +{ + /* vanuit filesel */ + char str[256]; + + strcpy(str, name); + BLI_convertstringcode(str, G.sce, G.scene->r.cfra); + + if(saveover(str)) { + if(BLI_testextensie(str,".blend")) { + error("Wrong filename"); + return; + } + waitcursor(1); /* from screen.c */ + schrijfplaatje(str); + strcpy(G.ima, name); + waitcursor(0); + } +} + +/* ripped from render module */ +/* void schrijfplaatje(char *name); */ + + +/* From matrix.h: it's really a [4][4]! */ +/* originally in initrender... maybe add fileControl thingy? */ +void schrijfplaatje(char *name) +{ + struct ImBuf *ibuf=0; + unsigned int *temprect=0; + char str[FILE_MAXDIR+FILE_MAXFILE]; + + /* Staat RGBA aan? Zo ja: gebruik alphakanaal voor kleur 0 */ + IMB_alpha_to_col0(FALSE); + + if(R.r.planes == 32) { + /* alles met minder dan 50 % alpha -> col 0 */ + if(R.r.alphamode == R_ALPHAKEY) IMB_alpha_to_col0(2); + /* uitsluitend met 0 alpha -> col 0 */ + else IMB_alpha_to_col0(1); + } + + /* Seems to me this is also superfluous.... */ + if (R.r.imtype==R_FTYPE) { + strcpy(str, R.r.ftype); + BLI_convertstringcode(str, G.sce, G.scene->r.cfra); + + ibuf = IMB_loadiffname(str, IB_test); + if(ibuf) { + ibuf->x = R.rectx; + ibuf->y = R.recty; + } + else { + error("Can't find filetype"); + G.afbreek= 1; + return; + } + /* setdither(2); */ + } + + if(ibuf == 0) { + ibuf= IMB_allocImBuf(R.rectx, R.recty, R.r.planes, 0, 0); + } + + if(ibuf) { + ibuf->rect= (unsigned int *) R.rectot; + + if(R.r.planes == 8) IMB_cspace(ibuf, rgb_to_bw); + + if(R.r.imtype== R_IRIS) { + ibuf->ftype= IMAGIC; + } + else if(R.r.imtype==R_IRIZ) { + ibuf->ftype= IMAGIC; + if (ibuf->zbuf == 0) { + if (R.rectz) { + ibuf->zbuf = (int *)R.rectz; + } + else printf("no zbuf\n"); + } + } + else if((R.r.imtype==R_PNG) && (LICENSE_KEY_VALID)) { + ibuf->ftype= PNG; + } + else if((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) { + ibuf->ftype= TGA; + } + else if(R.r.imtype==R_RAWTGA) { + ibuf->ftype= RAWTGA; + } + else if(R.r.imtype==R_HAMX) { + /* kopie maken */ + temprect= MEM_dupallocN(R.rectot); + ibuf->ftype= AN_hamx; + } + else if(ELEM5(R.r.imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) { + if(R.r.quality < 10) R.r.quality= 90; + + if(R.r.mode & R_FIELDS) ibuf->ftype= JPG_VID|R.r.quality; + else ibuf->ftype= JPG|R.r.quality; + } + + RE_make_existing_file(name); + + if(IMB_saveiff(ibuf, name, IB_rect | IB_zbuf)==0) { + perror(name); + G.afbreek= 1; + } + + IMB_freeImBuf(ibuf); + + if (R.r.imtype==R_HAMX) { + MEM_freeN(R.rectot); + R.rectot= temprect; + } + } + else { + G.afbreek= 1; + } +} + + + +/* ------------------------------------------------------------------------- */ + +static int is_an_active_object(void *ob) { + Base *base; + + for (base= FIRSTBASE; base; base= base->next) + if (base->object == ob) + return 1; + + return 0; +} + +void persptoetsen(unsigned short event) +{ + static Object *oldcamera=0; + float phi, si, q1[4], vec[3]; + static int perspo=1; + + if(event==PADENTER) { + if (G.qual == LR_SHIFTKEY) { + view3d_set_1_to_1_viewborder(G.vd); + } else { + if (G.vd->persp==2) { + G.vd->camzoom= 0.0; + } else { + G.vd->dist= 10.0; + } + } + } + else if((G.qual & (LR_SHIFTKEY | LR_CTRLKEY)) && (event != PAD0)) { + if(event==PAD0) { + /* G.vd->persp= 3; */ + } + else if(event==PAD7) { + G.vd->viewquat[0]= 0.0; + G.vd->viewquat[1]= -1.0; + G.vd->viewquat[2]= 0.0; + G.vd->viewquat[3]= 0.0; + G.vd->view= 7; + } + else if(event==PAD1) { + G.vd->viewquat[0]= 0.0; + G.vd->viewquat[1]= 0.0; + G.vd->viewquat[2]= (float)-cos(M_PI/4.0); + G.vd->viewquat[3]= (float)-cos(M_PI/4.0); + G.vd->view=1; + } + else if(event==PAD3) { + G.vd->viewquat[0]= 0.5; + G.vd->viewquat[1]= -0.5; + G.vd->viewquat[2]= 0.5; + G.vd->viewquat[3]= 0.5; + G.vd->view=3; + } + else if(event==PADMINUS) { + /* deze min en max staan ook in viewmove() */ + if(G.vd->persp==2) { + G.vd->camzoom-= 10; + if(G.vd->camzoom<-30) G.vd->camzoom= -30; + } + else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2; + } + else if(event==PADPLUSKEY) { + if(G.vd->persp==2) { + G.vd->camzoom+= 10; + if(G.vd->camzoom>300) G.vd->camzoom= 300; + } + else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333; + } + else { + + initgrabz(0.0, 0.0, 0.0); + + if(event==PAD6) window_to_3d(vec, -32, 0); + else if(event==PAD4) window_to_3d(vec, 32, 0); + else if(event==PAD8) window_to_3d(vec, 0, -25); + else if(event==PAD2) window_to_3d(vec, 0, 25); + G.vd->ofs[0]+= vec[0]; + G.vd->ofs[1]+= vec[1]; + G.vd->ofs[2]+= vec[2]; + } + } + else { + + if(event==PAD7) { + G.vd->viewquat[0]= 1.0; + G.vd->viewquat[1]= 0.0; + G.vd->viewquat[2]= 0.0; + G.vd->viewquat[3]= 0.0; + G.vd->view=7; + if(G.vd->persp>=2) G.vd->persp= perspo; + } + else if(event==PAD1) { + G.vd->viewquat[0]= (float)cos(M_PI/4.0); + G.vd->viewquat[1]= (float)-sin(M_PI/4.0); + G.vd->viewquat[2]= 0.0; + G.vd->viewquat[3]= 0.0; + G.vd->view=1; + if(G.vd->persp>=2) G.vd->persp= perspo; + } + else if(event==PAD3) { + G.vd->viewquat[0]= 0.5; + G.vd->viewquat[1]= -0.5; + G.vd->viewquat[2]= -0.5; + G.vd->viewquat[3]= -0.5; + G.vd->view=3; + if(G.vd->persp>=2) G.vd->persp= perspo; + } + else if(event==PADMINUS) { + /* deze min en max staan ook in viewmove() */ + if(G.vd->persp==2) { + G.vd->camzoom= MAX2(-30, G.vd->camzoom-5); + } + else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2; + } + else if(event==PADPLUSKEY) { + if(G.vd->persp==2) { + G.vd->camzoom= MIN2(300, G.vd->camzoom+5); + } + else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333; + } + else if(event==PAD5) { + if(G.vd->persp==1) G.vd->persp=0; + else G.vd->persp=1; + } + else if(event==PAD0) { + if(G.qual & LR_ALTKEY) { + if(oldcamera && is_an_active_object(oldcamera)) { + G.vd->camera= oldcamera; + } + + handle_view3d_lock(); + } + else if(BASACT) { + if(G.qual & LR_CTRLKEY) { + if(G.vd->camera != OBACT) { + if(G.vd->camera && G.vd->camera->type==OB_CAMERA) + oldcamera= G.vd->camera; + + G.vd->camera= OBACT; + handle_view3d_lock(); + } + } + else if(G.vd->camera==0 && OBACT->type==OB_CAMERA) { + G.vd->camera= OBACT; + handle_view3d_lock(); + } + } + if(G.vd->camera==0) { + G.vd->camera= scene_find_camera(G.scene); + handle_view3d_lock(); + } + + if(G.vd->camera) { + G.vd->persp= 2; + G.vd->view= 0; + } + + } + else if(event==PAD9) { + countall(); + do_all_ipos(); + do_all_keys(); + do_all_actions(); + do_all_ikas(); + + reset_slowparents(); /* editobject.c */ + } + else if(G.vd->persp<2) { + if(event==PAD4 || event==PAD6) { + /* z-as */ + phi= (float)(M_PI/24.0); + if(event==PAD6) phi= -phi; + si= (float)sin(phi); + q1[0]= (float)cos(phi); + q1[1]= q1[2]= 0.0; + q1[3]= si; + QuatMul(G.vd->viewquat, G.vd->viewquat, q1); + G.vd->view= 0; + } + if(event==PAD2 || event==PAD8) { + + /* liggende as */ + VECCOPY(q1+1, G.vd->viewinv[0]); + + Normalise(q1+1); + phi= (float)(M_PI/24.0); + if(event==PAD2) phi= -phi; + si= (float)sin(phi); + q1[0]= (float)cos(phi); + q1[1]*= si; + q1[2]*= si; + q1[3]*= si; + QuatMul(G.vd->viewquat, G.vd->viewquat, q1); + G.vd->view= 0; + } + } + + if(G.vd->persp<2) perspo= G.vd->persp; + } + scrarea_queue_redraw(curarea); +} + +int untitled(char * name) +{ + if (G.save_over == 0 ) { + char * c= BLI_last_slash(name); + + if (c) + strcpy(&c[1], "untitled.blend"); + else + strcpy(name, "untitled.blend"); + + return(TRUE); + } + + return(FALSE); +} + +int save_image_filesel_str(char *str) +{ + switch(G.scene->r.imtype) { + case R_PNG: + if (LICENSE_KEY_VALID) { + strcpy(str, "SAVE PNG"); return 1; + } + case R_TARGA: + strcpy(str, "SAVE TARGA"); return 1; + case R_RAWTGA: + strcpy(str, "SAVE RAW TARGA"); return 1; + case R_IRIS: + strcpy(str, "SAVE IRIS"); return 1; + case R_IRIZ: + strcpy(str, "SAVE IRIS"); return 1; + case R_HAMX: + strcpy(str, "SAVE HAMX"); return 1; + case R_FTYPE: + strcpy(str, "SAVE FTYPE"); return 1; + case R_JPEG90: + strcpy(str, "SAVE JPEG"); return 1; + default: + strcpy(str, "SAVE IMAGE"); return 0; + } +} + +void BIF_save_rendered_image(void) +{ + if(!R.rectot) { + error("No image rendered"); + } else { + char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2]; + + if(G.ima[0]==0) { + strcpy(dir, G.sce); + BLI_splitdirstring(dir, str); + strcpy(G.ima, dir); + } + + R.r.imtype= G.scene->r.imtype; + R.r.quality= G.scene->r.quality; + R.r.planes= G.scene->r.planes; + + if (!save_image_filesel_str(str)) { + error("Select an image type in DisplayButtons(F10)"); + } else { + activate_fileselect(FILE_SPECIAL, str, G.ima, write_imag); + } + } +} + +int blenderqread(unsigned short event, short val) +{ + /* hier alle algemene toetsafhandelingen (niet screen/window/space) */ + /* return 0: niet aan andere queue's doorgeven */ +/* extern char videosc_dir[]; */ + extern int textediting; + ScrArea *sa; + Object *ob; + int textspace=0; + /* Changed str and dir size to 160, to make sure there is enough + * space for filenames. */ + char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2]; + + if(val==0) return 1; + if(event==MOUSEY || event==MOUSEX) return 1; + if (G.flags & G_FLAGS_AUTOPLAY) return 1; + + if (curarea && curarea->spacetype==SPACE_TEXT) textspace= 1; + + switch(event) { + + case F1KEY: + if(G.qual==0) { + /* this exception because of the '?' button */ + if(curarea->spacetype==SPACE_INFO) { + sa= closest_bigger_area(); + areawinset(sa->win); + } + + activate_fileselect(FILE_BLENDER, "LOAD FILE", G.sce, BIF_read_file); + return 0; + } + else if(G.qual & LR_SHIFTKEY) { + activate_fileselect(FILE_LOADLIB, "LOAD LIBRARY", G.lib, 0); + return 0; + } + break; + case F2KEY: + if(G.qual==0) { + strcpy(dir, G.sce); + untitled(dir); + activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file); + return 0; + } + else if(G.qual & LR_CTRLKEY) { + write_vrml_fs(); + return 0; + } + else if(G.qual & LR_SHIFTKEY) { + write_dxf_fs(); + return 0; + } + break; + case F3KEY: + if(G.qual==0) { + BIF_save_rendered_image(); + return 0; + } + else if(G.qual & LR_CTRLKEY) { + BIF_screendump(); + } + break; + case F4KEY: + if(G.qual & LR_SHIFTKEY) { + + memset(str, 0, 16); + ob= OBACT; + if(ob) strcpy(str, ob->id.name); + + activate_fileselect(FILE_MAIN, "DATA SELECT", str, 0); + return 0; + } + else extern_set_butspace(event); + + break; + case F5KEY: + if(G.qual & LR_SHIFTKEY) { + newspace(curarea, SPACE_VIEW3D); + return 0; + } + else extern_set_butspace(event); + break; + case F6KEY: + if(G.qual & LR_SHIFTKEY) { + newspace(curarea, SPACE_IPO); + return 0; + } + else extern_set_butspace(event); + break; + case F7KEY: + if(G.qual & LR_SHIFTKEY) { + newspace(curarea, SPACE_BUTS); + return 0; + } + else extern_set_butspace(event); + break; + case F8KEY: + if(G.qual & LR_SHIFTKEY) { + newspace(curarea, SPACE_SEQ); + return 0; + } + else extern_set_butspace(event); + break; + case F9KEY: + if(G.qual & LR_SHIFTKEY) { + newspace(curarea, SPACE_OOPS); + return 0; + } + else extern_set_butspace(event); + break; + case F10KEY: + if(G.qual & LR_SHIFTKEY) { + newspace(curarea, SPACE_IMAGE); + return 0; + } + else extern_set_butspace(event); + break; + case F11KEY: + if(G.qual & LR_SHIFTKEY) { + newspace(curarea, SPACE_TEXT); + return 0; + } + else BIF_toggle_render_display(); + return 0; + break; + case F12KEY: + if(G.qual & LR_SHIFTKEY) { + if (G.qual & LR_CTRLKEY){ + newspace(curarea, SPACE_NLA); + return 0; + } + newspace(curarea, SPACE_ACTION); + return 0; + } + else BIF_do_render(0); + return 0; + break; + + case LEFTARROWKEY: + case DOWNARROWKEY: + if(textediting==0 && textspace==0) { + if(event==DOWNARROWKEY) CFRA-= 10; + else CFRA--; + + if(G.qual & LR_SHIFTKEY) CFRA= SFRA; + if(CFRA<1) CFRA=1; + + update_for_newframe(); + return 0; + } + break; + + case RIGHTARROWKEY: + case UPARROWKEY: + if(textediting==0 && textspace==0) { + if(event==UPARROWKEY) CFRA+= 10; + else CFRA++; + if(G.qual & LR_SHIFTKEY) CFRA= EFRA; + + update_for_newframe(); + } + break; + + case ESCKEY: + sound_stop_all_sounds(); + break; + case TABKEY: + if(G.qual==0 ) { + if(textspace==0) { + if(curarea->spacetype==SPACE_IPO) set_editflag_editipo(); + else if(curarea->spacetype==SPACE_SEQ) enter_meta(); + else if(G.vd) { + /* ook als Alt-E */ + if(G.obedit==0) enter_editmode(); + else exit_editmode(1); + } + return 0; + } + } + else if(G.qual & LR_CTRLKEY){ + if(G.obpose) exit_posemode(1); + else + enter_posemode(); + allqueue(REDRAWHEADERS, 0); + + } + else if(G.qual & LR_SHIFTKEY) { + if(G.obedit) exit_editmode(1); + if(G.f & G_FACESELECT) set_faceselect(); + if(G.f & G_VERTEXPAINT) set_vpaint(); + if(G.f & G_WEIGHTPAINT) set_wpaint(); + if(G.obpose) exit_posemode(1); + } + break; + + case BACKSPACEKEY: + break; + + case AKEY: + if(textediting==0 && textspace==0) { + if(G.qual & LR_ALTKEY) { + if(G.qual & LR_SHIFTKEY) play_anim(1); + else play_anim(0); + return 0; + } + } + break; + case EKEY: + if(G.qual & LR_ALTKEY) { + if(G.vd && textspace==0) { + if(G.obedit==0) enter_editmode(); + else exit_editmode(1); + return 0; + } + } + break; + case IKEY: + if(textediting==0 && textspace==0 && curarea->spacetype!=SPACE_FILE && curarea->spacetype!=SPACE_IMASEL) { + if(G.qual==0) { + common_insertkey(); + return 0; + } + } + break; + case JKEY: + if(textediting==0 && textspace==0) { + if(R.rectot && G.qual==0) { + BIF_swap_render_rects(); + return 0; + } + } + break; + + case NKEY: + if(textediting==0 && textspace==0 ) { + if(G.qual & LR_CTRLKEY); + else if(G.qual==0 || (G.qual & LR_SHIFTKEY)) { + clever_numbuts(); + return 0; + } + } + break; + + case OKEY: + if(textediting==0) { + if(G.qual & LR_CTRLKEY) { + /* There seem to be crashes here sometimes.... String + * bound overwrites? I changed dir and str sizes, + * let's see if this reoccurs. */ + sprintf(str, "Open file: %s", G.sce); + + if(okee(str)) { + strcpy(dir, G.sce); + BIF_read_file(dir); + } + return 0; + } + } + break; + + case SKEY: + if(G.obpose==0 && G.obedit==0) { + if(G.qual & LR_CTRLKEY) { + if(G.qual & LR_SHIFTKEY); + else { + strcpy(dir, G.sce); + if (untitled(dir)) { + activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file); + } else { + BIF_write_file(dir); + free_filesel_spec(dir); + } + return 0; + } + } + } + break; + + case TKEY: + if(G.qual & LR_ALTKEY) { + if(G.qual & LR_CTRLKEY) { + int a; + + if (G.qual & LR_SHIFTKEY) { + double delta, stime; + + waitcursor(1); + + stime= PIL_check_seconds_timer(); + for(a=0; a<100000; a++) { + scrarea_do_windraw(curarea); + + delta= PIL_check_seconds_timer()-stime; + if (delta>5.0) break; + } + + waitcursor(0); + notice("FPS: %f (%d iterations)", a/delta, a); + } else { + int event= pupmenu("10 Timer%t|draw|draw+swap"); + if(event>0) { + double stime= PIL_check_seconds_timer(); + char tmpstr[128]; + int time; + + printf("start timer\n"); + waitcursor(1); + + for(a=0; a<10; a++) { + scrarea_do_windraw(curarea); + if(event==2) screen_swapbuffers(); + } + + time= (PIL_check_seconds_timer()-stime)*1000; + + if(event==1) sprintf(tmpstr, "draw %%t|%d", time); + if(event==2) sprintf(tmpstr, "d+sw %%t|%d", time); + + waitcursor(0); + pupmenu(tmpstr); + + } + } + return 0; + }} + break; + + case UKEY: + + if(textediting==0) { + if(G.qual & LR_CTRLKEY) { + if(okee("SAVE USER DEFAULTS")) { + BIF_write_homefile(); + } + return 0; + } + } + break; + + case WKEY: + if(textediting==0) { + if(G.qual & LR_CTRLKEY) { + if(G.qual & LR_SHIFTKEY); + else { + strcpy(dir, G.sce); + if (untitled(dir)) { + activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file); + } else { + BIF_write_file(dir); + free_filesel_spec(dir); + } + return 0; + } + } + else if(G.qual & LR_ALTKEY) { + write_videoscape_fs(); + } + } + break; + + case XKEY: + if(G.qual & LR_CTRLKEY) { + if(okee("ERASE ALL")) { + if( BIF_read_homefile()==0) error("No file ~/.B.blend"); + } + return 0; + } + + break; + } + + return 1; +} + +/* eof */ diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c new file mode 100644 index 00000000000..d811c740d3c --- /dev/null +++ b/source/blender/src/toolbox.c @@ -0,0 +1,1454 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#define PY_TOOLBOX 1 +#include <math.h> +#include <ctype.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif + +#include <fcntl.h> +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_image_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_plugin_types.h" +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_main.h" + +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_mainqueue.h" +#include "BIF_interface.h" +#include "BIF_toolbox.h" +#include "BIF_mywindow.h" +#include "BIF_editarmature.h" +#include "BIF_editfont.h" +#include "BIF_editmesh.h" +#include "BIF_editseq.h" +#include "BIF_editlattice.h" +#include "BIF_editsima.h" +#include "BIF_screen.h" +#include "BIF_tbcallback.h" +#include "BIF_editnla.h" + +#include "BDR_editobject.h" +#include "BDR_editcurve.h" +#include "BDR_editmball.h" + +#include "BSE_editipo.h" +#include "BSE_buttons.h" + +#include "IMB_imbuf.h" + +#include "mydevice.h" +#include "blendef.h" + +#include "interface.h" +#include "render.h" + +/* ******** NOTES *********** ***************************** + + - Toolbox items zelf invullen + - de colormap kleuren staan met comments in de bgntoolbox() + - de funktie extern_qread eventueel vervangen + - let op de benaming van bijzondere toetsen (NumL etc) + - meelinken: Button.c, ivm rawcodes + + ***************************** ***************************** +*/ + + +static int tbx1, tbx2, tby1, tby2, tbfontyofs, tbmain=0; +static int tbmemx=TBOXX/2, tbmemy=(TBOXEL-0.5)*TBOXH, tboldwin, addmode= 0; +static int oldcursor; + + /* variabelen per item */ +static char *tbstr, *tbstr1, *keystr; +static void (*tbfunc)(int); +static int tbval; + +/* *********** PC PATCH ************* */ + +void ColorFunc(int i) +{ + if(i==TBOXBLACK) glColor3ub(0, 0, 0); + else if(i==TBOXWHITE) glColor3ub(240, 240, 240); + else if(i==TBOXGREY) glColor3ub(160, 160, 160); + else glColor3ub(0, 0, 0); +} + +/* ********************* PYTHON TOOLBOX CALLBACK ************************* */ + +#ifdef PY_TOOLBOX +/* see bpython/intern/py_toolbox.c */ + +/* moved to BIF_toolbox.h */ +/* typedef char** (*tbox_callback)(int, int); */ + +TBcallback *callback_dummy(int level, int entry) +{ + return NULL; +} + +/* callback func ptr for py_toolbox */ +Tbox_callbackfunc g_toolbox_menucallback = &callback_dummy; + +void tboxSetCallback(Tbox_callbackfunc f) +{ + g_toolbox_menucallback = f; +} + +#endif + +/* ********************* TOOLBOX ITEMS ************************* */ + +void tbox_setinfo(int x, int y) +{ + /* afhankelijk van tbmain worden vars gezet */ + tbstr= 0; + tbstr1= 0; + tbfunc= 0; + tbval= 0; + keystr = NULL; + +/* main menu entries: defined in BIF_toolbox.h */ + + if(x==0) { + switch(y) { + case TBOX_MAIN_FILE: tbstr= "FILE"; break; + case TBOX_MAIN_EDIT: tbstr= "EDIT"; break; + case TBOX_MAIN_ADD: + if (addmode==OB_MESH) tbstr= " MESH"; + else if(addmode==OB_CURVE) tbstr= " CURVE"; + else if(addmode==OB_SURF) tbstr= " SURF"; + else tbstr= "ADD"; + break; + case TBOX_MAIN_OBJECT1: tbstr= "OBJECT"; break; + case TBOX_MAIN_OBJECT2: tbstr= "OBJECT"; break; + case TBOX_MAIN_MESH: tbstr= "MESH"; break; + case TBOX_MAIN_CURVE: tbstr= "CURVE"; break; + case TBOX_MAIN_KEY: tbstr= "KEY"; break; + case TBOX_MAIN_RENDER: tbstr= "RENDER"; break; + case TBOX_MAIN_VIEW: tbstr= "VIEW"; break; +#ifdef PY_TOOLBOX + case TBOX_MAIN_PYTOOL: + { + if (g_toolbox_menucallback(0, 0)) // valid callback? + tbstr= "PYTOOL"; + break; + } +#endif + } + } + +/* TOPICS */ + else { + + +/* FILE TOPICS */ + if(tbmain==TBOX_MAIN_FILE) { + switch(y) { + case 0: tbstr= "New"; tbstr1= "c|x"; keystr= "Ctrl X"; break; + case 1: tbstr= "Open"; tbstr1= "F1"; keystr= "F1"; break; + case 2: tbstr= "Reopen Last"; tbstr1= "c|o"; keystr= "Ctrl O"; break; + case 3: tbstr= "Append"; tbstr1= "shift+F1"; keystr= "Shift F1"; break; + case 4: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 5: tbstr= "Save As"; tbstr1= "F2"; keystr= "F2"; break; + case 6: tbstr= "Save"; tbstr1= "c|w"; keystr= "Ctrl W"; break; + case 7: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 8: tbstr= "Save Image"; tbstr1= "F3"; keystr= "F3"; break; + case 9: tbstr= "Save VRML"; tbstr1= "c|F2"; keystr= "Ctrl F2"; break; + case 10: tbstr= "Save DXF"; tbstr1= "shift+F2"; keystr= "Shift F2"; break; + case 11: tbstr= "Save VideoScape"; tbstr1= "a|w"; keystr= "Alt W"; break; +/* case 12: tbstr= ""; tbstr1= ""; keystr= ""; break; */ + case 13: tbstr= "Quit"; tbstr1= "q"; keystr= "Q"; break; + } + } + +/* EDIT TOPICS */ + if(tbmain==TBOX_MAIN_EDIT) { + switch(y) { + case 0: tbstr= "(De)Select All"; tbstr1= "a"; keystr= "A"; break; + case 1: tbstr= "Border Select"; tbstr1= "b"; keystr= "B"; break; + case 2: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 3: tbstr= "Duplicate"; tbstr1= "D"; keystr= "Shift D"; break; + case 4: tbstr= "Delete"; tbstr1= "x"; keystr= "X"; break; + case 5: tbstr= "Edit Mode"; tbstr1= "Tab"; keystr= "Tab"; break; + case 6: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 7: tbstr= "Grabber"; tbstr1= "g"; keystr= "G"; break; + case 8: tbstr= "Rotate"; tbstr1= "r"; keystr= "R"; break; + case 9: tbstr= "Scale"; tbstr1= "s"; keystr= "S"; break; +/* case 10: tbstr= ""; tbstr1= ""; keystr= ""; break; */ + case 11: tbstr= "Shear"; tbstr1= "c|s"; keystr= "Ctrl S"; break; + case 12: tbstr= "Warp/Bend"; tbstr1= "W"; keystr= "Shift W"; break; + case 13: tbstr= "Snap Menu"; tbstr1= "S"; keystr= "Shift S"; break; + } + } + +/* ADD TOPICS */ + if(tbmain==TBOX_MAIN_ADD) { + + if(addmode==0) { + switch(y) { + case 0: tbstr= "Mesh"; tbstr1= ">>"; keystr= ">>"; tbval=OB_MESH; break; + case 1: tbstr= "Curve"; tbstr1= ">>"; keystr= ">>"; tbval=OB_CURVE; ; break; + case 2: tbstr= "Surface"; tbstr1= ">>"; keystr= ">>"; tbval=OB_SURF; break; + case 3: tbstr= "Text"; tbstr1= ""; keystr= ""; tbval=OB_FONT; tbfunc= add_primitiveFont; break; + case 4: tbstr= "MetaBall"; tbstr1= ""; keystr= ""; tbval=OB_MBALL; tbfunc= add_primitiveMball; break; + case 5: tbstr= "Empty"; tbstr1= "A"; keystr= ""; tbval=OB_EMPTY; break; + case 6: tbstr= ""; tbstr1= ""; keystr= ""; tbval=0; break; + case 7: tbstr= "Camera"; tbstr1= "A"; keystr= ""; tbval=OB_CAMERA; break; + case 8: tbstr= "Lamp"; tbstr1= "A"; keystr= ""; tbval=OB_LAMP; break; + case 9: tbstr= "Armature"; tbstr1= ""; keystr= ""; tbval=OB_ARMATURE; tbfunc=add_primitiveArmature; break; + case 10: tbstr= ""; tbstr1= ""; keystr= ""; tbval=0; break; + case 11: tbstr= "Lattice"; tbstr1= "A"; keystr= ""; tbval=OB_LATTICE; break; + case 12: tbstr= ""; tbstr1= ""; keystr= ""; tbval=0; break; + case 13: tbstr= ""; tbstr1= ""; keystr= ""; tbval=0; break; + } + if(tbstr1 && tbstr1[0]=='A') tbfunc= (void (*)(int) )add_object_draw; + } + else if(addmode==OB_MESH) { + switch(y) { + case 0: tbstr= ">Plane"; tbstr1= "A"; keystr= ""; tbval=0; break; + case 1: tbstr= ">Cube"; tbstr1= "A"; keystr= ""; tbval=1; break; + case 2: tbstr= ">Circle"; tbstr1= "A"; keystr= ""; tbval=4; break; + case 3: tbstr= ">UVsphere"; tbstr1= "A"; keystr= ""; tbval=11; break; + case 4: tbstr= ">Icosphere";tbstr1= "A"; keystr= ""; tbval=12; break; + case 5: tbstr= ">Cylinder"; tbstr1= "A"; keystr= ""; tbval=5; break; + case 6: tbstr= ">Tube"; tbstr1= "A"; keystr= ""; tbval=6; break; + case 7: tbstr= ">Cone"; tbstr1= "A"; keystr= ""; tbval=7; break; + case 8: tbstr= ">"; tbstr1= ""; keystr= ""; break; + case 9: tbstr= ">Grid"; tbstr1= "A"; keystr= ""; tbval=10; break; + case 13: tbstr= ">Monkey"; tbstr1= "A"; keystr= ""; tbval=13; break; + } + if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveMesh; + } + else if(addmode==OB_SURF) { + switch(y) { + case 0: tbstr= ">Curve"; tbstr1= "A"; keystr= ""; tbval=0; break; + case 1: tbstr= ">Circle"; tbstr1= "A"; keystr= ""; tbval=1; break; + case 2: tbstr= ">Surface"; tbstr1= "A"; keystr= ""; tbval=2; break; + case 3: tbstr= ">Tube"; tbstr1= "A"; keystr= ""; tbval=3; break; + case 4: tbstr= ">Sphere"; tbstr1= "A"; keystr= ""; tbval=4; break; + case 5: tbstr= ">Donut"; tbstr1= "A"; keystr= ""; tbval=5; break; + } + if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveNurb; + } +/* else if (addmode==OB_ARMATURE){ + switch(y) { + case 0: tbstr= ">Bone"; tbstr1= "A"; keystr= ""; tbval=0; break; + case 1: tbstr= ">Hand"; tbstr1= "A"; keystr= ""; tbval=1; break; + case 2: tbstr= ">Biped"; tbstr1= "A"; keystr= ""; tbval=2; break; + } + if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveArmature; + } +*/ + else if(addmode==OB_CURVE) { + switch(y) { + case 0: tbstr= ">Bezier Curve"; tbstr1= "A"; keystr= ""; tbval=10; break; + case 1: tbstr= ">Bezier Circle"; tbstr1= "A"; keystr= ""; tbval=11; break; + case 2: tbstr= ">"; tbstr1= ""; keystr= ""; break; + case 3: tbstr= ">Nurbs Curve"; tbstr1= "A"; keystr= ""; tbval=40; break; + case 4: tbstr= ">Nurbs Circle"; tbstr1= "A"; keystr= ""; tbval=41; break; + case 5: tbstr= ">"; tbstr1= ""; keystr= ""; break; + case 6: tbstr= ">Path"; tbstr1= "A"; keystr= ""; tbval=46; break; + } + if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveCurve; + } +/* else if(addmode==OB_MBALL) { + switch(y) { + case 0: tbstr= "Ball"; tbstr1= "A"; tbval=1; break; + case 1: tbstr= ""; tbstr1= ""; break; + case 2: tbstr= ""; tbstr1= ""; break; + case 3: tbstr= ""; tbstr1= ""; break; + case 4: tbstr= ""; tbstr1= ""; break; + case 5: tbstr= ""; tbstr1= ""; break; + case 6: tbstr= ""; tbstr1= ""; break; + case 7: tbstr= ""; tbstr1= ""; break; + case 8: tbstr= ""; tbstr1= ""; break; + case 9: tbstr= ""; tbstr1= ""; break; + case 10: tbstr= ""; tbstr1= ""; break; + case 11: tbstr= "Duplicate";tbstr1= "D"; break; + } + if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveMball; + }*/ + } + +/* OB TOPICS 1 */ + else if(tbmain==TBOX_MAIN_OBJECT1) { + switch(y) { + case 0: tbstr= "Clear Size"; tbstr1= "a|s"; keystr= "Alt S"; break; + case 1: tbstr= "Clear Rotation"; tbstr1= "a|r"; keystr= "Alt R"; break; + case 2: tbstr= "Clear Location"; tbstr1= "a|g"; keystr= "Alt G"; break; + case 3: tbstr= "Clear Origin"; tbstr1= "a|o"; keystr= "Alt O"; break; + case 4: tbstr= "Make Parent"; tbstr1= "c|p"; keystr= "Ctrl P"; break; + case 5: tbstr= "Clear Parent"; tbstr1= "a|p"; keystr= "Alt P"; break; + case 6: tbstr= "Make Track"; tbstr1= "c|t"; keystr= "Ctrl T"; break; + case 7: tbstr= "Clear Track"; tbstr1= "a|t"; keystr= "Alt T"; break; +/* case 8: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 9: tbstr= ""; tbstr1= ""; keystr= ""; break; */ + case 10: tbstr= "Image Displist"; tbstr1= "c|d"; keystr= "Ctrl D"; break; + case 11: tbstr= "Image Aspect"; tbstr1= "a|v"; keystr= "Alt V"; break; + } + } + +/* OB TOPICS 2 */ + else if(tbmain==TBOX_MAIN_OBJECT2) { + switch(y) { + case 0: tbstr= "Edit Mode"; tbstr1= "Tab"; keystr= "Tab"; break; + case 1: tbstr= "Move To Layer"; tbstr1= "m"; keystr= "M"; break; + case 2: tbstr= "Delete"; tbstr1= "x"; keystr= "X"; break; + case 3: tbstr= "Delete All"; tbstr1= "c|x"; keystr= "Ctrl X"; break; + case 4: tbstr= "Apply Size/Rot"; tbstr1= "c|a"; keystr= "Ctrl A"; break; + case 5: tbstr= "Apply Deform"; tbstr1= "c|A"; keystr= "Ctrl Shift A"; break; + case 6: tbstr= "Join"; tbstr1= "c|j"; keystr= "Ctrl J"; break; + case 7: tbstr= "Make Local"; tbstr1= "l"; keystr= "L"; break; + case 8: tbstr= "Select Linked"; tbstr1= "L"; keystr= "Shift L"; break; + case 9: tbstr= "Make Links"; tbstr1= "c|l"; keystr= "Ctrl L"; break; + case 10: tbstr= "Copy Menu"; tbstr1= "c|c"; keystr= "Ctrl C"; break; + case 11: tbstr= "Convert Menu"; tbstr1= "a|c"; keystr= "Alt C"; break; + } + } + +/* mesh TOPICS */ + else if(tbmain==TBOX_MAIN_MESH) { + switch(y) { + case 0: tbstr= "Select Linked"; tbstr1= "l"; keystr= "L"; break; + case 1: tbstr= "Deselect Linked"; tbstr1= "L"; keystr= "Shift L"; break; + case 2: tbstr= "Extrude"; tbstr1= "e"; keystr= "E"; break; + case 3: tbstr= "Delete Menu"; tbstr1= "x"; keystr= "X"; break; + case 4: tbstr= "Make edge/face"; tbstr1= "f"; keystr= "F"; break; + case 5: tbstr= "Fill"; tbstr1= "F"; keystr= "Shift F"; break; + case 6: tbstr= "Split"; tbstr1= "y"; keystr= "Y"; break; + case 7: tbstr= "Undo/reload"; tbstr1= "u"; keystr= "U"; break; + case 8: tbstr= "Calc Normals"; tbstr1= "c|n"; keystr= "Ctrl N"; break; + case 9: tbstr= "Separate"; tbstr1= "p"; keystr= "P"; break; + case 10: tbstr= "Write Videosc"; tbstr1= "a|w"; keystr= "Alt W"; break; +/* case 11: tbstr= ""; tbstr1= ""; keystr= ""; break; */ + } + } + +/* CURVE TOPICS */ + else if(tbmain==TBOX_MAIN_CURVE) { + switch(y) { + case 0: tbstr= "Select Linked"; tbstr1= "l"; keystr= "L"; break; + case 1: tbstr= "Deselect Linked"; tbstr1= "L"; keystr= "Shift L"; break; + case 2: tbstr= "Extrude"; tbstr1= "e"; keystr= "E"; break; + case 3: tbstr= "Delete Menu"; tbstr1= "x"; keystr= "X"; break; + case 4: tbstr= "Make Segment"; tbstr1= "f"; keystr= "F"; break; + case 5: tbstr= "Cyclic"; tbstr1= "c"; keystr= "C"; break; +/* case 6: tbstr= ""; tbstr1= ""; keystr= ""; break; */ + case 7: tbstr= "Select Row"; tbstr1= "R"; keystr= "Shift R"; break; + case 8: tbstr= "Calc Handle"; tbstr1= "h"; keystr= "H"; break; + case 9: tbstr= "Auto Handle"; tbstr1= "H"; keystr= "Shift H"; break; + case 10: tbstr= "Vect Handle"; tbstr1= "v"; keystr= "V"; break; + case 11: tbstr= "Specials"; tbstr1= "w"; keystr= "W"; break; + } + } + +/* KEY TOPICS */ + else if(tbmain==TBOX_MAIN_KEY) { + switch(y) { + case 0: tbstr= "Insert"; tbstr1= "i"; keystr= "I"; break; + case 1: tbstr= "Show"; tbstr1= "k"; keystr= "K"; break; + case 2: tbstr= "Next"; tbstr1= "PageUp"; keystr= "PgUp"; break; + case 3: tbstr= "Prev"; tbstr1= "PageDn"; keystr= "PgDn"; break; + case 4: tbstr= "Show+Sel"; tbstr1= "K"; keystr= "Shift K"; break; +/* case 5: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 6: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 7: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 8: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 9: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 10: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 11: tbstr= ""; tbstr1= ""; keystr= ""; break; */ + } + } + +/* RENDER TOPICS */ + else if(tbmain==TBOX_MAIN_RENDER) { + switch(y) { + case 0: tbstr= "Render Window"; tbstr1= "F11"; keystr= "F11"; break; + case 1: tbstr= "Render"; tbstr1= "F12"; keystr= "F12"; break; + case 2: tbstr= "Set Border"; tbstr1= "B"; keystr= "Shift B"; break; + case 3: tbstr= "Image Zoom"; tbstr1= "z"; keystr= "Z"; break; +/* case 4: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 5: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 6: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 7: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 8: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 9: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 10: tbstr= ""; tbstr1= ""; keystr= ""; break; + case 11: tbstr= ""; tbstr1= ""; keystr= ""; break; */ + } + } + +/* VIEW TOPICS */ + else if(tbmain==TBOX_MAIN_VIEW) { + switch(y) { +/* case 0: tbstr= ""; tbstr1= ""; break; + case 1: tbstr= ""; tbstr1= ""; break; + case 2: tbstr= ""; tbstr1= ""; break; + case 3: tbstr= ""; tbstr1= ""; break; */ + case 4: tbstr= "Centre"; tbstr1= "c"; keystr= "C"; break; + case 5: tbstr= "Home"; tbstr1= "C"; keystr= "Shift C"; break; +/* case 6: tbstr= ""; tbstr1= ""; break; + case 7: tbstr= ""; tbstr1= ""; break; + case 8: tbstr= ""; tbstr1= ""; break;*/ + case 9: tbstr= "Z-Buffer"; tbstr1= "z"; keystr= "Z"; break; +/* case 10: tbstr= ""; tbstr1= ""; break; + case 11: tbstr= ""; tbstr1= ""; break;*/ + } + } +#ifdef PY_TOOLBOX + else if(tbmain==TBOX_MAIN_PYTOOL) { + TBcallback *t= g_toolbox_menucallback(0, y); // call python menu constructor + if (t) { + tbstr = t->desc; + keystr = t->key; + tbfunc = t->cb; + tbval = t->val; + } + } +#endif + } +} + +/* ******************** INIT ************************** */ + +void dummy(void) +{ + +} + + +void bgnpupdraw(int startx, int starty, int endx, int endy) +{ + #if defined(__sgi) || defined(__sun__) + /* this is a dirty patch: XgetImage gets sometimes the backbuffer */ + my_get_frontbuffer_image(0, 0, 1, 1); + my_put_frontbuffer_image(); + #endif + + tboldwin= mywinget(); + + mywinset(G.curscreen->mainwin); + + /* pietsje groter, 1 pixel aan de rand */ + + glReadBuffer(GL_FRONT); + glDrawBuffer(GL_FRONT); + + glFinish(); + + my_get_frontbuffer_image(startx-1, starty-4, endx-startx+5, endy-starty+6); + + oldcursor= get_cursor(); + set_cursor(CURSOR_STD); + + tbfontyofs= (TBOXH-11)/2; /* toolbox, hier stond ooit getheigh */ +} + +void endpupdraw(void) +{ + glFinish(); + my_put_frontbuffer_image(); + + if(tboldwin) { + mywinset(tboldwin); + set_cursor(oldcursor); + } + + glReadBuffer(GL_BACK); + glDrawBuffer(GL_BACK); +} + +/* ********************************************** */ + +void asciitoraw(int ch, unsigned short *event, unsigned short *qual) +{ + if( isalpha(ch)==0 ) return; + + if( isupper(ch) ) { + *qual= LEFTSHIFTKEY; + ch= tolower(ch); + } + + switch(ch) { + case 'a': *event= AKEY; break; + case 'b': *event= BKEY; break; + case 'c': *event= CKEY; break; + case 'd': *event= DKEY; break; + case 'e': *event= EKEY; break; + case 'f': *event= FKEY; break; + case 'g': *event= GKEY; break; + case 'h': *event= HKEY; break; + case 'i': *event= IKEY; break; + case 'j': *event= JKEY; break; + case 'k': *event= KKEY; break; + case 'l': *event= LKEY; break; + case 'm': *event= MKEY; break; + case 'n': *event= NKEY; break; + case 'o': *event= OKEY; break; + case 'p': *event= PKEY; break; + case 'q': *event= QKEY; break; + case 'r': *event= RKEY; break; + case 's': *event= SKEY; break; + case 't': *event= TKEY; break; + case 'u': *event= UKEY; break; + case 'v': *event= VKEY; break; + case 'w': *event= WKEY; break; + case 'x': *event= XKEY; break; + case 'y': *event= YKEY; break; + case 'z': *event= ZKEY; break; + } +} + +void tbox_execute(void) +{ + /* als tbfunc: functie aanroepen */ + /* als tbstr1 is een string: value tbval in queue stopen */ + unsigned short event=0; + unsigned short qual1=0, qual2=0; + + if(tbfunc) { + tbfunc(tbval); + } + else if(tbstr1) { + if(strcmp(tbstr1, "Tab")==0) { + event= TABKEY; + } + else if(strcmp(tbstr1, "PageUp")==0) { + event= PAGEUPKEY; + } + else if(strcmp(tbstr1, "PageDn")==0) { + event= PAGEDOWNKEY; + } + else if(strcmp(tbstr1, "shift+F1")==0) { + qual1= LEFTSHIFTKEY; + event= F1KEY; + } + else if(strcmp(tbstr1, "shift+F2")==0) { + qual1= LEFTSHIFTKEY; + event= F2KEY; + } + /* ctrl-s (Shear): switch into editmode ### */ + else if(strcmp(tbstr1, "c|s")==0) { + if (!G.obedit) { + enter_editmode(); + /* ### put these into a deselectall_gen() */ + if(G.obedit->type==OB_MESH) deselectall_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) deselectall_nurb(); + else if(G.obedit->type==OB_MBALL) deselectall_mball(); + else if(G.obedit->type==OB_LATTICE) deselectall_Latt(); + /* ### */ + } + qual1 = LEFTCTRLKEY; + event = SKEY; + } + else if(strcmp(tbstr1, "W")==0) { + if (!G.obedit) { + enter_editmode(); + /* ### put these into a deselectall_gen() */ + if(G.obedit->type==OB_MESH) deselectall_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) deselectall_nurb(); + else if(G.obedit->type==OB_MBALL) deselectall_mball(); + else if(G.obedit->type==OB_LATTICE) deselectall_Latt(); + /* ### */ + } + qual1 = LEFTSHIFTKEY; + event = WKEY; + } + + else if(strlen(tbstr1)<4 || (strlen(tbstr1)==4 && tbstr1[2]=='F')) { + + if(tbstr1[1]=='|') { + if(tbstr1[0]=='c') qual1= LEFTCTRLKEY; + else if(tbstr1[0]=='a') qual1= LEFTALTKEY; + + if (tbstr1[2]=='F') { + switch(tbstr1[3]) { + case '1': event= F1KEY; break; + case '2': event= F2KEY; break; + case '3': event= F3KEY; break; + case '4': event= F4KEY; break; + case '5': event= F5KEY; break; + case '6': event= F6KEY; break; + case '7': event= F7KEY; break; + case '8': event= F8KEY; break; + case '9': event= F9KEY; break; + } + } + else asciitoraw(tbstr1[2], &event, &qual2); + } + else if(tbstr1[1]==0) { + asciitoraw(tbstr1[0], &event, &qual2); + } + else if(tbstr1[0]=='F') { + event= atoi(tbstr1+1); + switch(event) { + case 1: event= F1KEY; break; + case 2: event= F2KEY; break; + case 3: event= F3KEY; break; + case 4: event= F4KEY; break; + case 5: event= F5KEY; break; + case 6: event= F6KEY; break; + case 7: event= F7KEY; break; + case 8: event= F8KEY; break; + case 9: event= F9KEY; break; + case 10: event= F10KEY; break; + case 11: event= F11KEY; break; + case 12: event= F12KEY; break; + } + } + } + + if(event) { + if(qual1) mainqenter(qual1, 1); + if(qual2) mainqenter(qual2, 1); + mainqenter(event, 1); + mainqenter(event, 0); + mainqenter(EXECUTE, 1); + if(qual1) mainqenter(qual1, 0); + if(qual2) mainqenter(qual2, 0); + } + } + +} + +void tbox_getmouse(mval) +short *mval; +{ + + getmouseco_sc(mval); + +} + +void tbox_setmain(int val) +{ + tbmain= val; + + if(tbmain==0 && G.obedit) { + addmode= G.obedit->type; + } +} + +void bgntoolbox(void) +{ + short xmax, ymax, mval[2]; + + xmax = G.curscreen->sizex; + ymax = G.curscreen->sizey; + + tbox_getmouse(mval); + + if(mval[0]<95) mval[0]= 95; + if(mval[0]>xmax-95) mval[0]= xmax-95; + + warp_pointer(mval[0], mval[1]); + + tbx1= mval[0]-tbmemx; + tby1= mval[1]-tbmemy; + if(tbx1<10) tbx1= 10; + if(tby1<10) tby1= 10; + + tbx2= tbx1+TBOXX; + tby2= tby1+TBOXY; + if(tbx2>xmax) { + tbx2= xmax-10; + tbx1= tbx2-TBOXX; + } + if(tby2>ymax) { + tby2= ymax-10; + tby1= tby2-TBOXY; + } + + bgnpupdraw(tbx1, tby1, tbx2, tby2); +} + +void endtoolbox(void) +{ + short mval[2]; + + tbox_getmouse(mval); + if(mval[0]>tbx1 && mval[0]<tbx2) + if(mval[1]>tby1 && mval[1]<tby2) { + tbmemx= mval[0]-(tbx1); + tbmemy= mval[1]-(tby1); + } + + endpupdraw(); +} + + +void tbox_embossbox(short x1, short y1, short x2, short y2, short type) +/* type: 0=menu, 1=menusel, 2=topic, 3=topicsel */ +{ + + if(type==0) { + glColor3ub(160, 160, 160); + glRects(x1+1, y1+1, x2-1, y2-1); + } + if(type==1) { + glColor3ub(50, 50, 100); + glRects(x1+1, y1+1, x2-1, y2-1); + } + if(type==2) { + glColor3ub(190, 190, 190); + glRects(x1+1, y1+1, x2-1, y2-1); + } + if(type==3) { + cpack(0xc07070); + glRects(x1+1, y1+1, x2-1, y2-1); + } + + if(type & 1) cpack(0xFFFFFF); + else cpack(0x0); +} + + +void tbox_drawelem_body(x, y, type) +{ + int x1 = 0, y1, x2 = 0, y2; + + if(x==0) { + x1= tbx1; x2= tbx1+TBOXXL; + } + else if(x==1) { + x1= tbx1+TBOXXL; + x2= x1+ TBOXXR-1; + } + + y1= tby1+ (TBOXEL-y-1)*TBOXH; + y2= y1+TBOXH-1; + + tbox_embossbox(x1, y1, x2, y2, type); + +} + +void tbox_drawelem_text(x, y, type) +{ + int x1 = 0, y1, x2 = 0, y2, len1, len2; + + if(x==0) { + x1= tbx1; x2= tbx1+TBOXXL; + } + else if(x==1) { + x1= tbx1+TBOXXL; + x2= x1+ TBOXXR-1; + } + + y1= tby1+ (TBOXEL-y-1)*TBOXH; + y2= y1+TBOXH-1; + + if(type==0 || type==2) { + ColorFunc(TBOXBLACK); + } + else { + glColor3ub(240, 240, 240); + } + + /* tekst */ + tbox_setinfo(x, y); + if(tbstr && tbstr[0]) { + len1= 5+BMF_GetStringWidth(G.font, tbstr); +// if(tbstr1) len2= 5+BMF_GetStringWidth(G.font, tbstr1); else len2= 0; + if(keystr) len2= 5+BMF_GetStringWidth(G.font, keystr); else len2= 0; + + while(len1>0 && (len1+len2+5>x2-x1) ) { + tbstr[strlen(tbstr)-1]= 0; + len1= BMF_GetStringWidth(G.font, tbstr); + } + + glRasterPos2i(x1+5, y1+tbfontyofs); + BMF_DrawString(G.font, tbstr); + +// if(tbstr1 && tbstr1[0]) { + if(keystr && keystr[0]) { + if(type & 1) { + ColorFunc(TBOXBLACK); + + glRecti(x2-len2-2, y1+2, x2-3, y2-2); + ColorFunc(TBOXWHITE); + glRasterPos2i(x2-len2, y1+tbfontyofs); +// BMF_DrawString(G.font, tbstr1); + BMF_DrawString(G.font, keystr); + } + else { + ColorFunc(TBOXBLACK); + glRasterPos2i(x2-len2, y1+tbfontyofs); +// BMF_DrawString(G.font, tbstr1); + BMF_DrawString(G.font, keystr); + } + } + } +} + + +void tbox_drawelem(x, y, type) +int x, y, type; +{ + /* type: 0=menu, 1=menusel, 2=topic, 3=topicsel */ + + tbox_drawelem_body(x, y, type); + tbox_drawelem_text(x, y, type); + +} + +void tbox_getactive(x, y) +int *x, *y; +{ + short mval[2]; + + tbox_getmouse(mval); + + mval[0]-=tbx1; + if(mval[0]<TBOXXL) *x= 0; + else *x= 1; + + *y= mval[1]-tby1; + *y/= TBOXH; + *y= TBOXEL- *y-1; + if(*y<0) *y= 0; + if(*y>TBOXEL-1) *y= TBOXEL-1; + +} + +void drawtoolbox(void) +{ + int x, y, actx, acty, type; + + tbox_getactive(&actx, &acty); + + /* de background */ + for(x=0; x<2; x++) { + + for(y=0; y<TBOXEL; y++) { + + if(x==0) type= 0; + else type= 2; + + if(actx==x && acty==y) type++; + if(type==0) { + if(tbmain==y) type= 1; + } + + tbox_drawelem_body(x, y, type); + + } + } + + /* de text */ + for(x=0; x<2; x++) { + + for(y=0; y<TBOXEL; y++) { + + if(x==0) type= 0; + else type= 2; + + if(actx==x && acty==y) type++; + if(type==0) { + if(tbmain==y) type= 1; + } + + tbox_drawelem_text(x, y, type); + + } + } + glFinish(); /* for geforce, to show it in the frontbuffer */ + +} + + +void toolbox(void) +{ + int actx, acty, y; + unsigned short event; + short val, mval[2], xo= -1, yo=0; + + bgntoolbox(); + glColor3ub(0xB0, 0xB0, 0xB0); + uiDrawMenuBox((float)tbx1, (float)tby1-1, (float)tbx2, (float)tby2); + drawtoolbox(); + + /* + * De aktieve window wordt in queue terug gestopt. + */ + + while(1) { + event= extern_qread(&val); + if(event) { + switch(event) { + case LEFTMOUSE: case MIDDLEMOUSE: case RIGHTMOUSE: case RETKEY: case PADENTER: + if(val==1) { + tbox_getactive(&actx, &acty); + tbox_setinfo(actx, acty); + + if(event==RIGHTMOUSE) { + if(addmode) { + addmode= 0; + drawtoolbox(); + } + } + else if(tbstr1 && tbstr1[0]=='>') { + addmode= tbval; + drawtoolbox(); + } + else { + endtoolbox(); + tbox_execute(); + return; + } + } + break; + case ESCKEY: + /* altkeys: om conflicten met overdraw en stow/push/pop te voorkomen */ +#ifndef MAART +/* Temporary for making screen dumps (Alt+PrtSc) */ + case LEFTALTKEY: + case RIGHTALTKEY: +#endif /* MAART */ + if(val) endtoolbox(); + return; + } + } + + tbox_getmouse(mval); + if(mval[0]<tbx1-10 || mval[0]>tbx2+10 || mval[1]<tby1-10 || mval[1]>tby2+10) break; + + tbox_getactive(&actx, &acty); + + /* muisafhandeling en redraw */ + if(xo!=actx || yo!=acty) { + if(actx==0) { + if (acty==0) addmode=0; + + tbox_drawelem(0, tbmain, 0); + tbox_drawelem(0, acty, 1); + + tbmain= acty; + addmode= 0; + for(y=0; y<TBOXEL; y++) tbox_drawelem(1, y, 2); + } + else if(xo> -1) { + if(xo==0) tbox_drawelem(xo, yo, 1); + else tbox_drawelem(xo, yo, 2); + tbox_drawelem(actx, acty, 3); + } + + glFinish(); /* for geforce, to show it in the frontbuffer */ + + xo= actx; + yo= acty; + } + } + + endtoolbox(); +} + +/* ************************************ */ + +static int vconfirm(char *title, char *itemfmt, va_list ap) +{ + char *s, buf[512]; + + s= buf; + if (title) s+= sprintf(s, "%s%%t|", title); + vsprintf(s, itemfmt, ap); + + return (pupmenu(buf)>=0); +} + +static int confirm(char *title, char *itemfmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, itemfmt); + ret= vconfirm(title, itemfmt, ap); + va_end(ap); + + return ret; +} + +int okee(char *str, ...) +{ + va_list ap; + int ret; + + va_start(ap, str); + ret= vconfirm("OK?", str, ap); + va_end(ap); + + return ret; +} + +void notice(char *str, ...) +{ + va_list ap; + + va_start(ap, str); + vconfirm(NULL, str, ap); + va_end(ap); +} + +void error(char *fmt, ...) +{ + va_list ap; + char nfmt[256]; + + sprintf(nfmt, "ERROR: %s", fmt); + + va_start(ap, fmt); + if (G.background || !G.curscreen) { + vprintf(nfmt, ap); + printf("\n"); + } else { + vconfirm(NULL, nfmt, ap); + } + va_end(ap); +} + +int saveover(char *file) +{ + return (!BLI_exists(file) || confirm("SAVE OVER", file)); +} + +/* ****************** EXTRAATJE **************** */ + +short button(short *var, short min, short max, char *str) +{ + uiBlock *block; + ListBase listb={0, 0}; + short x1,y1; + short mval[2], ret=0; + + if(min>max) min= max; + + getmouseco_sc(mval); + + if(mval[0]<150) mval[0]=150; + if(mval[1]<30) mval[1]=30; + if(mval[0]>G.curscreen->sizex) mval[0]= G.curscreen->sizex-10; + if(mval[1]>G.curscreen->sizey) mval[1]= G.curscreen->sizey-10; + + block= uiNewBlock(&listb, "button", UI_EMBOSSX, UI_HELV, G.curscreen->mainwin); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1); + + x1=mval[0]-150; + y1=mval[1]-20; + + uiDefButS(block, NUM, 0, str, (short)(x1+5),(short)(y1+10),125,20, var,(float)min,(float)max, 0, 0, ""); + uiDefBut(block, BUT, 1, "OK", (short)(x1+136),(short)(y1+10),25,20, NULL, 0, 0, 0, 0, ""); + + uiBoundsBlock(block, 5); + + ret= uiDoBlocks(&listb, 0); + + if(ret==UI_RETURN_OK) return 1; + return 0; +} + +short sbutton(char *var, float min, float max, char *str) +{ + uiBlock *block; + ListBase listb={0, 0}; + short x1,y1; + short mval[2], ret=0; + + if(min>max) min= max; + + getmouseco_sc(mval); + + if(mval[0]<150) mval[0]=150; + if(mval[1]<30) mval[1]=30; + if(mval[0]>G.curscreen->sizex) mval[0]= G.curscreen->sizex-10; + if(mval[1]>G.curscreen->sizey) mval[1]= G.curscreen->sizey-10; + + block= uiNewBlock(&listb, "button", UI_EMBOSSX, UI_HELV, G.curscreen->mainwin); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1); + + x1=mval[0]-150; + y1=mval[1]-20; + + uiDefButC(block, TEX, 0, str, x1+5,y1+10,125,20, var,(float)min,(float)max, 0, 0, ""); + uiDefBut(block, BUT, 1, "OK", x1+136,y1+10,25,20, NULL, 0, 0, 0, 0, ""); + + uiBoundsBlock(block, 5); + + ret= uiDoBlocks(&listb, 0); + + if(ret==UI_RETURN_OK) return 1; + return 0; +} + +short fbutton(float *var, float min, float max, char *str) +{ + uiBlock *block; + ListBase listb={0, 0}; + short x1,y1; + short mval[2], ret=0; + + if(min>max) min= max; + + getmouseco_sc(mval); + + if(mval[0]<150) mval[0]=150; + if(mval[1]<30) mval[1]=30; + if(mval[0]>G.curscreen->sizex) mval[0]= G.curscreen->sizex-10; + if(mval[1]>G.curscreen->sizey) mval[1]= G.curscreen->sizey-10; + + block= uiNewBlock(&listb, "button", UI_EMBOSSX, UI_HELV, G.curscreen->mainwin); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1); + + x1=mval[0]-150; + y1=mval[1]-20; + + uiDefButF(block, NUM, 0, str,(short)(x1+5),(short)(y1+10),125,20, var, min, max, 0, 0, ""); + uiDefBut(block, BUT, 1, "OK",(short)(x1+136),(short)(y1+10), 35, 20, NULL, 0, 0, 0, 0, ""); + + uiBoundsBlock(block, 2); + + ret= uiDoBlocks(&listb, 0); + + if(ret==UI_RETURN_OK) return 1; + return 0; +} + +int movetolayer_buts(unsigned int *lay) +{ + uiBlock *block; + ListBase listb={0, 0}; + int dx, dy, a, x1, y1, sizex=160, sizey=30; + short pivot[2], mval[2], ret=0; + + if(G.vd->localview) { + error("Not in localview "); + return ret; + } + + getmouseco_sc(mval); + + pivot[0]= CLAMPIS(mval[0], (sizex+10), G.curscreen->sizex-30); + pivot[1]= CLAMPIS(mval[1], (sizey/2)+10, G.curscreen->sizey-(sizey/2)-10); + + if (pivot[0]!=mval[0] || pivot[1]!=mval[1]) + warp_pointer(pivot[0], pivot[1]); + + mywinset(G.curscreen->mainwin); + + x1= pivot[0]-sizex+10; + y1= pivot[1]-sizey/2; + + block= uiNewBlock(&listb, "button", UI_EMBOSSX, UI_HELV, G.curscreen->mainwin); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_RET_1); + + dx= (sizex-5)/12; + dy= sizey/2; + + for(a=0; a<10; a++) { + uiDefButI(block, TOGR|BIT|a, 0, "",(short)(x1+a*dx),(short)(y1+dy),(short)dx,(short)dy, lay, 0, 0, 0, 0, ""); + if(a==4) x1+= 5; + } + x1-= 5; + + for(a=0; a<10; a++) { + uiDefButI(block, TOGR|BIT|(a+10), 0, "",(short)(x1+a*dx),(short)y1,(short)dx,(short)dy, lay, 0, 0, 0, 0, ""); + if(a==4) x1+= 5; + } + x1-= 5; + + uiDefBut(block, BUT, 1, "OK", (short)(x1+10*dx+10), (short)y1, (short)(3*dx), (short)(2*dy), NULL, 0, 0, 0, 0, ""); + + uiBoundsBlock(block, 2); + + ret= uiDoBlocks(&listb, 0); + + if(ret==UI_RETURN_OK) return 1; + return 0; +} + +/* ********************** CLEVER_NUMBUTS ******************** */ + +#define MAXNUMBUTS 24 + +VarStruct numbuts[MAXNUMBUTS]; +void *numbpoin[MAXNUMBUTS]; +int numbdata[MAXNUMBUTS]; + +void draw_numbuts_tip(char *str, int x1, int y1, int x2, int y2) +{ + static char *last=0; /* avoid ugly updates! */ + int temp; + + if(str==last) return; + last= str; + if(str==0) return; + + glColor3ub(160, 160, 160); /* MGREY */ + glRecti(x1+4, y2-36, x2-4, y2-16); + + cpack(0x0); + + temp= 0; + while( BMF_GetStringWidth(G.fonts, str+temp)>(x2 - x1-24)) temp++; + glRasterPos2i(x1+16, y2-30); + BMF_DrawString(G.fonts, str+temp); +} + +int do_clever_numbuts(char *name, int tot, int winevent) +{ + ListBase listb= {NULL, NULL}; + uiBlock *block; + VarStruct *varstr; + int a, sizex, sizey, x1, y2; + short mval[2], event; + + if(tot<=0 || tot>MAXNUMBUTS) return 0; + + getmouseco_sc(mval); + + /* size */ + sizex= 235; + sizey= 30+20*(tot+1); + + /* midden */ + if(mval[0]<sizex/2) mval[0]=sizex/2; + if(mval[1]<sizey/2) mval[1]=sizey/2; + if(mval[0]>G.curscreen->sizex -sizex/2) mval[0]= G.curscreen->sizex -sizex/2; + if(mval[1]>G.curscreen->sizey -sizey/2) mval[1]= G.curscreen->sizey -sizey/2; + + mywinset(G.curscreen->mainwin); + + x1= mval[0]-sizex/2; + y2= mval[1]+sizey/2; + + block= uiNewBlock(&listb, "numbuts", UI_EMBOSSX, UI_HELV, G.curscreen->mainwin); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_ENTER_OK); + + /* LET OP: TEX BUTTON UITZONDERING */ + /* WAARSCHUWING: ALLEEN EEN ENKELE BITJES-BUTTON MOGELIJK: ER WORDT OP KOPIEDATA GEWERKT! */ + + uiDefBut(block, LABEL, 0, name, (short)(x1+15), (short)(y2-35), (short)(sizex-60), 19, 0, 1.0, 0.0, 0, 0, ""); + + if(name[0]=='A' && name[7]=='O') { + y2 -= 20; + uiDefBut(block, LABEL, 0, "Rotations in degrees!", (short)(x1+15), (short)(y2-35), (short)(sizex-60), 19, 0, 0.0, 0.0, 0, 0, ""); + } + + varstr= &numbuts[0]; + for(a=0; a<tot; a++, varstr++) { + if(varstr->type==TEX) { + uiDefBut(block, TEX, 0, varstr->name,(short)(x1+15),(short)(y2-55-20*a),(short)(sizex-60), 19, numbpoin[a], varstr->min, varstr->max, 0, 0, varstr->tip); + } + else { + uiDefBut(block, varstr->type, 0, varstr->name,(short)(x1+15),(short)(y2-55-20*a), (short)(sizex-60), 19, &(numbdata[a]), varstr->min, varstr->max, 100, 0, varstr->tip); + } + } + + uiDefBut(block, BUT, 4000, "OK", (short)(x1+sizex-40),(short)(y2-35-20*a), 25, (short)(sizey-50), 0, 0, 0, 0, 0, "OK: Assign Values"); + + uiBoundsBlock(block, 5); + + event= uiDoBlocks(&listb, 0); + + areawinset(curarea->win); + + if(event & UI_RETURN_OK) { + + varstr= &numbuts[0]; + for(a=0; a<tot; a++, varstr++) { + if(varstr->type==TEX); + else if ELEM( (varstr->type & BUTPOIN), FLO, INT ) memcpy(numbpoin[a], numbdata+a, 4); + else if((varstr->type & BUTPOIN)==SHO ) *((short *)(numbpoin[a]))= *( (short *)(numbdata+a)); + + if( strncmp(varstr->name, "Rot", 3)==0 ) { + float *fp; + + fp= numbpoin[a]; + fp[0]= M_PI*fp[0]/180.0; + } + } + + if(winevent) { + ScrArea *sa; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==curarea->spacetype) addqueue(sa->win, winevent, 1); + sa= sa->next; + } + } + + return 1; + } + return 0; +} + +void add_numbut(int nr, int type, char *str, float min, float max, void *poin, char *tip) +{ + if(nr>=MAXNUMBUTS) return; + + numbuts[nr].type= type; + strcpy(numbuts[nr].name, str); + numbuts[nr].min= min; + numbuts[nr].max= max; + if(tip) strcpy(numbuts[nr].tip, tip); + + /* LET OP: TEX BUTTON UITZONDERING */ + + numbpoin[nr]= poin; + + if ELEM( (type & BUTPOIN), FLO, INT ) memcpy(numbdata+nr, poin, 4); + if((type & BUTPOIN)==SHO ) *((short *)(numbdata+nr))= *( (short *)poin); + + if( strncmp(numbuts[nr].name, "Rot", 3)==0 ) { + float *fp; + + fp= (float *)(numbdata+nr); + fp[0]= 180.0*fp[0]/M_PI; + } + +} + +void clever_numbuts(void) +{ + Object *ob; + float lim; + char str[128]; + + if(curarea->spacetype==SPACE_VIEW3D) { + lim= 1000.0*MAX2(1.0, G.vd->grid); + + if(G.obpose){ + if (G.obpose->type == OB_ARMATURE) clever_numbuts_posearmature(); + } + else if(G.obedit==0) { + ob= OBACT; + if(ob==0) return; + + add_numbut(0, NUM|FLO, "LocX:", -lim, lim, ob->loc, 0); + add_numbut(1, NUM|FLO, "LocY:", -lim, lim, ob->loc+1, 0); + add_numbut(2, NUM|FLO, "LocZ:", -lim, lim, ob->loc+2, 0); + + add_numbut(3, NUM|FLO, "RotX:", -10.0*lim, 10.0*lim, ob->rot, 0); + add_numbut(4, NUM|FLO, "RotY:", -10.0*lim, 10.0*lim, ob->rot+1, 0); + add_numbut(5, NUM|FLO, "RotZ:", -10.0*lim, 10.0*lim, ob->rot+2, 0); + + add_numbut(6, NUM|FLO, "SizeX:", -lim, lim, ob->size, 0); + add_numbut(7, NUM|FLO, "SizeY:", -lim, lim, ob->size+1, 0); + add_numbut(8, NUM|FLO, "SizeZ:", -lim, lim, ob->size+2, 0); + + sprintf(str, "Active Object: %s", ob->id.name+2); + do_clever_numbuts(str, 9, REDRAW); + + } + else if(G.obedit->type==OB_MESH) clever_numbuts_mesh(); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) clever_numbuts_curve(); + else if (G.obedit->type==OB_ARMATURE) clever_numbuts_armature(); + } + else if(curarea->spacetype==SPACE_NLA){ + clever_numbuts_nla(); + } + else if(curarea->spacetype==SPACE_IPO) { + clever_numbuts_ipo(); + } + else if(curarea->spacetype==SPACE_SEQ) { + clever_numbuts_seq(); + } + else if(curarea->spacetype==SPACE_IMAGE) { + clever_numbuts_sima(); + } + else if(curarea->spacetype==SPACE_BUTS){ + clever_numbuts_buts(); + } + + +} + + +void replace_names_but(void) +{ + Image *ima= G.main->image.first; + short len, tot=0; + char old[64], new[64], temp[80]; + + strcpy(old, "/"); + strcpy(new, "/"); + + add_numbut(0, TEX, "Old:", 0, 63, old, 0); + add_numbut(1, TEX, "New:", 0, 63, new, 0); + + if (do_clever_numbuts("Replace image name", 2, REDRAW) ) { + + len= strlen(old); + + while(ima) { + + if(strncmp(old, ima->name, len)==0) { + + strcpy(temp, new); + strcat(temp, ima->name+len); + BLI_strncpy(ima->name, temp, sizeof(ima->name)); + + if(ima->ibuf) IMB_freeImBuf(ima->ibuf); + ima->ibuf= 0; + ima->ok= 1; + + tot++; + } + + ima= ima->id.next; + } + + notice("Replaced %d names", tot); + } + +} diff --git a/source/blender/src/unix_creator_splash.jpg.c b/source/blender/src/unix_creator_splash.jpg.c new file mode 100644 index 00000000000..f9da6b88ea3 --- /dev/null +++ b/source/blender/src/unix_creator_splash.jpg.c @@ -0,0 +1,939 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#if !defined(WIN32) && !defined(__APPLE__) + +/* DataToC output of file <splash_jpg> */ + +int datatoc_splash_jpg_size= 28762; +char datatoc_splash_jpg[]= { +255,216,255,224, 0, 16, 74, 70, 73, 70, 0, 1, 2, 0, 0,100, 0,100, 0, 0,255,236, 0, 17, 68,117, + 99,107,121, 0, 1, 0, 4, 0, 0, 0, 50, 0, 0,255,238, 0, 14, 65,100,111, 98,101, 0,100,192, 0, 0, 0, 1,255,219, 0, +132, 0, 8, 6, 6, 6, 6, 6, 8, 6, 6, 8, 12, 8, 7, 8, 12, 14, 10, 8, 8, 10, 14, 16, 13, 13, 14, 13, 13, 16, 17, 12, + 14, 13, 13, 14, 12, 17, 15, 18, 19, 20, 19, 18, 15, 24, 24, 26, 26, 24, 24, 35, 34, 34, 34, 35, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 1, 9, 8, 8, 9, 10, 9, 11, 9, 9, 11, 14, 11, 13, 11, 14, 17, 14, 14, 14, 14, 17, 19, 13, 13, 14, 13, 13, 19, 24, + 17, 15, 15, 15, 15, 17, 24, 22, 23, 20, 20, 20, 23, 22, 26, 26, 24, 24, 26, 26, 33, 33, 32, 33, 33, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39,255,192, 0, 17, 8, 1, 15, 1,244, 3, 1, 34, 0, 2, 17, 1, 3, 17, 1,255,196, 0,192, 0, 0, 1, 5, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 2, 4, 5, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 16, 0, 2, 1, 3, 2, 4, 3, 4, 4, 9, 9, 4, 7, 5, 6, 7, 1, 2, + 3, 0, 17, 4, 18, 5, 33, 49, 19, 6, 65, 81, 20, 97,113, 34, 50,129,145,209, 7,161,193,225, 66, 82,146,178, 35, 21,177, 98, +114,130, 51, 67,115, 36, 22,240,210, 99,131,162, 83,195,211, 52, 84, 54,147,163,179,196, 37,241,194,226,132, 69, 23, 68,100,116, +148,164, 53, 38, 17, 0, 2, 1, 3, 2, 4, 3, 6, 4, 6, 3, 1, 0, 0, 0, 0, 0, 1, 2, 17, 3, 4, 33, 18, 49, 65, 81, + 5, 97,113, 19,129,145,161,209, 34, 50,177,193, 66,146,240,225, 82,114, 51, 20, 98,147, 21, 52,255,218, 0, 12, 3, 1, 0, 2, + 17, 3, 17, 0, 63, 0,246, 67, 44,170,177,170,200,202, 58,113,216, 2, 64,249, 22,165, 28,211, 27,222, 70, 63,214, 52, 39,252, +207,240,227,253,133,169, 68, 56, 80, 19,146,105,195, 11, 72,214,183,233, 26,129,201,152, 31,237, 31,245,141, 41, 47,127,162,132, +215,181,205, 8, 27,212, 77,107,137, 27,245,141, 64,207,144, 77,186,174, 63,172,126,218,130,222,215,183, 26,144, 31,150,128, 32, +154,126, 70, 87,253, 99,246,211,117, 38,240,154, 79,214, 52,220, 41,112, 20, 3,153,114, 57,137, 95,245,141, 71,212,100,218,253, + 86,253, 99, 75,141,239,225, 81, 60, 61,212, 0,242, 50,178,148, 40,234,186,220,222,225,141, 9,179, 50,173, 97, 60,151,254,155, +125,181, 12,182, 38, 69, 91,240, 2,227,233, 63,146,129,126, 23,168,202, 28,101,229,158,121, 18,126,187,125,181, 47, 87,149,111, +237,228,253,118,251,104, 11,114, 44, 41,244,249,208, 19, 25,153,135,148,242,126,187,125,181, 33,149,152,120,122,137, 63, 93,190, +218, 26, 0, 13, 45, 66,228,208, 22, 6, 78, 80, 3,247,242,126,187,125,180,155, 47, 36,127,127, 39,235, 31,182,171,150,189,173, + 72,113,226,104, 11, 17,230,207,168,234,157,199,149,216,253,180, 81,149, 59,114,157,173,231,172,253,180, 56, 87,224, 36,128, 69, +207,217, 75,167, 17, 36,232, 28, 57,158, 21, 0, 83,149,144,160, 30,163,145,231,168,253,181, 33,149, 63,140,175,236,248,143,219, + 85, 66, 33, 54, 26,138,155,145,107,216, 91,221, 78,177, 48,184, 12,126,159, 42, 2,192,201,200, 34,253,103,227,225,168,253,180, +189, 70, 79, 31,222,191,235, 31,182,171,105,113, 98,172, 8, 30,202,145, 50, 34,252, 74, 15,184,241,227,244, 80, 7,245, 19,219, +251,103,253, 99,246,208, 95, 39, 33, 44, 76,242,126,187, 31,199, 80, 46,121,233, 35,219, 80, 36, 61,128, 22,183, 62, 21, 64, 83, +153,145,109, 66,119, 2,215, 39, 83,125,181, 89,179,179, 29,137, 19,202, 7,128, 14,223,109, 54, 64, 32,168,252,211, 81, 69,176, + 44,220, 7, 59,249, 10,160, 55,172,203, 69,187,100, 72,124,134,182,226,126,186,143,173,205, 95,155, 34, 66, 79, 19,241,181,135, +225,160, 25, 1, 96, 79, 46, 72, 42, 46, 25,141,193,176,243,160, 12,115, 51, 65,185,202,148, 15, 32,237,246,212,134,118, 91, 11, +174, 68,191,174,223,109, 87, 26, 72,177,248,173, 76, 9,189,128,176,160, 14, 51, 51,175,241,100,200, 63,174,223,109, 55,175,204, + 71, 23,201,148,131,225,173,190,218, 4,128, 14, 36,212,161,143, 89,212,227,133, 1,115,215,229, 30, 2,121, 13,255, 0,158,223, +109, 15,213,103,173,203,100, 75,199,144,234, 55,219, 72, 0, 13,192,166, 97,168,251,168, 8,182,110,127,132,242,254,187,125,180, +227, 43,112, 97,127, 81, 42,255, 0, 93,190,218, 64, 0,220,254,138,137,148, 51,149, 81,192, 80, 5, 89,243, 56, 95, 38, 99,255, + 0, 49,128,254, 90,155,103,100, 71,192,228, 73,127,233,183,219, 84,220,189,248,181,133, 51,105,249,173,115, 64, 89,108,236,203, +124, 51,200,111,252,246,251,106, 7, 63, 48, 45,142, 68,154,189,142,223,109, 7, 81, 43,199,129, 53, 16,128, 27,243, 52, 1,151, + 51, 56,113, 57, 50,253, 50, 55,219, 69,254, 33,150, 5,186,242, 19,230, 93,190,218,173, 74,213, 42, 90, 6,245,217,167,255, 0, +226, 37,253,118,251,105,122,220,223,252,204,191,174,223,109, 6,254, 84,220,104, 11, 30,183, 51,255, 0, 51, 47,235,183,219, 75, +214,230,255, 0,230, 37,253,118,251,104, 43, 27, 55,202,164,219,157,133, 19,211,184,249,172,190,210, 71,226,161, 73,122,204,223, +252,204,191,174,223,109, 63,172,204,255, 0,204, 75,250,237,246,211, 8,163, 28,216,183,157,135,227, 53, 32,138,162,225, 56,255, + 0, 56,210,132,170, 23,172,205,255, 0,204, 75,250,237,246,212,214,125,193,141,132,210,253, 46,195,249, 77, 48, 45,127,132,219, +149,244,139, 84,132,122,188, 73,243,189, 5, 73,137,178,193,179,229,184,243, 1,216,159,229,162, 12,153, 0, 7,175, 59,158,127, + 57, 0,255, 0, 45, 4, 71,241, 21, 35,219,122, 48,138,235,195,151, 35,237,160, 37,235,178, 84,133, 71, 97,115,249,204,205,251, + 70,153,178, 50,216,241,154, 65,238, 98, 7, 15,117, 38,232, 34,252,108,183,191,157, 66, 92,172,100, 85, 0,146, 0,240, 28,232, + 66, 67, 35, 36,139,137,228,229,250, 77,207,235,169,117,179, 47,110,172,150,225,115,169,190,218,164,251,154, 14, 17,197,244,147, + 80,245,243, 30, 54, 22,242,170, 83, 76,190, 85,174, 39,144,127, 92,253,180,199, 42, 72,200,213,146,223, 75,147,248,235, 22, 73, +166,123,106,114,111,237,166,138, 22,119, 3,206,130,134,217,206, 22, 54,201,144,248,177, 5,141,135,226,168, 54,236,170, 56, 77, + 35, 27, 90,247, 35,241,214,119,167, 60,188,124,104,114,194, 69,128, 28,232, 13,143,226, 11,209,234,234,125, 93, 13, 90,238,111, +110,190,142,124,233, 85, 45, 31,229,109,255, 0,242,182,255, 0,252,170, 85, 6,166,131,254,103,248,113,254,194,209, 20, 27, 90, +160,220, 76,127,208,143,246, 22,138, 56, 85, 32, 25, 20,130, 56,248, 84, 13,207,133,237, 68,152,141, 67,221, 67, 13, 66, 14, 9, +229, 76,172,215, 55,229, 78, 8,164,109,202,244, 4,129,164, 77, 55, 0, 56,210,184,160, 28, 48, 96, 64,240,168, 53,185, 83,222, +222, 21, 18, 13,232, 10, 51, 13, 83, 48, 7,217,245, 10, 96,162,244,139, 93,203,121,241,166,185,250,234, 20, 37,192, 53, 2,196, +210, 28,233,207,133, 0,128, 52,136,225, 75, 87,133, 49,185, 52, 2, 98,168, 9, 60, 0, 28,107, 22, 77,246, 93,127,185,141,116, + 14, 90,174, 73,250,136,173,189, 0,131,126, 53,135,159,180, 52,122,167,197, 26,147,155, 71,226, 61,222,202,249,253,201,229, 43, +113,150, 51,105, 70,174,116,251,188, 61,135,187, 1, 99, 57,184,228, 42,185, 81, 70,191,105,181,182,110,184,185, 81,136,207,193, + 48,185,100, 60,111,253, 27, 85,177, 36,102,230,224, 31,111, 10,225, 85,153, 24, 50,146,172, 56,130, 56, 16,107,123, 3,121, 18, + 21,135, 44,128,246,210,178,242, 7,250, 94,218,225,133,221, 35,114,150,242, 26,140,184, 41,112,140,188,250, 51,182,103,109,112, +173,203, 21,148,121,199,156,124,186,163,105, 26,224,105,112, 1, 55, 60,124, 61,148,101,110, 60,207, 42, 8,143, 85,135, 2, 45, +240,154,136, 81, 96,120, 11, 27,112,225,192,251,171,235, 31, 44, 63,194, 79, 3,196,241,166,147,243,124, 8, 60,126,138, 75, 24, +230, 24,170,158, 39,141,237,244, 84, 25, 13,238,206, 79,180,129,227, 64, 73,136, 60,121, 83, 16, 13,200,229, 80, 34, 91,243, 7, +232,169, 47, 1,118,230,121,213, 64, 20,202, 88,173,248,216,218,213, 94, 73, 3,157, 63,152,167,137,243, 52,249, 19,107, 98,171, +200,112,189, 1,152, 11,105, 21, 65, 55,212,126, 81, 76, 56,139, 22,247,211, 6,118, 91, 90,146,196,121,147,245, 80, 13,173, 84, +217, 71,190,157,131, 63,202, 44, 42, 65, 66,241,254, 90,125,106, 77,135, 19, 64, 67,163,113,114,111, 68, 67,111,162,161,169,239, +199,128,166, 96,191, 49,250,168, 3,222,226,152,115,227,194,133,114, 87,128, 32,211,171, 89,120,243,160, 38,206,161,180,142, 36, +243, 52, 50, 72, 54, 31, 8,164, 73, 39,202,144, 70,110, 64,154, 84,180, 25,136,111, 11,211,241,162,172, 12,126,102, 85,247,159, +178,245, 53,134, 33,109, 76,205,127, 5, 22,252, 38,160, 43,210,226,120, 14, 53,100, 34,143,149, 1,183,139, 27,253,130,156, 6, + 60, 20,219,196,128, 45, 65, 80, 2, 41, 15,133,189,252, 63,150,164,176,175,231, 56, 30,238, 38,140, 18,254, 28,111, 98, 77, 16, + 68, 0, 55,225,106,162,160, 82, 56,135,230,179, 31,105,176, 63,142,136, 44,132,104,141, 86,198,230,227, 81, 31, 75, 94,164, 12, + 42, 6,183, 23,246,154,139,102, 98,198, 44, 46,199,194,194,160, 36,194, 70,248,152,146,181, 14,159,144,231,202,245, 19,184, 6, + 0, 36,124, 7,153,170,242,230,206,120, 11, 47,184, 85, 33,116, 66, 72,227,244,210,126,146, 11,187,143,109,205,103,135,154, 65, +114,196,253, 53, 6,141,139, 88,248, 80,180, 47,140,140,116, 6,198,254,225, 80,125,192, 45,130, 71,245,208, 98,135,224,213, 79, + 36, 26,108,222, 28,168, 6,245,147,181,200,178,251,168,114, 75, 59,252,206, 79,211, 83, 8, 17,110,124,120,213,136,162, 89,192, + 85,176,241, 38,161,170,104, 82, 72,216,176,246,213,159, 76,126,190, 53,100,194, 49,238,206, 65,225,194,213, 88,101, 93,249,112, +228, 42,153, 43,152,237,194,220,104,226, 61, 42, 1,171, 3, 77,245,145,241, 30, 32,213, 73,139, 51,149, 28,133, 67, 75, 77, 67, + 8, 58,150, 43,225, 86, 18, 22,128,221,184, 55,128,246, 80,112,216,131,165,188, 42,212,236, 76,108,192, 88,208,141,213,212,174, +243,194,135, 72,107, 31,101, 69,204,110, 0, 13,123,254,117, 85,100, 0, 95,196,212,161, 4, 95,202,140, 71,142,166,135, 75,252, +175,204, 45,233,173,227,255, 0,153,189, 42,157,135,166,211,225,233,255, 0,249,138, 85, 13,233,241, 44,143,154, 59,248, 71, 31, +236, 45, 18,226,153, 22,250, 79,252, 56,255, 0, 97,106,102, 32,124, 43, 71, 34,188,214,212, 61,212, 3, 86, 38,138,237,244, 80, + 76, 70,212, 33, 16,105,245,120,211, 24, 72,241, 53, 33, 23, 14,116, 3, 95,198,244,181,120,211,136, 72,241,164, 81,173,194,128, +107,154,119, 98, 17,136, 60, 64, 36,125, 84,214, 97,225, 66,154,253, 50, 60,237,106, 2,184,224, 41,137, 23,247, 82,211,231, 78, + 5, 66,141,198,168, 79,187,226, 68,250, 6,169, 72,230, 86,214,250,205, 95,149,117,163, 32, 54, 44, 10,131,229,113, 92,203,237, +217,145,177, 83, 17, 54,241, 94, 34,190,127,112,200,201,180,160,177,224,222,234,214, 73,110,167,129,238,193,177,143,117,203,215, +157, 41, 74, 70,187,107,226,105,141,247, 28,127,116,255, 0,130,159,248,238, 63,253, 83,254, 10,201,244, 25,159,245, 15,245, 82, + 56, 57, 96, 18, 97, 96, 7, 18, 72,229, 95, 51,253,254,227,253, 47,254,191,228,125, 15,244,176, 63,169,126,255, 0,230,107,255, + 0, 30,130,223,217, 63,224,166, 27,252, 35,251,167,252, 21,131, 74,185,255, 0,235,101,255, 0, 82,253,168,233,255, 0,153,139, +253, 47,247, 50,230,108,248,153, 7,169, 4, 77, 20,159,157,203, 73,246,251,234,157, 88,199,193,204,202,255, 0,195, 99,201, 40, +243, 69, 36,125, 98,142,251, 46,237, 26,234,124, 41,128,243, 8, 79,242, 87,150,106,237,214,238,250,111, 93, 91,140,105, 31,129, +233,131,181,105, 43,123,214,156, 20,165, 87,241, 11,182,239, 50,225,145, 20,215,146, 14, 67,244,151,221, 93, 20, 89, 80, 76,169, + 36,110, 25, 15, 27,215, 20,202,202, 74,176, 42,195,129, 7,129, 21, 99, 11, 58,124, 25, 53,196,110,167,230,140,252,166,189,184, + 93,206,118,105,110,245,101, 14, 21,253, 81,249,163,199,153,219,161,118,183, 45, 82, 51,227, 79,211, 47,230,118,183,140,252,173, +123,212, 69,175,196,251,135,133, 3, 11, 51, 27,113,139,169, 24,248,199,207, 25,181,212,209,210, 40,155, 87,195,106,253, 12, 39, + 25,197, 78, 13, 74, 47, 84,209,240,167, 9, 66, 78, 19, 78, 45,113, 76,123, 17,196, 26,167, 60,167,140,106,127,164,107, 51,112, +238,222,222,218,183, 70,218,179,231,147, 30,100, 10,218,217, 88,199,103, 26,135, 21,213,248, 69, 88,199,204,195,207, 86,159, 7, + 33, 50, 33, 44, 64,146, 54, 12, 56,120,112,241,174,190,156,210, 82,113,105, 61, 83,166,135, 40,220,132,155,140,100,155, 92, 85, +117, 94,192,129, 84,240, 60,106, 93, 52, 94, 52,246, 35,143, 0, 42, 12, 67, 31, 96,229, 80,216,236,234,163,206,145,102, 43,240, +240,243,160,205, 52, 80, 33,154,119, 88,163, 95,154, 71, 33, 84, 95,135, 51, 85,227,221,118,217, 92, 69, 14,108, 18, 72,230,202, +139, 42, 49, 39,200, 0,111, 85, 38,245, 73,145,180,157, 27, 72,182, 45,201,154,230,151, 16,108,171, 97,226,105,128,241, 28,232, +168,186,172, 88,123,133, 66,144, 96, 26,220, 79,184, 84,214, 57, 72,176, 75,123,255, 0, 45, 29, 85,185, 14, 22,169,232, 60, 9, + 54,160, 43,116, 79,231, 48,254, 90,113, 26, 15,109, 21,204, 75,114, 88, 90,161,215,132,114,187, 80, 8, 40, 6,192,123,168,129, + 9, 31,203, 85,253, 93,219,225, 90,140,153, 51,242, 83,167,221, 64, 92,142, 62, 23,229,195,232,167,253,202,233,212,226,254,250, +206, 38, 86, 6,236, 77, 74, 40, 73, 60,121, 84, 43, 45,190, 86, 50,147,205,143,128, 3,237,168, 28,209,205, 19,143,133,232, 18, + 67, 98, 44, 47,126, 85, 9,230,197,194,136,205,153, 50, 67, 18,124,210, 72,193, 84,120,115, 53,124, 16, 92,219,209, 46,161, 61, + 94, 68,134,192,216,123, 5, 52,166, 98, 46,204, 77, 99,225,247,119,111,207,184,195,182, 98,100, 28,137,230, 37, 85,163, 67,160, + 16, 11, 27,187,105,240, 30, 21,188,206,146, 2, 1,171, 56,202, 52,223, 23, 26,170,235,161,152, 78, 19,174,201, 41, 81,211, 71, + 82,162, 33, 36,212,218, 18, 8,189, 77,237, 24, 26,120,154, 36,110, 28, 93,150,252,107, 38,221, 22,132, 99,137, 85, 56,248,158, + 20,165,140,150,224, 47,194,163, 51,187, 53,129,176, 28,109, 82, 71, 61, 62, 60,239, 70, 34,170,197,113, 18,233, 60,232,202,136, +227, 81, 54,247, 85,102, 82,206, 73,240,163, 70,116, 32,225, 64,223, 34, 18,200,200, 66,175, 33,203,221, 68,138, 70,117,185,240, +225,106,140,202,215,189,185,242,167,141, 25, 69,173,239,163, 44,122,178, 19,130,196, 1,192, 26,150, 61,208,176,246,126, 58, 56, +135,169,236, 35,145, 52, 97, 10, 34,128, 88, 22,183, 26, 34, 73,213,129,158,230, 50, 7, 30, 21, 76, 38,162, 0,173, 5, 88,199, + 6,107,147,194,162, 68, 41,193, 23,159,141, 8, 5,143,230,223,143, 42, 71, 29,205,221, 69,193,242,162,248,240, 94, 60,233,195, +203, 99, 99,111,203, 64,216,209,167, 73, 77,248,177,169,135, 12,182, 32,123,141, 67, 75, 95,226, 54,185,181,233,116,195, 29, 55, +189,207, 58,180, 37, 65, 54, 48, 36,126,241,109,227,115,202,138, 32,141, 80, 1, 42,223,196,241,227, 72,198,131,133,206,190, 76, + 60, 61,149, 49, 2,233, 23, 35,135, 19, 80,181, 15,165,125, 61,186,131,255, 0, 15,107,216,242,235,243,165, 74,195,211,223, 65, +183,167,183,254,255, 0,253,141, 42, 10,151,163, 0, 34, 31, 52,143,246, 22,164,196, 84, 7, 4, 75,255, 0,213,167,236,138,112, + 65, 23,170,100, 12,164,131,244, 80,239,122,124,134,248,199,135, 10, 21,237, 64, 19,133, 56, 32, 80, 67, 3,227, 83,189, 1, 45, + 64,251, 41, 84, 41,193, 2,128,127, 27,145, 85,242,152,104, 10, 60,239,245, 81,153,170,158, 73, 37,213,124, 45, 70, 16, 32, 77, +172, 41, 11,158, 52,227,128,167, 4, 1, 80,163, 91,198,154,215,106,123,155, 85, 44,204,248,176,198,155,235,152,242, 65,225,253, + 42,231,118,236, 45, 65,206,228,148, 98,185,179,118,237,206,228,148, 45,197,201,190, 72,181, 54, 68, 56,177,235,149,172, 60, 7, +137,246, 1, 92,246,110,227, 46, 89, 42, 62, 8,175,193, 7,143,244,170,188,249, 18,228,191, 82, 86,185,240, 30, 0,123, 40, 85, +249,220,222,229, 59,245,133,186,194,223, 78,114,254,239,145,247,176,251,124, 44,210,115,164,231,240,143,151,204, 85,218,236, 61, +169, 18,198,153,155,162,107,145,172,201,142,126, 85, 30, 26,252,207,178,176,251, 95, 9, 51,119,120,132,130,241,194, 12,204, 60, +244,219, 79,253, 34, 43,161,251,192,238, 41,123,107,182,178, 51,113, 72, 25,115, 50,227,226,177,252,215,146,255, 0, 31,245, 85, + 73, 30,218,245,118,108, 8,222,126,172,210,151,213,182, 17,124, 43,206, 76,243,119,108,231,102, 46,220, 91,141, 35,186,109,113, +167, 68, 79,125,239,126,216,237,114, 49,179,114, 71,168, 81,195, 19, 29,117,186,143,231, 42,240, 95,235, 17, 88, 56,255, 0,124, +189,165, 52,154, 37,143, 47, 29,111,253,164,145, 41, 95,167,166,238,223,130,188, 22, 89,100,154, 71,154,103,105, 37,144,150,119, + 98, 75, 51, 30, 36,146,121,147, 80,175,217,199,183,218, 81,164,155,111,170,211,220,143,199, 79,185, 94,114,172, 84, 82,232,245, +247,179,234,126,150,195,221, 88, 67, 43, 26, 72,242,162,126, 17,229, 66, 70,165, 62, 87,230, 8,253, 22,174, 23,119,218,103,218, + 50,140, 18,252, 72,223, 20, 82,142, 76,191,104,241,175, 61,251,191,238,124,174,220,223,241,173, 33,244, 57,146, 36, 25,144,147, +240,149,115,164, 73,111,210, 66,111,127,162,189,239,186,112,151, 47,104,149,237,251,204,127,222,161,247,124,195,245,107,243,253, +239,181, 65, 70, 83,138,250,146,114, 82, 90, 57, 37,198, 50, 63, 65,217,187,164,164,227, 9,125,173,168,202, 60, 84, 91,225, 40, +158,125,135,149, 38, 28,235, 60,103,151,204,190, 12, 60, 65,174,211, 27, 38, 57, 98, 89,149,134,153, 62, 32, 79, 10,225, 43,165, +237,217,217,241,228,128,255, 0,116,193,151,220,223,148, 87,199,236,249, 14, 55, 93,134,254,153,166,215,132,151,205, 31, 87,186, +216, 82,182,175, 37,245, 65,164,252, 98,254, 76,242,175,188,162, 15,117,228, 21, 32,142,148, 60, 71,244, 5,116,191,119,217,152, +152, 61,183, 52,249,115, 36, 17,174, 75,221,228, 96,163,228, 79, 19, 92,215,222, 80,183,117,228, 15,248, 80,254,192,172, 61,171, +107,220,247,201, 6, 14, 16, 46,145,221,219, 83, 90, 56,245, 88, 22, 62,251,123,235,247, 62,156,110, 98, 91,140,165,181, 40,197, +183,224,145,248,133,118, 86,243, 46, 74, 49,223, 39, 41, 36,188, 91, 61, 94, 78,247,237,130,253, 51,184, 15,105, 17,200, 87,235, + 9,106,211,193,220,182,237,205, 11,224,100, 71,144, 23,152, 70, 4,143,120,230, 43,206, 37,251,181,222, 22, 3, 36, 57, 16, 77, + 32, 23,233, 2,202, 79,176, 22, 22,250,235,149, 73, 51,246,124,210, 81,159, 23, 51, 29,136, 54,248, 89, 88,115, 6,184,172, 75, + 23, 19,244,110,182,215, 95,225, 30,135,155,145,105,175, 94,210, 73,244,211,230,122,207,123, 2, 59,103, 63, 87,148,124, 63,230, +165,121,159,106,255, 0,234, 45,186,223,245,195,241,215,107,184,111, 75,191,118, 30, 94, 99, 0,185, 41,211,139, 37, 71, 32,226, + 72,248,129,228,192,222,184,190,212, 23,238, 45,184,127,198, 31,200,107,166, 52, 92,113,239, 70, 90, 52,228,159,237, 57,229, 78, + 51,201,177, 56,186,169, 40, 53,251,143,108,186,170,150,119, 10,170, 46,196,144, 0, 3,204,154,195,204,239,206,220,193,144,198, + 50,122,238, 56, 30,138,151, 3,250,223, 47,225,174, 43,191, 59,134,124,156,233, 54,108,103, 41,137,140,116,206, 1,183, 82, 65, +207, 87,177,121, 91,206,170,246,175,103, 54,255, 0, 19,230,100,204,113,240,209,186,106, 84, 93,221,128,185,211,126, 0, 11,243, +174, 16,196,183, 27,106,237,249, 56,167,170, 75,199,129,222,230,101,201, 93,118,113,226,164,214,141,191, 14, 39,109, 31,222, 54, +197, 51,233, 51, 73, 8, 60, 53, 60,102,223,244,117, 86,238, 54,116, 59,140, 98,124, 60,133,158, 35,249,241,176, 97,127, 35,106, +225,247,127,187,104, 97,197,121,246,172,153, 30,100, 5,132, 19,105, 58,236, 47,101,101, 11, 99,229,194,184,253,135,124,203,216, +115,211, 46, 6, 38, 59,129,145, 13,254, 23, 79, 16, 71,159,145,240,170,177,108,221,131,150, 60,157, 87, 41, 7,151,126,204,212, + 50, 96,169, 47,213, 19,220, 94, 59, 45, 48, 84, 68, 37,200, 0, 2, 73, 60, 0, 2,188,223,239, 15, 62, 71,147,108,155, 26,103, + 88,230,133,228, 82,140, 86,225,138,144,120,123, 43,151,219,155,123,221, 36, 59, 78, 20,178,202,114,136,234, 70, 92,216,132,185, +187,146,120, 40,191, 26,197,188, 39, 59,106,227,154,138,124,106,184, 81,234,110,230,122,133,215,105, 91,114,107,133, 31, 26,173, + 52, 61, 79, 35,189, 59,103, 6, 83, 19,230, 9, 92,112, 61, 21,105, 0,254,178,141, 63,134,173,237,221,205,176,111, 14, 35,194, +204, 83, 49,229, 12,128,198,231,250, 33,192,191,209, 92, 43,125,216,238,171, 14,191, 89, 1,150,223,217,217,237,127, 45, 86,252, + 85,198, 79, 6, 70, 14, 76,152,243, 3, 22, 68, 14, 85,135,138,178,159, 2, 43,172, 49, 49,174, 38,173,220,110, 75,248,224,113, +158,110, 85,166,165,118,210, 81,124,191,157, 79,161, 32,117, 50,105, 97,116, 52, 45,211,113,193,219, 99, 15,145, 60,120,200,222, + 50, 48, 4,251,175,206,185,156, 14,229, 56,253,149, 30,255, 0,148, 58,153, 17,131, 2,131,253,228,193,138, 45,253,224,106, 53, +229,185,185,219,134,245,156,114, 50,157,242, 50,167, 96,170, 57,241, 38,202,136,190, 3,200, 10,227, 99, 10, 83,148,183, 61,177, +131,113,111,171, 93, 14,249, 25,241,132, 97,177,110,148,210,146, 93, 19,234,122,250,119,223,108, 2, 17,179,198,174, 87,233,201, +111,175, 69,171, 47,188,179,112,247, 30,214,202,200,194,157, 50, 35,215, 16,213, 27, 6,183,239, 23,129,183, 42,231,113, 62,236, +183,185,224, 18,228, 79, 6, 51,176,191, 73,139, 51, 15,233,104, 4,126, 26,193,222,118, 61,223,183, 36, 56,217,156, 33,200, 22, + 18, 68,196,197, 40, 83,127,103, 35,198,196, 87,123,120,248,254,164,125, 43,181,148, 90,116,122,214,157, 15, 61,220,172,175, 74, + 74,237,154, 70, 81,106,171, 74, 87,175, 16,221,155,255, 0,169,182,255, 0,233,183,255, 0, 13,171,218, 1, 72,149,230,145,130, + 70,162,236,236,108,160, 15, 50,107,198, 59, 43,255, 0, 84,237,188, 47,241,183, 15,249,109, 90,125,251,220,147,238, 27,140,187, + 78, 59,116,240, 48,219, 67, 34,155,117, 37, 95,153,159,207, 73,224, 5, 92,171, 18,189,145, 24,167, 68,161, 86,252, 42,204,226, +100, 70,198, 52,230,213, 91,157, 18,234,232,142,207, 55,190,123,111, 22, 66,158,168,206,194,247,232,161,113,250,220, 20,253, 6, +161,139,247,131,219, 50, 48, 71,154, 72,117, 31,154, 72,205,133,255, 0,161,170,184,254,209,236, 86,238, 28,118,220, 51, 39, 56, +216, 97,138, 71,160, 2,242, 21,249,136, 45,192, 11,240,173,125,247,238,198, 44, 92, 41,114,246,140,153, 36,146, 21, 46,113,230, + 10, 75,128, 46, 66,178, 5,227,229,194,185,187, 56,113,151,167, 41,203,119, 6,249, 87,220,117, 87,243,167, 31, 86, 48,134,222, + 41,115,107,222,119,216,242,226,238, 17, 46, 86, 20,241,207, 11,114,120,216, 48,191,209, 86, 12, 74, 56,106,225, 94, 19,219, 93, +193,147,219,251,140,121, 40, 75, 99, 49, 11,149, 5,248, 58,120,240,253, 33,224,107,167,251,204,202,149, 55, 44, 9, 49,102,116, +138, 92, 80,234, 81,138,134, 5,218,205,195,217, 88,150, 11, 87,163,111,118,146, 77,169, 83,167, 35,112,238, 9,217,149,205,191, + 84, 90, 78, 53,235,205, 51,211, 50, 50,112,241, 49,218,124,151, 88,161,140, 93,229,114, 20, 1,237, 38,176,240,123,207, 97,221, + 55, 20,219, 48, 93,228,154, 66,221, 54,208, 66, 29, 10, 92,241,107, 30, 75,229, 94, 67,132,155,206,245, 42,109, 56,143, 46, 75, + 76,193,196, 37,201, 91,168, 63, 27,106, 54, 0, 3,204,215,160,246,199,221,254,227,178,110,248,187,166,110, 94, 57, 88, 67,235, +134, 50,204,223, 28,109, 31, 3,164, 14, 5,171, 83,197,179,106, 18,245, 46, 86, 84,110, 41,105,228,102,222,101,235,211,143,167, +110,144,170, 83,111, 95, 61,116, 59,237, 82, 95,135,251, 90,164, 21,207,143,151,225,167, 89, 49,215,135, 82,246,231, 97,122, 94, +163, 29, 15, 5,102,252, 21,225, 62,128,180,147,113,171,226, 30, 20,226, 62, 31, 23, 51, 96, 13, 67,213, 0, 78,152,199,210,105, +122,201,185, 40, 85, 30,234,133, 12, 33, 55, 12, 5,207, 48, 40,166, 2, 5,244,155,145,207,194,169, 28,172,131,253,225, 3,200, +112,160,201, 36,172, 9, 46, 79,211, 66, 26, 38, 38,183,198,202, 7, 1,123,142, 66,163,254, 93, 78,166,148, 27,120, 10,205, 13, +195,143, 62, 20, 80, 56, 80, 23, 12,248,160,113, 37,207,186,132,114,224, 65,240,196, 77,188,205, 86,123, 0,125,148, 34,218,191, + 5, 90,130,240,205, 65,109, 48, 1,239, 98,105,206,107, 19,113, 18, 2,124,120,159,199, 84, 75, 16,120, 11,220, 88, 84,212,240, + 23,231,227, 80, 26,190,166, 79, 79,125, 43,253,134,171, 91,133,253, 70,159, 58, 84, 27,255, 0,150,255, 0,242,223,252,205, 42, + 3, 80,142, 9,253, 4,253,145, 74,145, 63, 39,244, 19,246, 69, 43,213, 33, 95, 35,230, 23,242,160, 17,126, 20,105,219,227, 3, +217, 67, 23,191, 1, 64, 64, 42,169, 62,102,165,164,248, 26,144,181, 53,184,208, 12, 1,177, 6,155, 65, 6,247,231,225, 69, 2, +244,228, 80, 2,227,227, 84,166, 26,165, 98, 57,125,130,175,176,181,103, 23, 5,139,121,241,181, 25, 80,225, 71, 35, 82, 32, 15, + 96, 21, 16,213,129,186,231,201, 36,175,140,135, 76,104,116,181,191, 56,142,119,175, 46, 94, 84, 49,173,239,146,171,110,145, 75, +155, 61, 24,216,211,200,185,178, 58, 37,171,111,146, 44,103,238,225,111, 22, 33,185,228,101,240, 31,209,172, 82, 75, 18,204,110, + 79, 18, 79, 58,106,209,219,246,169, 50,136,150, 91,164, 62, 30,109,238,175,206,206,230, 78,117,228,190,231,202, 43,237,138,254, + 57,159,122, 48,199,195,180,223, 5,206, 79,238,147, 43, 99, 97,203,149,168,160,180,104, 9,103, 60,133,170,189,118, 75, 12,113, +199,209, 69, 10,150,176, 3,219, 92,132,177,152,164,120,219,154, 18,167,232,174,153,216, 43, 26, 22,181,220,229, 93,207,149,116, +162, 71, 60, 60,199,145, 59,186,109, 81,166,213,206,154,213,179,161,236,169, 85, 55, 89, 35, 60,228,133,130,251,193, 86,254, 65, + 82,251,220,219, 39,220, 59, 73,166,129, 75,182, 12,233,146,234, 57,244,192,104,220,253, 26,239, 88, 24,121, 82,224,229, 69,151, + 15,207, 19, 6, 30,223, 48,125,226,189, 63, 7, 59, 19,118,195, 19, 69,103,142, 65,166, 88,154,198,196,143,137, 28, 87,211,236, + 89, 81,140,125, 63,213,110, 91,146,235, 22,124,238,245,138,230,220,191, 77,200,237,111,164,145,242, 93, 42,246,142,229,251,154, +139, 38,119,203,237,188,148,198, 14, 75, 28, 44,139,244,212,159,250,183, 80,196, 15, 97, 7,223, 92,238, 63,220,207,116,201, 40, + 92,137,177, 32,143,198, 78,163, 57,183,177, 85, 43,246, 17,203,177, 40,215,122, 94, 15,137,248,249, 97,100, 70, 91,118, 55,226, +184, 28,111,110,109,147,239, 27,238, 6,221,142,165,154,105,144, 49, 31,154,128,234,119, 63,209, 80, 77,125, 57,190,202,176,236, +249,174,230,192,196,200, 61,238, 52, 15,194,107, 23,179,251, 19,106,237, 8,218, 72, 9,201,207,149,116,205,153, 32, 0,233,231, +162, 53,227,165,106,143,119,111,113,229, 48,219,113, 91, 84,113,182,169,220,114, 44, 57, 40,247,120,215,196,239, 57,246,213,169, + 52,244,218,227, 10,241,148,164,125,222,205,129,113, 77, 39,197,201, 74,116,225, 24,196,229,107,107,183, 89,132,211,128, 9, 5, + 69,192,247,214, 45,116,125,185, 1, 88,101,156,143,237, 24, 42,251,151,242,154,252,167,108,139,150, 93,186,126,154,183,229, 67, +244,221,198, 74, 56,183, 43,206,137,121,212,242,191,188,131,126,234,200, 54, 35,247, 80,243,254,128,174,147,238,209, 97, 27, 70, + 73, 81,121,155, 32,137, 15,142,144,139,167,249, 77,115,159,121, 60,123,175, 35,252, 56,191, 96, 86, 70,197,191,231,246,252,237, + 62, 40, 13, 20,195, 76,176,189,244,190,159,119,136,191, 58,254,132,237, 74,230, 28, 33, 30, 59, 98,252,232,126, 6, 55, 99,107, + 54,115,146,211,116,147,240,175, 51,219,129, 40,223,205, 53,228,255, 0,120,171, 8,238, 50, 98,182,182,130, 51, 53,191, 79,136, +253,144, 43, 70,111,188,201,154, 43, 67,183,170,203,111,153,228, 44,160,255, 0, 68, 42,147,245,215, 25, 52,217,187,190,115, 75, + 38,172,140,188,151,228,162,229,152,240, 10,160,126, 10,231,135,141,114,220,220,238, 45,170,141,113, 58,230,229, 90,187,109, 91, +182,247, 54,211,225,243, 54,246, 98,255, 0,233, 78,226, 31,221,143, 75,111,233,117, 56,213, 62,211,255, 0,212,155,111,248,195, +241,215, 99,151,177, 29,135,176, 51, 96,154,222,170,110,156,217, 54,240, 99, 34, 0,159,213, 31,134,184,222,211,255, 0,212,155, +111,248,195,249, 13,118,140,212,237,228, 74, 60, 27,151,194, 41, 28, 39, 9, 66,230, 52, 37,197, 40,215,219, 54,202,155,206,191, +226,251,135, 83,231,245, 51,106,191,158,182,171,219,102,203,220,249,152,139, 62,215, 20,205,138,197,130,152,229, 10,183, 6,205, +195, 88,173,174,254,237,201,241,115,164,222,113,144,190, 38, 73,213, 57, 2,253, 57, 57, 29, 94,198,231,127, 58,167,218,157,231, + 55,110,163,226, 75, 15,168,195,145,181,233, 7, 75,163, 17, 98, 86,252, 8, 54,229, 90,245, 37, 59, 17,157,149, 25, 58, 45, 31, +197,121,153,118,227, 12,137, 66,251,148, 21, 95,212,190, 15,200, 97,219, 61,244,127,184,201, 63,243,199,253,229, 86, 61,145,221, + 92,206,220,255, 0,175, 31,251,245,209,238,255, 0,121,141, 62, 36,152,251, 78, 51,193, 44,160,169,200,149,133,208, 30, 23, 69, + 75,241,242, 55,171, 61,139,221, 59,238,229,146,187,110, 84, 39, 54, 5, 31, 30,105, 58, 90, 33,224,100,110, 77,252,181,203,212, +202,141,183,113,194,220,105,197,112,116,247,157,125, 44, 73, 92, 86,213,203,146,175, 6,181, 85,247, 24, 29,225,141,147,135,183, +236, 24,249,138, 83, 34, 60, 86, 73, 16,144, 72, 42,202, 0,225,127, 10,212,251,172,137, 27, 43,114,148,139,186,199, 26,169,242, + 12, 88,159,217, 21, 47,189, 96,163, 47,109,177,191,238,164,253,165,169,125,213, 50, 44,187,161,111,209,134,223, 92,149,153, 74, +184, 46, 92, 43,175,190,102,163, 20,187,130,143, 26,105,175,132, 15, 72, 28,173,107,215,137,247,202,132,238,157,192, 1,111,137, + 9,247,152,210,245,237,162,120,193,176, 91,249,215,138,119,209, 13,221, 89,228, 11, 11,199,195,254, 82, 87, 14,221,254,105,127, + 99,252, 81,232,238,127,225,143,247,175,193,135,204, 50,255, 0,160,118,208, 9,233, 28,233,110, 60, 47,165,173,248,232,125,131, + 20, 18,247, 78, 18,207,107, 14,163, 71,127,211, 17,177, 90,233,118, 45,168,239,189,130,118,208, 66,201,214,146, 88, 24,248, 72, +173,194,231,200,242,175, 62, 43,157,180,103, 13, 65,241,115,113, 92, 48,191, 6, 86, 83,112,107,217, 6,167, 27,246,147,164,183, + 77,126,238,103,134,226,118,229, 98,243, 85,142,216, 63,219,200,250, 47,162,223,163,107,120,154,228, 62,242, 98,135,253, 48,237, + 54,158,170,205, 17,135,136,190,162,108,109,253, 91,215, 51,141,247,161,148,176,133,204,193, 19, 74, 7,246,137, 33, 64, 79,153, + 82,175,252,181,206,119, 15,115,110, 29,198,234,103, 81, 22, 52, 63, 20,112, 71,114, 1, 60, 53, 49, 60,207,133,121, 44, 97,222, +141,216,202, 75,106,139,173,107,198,135,179, 35, 54,196,172,202, 48,110, 78, 74,148,167, 10,245, 39,217, 36, 14,233,219, 75, 27, + 13,109,115,255, 0, 45,235, 31, 63, 87,174,201,215,243,245,100,213,126,119,212,111, 90,189,157,255, 0,169,118,255, 0,233,183, +236, 53,105,247,207,110,228, 96,231,203,186,193, 25,108, 44,182,214,229, 71,246,114, 55,204, 27,216,199,136, 53,238,119, 35, 28, +157,175, 77,208, 84,243, 77,232,120, 21,185, 75, 23,122,213, 66,227,175,147, 75, 83, 55,110,217,187,171, 43, 14, 57,246,212,156, +226, 61,250,102, 57, 66,175, 2, 65,178,235, 30, 34,173,127,167,251,220,220,116,242, 79,159,239,199,253,229, 75,182, 59,206,109, +134, 19,133, 60, 71, 35, 16,177,100, 10,108,232, 79,205,166,252, 8, 62, 85,163,188,125,226,190, 78, 43,227,109, 80, 62, 59, 74, + 10,182, 67,176,212,160,254,128, 95, 31,109,235,156,229,147,234, 56,198,220, 28,107,164,159, 79, 29, 78,176,142, 47,164,165, 43, +183, 20,146,214, 43,175,134,134, 31,250, 47,185,207,255, 0,167,191,235,199,254,253, 93,239,100,202,137, 54, 56, 51, 65, 92,136, +118,248,227,145, 73,185, 5, 9, 91, 92, 95,202,186, 30,200,238,109,251,116,155,208,228,192,114,225,140,124,121,163,225,100,242, + 14,121, 53,254,186,202,251,205,212,119, 76, 34,194,223,229,205,191, 93,171, 49,187,117,228,198,221,197, 31,165, 55,244,249, 26, +149,171, 75, 22, 87,109, 57,253, 77, 38,165,224,203,191,117,184,241,150,220,114,200,253,234,136,226, 86,242, 86,212,205,245,149, + 21,232, 78,108,121,251,171,130,251,172, 70,120, 55, 61, 54,224,241, 94,254,231,175, 65, 56,199,243,156,125, 2,188, 57,191,253, + 19,246,126, 7,191, 6,139, 26, 30,223,197,130, 78, 28,124,205, 26,215,168, 34,120, 14, 53, 97, 99, 38,188,199,168, 22,154, 68, + 90,140,176,233, 26,126,154,118,138,224,128,104, 64, 58, 65, 91,138,131,139, 3, 86, 85, 2,173,175,202,129, 38,146, 56, 30, 38, +247,161, 65, 44, 50,177, 4, 33,250,104,139, 20,173,228, 62,154, 34, 72, 20, 1,227,192, 1,239,166, 87, 9,241, 17,194,252,104, + 4, 49, 93,175,119, 3,232,164, 49, 71,139,159,160, 85,152,110, 80, 19,192,154,150,154, 16,173,233, 80,115,103,255, 0,111,162, +159,211, 69,230,231,233,171, 36, 83, 90,128, 39, 66, 63, 77,107, 31,252, 61,175,126, 54,245, 26,169, 81,173,254, 95,217,209,255, + 0,182,165, 84, 6, 98,192,160,183,230, 39,236,138,125, 71,202,164,127, 52,255, 0, 49, 63,100, 84,117, 80, 21,231,249,193,177, +229, 66, 50, 91,192,213,137, 79, 27,143, 42, 13,181, 30, 52, 4,117, 27,114,250,169,150, 66, 79, 17,106, 48, 22,247, 82,160, 35, +170,194,159, 80, 62, 52,228, 14, 70,163,164, 2,111, 64, 66, 70,178,146,166,246, 4,253, 85, 72, 10,181, 56, 2, 38, 35,129,224, + 7,215, 85,116,155,115,168,202,132,109, 88,121,219, 84,239, 59,203, 5,157,100, 58,136,189,136, 39,159, 58,218, 35,198,151, 32, + 43,207,147,139,111, 34, 10, 23, 43,163,170,107, 70,142,248,249, 55, 44, 73,202,221, 53, 84,105,234,140,156, 45,160, 35,117, 50, +172,196,114,140,113, 31,214,173,158, 32,112, 22,183, 42, 96, 56,209,121, 10,184,248,214,172, 71,101,168,211,171,124, 95,155, 37, +252,139,151,165,186,227,175, 69,201,121, 32, 68,177,172, 77,227, 12,134,245, 72, 46, 15, 9, 63, 17,173,202,137, 10,192,134, 23, + 7,129, 6,166, 86, 60,114, 45, 74,220,180,230,159, 73,114,101,198,191, 43, 23, 85,200,235,201,174,171,161,199, 85,172, 29,195, + 47,110,155,173,137, 41,141,185, 48,230,172, 60,152, 30, 6,172,231,109, 79, 17, 50,227, 13,113,243, 41,226,191,104,172,202,252, +189,219, 55,177,174, 82, 73,194, 75,132,151,227, 22,126,142,221,219, 89, 22,235, 26, 74, 47,138,127,131, 71,101,139,223, 35, 72, + 25,184,167, 87,139,196,120, 31,234,183,219, 86, 31,190, 48, 0,253,222, 52,204,222, 77,165, 71,215,118,174, 22,149,122, 35,221, +115, 18,166,244,252, 92, 85, 78, 15,182,226,183, 93,141,120, 38,232,110,238,125,213,184,231,169,134, 59, 99, 66,220, 25, 99, 55, + 98, 60,139,253,149,133, 74,143,141,135, 62, 91,232,133,110, 60, 92,240, 81,239, 53,230,157,203,249, 23, 22,231, 43,146,122, 37, +199,220,143, 68, 97,102,196, 30,213, 27,113, 90,183,243,100,113,177,228,202,153, 96,136, 93,152,243,240, 3,196,154,236, 97,137, +177,160, 72, 34,182,148, 22, 30,103,204,208,176, 54,248,182,248,236,191, 20,140, 62, 57, 15, 51,236, 30,202,178, 79, 59,120,215, +232, 59,118, 23,250,240,114,159,249, 39,199,254, 43,167,204,248, 89,249,158,188,148, 97,246, 67,135,252,159, 83, 3,119,237,189, +159,114,202,245,121,216, 41, 38, 67,128, 26, 66,207,114, 20, 0, 57, 17, 85,135,107,108,103, 12,224, 54, 26,122,109, 70, 64,156, +120, 57, 0, 22, 86, 39, 80,224, 60, 13,110,228,187, 7, 85, 2,246, 20, 3,241, 14,126,251, 87,213, 87, 46, 81, 45,242,162,225, +171,208,249,222,149,186,183,178, 53,124,116, 90,156,179,125,222,246,216,125, 90, 38, 11,250, 34, 67,111,182,182,118,173,139,102, +218, 62, 45,191, 21, 98,114, 44,101, 55,103, 35,250,111,115, 87,199,149,184,121,154, 99,240,158,100,251, 5, 89, 94,187, 37, 73, + 78, 77,116,108,145,177,106, 46,177,183, 20,250,164, 67, 51, 19, 19,113,199,124, 60,180, 19, 65, 37,181,198,110, 1,177, 12, 57, + 88,243, 21,159,139,218,189,191,135,147, 30, 86, 46, 10, 71, 52, 71, 84,110, 25,201, 7,207,139, 86,153,186,157, 67,135,157, 16, + 27,241,243,172,169,205, 42, 41, 52,159, 20,158,134,157,184, 73,169, 74, 41,181,193,181, 86, 59, 42,178,149,112, 25, 72,177, 83, +196, 16,107,155,204,236,174,219,204,145,156,226,116, 88,243, 48,179, 32,253, 80,116,254, 10,233, 41,116, 46,111,126,124,105, 27, +147,134,176,147,143,147,160,157,184, 79, 73,197, 75,205, 84,229, 35,236, 30,219,133,131, 52, 50, 75,111, 9, 36,107,127,209,211, + 93, 14, 22, 54, 46, 12, 35, 31, 14, 36,130, 37,228,136, 2,143,193, 87, 6, 58,158,102,156,197, 26,142, 34,147,187,114,127,124, +165, 47, 54,102, 22,173,195,236,132, 99,228,140,189,199,101,218,119,102,141,247, 28,101,157,162, 4, 70, 88,176,176, 60,254, 82, + 41,182,253,155,107,218,122,135,109,198, 88, 12,182, 18, 21, 44,111,166,246,249,137,243,168,111,251,254, 23,110,225,250,156,132, + 50,203, 33, 43, 4, 10,108, 93,135, 62, 62, 0,120,154,226,225,238,238,243,222,157,206,207,134,189, 53, 60,122, 49,107, 11,236, +103,144,145,122,155,231,183,110,231,183,165,116,247, 26,244,225,187,126,216,238,235, 77,125,231,162,160, 36,214,118,103,107,236, + 59,134, 75,229,230, 97, 44,185, 18,216,188,132,184, 39, 72, 10, 57, 48, 28,133,113,113,119,215,112,237, 25,131, 31,126,194, 86, +228, 93, 10, 24,164,183, 45, 74,126, 83,245, 87, 77,220,189,210,216, 61,191,135,188,236,173, 28,131, 42,100, 64,100, 82,195, 67, + 36,140, 69,129, 22, 96,201, 99, 72,202, 81,117,139,113,126, 14,130, 81,140,149, 37, 21, 37,226,170,109,225,109,216,123, 94, 58, +226,224,194, 33,128, 18, 68, 96,147,197,185,159,136,154, 14,235,177,237, 91,178,129,184, 98,164,197, 69,149,248,135, 3,216,203, + 99, 92, 64,251,201,207,109,177, 17, 32,142, 93,214, 73, 24, 92, 35, 8,210, 48, 6,159,134,228,179, 30, 62, 53,167,218,189,203, +187,231, 54,224,119,214, 17,199,143, 26,200, 11, 71,210,210,191, 22,163,200,112,248,105,186, 73,238, 77,215,173,117,247,141,145, +113,218,226,182,244,166,158,226,192,251,185,237,211,251,194, 37,183,232,117, 13,190,218,216,131,180,118, 8,176,223, 5, 49, 23, +211,203, 99, 42,241,187,105, 55, 93, 79,125, 70,199,219, 92,118, 79,126,238,251,142, 96,193,237,204, 48,192,155, 70, 93, 75,200, +224,126,118,144, 66,168,247,212,178, 55,207,188, 77,142, 47, 89,184,226,163, 99, 11,106, 44,145,186,129,203,226, 56,237,117,231, +227, 91,119,174,202,149,156,157, 60, 76, 43, 22, 99, 93,182,226,171,167, 4,118, 24,157,161,219,216, 57, 9,149,139,132,177,207, + 17,186, 62,167,184, 36, 91,197,188,171, 93,177,160,145, 74, 60,106,200,194,204,172, 46, 8, 62, 96,214, 55,106,247, 86, 47,114, +227,189,147,161,153, 13,186,240, 94,226,199,147,161,241, 95,228,172, 30,233,239,220,157,191,113,125,159,101,129,101,200,140,136, +228,154, 64, 91,247,135,243, 35, 69, 34,228, 94,220,124,124, 43, 18,148,164,235, 41, 54,252, 93, 77, 70, 17,138,164, 98,162,159, + 36,168,107,229,246, 7,108,101,185,127, 71,208, 99,204,192,236,131,245,110, 87,240, 80,224,251,186,237,120, 92, 57,199,146,107, +120, 73, 35, 17,245, 46,154,202, 51,125,233,170, 28,142,140, 68, 1,171,162, 4, 26,173,229,109, 87,252, 55,163,118,143,126,228, +238,251,130,237, 27,172, 9, 30, 68,129,132, 51, 71,117, 5,144, 22, 40,232,196,216,144, 15, 27,251, 45, 93, 61,123,212,167,169, + 42,121,179, 31,235,217,173,125, 56, 87,201, 26,187,198,251,179,246,124, 56,184,173,138,233, 12,193,250, 49,226,162,105, 26, 52, +234,213,169,147,244,170, 16, 98,108, 29,221,137,139,186,228, 97, 25, 67,171, 36, 38,107,171, 42,164,140,172, 8,141,237,204, 26, +243,206,241,207,238, 28,233,113,198,251,137,233,150, 38,148, 98,158,155, 71,172, 18,154,190, 98,111,107, 45,109,246, 86,231,221, + 40,155,110, 22, 62, 22,189,156,200, 85,178,122, 76,126, 6,145,140,135, 93,237,193,137,240,174,106, 82, 79,114,147, 79,170,122, +157, 28, 98,227,181,197, 53,209,173, 15, 65,218,246, 77,175,103, 89, 23,109,198, 92,113, 49, 6, 64,165,141,202,222,223, 49, 62, +117,160, 86,245,195,119, 87,222, 18,237, 25, 79,182,237, 80,172,249, 81,124, 51,205, 37,250,104,223,160, 21,108, 88,143, 30, 60, + 43, 32,119, 15,222, 75,197,235, 87, 13,250, 22,213,164, 99, 14, 94,122, 79,199,106, 54,219,172,155,109,243, 98, 49, 81, 84,138, + 73, 46, 75, 67,209, 24,178, 18, 7, 11,240, 52, 95, 80,162,184,126,218,251,196,143,112,204,143,111,223, 49, 99,134,105, 88, 36, +121, 81,130, 20,185,224, 22, 68, 98,116,223,206,244,253,225,222, 91,175,110,110,177,225,237,241,227,152,164,129,102, 61, 88,203, + 29, 69,228, 78, 4, 48,225,100, 21, 10,118,199, 36,147,193, 73,247, 80,245,229, 57,248, 85,173,229,106,243,253,195,239, 43,120, +201, 49,227,236, 24,234, 93, 99, 67,145, 56,136,187, 25, 10,141,122, 19,146,168,107,243,189,118,221,161,187,238, 59,166,199, 6, + 94,230,223,230,153,228, 89, 62, 29, 31, 35,149, 23, 81,107, 80, 22,140, 25,175,199, 67, 83,166, 30, 69,238,203, 96, 57,220,214, +145,118, 62, 60, 40, 76, 73,241,168, 42, 9, 98, 23,189,174, 64,231, 81,133, 67, 2, 8,241,171, 3,130,159,170,131,143,192,146, + 60, 13, 0,117, 26, 69, 61,169, 15, 58,112,124, 13, 80, 70,220,105,237, 72,248, 82, 30,202, 2,207,247, 31,242,127,237,169, 82, +254,230,255, 0,240,127,237,169, 80, 7, 99,193,109,250, 9,251, 34,160,215,224,109, 78, 75, 89, 47,207, 66, 95,245, 69, 49,227, +225, 64, 6, 91,223,151, 27, 83, 1,244,121,211,202, 78,176, 60,133, 13, 89,174,111,202,128, 37,239,225, 72,240,240,168,131,231, + 78, 79, 10, 1,115,226,105,137,189, 32,199, 81, 4, 88, 83, 49,183, 42, 2,182, 75,130,170, 61,183, 31, 69, 8,176, 2,165,148, +110,234,190, 0, 94,254,255, 0,254,202, 15,182,163, 40,137,184,165,199,202,157, 71, 11,211,248, 80, 12, 27,141, 72,177, 60, 5, + 12, 30,102,164, 8, 2,128, 64, 94,156, 40,164,164, 83,223,141, 0,232,128,184, 30, 23,226, 15,149, 71, 39,107,194,200,248,158, + 32, 63,156,188, 15,224,162, 70, 70,176, 73,181,184,209, 67, 45,185,254, 74,196,225, 9,173,179,138,146,232,213, 77, 66,115,131, +221, 9, 56,190,169,208,195,151,183,225,215,166, 41,153,111,224,202, 27,240,252, 52,227,182,150,246,245, 71,245, 63,252, 85,180, +192,107, 94, 63, 64,162,106,191,202,120,138,242, 62,219,134,221,125, 37,236,148,151,230,122, 87,112,203, 74,158,171,247, 69,254, + 70,108, 29,189,131, 29,139,234,149,191,156,108, 62,161, 87, 4, 9, 24, 9, 31,194,163,192, 90,194,172,107,241,231, 80, 33,124, +121,215,162,213,139, 86,149, 45,194, 49,242, 90,251,206, 23, 47, 93,184,235,114,110, 94,111, 79,112, 62,155, 51,104, 46,108, 7, +178,145,137,199,231,146, 61,194,166,135,226, 53, 49, 96,124,197,117, 57,153,185, 28, 37, 40,198,246,183, 31,162,244, 11,233, 60, + 57,120,154, 54, 75,106,153,216,114,189,184,251, 56, 80, 65,191, 42,208, 28,216,241,231,236,167, 6,226,199,129,168, 19, 99, 79, +239,160, 23, 1,195,159,153, 52, 65,206,212, 16, 65, 54, 30, 52,117, 28,111, 70, 7, 85,185, 21, 98,212, 52, 28, 69, 26,161, 4, + 5, 66, 69,184,181, 76, 83, 61,172,106,131,202,254,243,132,163, 55, 0,159,236,140, 79,163,250, 90,190, 47,193,166,187, 62,198, + 56,199,182, 48,125, 53,184, 6, 19, 91,159, 83, 81,215,171,219,248,170,206,253,219,184,157,197,130, 49,114, 73,142, 68, 58,224, +157, 64, 44,141,238, 60,193,241, 21,195,199,216,157,225,180,202,199,105,207, 69, 70,230,208,204,241, 19,253, 53, 34,223,132,208, + 29,103,116,207,218,152,205,142,123,133, 22, 73, 92, 63,167, 82,133,200, 3, 78,175,148, 27, 10,230,251,201,182,105,123, 55, 6, +125,142, 51, 30, 19,102,142,152,179, 40,224,147,134,178,183,243,129,161, 67,247,117,190,110, 25, 35, 39,126,207, 91, 18, 3,176, +118,154, 98, 47,200, 23, 1, 71,214,125,213,211,247, 63,106,201,185,236, 56,155, 46,208, 98,129,113,101, 71, 81, 49, 96,186, 18, + 57, 19,154, 43,146,196,189,232, 12,159,186,204, 12, 51,182,229,238, 50, 68,175,146,103, 48, 7, 97,114,168,168,143,101,242,185, +126, 53,191,222,234,195,181,183, 31, 78,128, 62,132,189,135,230,245, 19, 95,253, 27,212,123, 47, 97,204,237,221,174,108, 44,215, +138, 73,100,200,105,149,161, 44,203,165,146, 52,177,214,168,111,116,173,233,162,143, 34, 39,130,101, 15, 20,170, 82, 68,110, 32, +171, 11, 16,125,244, 7,137,246,148,125,193, 38, 84,235,219,211, 71, 14, 70,133,234,117, 4,100,148,191,230,245, 21,248, 95,157, +171,173,200,193,251,204,155, 30, 88,178,115,113,206, 59,163, 44,193,198, 56, 82,132, 89,174,122, 94, 84, 28,223,187,157,199, 7, + 52,102,118,230,112,139,226, 45, 18, 72,204,142,159,205, 18, 32,109, 67,223,106,108,142,216,251,193,221,163,244,123,142,225, 31, +166, 54,214,173, 37,148,129,250, 75, 18,124, 95, 77, 10, 63,100,246,214,233,179,239,139,149, 52,184,239, 11, 68,241,202,176,204, +174,214, 32, 17,240,175,243,128,170,121,157,239,189,110,251,184,193,237,248,161,131,169, 46,140,105, 12,104,210, 55, 30, 14,205, + 32, 42, 60,249,112,174,215,181,187, 75, 15,182, 99,118, 87, 57, 25,179, 0,179,100, 17, 97,164,113,208,131,141,135,159,157,114, +123,159,221,198,235,143,184,156,238,223,201, 64,130, 78,172, 40,204, 99,146, 35,125, 64, 41, 0,130, 7,135, 42, 16,211, 93,143, +239, 19, 32, 19,149,190,195, 10,158, 45,211,224,195,207,228,138, 49,245, 26,226,187, 57, 66,119,142, 10, 43,245, 85,102,144, 9, + 7, 38, 1, 31,226,250,107,177,255, 0, 78,247,238,235, 31,166,222, 55,132,131, 16,252, 50, 44, 90,117,178,248,143,221, 36,119, +250, 90,129,178,253,223,110,219, 62,255, 0,143,185, 44,248,242, 98, 99,202,197, 84,187,245, 76,100, 50,139,142,144, 93, 90, 79, +157,175, 64, 67,239,107,255, 0,209,255, 0,252,207,253,141,116,127,119,255, 0,250, 79,111,255, 0,157,255, 0,199,146,131,222, +253,181, 55,113,227, 99,156, 89, 18, 60,140, 70,114,130, 75,133, 97, 32, 26,150,234, 13,143,192, 43, 7,183,251, 95,189,118,220, +156, 53,245, 98, 45,186, 41,227,146,108,117,157,180,152,245,134,145, 66, 1,111,136, 95,133, 1,201,237,134, 37,239, 8, 78,231, +109, 35, 56,245,245,242,215,212, 63, 54,175, 13, 92,239, 94,239,106,226, 59,163,238,254, 29,235, 37,247, 29,186,101,197,203,147, +140,209,184, 38, 55,111,210,186,220,169, 62, 60, 13, 97,175,105,125,224,164, 94,137, 55, 34, 49,128,210, 20,101, 72, 19, 79,144, +225,123,123, 40, 14,119,188,122, 45,221,123,135,160,226, 12,203,167,167,255, 0, 91,165,122,150,183,143, 82,245,167,247,151,171, +248,238, 54,187,107,244,105,170,220,175,213,150,245,211,118,215,221,194,109,121,113,238, 27,188,233,147, 60, 39, 92, 80,196, 15, + 77, 92,113, 14,204,192, 22,183,135, 1, 77,221,221,151,186,247, 38,231, 30,118, 12,216,241,197, 28, 34, 18, 38,103, 86,212,175, + 35,220,104,141,197,172,254,116, 7, 71,218, 24, 56,216, 29,185,183, 12,116, 8,103,199,142,121,152, 14, 44,242,168,144,150, 62, + 60,237, 91,158, 53, 83,104,196,147, 7,107,193,193,152,171, 73,139,143, 20, 50, 20,185, 82,209,162,161,211,112, 13,174, 60,170, +223, 1, 64, 34,106, 52,244,136,242,160, 23,133,168,112, 14, 13,239, 52, 91,112,161, 64, 46, 27,222,104, 3, 45,199,141, 63,133, + 66,245, 32,124, 40, 5,237,167,191, 11, 83, 91,143,182,149,135, 42, 2,213,191,113,255, 0, 39,254,218,149, 53,191,113,111,248, + 63,246,212,168, 3, 57,249,127,160,159,178, 41,129,252, 52,158,255, 0, 15,244, 19,246, 69, 66,255, 0, 93, 1, 9,109,168,123, +184,154,129, 3,207,157, 52,199,227, 30,234,134,174, 55,160, 9,123, 10, 90,133,114, 57,127,121, 29,147,131,151, 62, 30, 94,241, + 28, 89, 56,210, 60, 51,198, 82, 82, 86, 72,201, 71, 94, 8, 71, 2, 41,247,175,188, 30,218,217, 54,140,125,246, 76,131,153,131, +149, 33,139, 30, 76, 48, 37,212,224, 18, 87,230, 80, 8,177,230,104, 14,178,230,154,215,230,106,166, 14,100,123,134, 22, 54,124, + 33,150, 44,168,146,116, 87, 0, 48, 89, 20, 58,134,177, 34,246, 62,117,102,246,160, 41, 79,115, 51, 1,198,214, 3,234,168, 89, +185, 84,201, 13, 33,111, 2,111, 89, 93,193,220, 59,119,108,237,175,187,110,101,198, 50, 50,161,233, 46,182,212,223, 40, 2,226, +161, 77, 64,167,149, 62,159, 10,169,180,110,152,251,198,219,139,186,227, 43,164, 25,113,172,209, 44,128, 7, 10,194,227, 80, 82, +194,255, 0, 77, 91,213, 64, 69, 82,252, 41,244, 11,211,171, 0, 77, 87,200,220,182,252, 39, 84,204,203,135, 29,228, 35,166,179, + 72,168, 90,255, 0,162, 24,139,208, 22,130,129,106,123, 0, 41,181,131, 98, 56,131,196, 26,173,151,185,237,248,110,145,229,229, + 67,142,207,242, 44,178, 42, 22,191, 15,132, 49, 23,160, 46, 34,130,192, 31, 11,154,150,149,253, 17,245, 80, 61, 86, 52, 8,102, +200,149, 34,140, 91,247,142,193, 87,143, 46, 45,194,148, 59,150,221,146,230, 60,124,184,101,107, 95, 76,114, 43, 27, 14,102,192, +212, 5,160,145,159,204, 4,210, 17, 39,151, 58, 98,227, 69,213,197, 50,200,190, 7,143,141, 0,229, 19, 87,209,202,145,141, 56, + 91,249, 77, 46,160, 26,189,166,164, 25, 73,247,113, 6,128,128,140, 92,243, 31, 77, 51, 71,252,230,250,205, 76,145,196,130, 5, + 69,136,177, 36,248,114,240,160, 51, 24,252,108,109,192,146,110,106, 36,129,198,247,246, 84,250,100,143,140,210,248, 23,144,227, + 90, 4,126, 34, 62, 17,111,109, 56, 65,249,198,244,236,237,238, 21, 6, 32,241,230,104, 9, 13, 33,130,168,231, 86, 20, 85,104, +238, 88, 19,225, 86, 65,168,192, 69,240,169,138,130,243,169,213, 32,168,114,181,172, 60,232,134,162,224, 90,244, 3,175, 5, 21, + 32,120,212, 11, 1, 96, 77, 61,252,111, 64, 41, 60, 7,155, 10, 32,160,187,128,203,115,227,115, 79,215, 79, 14, 52, 1, 9,240, +165, 81, 46, 45,198,162,210,162,159, 31,174,165, 69, 9, 55,206,131,223, 83,170,230, 97,168, 17,225,127,195, 69, 15, 74,138, 4, +231, 78, 5, 4,202,160, 94,194,134,217, 32, 14, 85, 69, 11,118, 54,229, 81, 38,220,248, 80, 35,201, 46,214,181,135,157, 16,189, +133,234, 54,139, 70, 14, 72,248,179,223,221, 70, 75, 5, 81,127, 10, 4,211,128, 52,142, 55,231, 80,245, 76, 0, 22,229, 68, 11, +124, 5, 32, 69,255, 0, 37, 6, 25, 89,248,158, 84, 91,240,184,231, 81,201, 33,181,147, 38,135, 13,180,146, 13,248,154,132,147, +133, 22,241, 52, 37,152,168,178,213, 78,164,161,112, 94,252,143,224,167, 98, 9,170,177,100, 22, 32, 53, 28, 27,213, 4,214,222, +127,130,152,243,225, 72, 82, 52, 3,248, 80,160, 97,102,225,110, 52,111, 11,208,113,248,134, 30,218, 0,162,244,246,243,165,200, +210, 54, 2,230,132, 28,138, 64,208,250,171,107, 95,149, 46,170,208,165,219,254,227,151,247, 63,246,212,170, 29, 81,208,191,252, + 27,255, 0,239,173, 74,128,103,150, 75, 39, 31,238,227, 39,128,241, 69,168,117, 31,206,147,143,236,255, 0,195,143,246, 22,161, + 66,130,200,146, 77, 96, 6,225,111, 33, 66, 18,201, 99,198,231,218, 41,100,147,172,123,191, 25,160,113,170, 15,154,179,114, 38, +139,187, 59,216, 69,181, 13,212,207,252, 78, 39,186,234,244,170,217, 55, 57,128,105,110, 49, 91,129,225,107,243,166,205,151,111, +255, 0,246,199, 7, 27, 14,119,150,101,221,158, 92,196,145,116,152,228,124,114,161, 83,139, 93, 52,160,177,243,189,118,217, 63, +118,189,237, 30,251,190,238,155, 70,225,129,143, 22,242,249, 81,190,182,144,201,233,178,165,234,148, 35,160,193, 90,192,114, 62, +227, 79,147,247, 57,184,167,108, 69,180,224,102,227,201,184, 62, 88,203,203,154, 98,241,197,165, 99,104,214, 56,244, 36,140,109, +170,247, 32, 84, 0,123,151,190,247, 92, 7,237,222,219,195,221, 63,130, 97, 13,187, 22, 92,221,197, 98, 51, 56, 47, 23,194, 52, +168,102,210, 52,143,151,206,177,223,239, 71,188,102,236,245,145,119, 3, 30,118, 62,106,227,201,148,177,197,174, 72,100,137,164, + 64,196,161,179, 43, 70,120,139, 19, 93,143,113,125,220,111, 89, 51,236,219,206,195,151, 4, 59,198,217,139, 6, 52,201, 53,204, + 78, 96, 93, 58,208,148,107,243, 43,102, 91, 17, 66,223,187, 19,189,123,155, 96,143, 15,114,201,219,151, 61, 51, 6, 64, 17, 6, +138, 20,132, 68, 99,209,120,225, 36,190,182, 39,136,250,104, 12,110,222,239, 14,238,194,239, 92, 13,183,126,220, 70, 86, 30, 78, + 42, 75, 44, 72,163, 64,141,241,125, 82, 48,248, 85,181,173,133,207,143, 26,230,187,139,185,187,171,187,182, 77,195,118,203,202, + 72,182, 88,179, 34,130, 61,185, 85, 69,153,195,200,159, 16, 93, 71, 64, 94, 36,158, 55,175, 66,143,238,223,120,255, 0, 87,237, +219,228,243, 98,182, 6, 54, 44, 24,185, 17, 7,147,170,221, 60, 95, 74,250, 7, 75, 77,175,202,237,202,185,255, 0,255, 0,104, +123,194, 60, 28,237,155, 27,114,195, 27,108,185, 9,145, 18, 72, 94,242, 52,122,145, 25,200,137,138, 29, 15,196, 11,241,250,232, + 10,217,189,235,184,224, 97,118,191,110, 98,110,159,193, 48,191,135, 99,205,155,184,172, 70,103, 5,212,149, 26, 20, 51,105, 26, + 71,203,231,236,170,173,247,153,221,146,246,112,149,115,204,121,208,102,174, 60,153, 75, 28, 90,164,134, 72,157,212, 53,208,217, +149,163, 63, 16,177,174,175,116,251,178,223, 66,108, 59,158,201,153,143, 14,245,180,226,195,139, 58,201,168,195, 33,132, 27, 58, + 22,141,175,193,138,144,203, 98, 40,187,255, 0, 98,247,183,115,108, 17, 97,110,121, 59,114,231,174, 96,200, 81, 16,120,161, 72, + 68, 70, 61, 23,142, 18, 75,235, 98,120,143,166,160, 58, 30,192,255, 0, 87,101, 46, 94,235,220,210,127,150,206,143, 26, 93,174, + 5,101, 97, 28,101, 92,182,160,188,117, 21,208, 77,235,153,251,208,236,206,219,196,219,183,126,234,206,200,152,110,121, 79, 24, +196, 82,224, 39, 82,202,139, 18, 38,158, 55, 85, 36,220,215,166,237, 56,242, 96,109,120, 56, 51, 16,210, 99, 99,197, 12,140,151, + 42, 90, 52, 84, 37, 73, 0,218,227,202,188,235,239, 3,177,187,203,188,119,104,230,131, 43, 6, 29,179, 16, 91, 11, 30, 89, 37, +189,205,139,201, 34,136, 25,117, 49, 28,184,139,125, 52, 7, 67,247, 92,187,146,246, 70,219,252, 72,177,114, 28,227,137, 47,168, + 64, 92,244,175,127, 13, 63, 47,243,109, 92,183,222,135,102,118,222, 46,221,187,119, 94,118, 68,195,116,202,120,198, 34,151, 1, + 58,150, 84, 88,145, 52,241,186,169, 38,230,181,165,237,255, 0,188,166,237,168, 48, 34,222,241,211,120,143, 41,164,147, 41, 89, +150, 51,141,211,210,145, 46,156,127, 6,227,109, 31, 77,103,247,215, 98,119,183,120,110, 16, 72,153,152, 17,224, 97,160, 92, 88, + 36,146, 98, 75,216,117, 37,145, 70, 59, 46,166, 35,234,250,104, 10, 47,183,247, 6,127,220,158, 22, 8,197,159, 51, 55, 38,116, + 24,209, 34, 52,146,250, 97, 43, 73, 29,192, 4,133, 10,156, 9,225,166,212,190,231,242, 59, 95, 31,125,125,184,237,121, 59,119, +114,199,138,216,243,156,137, 12,137, 33, 66,134,123, 70,202,134, 39,212,151,211, 99, 97,113,122,236, 32,217,126,242, 32,237, 56, +113, 32,222,240,255, 0,212, 16,102,117,186,231,251, 6,196,233, 24,198, 57, 6, 1,199, 83, 95,228,240,231, 84,123, 27,238,251, +118,218,251,135, 43,187,251,171, 58, 12,173,214,112,250, 18, 3,240,134,151,131,187, 29, 49,139,233,248, 64, 81,106, 3,210, 0, + 5,245, 34, 11, 19, 99,127, 33, 82, 17, 41, 60, 84,113,161, 2,164, 31,222, 5, 4,254, 15, 42, 47, 82, 59,243, 22,247,138,128, + 99, 26, 95, 78,129,111, 58,115, 20, 97,117,104, 31, 85, 49,149, 73,210, 10,251,110,124, 61,148,158, 84, 11,240,176, 55, 28,174, + 40, 8,172, 72, 84, 53,135,183,133, 69,226, 65, 27, 54,144, 8, 7,240, 84,186,136, 0,187, 15,117,232, 83,186, 52, 68, 6, 6, +246,225,244,213, 5, 38, 55, 55,231, 76, 77,253,254,202, 71,129,243,166, 60, 56,255, 0, 37, 80, 43,218,157, 16,185,225, 81, 0, +187, 0, 5,201,228, 42,242, 70,177,141, 35,233, 52, 0,244,104, 81,237,231, 72, 84,229, 60, 20,125, 53, 17, 80, 15,114, 57, 11, +210, 13, 35,114, 90,139,177, 94, 94, 84, 72,217,180, 19, 84,131,161,107,217,133,169,228, 54, 90, 26, 73,198,237,206,162,242,106, + 36, 14, 94, 20, 2, 23,102,213, 69, 98, 21, 73, 60,170, 3,225, 80, 60,106, 46,192,139, 30, 53,142, 44,215, 0, 26,153,137, 52, + 72,148,146, 88,210, 80, 13, 78,224, 30, 28,171, 79,128, 68,216,133, 66, 72,170,186,137,185,162,200, 67, 0, 56,251,104, 97, 69, + 68,168, 25, 56,151, 81,187,114, 21,101, 57, 94,132,186, 84, 1,106, 76,192, 39, 11,234, 63,101, 71, 86,202, 10, 89, 9,126, 28, +133, 68,150, 60, 60,234, 6,141, 18,168,248,143,209, 90,224,136, 22, 53,208,162,166,237,161,110,109, 67,212, 63, 37, 10,103, 86, +109, 35,144,254, 90,197, 42,202, 66,250,137, 38,157, 87, 83, 5,168, 10,179, 2,128, 11, 17,196,158, 21,182,232,136, 25, 64, 80, + 2,248, 81, 89,180, 45,201,224, 5, 6,235,229,195,141, 15, 34, 69, 63, 2,253, 38,185,165, 86, 80, 46,197,220,177,165,200, 14, + 53, 19,236, 20,104, 81, 73, 12,195,128,174,156, 17,144,144, 69, 97,115,204,209,148,216,218,163,169,124, 56, 15, 26, 76, 80, 2, +199,152, 21,132,221,124,205, 53,160,117, 35,133, 73,173,107,147,202,170,166, 66, 0,111,196,249, 80,222,102,144,241,224,190, 85, +208,197, 3,174, 72,107,171, 11, 15, 3, 90, 24,219,111,238, 86, 94,175,246,128, 61,180,242,184,191,157, 98,151, 26, 74, 91,230, + 35,141,117,144, 41,142, 8,162,110,104,138,166,220,184, 11, 82, 58,135,162, 40,182, 13,184,245, 63,232,254, 90,207,155, 87, 77, +173,227,194,183,102,226, 56, 87, 59, 46, 66, 94, 72,127, 57, 88,175,212,109, 85,170, 80,139,130, 24,194,162, 61,125,102, 39, 77, +213, 71, 59,212, 63,115,162,226, 73, 11,248,175, 15,178,152, 72,209,178,200, 99,248, 84,105,185,228,106, 17, 49,107,155,113, 38, +245,154,154,161,163,211, 95, 65,212,214,218,250, 22,183,179,175,170,244,169,238,125, 22,155,255, 0,113,207,254,125,169, 85,168, +161, 41, 7,246,127,225,199,251, 11, 67,169,201,253,223,248,113,254,194,212, 40, 10,185, 54,214, 61,223,140,208, 15, 42, 62, 79, +246,131,221,248,205, 7,149, 80,114, 35,191,182,229, 68,105, 32,117, 45,131,149,184, 63, 16, 66,250, 70,145, 30, 18,127, 72,152, + 94,222,234,218,143,127,219,164,127, 74,101, 11,156,177,117,100,196,227,117, 97, 24,153,163,213, 96,165,194,181,202,243,183, 27, + 90,184,252,191,187,237,194,121,115, 89, 50, 32, 84,200,220, 68,209, 41, 47,240,224, 72,114, 91, 35, 29,128, 79,152,182,100,133, + 84,112,229,198,180,215,181, 51, 7,112,228,110, 4, 35,227,188,243,229,195, 51,228,100, 93, 90,124,111, 75,211, 24,128,244, 21, +129, 45,121, 56,146,188, 45,228, 6,198, 23,116,237, 25, 49,109,198, 73,215, 31, 35,114,199,131, 42, 28,119,189,213,114, 23, 84, +106,236, 6,144, 91,136, 91,159,136,142, 20, 72,123,163,183,231,199,147, 46, 45,194, 54,130, 38,141, 30, 79,136, 11,206,116,195, +107,139,145, 33,249, 72,224,124, 43,157,195,237, 77,227, 14, 24, 48, 63,202, 75,143, 62, 22,221,139,157, 59,150,102,137,176, 99, +104,228, 48, 35, 39,198, 90,227,166,196,174,147,198,212,161,237, 61,222, 65,141, 38, 75, 99,197, 46, 32,218, 49,213, 99,119,100, +120,118,188,131,145, 36,166,241,130, 30, 64,196, 42,120,120,181, 1,208,227,119, 70,193,149,212, 48,103,163, 44, 48,190, 76,165, +131, 32, 88,163, 58,100,114, 93, 87,228, 60, 24,115, 95, 26,187,139,185,237,249,152,146,103, 99, 76, 31, 30, 45, 66, 86,179, 2, +133, 5,217, 89, 24, 6, 4, 14, 54, 34,184,233, 59, 39,114,151, 22, 76,115, 60, 10, 95, 19,116,199, 86, 13, 39,246,153,185,233, +157, 7, 37, 7, 72, 84,179,145,196, 30, 87,174,139,182,118,169,246,172,108,175, 81, 26,195, 46, 94, 75,100,180, 99, 34,124,182, + 23, 72,226, 29, 73,242,137,119,107, 70, 60,135,135,182,163, 0,246,206,242,216, 55, 72,118,249, 23, 32, 65, 54,226,145,201, 14, + 60,160,135, 29, 86, 40,138,228, 2,160,179, 41, 85,227,241, 30, 87,167,238, 78,238,219,251,110, 65, 6, 76,111, 44,205,137,145, +154,170,131,129, 92,109, 55, 91,159, 22,212,109,238,227,225, 92,238,217,217,155,214, 38, 38, 62,221, 59, 99, 24, 92,109,169,149, + 60,114,185,100, 27, 92,253,101, 49,171, 68,186,186,202, 20,113, 35, 73,191,205, 90,189,235,219,219,151,112,116,255, 0,135, 60, + 11,254, 75, 63, 10, 79, 80,238,150,245, 98, 29, 14,186, 35,146,250, 90, 30, 35,135, 3,244, 84, 6,178,119, 22,217,145, 38, 56, +196,158, 57, 34,150,121,113,165,145,152,198, 81,225,133,178, 88,105,117, 26,190, 21, 7,195,225, 58,185, 85,141,191,121,218,247, + 72,165,159, 3, 37,102,142, 27, 25, 77,153, 74,134, 93,106,214,112, 14,150, 94, 42,121, 17,202,185,249, 59, 99,114,109,202, 76, +228,124,118, 70,220,178, 51,213, 36,214,192,199, 54,217,252, 61, 85,212, 40,185,234,113, 97,127,151,198,252, 40,221,183,178,110, + 91,110, 30,126, 62, 80,142, 36,157, 82, 60, 92,100,154, 76,133,136, 44,101, 24, 9,166, 69,147,167,171,228, 67,125, 43,245, 80, + 26, 43,221, 93,186,240, 67, 58,231,198, 98,200, 36, 67, 32, 13,165,128,209,169,175,110, 8, 58,139,118, 63, 8, 38,215,164,157, +203,182, 69,235,206, 99,250,101,194,204, 56, 23,107,177,146, 65, 4,121, 68,162,160, 45, 96,146,113,225,194,196,242,174,103, 63, +178,115,242, 54,237,159, 8,244,167, 56,219, 82,109, 57,137,234,114,113,226, 4, 8,181, 75,254, 91, 67, 78,159, 3,126,237,237, +126, 21, 99,114,237, 45,202,121,178,179, 34,104,229, 50,110, 82,230,199, 0,202,159, 16,180, 83, 97, 69,133,103,159, 24, 7, 86, + 87,143, 81, 81,112,203,194,254, 20, 7, 82, 55,221,149, 50,177,240, 78,100,126,171, 37, 81,162, 85, 37,129, 18,130,209, 93,212, + 21, 29, 64,167, 77,207,197,225, 85,207,116,118,254,172,139,102,199,254, 90,203, 45,131,113, 38, 78,143,238,254, 31,222,126,243, +224,248, 47,241,112,231, 92,244,157,167,187,174,102,214, 33,124,127, 67,182,174,219,210, 65, 60,209, 42,156, 43,172,203,210, 9, + 39, 80,178,219, 67, 72,196,139, 91,133,239, 85,165,236,221,226,102,157,175,141, 4,107, 44, 89, 17,226, 99,229, 78,137, 44,137, +147,234, 36,104,100,211,213,195, 18, 33,249, 99, 98, 53,241,246,208, 29,202,110, 59,123,109,255, 0,197, 70, 68,127,195,214, 54, +153,178,137,248, 21, 18,250,203, 19,203, 77,141,252,171, 27, 51,188,182,152, 83,111,244,108, 51, 27,112,204, 24, 49, 1,170, 62, +155,132, 50, 72,210, 6, 77, 67, 74,219,225, 34,230,227,195,141, 69, 59,117,191,209,179,118,222,184,160,200,153, 39, 35, 76,146, +205, 18,203, 52,175,144, 53, 73, 57, 50,184,212,223, 19, 30, 39,137,176,229, 85,211, 96,220, 39,207,139,118,201,104, 33,200,147, +120, 77,207, 35, 25, 36,105, 17, 34,139, 1,182,245, 68,126,154,106,114,108,198,224, 15,171,136, 23,119, 94,245,218,182,141,205, +246,156,148,115, 60, 67, 12,200,225,108,161,115, 39,244,192,159,232,124,199,216,120,113,171,239,220,253,187,208,198,203, 25,136, +144,230, 23,244,238, 67, 11,136,216, 69, 33, 96, 69,208, 43,252, 44, 90,214, 60, 13, 99,239,221,189,159,185,119, 4, 91,158, 44, +152,227, 22,219,103, 88, 72,238,178, 41,219,243,155, 53,180,170,198,234,218,210, 66, 5,216,113, 30,219,140,108,206,197,207,154, + 8, 96,102,135, 32, 58,238, 16, 79, 31,170,202,199,141, 83, 55, 53,179, 35,145,134, 54,134,152, 8,219, 75, 70,214, 26,173,199, +198,128,236, 55,173,225,182,201, 48, 49,161,196, 57, 89, 59,140,175, 4, 40,174,177,128, 99,134, 76,134, 44,207,195,229,140,214, + 70, 63,121,237,185,240, 75, 51,198,248,145,227,195,139, 60,141, 41, 7,142, 75,207, 10,196,130, 61, 90,142,184, 8, 26,111,170, +226,213,103,186,246,105, 55,183,218,165,135, 19, 15,112,143, 3, 34, 73,178, 48,119, 6,100,134, 85,120, 37,129,120,136, 50, 69, +213,164, 13,197, 60, 43,154, 94,194,220,227,196,154, 51,145, 28,164,122, 7,130, 24,230,154, 15,252, 38, 78, 84,237,142,179, 42, +245, 35, 85,143, 33, 99,137,215,143,195,196, 10, 3,160,159,185,246, 28,104, 33,200,159, 54, 53,138,116,105, 98,111,136,221, 17, +130, 59,124, 32,144, 21,152, 6,191, 47, 26, 28,253,197,183,199,188, 99,108,145,191, 87, 42,121, 94, 25, 21,121, 68, 83, 29,242, +254, 50, 69,190, 69, 28, 1,225,113,122,198,159,177,115,228,219, 78, 28, 45,143, 11,190,215,184,225, 21, 50,207, 34,140,140,236, +152,242,148,245, 37, 87,145,212,105,109, 76,120,147,249,190, 87, 37,237, 77,202, 77,228,200,173,142,187,105,205,201,206, 51,235, +126,191,249,172, 23,194,233,136,180,105,186, 59,106,190,190, 35,219, 84, 27, 24,253,199,219,195, 18, 76,229,207,139,161, 27, 34, + 73, 49,184, 0,202,109, 21,174, 1, 42,255, 0,154,195,131,120, 81,247, 13,225,177,162,196,147, 11, 18, 92,231,205, 63,185, 72, +237, 26,132,208,101, 47, 43,203,165, 80,105, 22,227,198,230,213,202,237,157,151,184,227,226,199, 20,162, 24,231, 73,246,150,119, + 57, 89, 57, 70, 72,182,217,186,174,218,178, 1,209,170,237,211,141, 84, 1,226,124,186, 30,232,192,221,247, 44, 72,176,246,206, +145,130, 73, 63,250,140, 82,207, 38, 51, 75, 6,147,120, 82,104, 98,157,151, 91, 91, 81, 2,250,110, 1,227, 80, 18,110,224,138, +125,155, 15,121,193,198,155, 41,115,150, 22,198,199, 85, 2, 66,114, 10,233,214, 73,210,129,111,118, 98,108, 7,157, 79, 3,125, +195,202,218,230,221,167,255, 0, 39, 14, 51, 77, 22, 80,152,143,221,190, 60,141, 12,163, 82,146,172, 53, 33,177, 28,234,158,227, +139,220,146,109,143,133,181,199,135,129, 39, 75, 30, 56, 68,115, 72, 4,106, 24,140,136,227,127, 79,240,218, 48, 22, 38,233,251, +108, 44, 42, 67,104,159,253, 47, 46,207, 30, 6, 28, 47,211, 49, 38, 19, 75, 44,248,197,111,115,174,110,156, 50,150,113,114, 91, + 77,245,113,227, 64, 29,187,155, 96,209, 12,173,156,138,179, 23, 69, 12, 25, 88, 50, 21, 87,234, 43, 40,104,244,151, 91,151, 2, +215, 30,117, 57,123,143,108,134,118,193,138,120,229,203,142,120,113,231,132,177, 77, 6,121, 35,140, 93,180,145,171,247,160,170, +254,117,113,249, 61,141,188,100,170,140,150,142,113, 52,121, 24,239, 4,185,185, 75,210,138,105, 35,116,235, 77, 0,137,242,244, +170, 48,101,146,215,225,199,133,235,126,110,218,206,127, 93,166, 72, 71,169,223, 48,247,100,185,110, 16, 99,250, 77,104,223, 7, +206,125, 59, 88,114,229,198,169, 13, 47,245, 22,197,124,192,217,145,223, 8, 51,100, 18, 72, 10,177,182,135, 32,145,102,210,195, + 73,211,123, 30, 28,232,219,126,126, 38,229, 9,202,194,144, 75, 16, 98,135,129, 82,174,191, 50,186,184, 12,164,121, 17, 92,110, + 63,102,231,227,156,244,104,113,178, 75,195,147,143,142,217, 57, 57, 82,164,201,147,146, 50,116,180, 55, 9,142, 52,168, 7,166, + 9,213,241,123,247,251,127, 3,121,218,177,189, 62,113,137,224,145,166,151,140,175, 52,232, 89,147,163, 27, 74,241,167, 86,201, +171, 83,183,197,123, 14, 35,141, 71,208,168,216,146, 70,191, 10, 17,145,252,232,202,188, 56,208,221, 46,228, 94,192, 80,164, 68, +174, 60,105,117, 95,206,159,166, 63, 72, 83,244, 71,233,138,164, 33,212,127, 58,113, 35,143, 26,159, 64, 18, 70,161,236,168,152, +136,241, 31, 93, 0,186,210,121,210, 18,185, 54, 39,133, 71,166,212,197, 72,230, 40, 2, 59, 5,182,151,213,126,124, 45, 77,214, +126, 94, 84,209,128,206, 1,228,106,200,199,140,208, 21,186,175, 77,173,141, 91,244,169,111,109, 47, 72,190,116, 5, 93,109, 83, + 19,201,107, 10,178,112,208,114, 52,222,144,121,212, 0, 58,242,123, 42, 61, 71, 60,192,163, 8, 65, 82, 60,174,111, 75,160, 45, +127, 42, 80, 3,214,213, 49, 51,129,164, 1, 79, 38, 57, 60, 84,219,194,171,184,116,109, 45,206,148, 5,245,109, 64, 95,253,189, +148, 9,100, 36,233, 28,133, 13, 36, 40,182, 39,230,229, 74,162,142,165,168,124,116, 73, 90,206,197,124,173, 86,198, 4, 39,143, + 89,190,161, 89,200,197, 88, 88,214,148, 47,169,125,181,163, 44,201,155,121,237, 44,105,228,199,200,238, 28, 24,103,137,140,114, + 69, 38, 76, 8,202,234,108,202,234,206, 10,144,121,222,182,207,122,246, 93,135,255, 0,244,123, 95,255, 0,222,227,255, 0,222, + 87,207,216,221,191,181,231,111, 93,245,190,229,237, 51,119, 30, 86,219,185,188,120,251, 30, 60,146, 70,204,179,228, 74, 31, 33, +250, 23,148,170,105,183,195,244,215, 59,221,125,169,180,109,189,243,137,177, 98,179,225, 97,102,174, 36,179, 99, 76,225,229,195, +108,149, 86,147, 25,223,197,146,252,205, 71, 37, 24,185, 62, 9, 85,251, 10,162,228,212, 87, 22,232,189,167,211,207,222,189,155, +126, 29,197,182, 91,255, 0,235,113,255, 0,239, 43, 3, 47,184,251, 64,203, 44,171,220, 91,113, 44,197,128, 25,112, 30,102,255, + 0,167, 95, 62,119, 22,199,183, 67,180,101,230,197,181,205,179, 77,131,150,184,176,137,164,103, 25, 72,218,174,192, 73,249,203, +166,228,175, 10,235,251, 91,177,123,123, 51,107,237,216, 39,216,178,183,111,245, 12, 82,201,157,220, 48, 78,233, 30,220,200,204, +154, 2, 32, 49,254,239, 77,223,169,207,195,202,179,106,252,111, 67,116, 83, 84,116,214,159,149, 81,210,237,169, 90,146,139,105, +213, 87, 74,254,116,103,176,109,187,158,217,188, 66, 78,221,155, 14,100, 80,217,100, 24,242,164,182, 99,196,106, 49,179, 90,174, + 44, 96, 46,168,238, 9,240, 53,228,223,114, 30,159, 15, 27,184, 33,235,163,198,153,113,199, 28,215, 0, 56, 85,113,168, 95,204, +113,175, 93, 86, 89, 34, 12,140, 24, 56,186,176, 55, 4, 30, 68, 17, 90, 57,150, 47,254, 75,249,221, 31,254, 98,149, 63, 76,250, +109, 54, 23,232, 91,255, 0,127,122, 84, 3,184,225, 31,248,113,254,194,212,106, 79,249,159,225,199,251, 11, 80,173, 2,174, 79, +206, 61,223,140,208, 13,239, 71,201, 31, 24,247,126, 51, 66,181, 1,230,178,247,142,253, 30, 6,118,102, 60,169,144,240, 38,230, +210,199,233,216, 38, 47,164,150, 72,241,216,202, 62, 6,215,160, 2,167,137,240,228,107,164, 29,231,128,219,251,236, 10,129,231, + 87,146, 4, 9, 42, 52,205, 44, 80,122,166,255, 0, 47,125, 97, 52,130,161,207, 2,194,222,218,188,221,181,130,219, 14, 87,111, + 25, 38,244,153,126,167,169, 38,165,234, 15, 87, 44,147,201,164,233,211,193,164, 58,126, 30, 94,116,223,233,204,113,159,147,151, +234,242, 86, 12,150,146, 89, 48,149,148, 69,214,154, 33,143, 36,151, 11,172,221, 7, 5, 45, 96,120,218,128,200,143,190,241,219, + 7, 51, 41,177, 66,201,135, 38, 52, 82, 40,158, 54,137, 61, 87, 5,105,231, 75,172,125, 51,113, 39, 3,164,143, 26,144,239,220, + 5,207,194,192,158, 1, 12,217,126,157, 90, 55,154, 62,160,124,183,104,162,233, 70, 13,229, 91,128, 89,151,128, 82, 15,186,198, + 31,102,197,131,142,241, 99,110,121,137, 33, 76,120,196,160,194, 62, 28, 64,201, 18,148, 88,130, 50,148,125, 46,172, 8, 60,249, +241,162, 97,118,118, 22,221, 46, 59, 97,101,229, 69, 20, 66, 30,180, 10,241,133,157,177,221,228,137,165, 34, 48, 71,197, 33,186, +161, 85, 60, 5,173, 64, 88,221,183,217, 54,252,216,176,113,112, 37,207,152,194,249,115,164, 68, 6, 72, 99,116,140,148, 82, 63, +120,228,191, 5, 30, 92,235, 23,111,239,137, 34,197,201,125,223, 24,129, 4, 91,134, 84,121, 17,178,129, 36,120, 89,167, 19,167, +160,219, 73,248,144, 92,158, 60, 79, 10,221,221,187,126, 45,215, 34, 44,161,149, 62, 28,171, 19, 99, 76,216,204,170,100,129,217, + 36,104,201,101, 98,191, 20, 98,204,150, 60,248,213, 79,244, 94,210,208,188, 45, 36,236,143, 6,110, 49,248,214,225,115,242, 6, +108,140, 8, 79,153, 36, 81,163,217,206,245, 24, 1,143,222,209,103, 99, 68,118,220, 65,155,155, 38, 84,184, 98, 24, 39, 71,132, +180, 48, 12,167,116,200, 80, 85,151,166,194,214, 31, 49,183,153,168,236, 93,216,251,166,243,153,179,188, 45,234, 35,152,200, 33, + 96, 35,124,108, 79, 79,141, 32, 51,131,115,172,203, 49, 64, 7,183,202,174,205,218,221,104, 35,213,185,229,250,248,167,147, 33, +119, 11,197,212, 13, 44, 71, 30, 68, 84,233,244,149, 52, 30, 0, 47, 3,199,157, 44, 46,206,219,112, 50,227,207,198,146,113,149, + 28,221,126,187, 50,179,178,156,120,241, 26, 25, 25,144,150,141,150, 37, 99,126, 58,184,222,160, 51,119,254,231,222,182,237,245, +182,204, 76,100,108,117, 27, 89, 70, 36,106,115,153,152,216,210, 47, 19,195, 82,174,145,228, 69,252,105,178,126,241,182,236, 28, + 44,108,172,200, 4, 45, 40,201,121,225,121,227, 82,163, 18,115,137, 42,195,175, 79, 89,203,169, 42,170, 56,129,225, 91, 59,151, +108, 98,110,123,164,123,172,211,207, 28,177,140, 80,209, 70, 80, 70,254,143, 35,214, 66, 91, 92,108,220, 28,144,108,194,224,251, +141, 87, 61,155,136,137, 10,227,102,101, 99, 20,245, 43, 43,196,200, 30, 88,178,242, 14,100,177, 51, 24,254, 16, 36, 63, 11, 37, +152, 14, 23,241,160, 23,117,238,249, 59, 92,187, 76, 80,100,122, 88,179, 50, 36,139, 34,117,129,178, 89, 85, 49,229,153,116,196, +128,147,118,140,114, 28,171, 27,183,187,159,118,221,183, 28,108,124,172,150,137, 31, 27, 14,117,244,152, 50,100,164,135, 34, 73, +208,180,210, 68,178, 46, 56,101,137, 79,198, 70,155,159,209, 54,236,114,246,232, 51, 51,112, 51,101,103, 18,109,210,188,208, 5, + 32, 41,105, 33,147, 24,135,184, 36,141, 50,158, 86,227, 89,123,103,104, 67,181,229,156,157,183,116,205,197,214,168,147,196,190, +153,210, 85, 73,102,157, 85,186,184,206,192, 94,119, 31, 1, 28, 61,188,104, 12, 44,238,247,220,160,147,185, 26, 22,131,161,143, +141,151, 46,202, 52, 92,135,219,153,113,242, 53,155,252, 90,164,123,143,101, 27,184, 59,139,185, 54,152, 55, 93,183, 26, 88,114, +119, 60, 89,118,223, 69,146, 97, 10, 25, 55, 9, 94, 13, 18, 70, 24,130,202,209, 30, 34,220, 8,173, 57,254,238,187,118,109,190, + 28, 16,210,194,209, 71, 60, 50,230, 69,209, 92,137,215, 37, 26, 57, 78, 68,157, 35,172,157, 90,185,124,192,123,170,232,237, 92, + 6,102,147, 47, 55, 35, 43, 46, 92,172, 92,201,115, 38,104,132,140,216, 46, 37,130, 61, 48,197, 28,107, 24, 35,136, 84, 7,137, +227,126, 52, 7, 41,157,223,251,156,185, 59,174, 70,214, 98, 59,118, 62,200,249,248,132,166,163,234,145, 49, 39,185,111,206, 80, +153,138, 45,231, 93,190,203,149, 36,248, 83,228, 75, 54, 78, 89, 70,109, 34,124, 41, 48,101,248, 84, 54,148,135, 33, 34,102,189, +248, 53,173,126, 23,225, 88,137,247,127,219,176, 98, 77,133, 20,243, 36, 83,227,102, 97,184, 87,142,253, 60,217, 99,158, 66, 63, +119,107,167, 73, 85, 60,148,113, 7,157,111,193,136,209,225,207,139,151,185, 79,184,245,195, 43, 75,144, 49,209,213, 89,116,149, + 95, 73, 12, 11,245,130,104, 12, 44,110,252,199,201,198,158, 69,193, 39, 38, 12,156, 44, 79, 79, 20,241, 74, 53,231,186,197, 18, +180,139,240,171,163, 18, 29,127, 52,142,102,168,238,221,253,150,155, 36,217,123,102, 6,156,248,241, 51,242,165, 14,234,201, 1, +194,156,225,177,226, 7, 86,242,142, 3,135,194, 62,138,209,195,236,189,183, 18, 20,137,179,114,167,233,182, 3,169,110,144, 23, +219, 31,169,140, 45, 28, 43,195,128, 15,231,236, 60,105,178,187, 23,107,203,197,108, 36,205,203,199,138, 72,243, 32,200,104,140, +101,228,135, 58,115,153, 44, 68,188, 46, 6,153, 79,194, 64,189,184,113,160, 54,183,205,230, 77,173,176,241,177,112,219, 55, 55, + 58, 71, 72, 32, 87, 17,139, 69, 27, 79, 35, 51,176,107,124, 41, 96, 45,196,145,239,172,101,239, 88,231,203,142, 39,219,102,135, + 17,229, 56,107,145, 49, 85,113,148, 49,125,115, 66,240,252,203,101, 82,183,253, 33,229,198,181,247,173,170, 29,223,211, 72,185, + 83,225,101, 98, 59, 62, 62, 86, 50,174,181,234, 70,208, 72,182,149, 29, 72,100,115,225,192,216,138,202, 61,163,131, 28,226, 88, + 50, 39,104,163, 38,104,113,102, 96,209,250,175, 77,232,189, 75, 49, 78,161, 99, 31, 59,181,174, 75, 90,244, 64,171,135,223, 16, + 78,152,173, 62,222,248,254,176,109,243, 71,119, 87,182, 62,230,207, 20, 19, 49, 94, 86,145, 52,178,251, 69, 83,155,190,142, 86, +217,159,151,135,131, 44, 49, 98,224, 13,193,242,195, 68, 74, 71, 47, 95,160, 81, 28,124,108,253, 11,242,183, 26, 9,236,124,216, +187, 94, 77,181,103, 25, 91,182, 78, 14, 22,220,102,150, 77, 49, 99,174, 32,212,173, 1,142, 37, 98,177,202,204,235,168,106, 60, + 56,240,173,215,236,237,169,240,243,176,117,202,144,231,224,227,237,146,132,101, 26, 33,198, 89, 18, 51, 21,208,217,173, 41,189, +238, 57,112,170, 10,217,125,222,209,110, 15,135, 22, 11,250,113,148,251,114,102,151, 91,122,148,199,108,182, 29, 47,155, 72, 85, +181,252,255, 0, 14, 52, 93,241,187,201,219,241,228,140, 21,254, 36,145,108,243, 74,197,215,167, 36,123,156,139, 25,117, 81,109, + 36,149, 96, 5,248, 92, 31, 49, 87,178, 59, 83, 55, 39,185, 6, 88,144, 69,181, 46, 81,207,100, 89,175,170, 70,197,124, 70,180, + 6, 31,133,201,107,150,234,149,176,224,160,147, 87,135,100,237,131, 9,240, 83, 35, 37, 21,241,182,252, 65, 40,104,245,170,237, +110,100,198,145,111, 25, 93,122,141,218,234, 65,242, 21, 0,221,197,221, 35, 97,144,175,162,108,146,184,146,238, 19,105,145, 80, + 36, 56,239, 18, 73,243, 3,169,191,123,192,120,211,158,233, 35,115,124, 4,193,119,132,229, 62,223, 14, 81,145, 84, 62, 90, 99, +156,190,150,131,196, 41, 85, 43,175,207,194,220,104,251,191,109, 97,111, 79, 41,203,150, 96,101,194,159,109,115, 25, 65,251,172, +134,141,221,248,161,248,239, 8,183,135, 62, 21, 52,237,188, 65,186, 13,207,173, 41, 65,144,115, 87, 12,232,232,140,166,135,210, +153,199,195,174,253, 59,240,213,107,155,218,244, 7, 51,179,119,190,118, 78, 28,121, 89,152,230, 92,217,177,246,211, 22, 36,101, + 18, 38,151, 57,230,141, 89, 95,226,101, 7,167,169,181, 94,192,112,227, 87,228,239,236,104,183, 12, 93,175, 47, 21,177,114,166, +120, 97,150, 9,165, 69,153,101,200,149,160,140, 69, 17,248,165, 77, 73,114,227,243, 72, 62,227, 98,118, 62,221,133, 3, 98,227, +229,229,107, 85,196, 92,105,220,196,207, 15,160,146, 73,177,244, 1, 18,169,183, 84,169,214, 13,215,219,198,172,197,218,176, 97, +228, 69,146,155,134, 97, 55,137,178,213,157, 15,169,146, 23,146,104,222,102,209,168,124, 82,155,170, 21, 82, 44, 45, 97, 84, 1, +222,187,137,118, 76,201, 36,149,100,146, 40, 54,220,173,193,224, 64,128, 55, 66, 72, 19,230,111,136, 55,239, 56,120, 80,223,187, +103,114,113, 35,219, 25,247, 37,205,151, 4, 98,117, 86,199,165,142,185,141, 39, 87, 77,191,179,112, 45,111,155,135, 46, 53,123, +118,237,188, 29,237,230,124,185, 37, 67, 54, 20,251,115,116,138,139, 69,144,209,200,236, 53, 35,124, 96,196, 45,225,236,160,100, +118,182, 46, 68,243,228, 99,229,228, 98,101, 75,148,249,195, 38, 35, 25,100,121, 49,215, 10, 68, 64,232,203,164,198,131,152, 36, + 55, 27,214,121,148,165,183,119,100,146,100, 77, 22, 92, 14,189,108,249, 49,113, 99,101, 17,188, 73, 30,221, 30,226, 86,101, 63, +157,125, 74,125,181, 86,126,242,159, 44,109,237,182,226,149,143, 37,246,151,201,154, 82,167,166,155,156,170, 4, 65,127, 56,244, +239,118, 28,137, 31, 69,233,123, 59, 10, 36, 79, 79,151,147, 20,139,146,114,214,109, 72,238, 25,177, 70,222,235,121, 99,123,134, +137,121,155,157, 92,111, 77,143,217,120, 0,225,244,178,178, 99,135, 13,112, 85,162, 6, 50, 38,109,181,131,227, 60,165,163, 38, +254, 13,163, 77,254,138,160,166,157,253,181,187,238, 42,145,245, 14, 12, 51,228, 36,113, 74,143, 35,174, 60,163, 28,172,136,166, +241, 51,187, 46,128,220,212,222,181,123,123,112,206,220,159,117, 92,248,150, 23,195,206, 56,201, 18,144,218, 80, 99,193, 45,181, +143,155,226,148,241,242,168,175,103, 97,152,115,113, 31, 43, 37,240,242, 82,104,163,198,214,170,144, 46, 68,134,119,233,105, 64, + 75, 7,226,165,245, 88,112,243,189,237,163,104,109,168,101,152,167,151, 46, 92,201,253, 86, 84,211,244,193, 50,152,227,132,233, + 17, 36,106, 22,209, 14, 22,160, 47,232,248,173,106,131, 1,126, 28, 42,210, 47, 81, 11,218,204, 57,138, 3, 1, 98,104, 6,143, +128,163, 69,140,217, 74,120,133,183,137,160,170, 18, 11, 6,211, 73, 6, 64, 23,138,246,246, 85, 33,100,109,210,197,251,210,192, +132,226,104,192,199,122,166, 95, 44, 45,155, 86,147,192,222,172, 1,126, 92, 61,180, 5,133, 49,241,189, 54,168,249,208,244,105, + 22,190,163,206,158,220, 40, 2,218, 51,204,253, 53, 61, 49,223,159, 42,174,110,126,142, 84,196,243,189, 1, 99,165, 29,188, 41, + 24, 19,149,232, 23, 32,243,167,214,111, 64, 77,227, 85, 22, 6,169,102, 71,240,134,241, 20,118,185,107, 10,110,152,157,213, 15, +203,205,189,194,136, 21, 6, 60,172, 35, 33, 24,131,226, 1,169,116, 39,255, 0,170,127,213, 53,180,160, 0, 20, 11, 1,192, 1, + 82, 0,121, 86,246,120,146,166, 68, 88,178,147,169,162,107, 15, 13, 38,172,193, 12,203,113,210, 96, 47,226,166,180,144, 85,132, + 22,246,212, 80, 85,226, 55, 46, 7,207, 93,187, 28, 11,222, 29,225,153, 54,214,132,225,238, 89, 6,109,247, 35,118,159,104,139, + 25,100,153,209, 96,103,199, 4,177,145,135, 42,226,123,227,105,158,126,243, 77,163,111,217, 27,110,205,200,233, 34, 98,166,100, +153,254,166, 89,152,178,100, 38, 76,220, 88, 74, 29,127,218,245,173,185,247, 62, 62,205,220,189,231,181,111, 91, 79,241,125,135, +114,221,178, 30,104, 58,175,142,203, 60, 19,202,209,188, 83,160,107, 27, 55, 17,110, 34,169, 79,189,239,251,159,222, 6,209,185, +250,120, 59,127, 39, 28, 99, 13,166, 12,242,240,226,193,141,142,191,184, 89, 36,148, 6, 49,149, 83,118,241,189,100,165, 94,235, +236,238,231,218, 54,244,220, 55, 45,203, 31,118,196,197,148, 98,100, 54, 38, 89,202,244,147,145,126,132,192,252,135,135,135, 10, +239,251, 59, 11, 30, 94,210,197,129, 59,110, 61, 91,140, 71,167,133, 39,112,101, 97, 77,186,180, 67, 76,178,195,134,131, 65,185, + 94, 71,249, 43, 63,191, 35,198,197,237, 93,194, 45,145,182, 28, 72, 51,178, 98,204,222, 34,219,247, 83,159,147,145, 40, 98, 17, + 97,141,145, 52, 70,141, 33,107, 10,196,237,254,251,124,120,182,108, 89,251,103,248,183,113,108,209,152,251,123, 48, 73, 50,178, +163,106,150, 62,166, 52,106,122,218, 53, 22, 78, 35,241,212, 73, 37, 68,168,188, 10,219,110,173,215,204,221,251,177, 92, 89,112, + 55,160,216,146,197, 12,155,148,105, 6, 36,110, 11, 70,204,146,232,132,153, 69,220,143,151,149,239, 94,229,135,135,144,152,176, + 33,199,149, 52,198,163, 67,130, 88, 88, 14, 12, 71, 2,107,199,126,230,167,200, 56, 27,180,153, 44,203,151, 38,239,138,210,198, + 85,181, 60,150,145,153, 25, 84,174,159,139,244,184, 3, 95, 67,141, 76,170,204, 10,177, 0,178, 92, 27, 31, 43,138,180, 33,149, +209,151,163,110,155, 95,165,107, 88,243,234,222,223, 85, 42,213,240,250, 63, 29, 42,180, 33,134,255, 0,153,254, 28,127,176,181, + 26,147,255, 0,119,254, 28,127,176,181, 31, 26, 20,173,146, 62, 49,238,252,116, 31,101, 27, 35,231, 30,239,199, 65, 60, 79, 10, + 3,205,159,188,183,232,242,159, 7, 84, 70, 69,118,219, 53,104, 23,254, 32,249,175, 12, 38,220, 56,122,116, 15,111,231, 95,194, +178,247,204,237,197,246,164,158, 28,163,139, 25,195,238, 61, 80, 66, 10, 41,108,124,193, 26,189,245, 95, 87, 16,111,225,198,220, +235,212,191,133,109,189, 67, 33,195,131,168,102, 25, 69,250, 73,171,174, 23, 64,158,246,191, 80, 47, 13, 92,237, 80,155,100,217, +178, 97, 72,178, 54,236,105, 99,136,202,209,163,193, 27, 42,153,201, 51, 21, 82,166,198, 77, 71, 87,157,248,208, 25,219, 14,102, +227,150, 55,172, 76,172,145, 36,216, 89,175,139, 6, 72,141, 84,133, 56,240, 78,164,160,224,116,180,199,232,231, 92, 31,109,110, +187,222, 58, 96,229,122,246,152, 73, 14,193, 22, 66, 74,161,245,174,102, 70, 68, 13,241, 49, 36, 50,171,124,195,137, 32, 94,189, + 86, 60,120, 33,105, 30, 24,150, 54,153,250,147, 50, 40, 82,239,164, 38,183, 35,230,109, 42, 5,207,128,170,176,236,187, 54, 48, + 43,143,183, 99, 68,165,146, 66, 18, 24,212,107,137,204,177,183,194,188,209,216,178,159, 2,111, 64,113, 11,191,238,216,216, 88, +179, 99, 73, 22, 62, 34,207,156,114,186, 72,146, 50, 21,220,100,130, 55,158, 38,110,168,133,128, 96, 94, 49,125,126,202,189,247, +129,184,238, 49,227,103,237,248,153, 62,150, 20,218,114,179,100, 96,160,188,140,175, 28, 74,129,184, 21,182,178,110,188,110, 71, +211,212, 54,197,179, 76,208,188,155,126, 51,182, 59, 52,144, 19, 18, 93, 25,223,170,236,191, 15, 2, 95,227, 63,206,227,206,139, +159,180,237,123,160,143,248,150, 20, 25,130, 45, 93, 49,145, 26,200, 23, 80,179, 0, 28, 30,118,227, 64,113,185,219,214,235,139, + 38,239,252, 57,146, 46,142,233, 42,207,209, 88,223, 37,161,143, 7, 30, 94,162, 69, 59, 1, 32, 87,113,212,211,241,104,229,198, +171,237,251,174,251, 47,112, 75,139,143,185,169, 77,207, 62, 24,250,157, 45, 73, 28,103,105, 92,239,220, 36,135,225, 4,128, 5, +253,231,137, 53,220,101,108,123, 54,104,101,203,192,199,157, 94, 78,187,137, 34, 70,213, 46,145, 25,145,174, 56,177, 69, 10, 73, +240,225,202,166, 54,157,181,114,198,122,225, 64, 51, 5,173,146, 34, 78,168,210,141, 18,254,242,218,184, 35, 21, 28,121, 27, 86, + 88, 60,237,247,125,202, 4,254, 37,133,144,152,114, 97,237,219,254, 80,140, 32,104,164, 56,155,138,233, 66,142,109,119,211,197, +185,241, 54,181,235,161,143,184,247, 92,173,217, 54,245,116,133, 37,221, 39,192, 91,160, 44,145, 38,214,185,201,207,155, 44,205, +199,217,194,186, 9,118, 45,146, 97, 23, 95,109,197,147,162,204,240,234,134, 51,161,164,126,179,149,248,120,106,127,137,188,207, + 19, 68, 59, 86,214, 51,206,232, 48, 96,245,228,131,235, 58, 73,213,190,131, 21,250,150,213,125, 7, 79,187,133, 1,230,253,183, +188,238,241,237,176, 70,153, 10,217, 89, 56,219, 20, 39,112,145, 53,200,131, 50,108,152,216,190,162, 67,149, 3, 74,234,252,227, +198,252,170,230,111,117,119, 4, 88,115,180,121, 17,172,184, 24,155,182, 67,205,209, 82, 50, 27,109,205,143, 22, 50, 3,112, 85, +145, 73,213,111,162,213,219,166,203,178, 69, 4,216,209,109,184,177,193,144, 2,207, 18, 67, 26,171,133,102,117, 14, 21, 69,236, +206,204, 61,164,154,179, 14,207,180, 52, 2, 3,129,142, 98, 88, 91, 21, 99, 49, 33, 81, 3,144,207, 13,136,249, 24,168, 37,121, + 27, 80, 23,211,160,218,194, 21,109, 7, 75,133,177,179, 88, 27, 27,114, 54, 53, 48,128,240, 3,129, 20, 56,224,199,133,165,104, + 34, 72,154,119,234,206, 81, 66,151,147, 74,166,183,183,204,218, 80, 11,159, 1, 68, 14,171,204,251, 42, 1,244,175, 1,111,193, + 76,169,169,141,252, 60,105,204,145,158,108, 62,186,138,202,151, 99,170,128, 38,158, 36,120, 82, 43,194,202, 61,244, 54,156, 27, +216,125, 54, 52,194, 96, 69,248,223,149,172,104, 2, 40, 30, 60, 77, 86,116,187, 27, 18, 7,128,169,245,124,129,191,186,212, 61, + 76, 71,219, 85, 2, 58, 72,225,170,164,169,126, 36,211,124,100, 95,144, 52,131, 58,242,250,234,130, 62, 45, 82, 21, 17,114, 73, +243,167, 6,220,234, 0, 87,185,191,157, 17,104, 98,166, 13,168, 4,163,137, 62,211, 79, 37,136,167, 65,195,223, 73,249, 26,164, + 43, 51,217, 72, 28,205, 52, 62, 38,160,255, 0, 49,162, 67,200,212, 52,136,207,196,139,211,192,108,191, 93, 59, 33,119,224, 64, +176,241,165, 24,178,253, 38,156,129,105, 82,209,168,241, 98, 77,207,144, 21, 93, 4,132, 29, 15,164, 33,184,250,120,209,165,111, +236,208,126,141,207,211,194,160, 47,165,200, 31, 48,225,244, 84, 41, 44, 91,221,139,120,243,247,208,228, 80, 46, 7,157, 58,200, + 47,195,198,220, 42, 46,220, 56,248,154, 2, 22, 26, 8,255, 0,110, 21, 56,115, 94, 5,208,160, 16, 77, 67,154, 31,166,141,142, +112,244, 1, 40, 58,189,246,173, 25, 38,251,137,146, 62,145, 64, 11,240,189,169,215,196,251,106, 83, 38, 9,140, 52, 71,247,151, + 26, 71,211, 77, 97,107, 80, 18, 39,203,240, 83,128, 10,143, 19,227, 81,183,157, 98,109,253,219,181,231,239,249,157,185, 16,150, + 60,236, 48, 75, 25, 21, 68,114,105,211,171,164,193,152,155,106, 28,192,160, 55,121,211, 1,115,236,242,172,248,119,156, 89,183, +140,157,141, 86, 65,149,139, 10,100, 73, 33, 3,166, 86, 66, 66,133, 58,181, 95,135,149,104,219,233, 52, 2, 35,128,166,181,137, +170,147,238,216, 88,251,150, 38,211, 43,145,151,154,178, 62, 60,122, 73, 5, 98, 26,156,150,228, 45, 87, 72, 38,128, 29,190, 48, +124,174,127, 5, 90,198,136,170,252, 95, 49,226,104, 81, 45,222,254, 2,141, 60,233,139,143, 46, 67,130, 82, 20,105, 24, 47, 59, + 40,212,109,123, 86,163,212,141,135, 11,237,169,128,195,149, 96,118,199,117,237,157,219,130,249,251,104,145, 22, 57, 12, 82, 67, + 58,170,200,166,193,129, 33, 25,197,152, 30, 6,245,115, 98,223,113, 55,236, 71,204,196, 89, 18, 56,230,151, 29,150, 96,161,181, + 66,218, 24,141, 44,194,215, 28, 43,123,136,245,224,106,134,183,133, 17, 28,248, 10,128,101,169,171, 45, 69,212,180,234,120,142, + 6, 79,110,227, 96,253,228, 75,221, 88,103, 55,105,110,225, 49,206,169,110,164, 93, 89,164,140, 79, 23,136,100,213,126, 21,205, +125,226, 77,178,231,253,226,118,235,225,110, 56,255, 0,194, 14, 30,222,145,238, 57, 10,179,192,177,163,186,235,158, 51, 96,214, +183,196,173,111,109,171,220,166,251,182,236, 93,195, 43, 35, 51, 51,102,134,105,242,164,105,178, 28,153, 6,185, 29,139,179,176, + 14, 5,201, 55,174,123, 51,177,123, 15, 27,188,118,238,220, 94,218,195, 56,217,184,147,229, 60,197,166,234, 6,133,130,133, 31, +188,211, 99,122,195, 84, 98,180, 60,203,239, 49,182, 60,206,213,193,108, 76,253,191, 47,116,219,243,167,130,105,161,151, 12,228, +205,142,120, 68,250, 48, 99,137, 52, 31,152, 45,142,145,194,247,189,118,221,191,184,246, 94, 22, 55,221,210,247, 12,126,151,116, + 24, 41, 54,217,187,220, 42,134, 23,139,211, 78,223,160,218,248,106,224, 15,151,142,148,127,117,219, 26,103, 24,114,187,107, 12, + 98,117,228,117,200, 12,111,209,185,233,199,164, 75,123,218,222, 31,101, 8,253,220,108,239, 54, 28,139,218,184,178, 71,166,101, +202,195, 50,241, 4, 55,238, 89, 28,203,111,148, 92,139,213,218,233, 81, 83,154,251,181, 68,105,251,134, 77, 43,172,119, 4, 33, +101, 42,173, 96, 94, 91,142, 36,112, 53,244, 17, 4,242, 21,231,187, 79,107,207,178, 9, 49,118,190,222,199,196,199,200,120,229, +151,211,206, 81, 67,198, 95, 75,221,165, 47,123, 53,122, 12,107,161, 21,110, 78,144, 5,201, 36,240, 30, 36,241, 53, 10, 63, 31, + 46, 54,165, 79,227, 74,128,192,126, 81,255, 0,135, 31,236, 45, 71,219,122,155,254, 96,255, 0,135, 31,236, 45, 67,143, 42, 2, +182, 65,248,199,187,241,208,175, 68,201, 7, 88,225,225,246,208,104, 9,220, 92, 19, 76, 24, 3, 92,252, 29,209,141, 58,109,206, + 98, 49,166,225,149,153,134,172,236, 45, 25,194,245, 26,221,207,232,183,166, 54,247,209,227,238,109,134, 92, 87,205, 76,216,206, + 60, 79, 28,110,228, 48,248,166,183, 74,192,128, 72,147, 80,210, 71, 3,225, 66, 27, 5,135, 17, 81,230, 57, 86, 68,157,209,176, +195, 28, 19, 73,157, 26,199,144,172,241, 49, 13,242,198,226, 57, 25,133,174,161, 24,217,181, 91, 79,141, 91,139,119,219,101,157, +113, 99,201, 86,153,229,151, 29, 99, 23,185,150, 1,170, 84,229,249,162,133, 47, 1,111,166,144,246,214, 36, 61,213,182,203,157, +155,181,179, 24,179, 49, 38,120, 18, 38,254,244,199, 2,101, 49, 67,109, 35,225,115,192,155,252, 38,167,133,220,219, 86,108, 27, +107, 60,194, 12,141,207, 30, 12,152,113,159,139, 42,228, 46,184,213,216, 13, 32,183, 16,183, 63, 17, 6,212, 33,178, 13, 76, 90, +177, 83,185,182, 7,108,149, 92,232,201,196,142, 89,242, 24,234, 1, 99,129,186,114,182,162, 44,116, 55, 6,183, 42,173,133,221, +120, 91,132,197, 49,192, 88,151, 50, 76, 19, 36,141,160,177,139, 20,102,179,164,108,186,143, 6,177, 83, 98, 44, 77, 70, 83,162, + 54,165,107,138,195,143,186,246, 9,113,167,204,143, 62, 54,131, 28, 68,101,112, 27,150, 71, 8,116,141, 55,126,161,224,186,111, +115,195,157, 79, 27,185,118,252,204,204, 28, 76, 22,245, 41,157, 30, 84,137,144,135,225, 83,134,209, 71, 34, 48, 54, 55,213, 55, +224,168, 13,114, 40,177, 70,150,212,220, 73,161,220, 85,144, 52,168,176, 0, 84, 3, 44,113, 3,196, 15,101, 18, 36,142,196,233, + 28,234, 60, 45,127, 46, 85, 56,192, 10, 13,253,188,104, 9,170,174,174, 64, 83, 27,234, 0, 1,167,196,211,135, 91,113,112,191, + 77, 69,229,128,114,113,245,208, 18, 42, 0,231,196, 10,174,165, 72, 60, 47, 99, 83, 51, 37,142,147,115,245,208,250,170, 7,202, +110, 61,134,128,145, 35,149, 0,241, 28, 20,223,149, 73,165, 6,215, 6,213, 18,227,219,245, 85, 64, 64,176,240,229,237,166, 37, +173, 97, 77,168, 88,240, 52,197,188,135, 10,160, 96,105,201,248, 79,186,162, 79, 10,102, 39, 77, 64, 48,169,120, 83, 10,149,184, + 80, 19, 28, 0,168,202,108,132,212,237, 67,152, 93, 44,106,144,168, 1,118,225,227, 86, 21, 64,184,168, 66,156,111,245, 83,220, +137, 9,246,214,120,179, 68,138,241,189, 13, 57,113,169,130, 75, 27,253, 21, 15, 42,160, 60,150, 36,183,146, 47,242,209, 18, 88, +213,132,103,196,218,254,223, 42, 25, 54, 81, 33, 31, 9, 26, 26,132, 75,232, 1, 84, 88,252, 90,252,170, 20,147, 42,130,204,162, +214,125, 32,143, 96,185,161,185,213,106, 40, 42,108,169,197, 99, 82, 75,121,179,115,161, 53,173, 84,130, 32,232,229,206,134,201, +196, 27, 85,227,112,128, 16, 8,181, 68,233, 54,248,106,144,168, 0, 18,165,185,112,254, 90,186, 15,215,231, 85, 9,188,227,195, +202,173,167, 27, 10, 2, 87, 21,230,114,109, 89, 25,153, 61,195,186,109, 67,255, 0,173,108,251,169,202,194, 0,113,117,232, 70, + 37,128,255, 0, 54, 85, 22,183,137,175, 77,210, 56, 15, 26,207,219,182,108, 93,179, 47,112,203,129,228,105, 55, 41,134, 68,225, +200, 42, 24, 40, 75, 38,149, 91, 11, 15, 27,208, 51,139,198,238, 8,179,119, 61,231,184,182,223,138,219, 4,121, 49, 33,177, 43, + 36,102,118, 49,183,181, 89,116,154,175, 38,201, 20, 61,140,189,212,153,121, 31,199,134, 34,110, 63,196,140,242,107,234, 48, 18, +152,244,235,209,167,142,141, 58,109, 93, 94, 7,106,236,155, 46,231,184,238, 56,218,245,110,128,140,140, 87, 42, 97, 80,196,179, + 8,215, 72, 32, 49, 39,133,205, 81, 94,200,219, 78, 58,237,199,115,206, 59, 48,109, 95,194, 76,171,209,176,109,125, 50,250, 58, +166, 59,254,110,170, 16,197,220,246,172, 61,243,187,187,107, 35, 48, 76,141,186, 96,203, 54, 74,199, 52,145,217,210, 20, 32, 38, +150, 26, 61,182,231,227, 94,135,184,229, 99,237,248, 25, 57,185,110, 83, 30, 8,158, 89, 89,121,133, 80, 73,211,111, 31, 42,202, +222, 59,115,110,222,103,193,202,108,140,140, 44,140, 13, 99, 30,124, 41, 58, 46, 18, 64, 21,227,190,150,248, 72, 21,177,149,135, +143,184,226,207,133,148,189, 76,108,152,218, 41, 80,240,186, 56, 42,194,227,216,104,138,121,107, 46, 70, 38,103,108,111, 91,118, +215, 62,213,141,153,185,226,227, 12,204,140,233, 38,200,201,135, 38,252, 38,128,151, 85, 12,130,252, 90,226,189, 83,118,255, 0, +253,102,111,248, 18,254,193,174,118, 15,187,220, 40,198,222, 50, 55,109,203, 38, 29,171, 34, 44,172, 8, 37,153, 12,104, 96, 55, + 68, 43,210,248,135,135,157,184, 2, 56,215, 87, 54, 58,100,227,203, 4,132,133,153, 26, 54, 43,204, 6, 26, 77,175,127, 58,220, + 81,147,203,182, 97,254,152,193,237,206,238,131,134,217,157,137,141,131,191,133,182,149,224, 18, 12,182,254,131, 29, 12,124,170, + 47, 60,208,246,116,207,143, 43, 70, 91,184,157, 75, 70,197,110,173,152,110, 46,190, 6,189, 19, 27,183, 54,220,110,223, 94,218, +101,105,246,245,128,227, 17, 49, 5,217, 8, 35,137, 80,162,252,121,129, 89,184,221,139,178,193,219, 50,246,167, 83, 34, 76, 25, + 28,203,214,119, 94,186,185,113, 32,117,116, 69, 0,171, 14, 31, 13, 90, 63,128, 1,221, 19,207, 31,117,118,124,105, 35, 34, 75, +145,148, 36, 69, 36, 6, 2, 11,141, 64,115,172,173,179,183,241,123,151,123,238,184,183,108,140,185, 98,131, 48, 69,141, 10,228, +204,145,199,170, 32,218,213, 17,212, 18, 9,224, 13,192,242,173,236, 94,199,198, 77,199,111,221,115,119, 93,195,112,204,219, 89, +219, 29,178,102, 70, 75, 58,232, 42, 80, 70, 7, 47, 17,196,248,154,218,218,246, 28, 77,175, 51,114,205,199,121, 30, 77,210, 97, +145,144,178, 21, 42,174, 20, 37,163,210,170, 64,176,241, 38,174,218,235, 64,121,102, 30,212,185,255, 0,117,159,234,252,172,252, +231,223,113,162,146, 92, 76,191, 85, 48,233,122,105,222, 20, 72,209, 92, 32, 26, 19,137,181,239,198,245,213,110,248, 24,221,199, +222,157,175, 6,230,210,180, 83,237, 19, 75, 56,134, 89, 32, 46,127,118,196, 51, 64,200,218, 73, 60,129,174,135, 15,178,182,204, +126,210,110,205, 73,103, 59,115, 71, 36, 70, 98,201,215,211, 44,141, 51,124, 93, 61, 23,212,220, 62, 10, 54,229,217, 88,123,150, + 86,223,157, 22,227,157,183,229,109,184,199, 14, 9,176,228,137, 24,198,214,190,190,164, 50,113, 58,124, 45, 88,104,154, 28,150, + 60,179,246,150,243,221,123, 54,213, 52,217, 91,102,221,181,255, 0, 21,197,198,158, 70,152,227, 76, 21,219,160,141, 33,102,210, +246,213, 98,107, 3, 11,105,238,252,205,147, 3,125,217, 54,124,231,238, 41, 86, 28,196,223, 36,220, 96,209, 54,178, 36,116,120, + 27, 32, 14,147, 33, 42, 19, 72,183,143,141,122,214,203,218,187, 78,199, 14, 82, 99, 35,207, 46,121,213,159,151,150,230,121,242, + 13,180,254,250, 71,230, 0, 60, 7, 42,199,199,251,184,197,194,255, 0, 45,131,189,110,152,187, 70,173, 99,104,139, 33, 68, 2, +237,168,198,172, 80,200, 35, 62, 43,171,233,169, 93, 40, 53, 49,101,218,191,212, 63,121, 57,176,110, 89, 25, 49,226,225, 97, 96, +229,140, 8,166, 34, 38,152, 57, 32, 72, 7, 6, 81, 99,112, 57,215,164,107,111, 10,204,139, 97,196,199,223,178,251,133, 30, 67, +151,153, 4, 88,210,198,197,122, 65, 33, 36,169, 81,167, 85,248,241,248,171, 70,222,102,170, 20,151, 34,122,155,240, 95,240,210, +166,176,183, 63, 15,199, 74,169,117,248, 24,207,111,128,255, 0,195,143,246, 22,163, 82,127,238,199,252, 56,255, 0, 97,105,174, + 43, 38,138,153, 63, 56,225,225,248,205, 4, 90,254, 20,124,147,241,143,119,219, 64, 34,230,128,226,113,123, 29,177,100,219,243, + 33,139, 10, 61,203, 31, 47,113,200,203,204, 84, 29, 73, 35,203, 92,181,129, 75,152,245, 62,158,188,122,149,184,112,225,126, 21, +153,254,155,238, 29,191, 15,171, 44, 73,147,149, 62, 94,204,197, 18,105,167, 58,241, 50, 23,171, 35,150,139,224,139,243,190, 17, +100, 95, 14, 21,233, 54,183, 42,110, 23,160, 60,219, 39,182,183,227, 43, 97, 71, 4, 70,109,207,111,222, 19, 42, 86,105, 61, 62, + 59,110, 89,145, 75,161,100, 17,157, 76,138,247, 10, 64,213,164,214,182,205,180,186,119,174,231,152,129,255, 0,135,226,198, 4, + 44,232,200, 14, 94, 66, 67, 22, 67, 33, 96, 3, 89, 49, 18,228,112,248,205,118,118,242,165, 99,206,128,227,223,182, 55,105,119, +121,164,102,129,112, 31,113,147,117,142, 85,119, 51, 93,176, 63,135,172, 44,134, 48,163,226, 58,137, 12,120, 85, 76, 62,200,220, + 49,242,118,174,183, 74,120,241,160,218,211, 33,253, 78, 76,105, 28,187,104,248,138, 99,199,162, 57,245,144,165, 26, 79,151,143, + 15, 10,238,238,105, 95,141,232, 14, 30, 78,199,220,228,197,146, 6,155, 29, 89,177, 55, 72, 20,221,200,234,102,231,166,124, 23, + 26, 7,194, 21, 44,254, 71,149,232,240,118,206,241, 46,104,220, 50,253, 52, 47, 38,229,145,158,240,199, 43,201,166, 57,182,223, +225,232,154,140, 73,118, 18,113, 60, 45,111,170,187, 43,220,210, 28,124,168, 15, 62,151,182,119, 45,155,109,143, 49,204, 83, 73, +129,141,177,198,177,196, 38,144, 52,187, 99, 72, 38,212, 35,137,164, 17,158,173,195, 42, 49, 28,202,240,173, 62,210,218,243, 2, + 99,238,153,152,201, 28,134,109,214, 75,182,184,221, 87, 55, 45,102, 66,144,200,154,172,235, 29,254, 34,164, 11,112,227,195,174, +226, 5, 43,240,172,129, 31,150,244, 93, 62,108,222,235,154, 24,177, 0,123,168,164,113,225, 80, 13,211, 83,207,143,176,154,152, +141, 15, 13, 60,233,128, 60,237,111,109, 72,159, 26, 1,155, 66,139, 90,149,134,145,224, 57, 84, 77,152, 11,155,241,169, 51,170, +242, 34,254, 92, 40, 9,128, 60,120, 82, 38,213, 3, 42, 88, 29, 87, 62, 85, 14,160, 60,193,250,141, 80, 72,183, 11,120, 94,163, +117,225,198,162,231, 80,249, 72, 30,102,154,195,202,128,123,175,157, 53,213,141,188,105,185, 48,169,112,184, 62, 53, 64,136, 21, + 9, 56, 39,188,212,137,227, 80,147,144, 30,218,128, 97,206,164,124,191,219,157, 68,115,169,131,241, 1,238,161, 2, 80,103,229, +106, 41, 54,170,242, 27,145, 84, 18, 78, 2,133,172,107,177,241,162, 19,101,181, 13, 20, 30, 36, 94,162, 70,153, 43,143,136,138, +135,128,189, 64, 48, 91,168, 22, 21, 54, 95,134,212, 97, 23, 35, 96, 21,145,184,131,107,211,201, 18, 24,244,139,233,240,170,235, + 37,133,173,254,192, 82,235,158, 64,154,148, 41, 38,210,171,161, 56, 10, 9, 55, 62,234,145, 96, 87,157, 51, 88, 11,143, 35, 84, +132,227,148, 76, 15, 11, 91,157, 44, 56,186,165,245, 19,111, 14, 62,250,134, 48,210,141,127, 31,178,173,225,170, 32,109, 0,241, + 2,247,243,170, 66, 45,131,103, 87, 86,189,188,253,212, 67, 3,143, 11,209,217,172,188, 60, 42, 9, 37,198,162, 45,127, 10, 10, +130, 42,203,206,153,125,156,105,222,112,218, 66,158, 12,108,105,214,195,149, 1,157,151,253,177,160, 14,116,124,145,121,218,220, +169,149, 13,239, 64, 58,196,229,194,113, 7,135, 47, 42,214,133, 2,128, 7,133, 1, 84, 25, 75,251,135,213, 86,227, 21, 80, 38, + 71,133, 61, 56, 23, 54,169,149,173,163, 13,144,226,105,194,211,218,222, 53, 52,189,105, 10,212,136, 4,114,162,169, 62, 53, 32, + 9,240,162, 42, 15, 26, 74,188,133,104, 73, 7,141,232,160,218,152, 40,181, 72, 14, 53,128,209, 32,212,204,205,249,181, 43, 82, +179, 84,208,210, 6, 88,248,138,129,183, 58, 54,155,243,168,148, 21, 83, 69, 33,195, 79,245,127,251,212,170,122, 69,190,143,199, + 74,173,127, 16, 98, 73,127,221,255, 0,135, 31,236, 45, 71,202,166,227,130,127,135, 31,236, 45, 68,242,172, 2,174, 79,246,163, +221,248,232, 86,183,178,139,147,109, 99,221, 66,250, 62,154, 1,136, 38,157,172, 57, 82,168,155,208, 10,252,105,248,211, 10,152, + 23, 23,231, 66, 17,229,194,155,223, 83, 35,141,237, 75,199,144,160, 26,222,218,110, 34,158,192,120,210,230,121,240,160, 28,113, + 28,105,236, 41,135,143,178,157, 77,239, 89,101, 18, 71,172,233,189,172, 47, 68,232,155,241,115,248, 41,225,252,239,163,141,168, +166,237,207,194,160, 0, 81, 75, 42,130, 79,152,189, 19,163, 17, 54,177, 62,194,105,180,218, 78, 64,123,104,132,248,139, 92, 26, + 1,214, 8,237,193, 64,168, 50,168, 54, 0, 81, 53,248,222,245, 2,202, 56,155,113,160, 35, 96, 89,109,239,162, 17,171,133,168, + 34, 68,215,243, 11, 84,218,104,248, 85, 4,103, 94, 10,183, 63, 69, 7, 74,222,215, 52, 71, 99, 39, 17,203,218, 42, 58, 15, 61, + 92,104, 6,208,188, 13,170, 54, 0,139, 84,237,252,227,194,162, 64, 4, 90,128,102,168, 63,133, 19,153,161,191,205,244, 80, 12, + 62,106,159,247,149, 5,231, 78,198,207,127, 97,161, 2, 57,225, 85,205,181, 15,109, 88, 83,169, 65,160,200, 44,254,234,160, 71, +198,153, 79, 11, 82,189, 9,195,169, 58,121, 26,134,137, 88, 53,248, 15, 97,169,181,200,250, 5, 2, 57, 26,225,124,205, 90,140, +160, 36,185,176,224, 56,209,132, 10,252, 62,131, 81, 60, 15, 31, 34, 42,221,161,117,109, 62, 7,249,106, 13,142, 15,178,245, 10, + 87, 22,191, 30, 85, 54,182,158, 30, 86,169,188, 4, 14, 7,253,191,216,212, 24, 89, 61,188,168, 9,142, 17,147,254,220,168,155, +123, 49,141,137,227,241,126, 42,129,225, 11, 95,157,143,242, 84,240, 56, 68,222,214,173, 35, 44,180,124, 41,141, 47,166,149, 8, + 86,149, 66,188, 96,114,189,205, 16, 92,159,101, 66,127,237,163, 95,125, 20, 3,110, 28,232, 82,132,214,235, 55,149,255, 0, 21, + 78, 53,212,109,238, 38,161, 37,204,173,239,171, 17, 45,184,248,208, 22, 35, 21,109, 5,133, 86,136, 85,181, 28,133,105, 34, 18, + 28, 5,252,105,174,124,233,201, 20,173,126, 85,184,163, 60, 69,195,196,212,209,194,242,161,149,164, 5, 86, 97,166,157, 75, 33, +201,241,162, 41,246,213,117,176,169, 6,227, 87,145,164,215, 50,200, 99, 68, 6,130,188, 71, 58,150,150, 28,107, 45, 34,238,168, +117, 97, 82,214, 60, 42,182,163, 82, 12,107, 46, 37, 65,175,126,116,223, 8,168,131, 76,199,202,148, 52,210, 37,194,223, 71,227, +165, 81,185,211,253, 95,199, 74,148,252, 73, 68, 99, 57,224,159,225,199,251, 11, 81,189, 73,199,201,254, 28,118, 63,212, 90,136, + 28,252,171, 37, 43,100, 31,140,113,240,160,158, 34,173,188, 61, 67,125, 86,240,183, 63,199, 81, 24,191,207,191,209, 64, 85,177, +167,183, 11, 94,172,250, 81,111,155,233,181, 33,139,252,239,193,249,104, 10,192,123,105, 10,179,233,136, 63, 63,224,252,180,189, + 48,253, 63,193, 64, 87, 44, 8,243, 52,194,252,237, 86, 6, 47, 31,159,240,126, 90,113,142, 57, 22,252, 20, 0, 62,129, 77,198, +220,232,254,159,249,223,131,242,210,244,198,255, 0, 55,224,252,180, 0, 7, 30, 53, 43, 11, 94,141,233,237,249,255, 0,130,159, +211,255, 0, 59,240, 84, 96, 18, 7, 0,133,181,185,241,169,252,100,139,176,191,141,133, 26, 60,114, 20,141, 92,205,249,126, 90, +151,167,254,119, 31,117,100, 0,233,241,212,206,111,244,114,167, 17, 90,255, 0, 17,227,237,163,244,180,143,154,254,241, 78, 34, + 35,155, 95,203,133, 80, 86, 49,174,174, 60,173,200,154,114,136, 0,176, 31, 85, 24, 68, 6,171,183, 63,103,229,167,232, 3,195, + 87,183,149, 0, 13, 34,246,176,164,193,121, 27, 81,154, 37,241,113,127,119,229,168,116,211,135,197,171,203,135, 26, 2,185,123, + 49,225,122,142,178,220, 0,250,232,230, 0, 73, 58,255, 0, 5, 68, 64, 0,249,191, 7,229,160, 2, 3,113, 23, 28,106, 60,117, +121,213,161,142, 79, 38,252, 31,150,155,211,113, 63, 23,224,160, 43,220,131, 80, 98, 73,227, 86,253, 53,255, 0, 59,240,126, 90, +131, 99, 92,159,139,240,126, 90, 2,186,243,168, 76, 72, 97, 97,194,223,203, 87, 6, 53,191, 59,240,126, 90,113, 0, 13, 98,220, +199,149, 1, 70, 57,116,130, 41, 51,234,227,231, 87,219, 14, 35,196,159,193, 85,155, 12,107,178,191, 15,119,229,160, 2, 1, 35, +233,169, 63, 20,107,120, 3, 86,125, 37,128,248,252,124,191, 45, 52,152,191, 3,124,118,184,242,252,180, 41,155, 23, 23, 23,163, +184,248, 73,246,209,163,194,211, 32,248,252, 47,203,217,239,162,182, 30,165, 54,107, 11,249,126, 90, 48,138,216,205,102, 32,242, + 35,249, 42,209, 38,212,240,225,105, 23, 47,199,221,249,104,190,155,143,207,127,163,242,212,101, 42,200, 79,133, 6, 78, 11,111, +119,242,213,247,199,254,117,175,195,151,229,170,242, 98, 94,195, 95,143,151,229,160, 4,126, 36,208, 57,159, 26, 44, 3,163, 3, + 22,227, 99,200, 84,198, 45,191, 63,240,126, 90,103,130,224,168,126,126,207,203, 90, 50, 68,102,192,120, 88,131,237,169, 28,172, +114,164, 18, 69,252,106,175,163, 55, 54,127,193,249,105,122, 54,253, 63,193,249,104, 7, 71, 15, 50, 11,234,176, 55, 53,117, 79, +219, 64,197,194, 33,245,234,229,236,252,181,115,211,241,190,175,193, 66,153,197, 63,124,215,240, 63,203, 71, 81,202,140,216,250, +152,177,110,126,207,203, 83,143, 27,143,205,248, 40, 66, 81,175, 10, 56,224,180,233, 0, 3,139,112, 28,233,139, 37,237,196,129, +236, 31,109,105, 52,184,146,143,144,173,194,144, 54,167, 5,125,191, 80,251,105, 89, 79,159,212, 62,218,187,215, 83, 31, 95, 66, + 65,133, 72,113,229, 81, 10, 61,191, 80,251,104,128,168,240, 63, 80,251,106,239,143, 84, 90, 75,160,214,106,112,188,121, 83,134, + 3,192,253, 67,237,169, 9, 71,232,159,168,125,181,119,199,168,113,125, 2, 37,133, 28, 63, 11, 85, 81, 34,254,139,125, 67,237, +169,137,208,126,107,125, 67,237,168,229, 30,165, 81,240, 15,196,248, 83,133, 52, 31, 84,159,162,223, 80,251,105,122,181,253, 22, +250,135,219, 89,220,186,136,169, 46, 40, 61,175, 77,166,132, 50,208,126,107,125, 67,237,164,114,227,253, 6,250,135,219, 83,114, +234, 89, 38,248, 6,211,252,159,142,149, 11,212, 46,157, 86,111,151, 87,135,233,105,243,165, 87,114,234, 74, 63,129,150,224,124, + 23,230, 99,143,246, 22,161,196, 30, 20, 83, 19,176,141,129, 91,116,227,230,234, 15,200,190, 4,138,110,139,255, 0, 51,245,211, +253,234,134,129,243,227, 74,227,143,242, 81, 58, 47,126,105,250,233,246,211,244, 30,255, 0, 50,114,227,241,175,251,212, 7,152, +108, 43,151,151,189,246,219, 77,148,207, 10, 63,112,200, 33,113,171,227,135,112,233, 43,106, 39,158,137, 52,175,232,129,195,157, + 27,119,238,253,255, 0, 3, 59,120,219,161, 49,153,182,181,204,203,102,116,186,140, 83, 22, 49,195,102,247, 62, 75, 95,207,166, +107,183,197,135, 99,235, 65,232,142, 15, 87,252,215,164,232,190, 62,191,237, 71,173,233,104,107,255, 0,107,110,173,191, 59,230, +227, 85, 32,218,182,156,125,227,120,206,201,205,131, 35, 59, 42, 8,134, 94, 60,242,227,218, 28, 52, 18,104, 86,140, 88,136,201, +103,187, 63, 63,162,128,231, 87,184,247,188, 77,204,109, 25, 19,166, 80,135,112,155, 17,243, 12, 74,157, 88,215,106, 59,146,139, + 39,194, 25, 36,176, 54,240,171,178,111,155,164,189,163,219,251,140,114,164, 57,219,199,240,200,230,200, 8, 10,198,115, 58,125, + 87, 68,111,134,255, 0, 17, 10, 15,137,171,237,141,217, 35,106,129, 92,237, 63,194, 4,228,227, 22,151, 20,227,250,139, 49, 58, + 11, 62,142,165,181, 95,198,215,171,217, 16,108,109,177,170,228,122, 31,224, 38, 40,194, 23,151, 28, 98,116, 78,158,142,147,171, +166, 23,229,209,111,101,170, 3,207, 49,119,253,251, 11, 99, 99,139,154,170,216, 88,219,222,233, 36,178,198, 36,245, 47,137,184, + 73, 26, 64, 53,183,194,150, 54,248, 77,197,214,222,221,188, 78,226,222,167,238,104,177,164,149, 87, 6, 77,206,109,184,226,116, +134,160,137,182, 46,226, 24,201,243,106, 18,112,247, 86,211,193,217,205,135,183,220,109, 3, 4, 74,231,108,253,238, 40,135,173, +212, 61, 79, 79,102, 11,171,169,243,105,252,238,124,106,240,135,103, 57,163, 71,160, 25,222,165,237,165,241,250,222,175,160, 53, +254,118,174,175,167,231,249,218, 63,155, 64,115,155, 6, 38,225,182,247, 81,218,103,220, 95, 46, 12, 45,143,111, 77, 46,182, 14, +235, 38, 68, 13, 53,139, 53,153,140, 90,137,185, 60,109,126, 2,177, 31,189,187,133, 50,223, 3, 84, 70, 69,118,218,131,104, 23, +254, 35, 38,116,144, 64,109,195,135,166, 69,123,127, 58,252,133,122, 11,193,183, 29,218, 62,161,195,254, 51,208,110,149,222, 1, +149,233,245,124, 90,126, 46,167, 79, 95, 63, 11,213, 67,143,219,190,160,234, 59,111,168,245,171,170,242, 99,107,245,253, 51,162, +255, 0, 21,253, 71, 78,246,252,237, 62,202, 3,140,151,188,247,200, 97,223, 39, 73, 86,100,199,219,242,243,176,165,104, 81, 34, + 18, 99,100, 54, 56, 17, 40,115, 35, 71,224,122,160, 18,192,219,133, 30,125,199,123,200,220,112,113,102,220,191,240,125,200,112, + 90, 68,141, 83,171, 9,219,142, 88, 87, 85, 54, 32, 23,101,183,184,243, 21,190,152,221,144,173,151,161,182,109, 69,103, 57,223, +189,195, 39, 70,161,234,122,223, 23,203,170,221, 75,240,191, 58,187,147,143,219,182,127, 88,118,219,122,196,234,117,100,198,255, + 0,199,232, 78,158,173, 77,253,190,141, 58,127, 58,214,160, 57,157,239,115,222,240,187,190,120,112, 51, 76,113,100,227,109, 88, +232,140,129,210, 15, 85,155, 60, 13, 40, 82,108, 95,225,176, 39,153, 96, 15, 32, 43, 99, 23,120,222,230,237, 28,252,213,147, 28, +110,120,147,102, 97,193,149, 57, 88, 97,149,241,242,100,197,142, 79,136,132, 26,244, 15, 29, 58,189,149,115,116,198,237,179,144, +195,121, 59,111,170, 56,228, 55,170,151, 24, 75,233,181,139,255, 0,104,218,186,122,237,236,213,237,171,139, 30,210,187, 33, 86, + 24, 45,176,244, 72,185,146, 15, 73,208,247,234,233,232,252, 21, 1,192,100,119,167,116, 44, 71, 31, 16, 60,249, 24,113,229,207, +144,179, 71,139, 3,131,143, 36, 81,172, 57,173, 52,241, 68,170,189, 67,169,160, 45,205, 72,241,173,204, 46,224,223,178,123,189, +246,254,153, 27, 88,205,159, 0,179,250,117, 64, 33,196, 25, 33,146,242,250,135,148,191, 49,211,211,160,251, 47, 90,190,159,176, +198, 46,223,212, 59, 63,167, 73, 95,248,118,169,113, 58,125,109, 74, 36,232,252, 86,103,215,167, 85,184,234,181,248,214,140,112, +246,224,223,221,227, 59,127,250,131, 69,164, 1,224, 57,154, 2,175,204, 47,212,182,141, 63, 69,188, 45, 64,112,125,220,251,154, +247,107, 65, 6,227, 36, 80,176,216,122,112,129,240,163, 75,185,201, 19, 53,131, 11,252,159, 23,233, 3, 99,192, 83,227,239,219, +196,171, 20,226, 76, 87,220,215,109,222, 18, 44,188,157, 49, 43, 75,139,185,195,131, 14,162, 74,198,186,197,184,114, 45,111, 10, +238,183, 24,187,103,248,158, 63,241, 83,183,127, 22,180,126,147,212,182, 63,169,183, 89,122, 93, 46,161,215,110,190,157, 54,252, +251, 91,141, 14, 72,187, 75,160,226, 67,181,244, 12, 57, 93, 77, 79,141,163,161,214, 30,183, 85,205,180,117,237,213,240,215,243, +113,160, 57,225,220, 59,148, 61,143,189,239, 29, 66,219,142,216, 50, 66, 12,136, 86, 57, 99,120, 87, 82,199,144,145,147, 17, 97, +126, 38, 51,164,139, 80, 19,121,238, 25,179,100,217, 61,122, 69, 47,241,108,140, 47,226, 70, 4,184,134, 28, 4,220, 21, 4,103, +224,185,119, 34,231,243, 71,159, 26,234,113,160,237,165,216,165, 92,115,183,127, 0, 11, 32,200,210,248,231, 19, 77,207, 87,170, +117, 24,249,223, 86,175,166,161,184,193,218,173,139,150, 55, 67,182,250,111, 82, 61,111, 94, 76,112,158,171,166,182,235, 23,107, +117,122, 90,126,111,139, 77,188, 40, 15, 60, 27,230,237,157,185,237,155,158, 84,131, 70,126, 39,110,206,248, 12,135,164,143,149, +158,241,188,145,139,240, 60, 11, 3,237, 30, 66,175,203,221, 93,192,152,145,102, 71,151, 20,210,110,121, 15, 6, 62,221, 18, 69, +234,113,213,115,253, 16, 48,245,154, 56,223,224,248, 73,149,173,212, 35,195,133,118, 89, 80,246,183,173,196,245,167,108,245,250, + 34,244, 29,103,198,235,116,250,171,209,232,107,109, 90,122,218,116,105,252,235, 91,141, 86,124, 94,200, 45,186,117, 27,105,214, +228,127, 24,188,184,183,191, 82,195,212,252, 95, 9,234,254,151,231,251,106,130,164, 27,246,226,189,147, 62,243,156,241, 98,103, +194,153, 1,164,101, 89,213, 76, 51, 60, 8,236,152,174,232, 92,133, 4,170,189,131,112,172, 21,221,183,205,198, 77,152, 79,149, + 38, 52,152,253,195, 38, 4,193,146, 37,146, 72,215, 18,105,149,103, 16, 59, 69,113,197, 72, 83,110, 71,152,174,227,211,236, 39, + 99, 35, 86, 15,240, 30,137, 6,210, 65,232,250, 22,227,199, 87, 79, 69,190,138,163, 22, 63,102, 46, 42,136,142,209,233, 6, 76, + 65,109, 38, 33,143,213,233, 29, 30, 58,173,214,211,109, 63,157,110, 84, 6, 94,239,188,111, 56,253,203, 22, 12, 57, 73, 6,223, + 43, 65,140,142,145,199, 58,172,211, 9, 9, 76,161,171,173, 28,141,240,152,184,104, 63,157, 92,191,109,119, 54,247, 14, 47,110, +227,156,198,204,142, 68,219,162,203, 13, 26,157, 35, 55,168, 63,127, 52,143,212,105, 62, 31,131, 64, 63, 41,215,206,189, 22,108, +126,218,254, 55, 11,100,182,221,252,116, 0, 32,234, 73,143,234,236, 67,105,208, 25,186,156,181, 90,222, 23,246,214,102, 54, 55, +221,247, 94, 54,198,109,143,175,117, 17,116,228,194,213,171,172,116,105, 10,220,250,215,181,191, 58,254, 52, 7, 53,147,185,247, + 6, 94, 62,203,186,201,185,116,214, 93,239, 47, 25, 49,226,136, 42,136,241, 87,112,141, 85,219, 85,223, 80,131,136, 60, 57, 30, + 98,167, 7,119,239,121, 56,152,236, 38,138, 41,103,199,237,199, 50,244,193, 8,251,180,175, 22, 75,105, 38,220,128, 42, 60, 43, +180,158, 14,218,244, 48,250,131,182,250, 15, 84,125, 55, 81,241,186, 62,179,170,247,233,234,109, 61,110,174,190, 95, 22,171,248, +214, 43,237,157,135,149,130,241,226,228,109, 80, 96,199, 62, 28,249, 45,137, 62, 26,163, 24,166, 50,227, 71, 57, 4,169, 71,112, +202, 20,243,226, 22,128,210,237,189,210,125,203,110, 97,155, 42,201,149, 14, 78,102, 47, 81, 64, 94,178, 98,100,201,140, 38, 8, + 60,194,139,219,133,235,139,155,188,119,252, 92, 28,204,238,188,115, 51,226,111, 51,193, 31, 72, 1, 3,237,153,107,141, 17,107, + 27,176,117,127,138,254, 54,181,119, 88, 24, 59, 7, 95, 6,109,166, 76, 59,199,139, 52, 88, 49,226,205, 6,147,140,210,196,102, +104,196,109,241, 40,145, 18,228,112, 7,218,107, 51,107,218,251, 43, 6, 29,194, 24,242, 54,220,146, 70, 67,238,114,205, 62, 36, +143,210,146,121, 38,153,114, 72, 35,247,105, 35,149,248,135, 11, 0,121, 84, 97, 25,153, 59,239,114, 97,247, 4, 59, 80,111, 85, + 6, 52,152, 17,229,206, 87, 30, 24,152,103, 75, 34,187, 55, 82,101,148, 21, 65,104,150, 53,107,149, 58,175,122,162,253,201,220, +204,249, 88,163, 38, 38,201,149,213,241, 98,140, 99,145, 44, 7, 36,199,171,108,152,201,210,149,186, 66,218, 38, 58,181,223,194, +187,124,188,126,223, 59,214, 35,103,157,191,248,192, 91, 97,117,164,199,245, 58, 73,107,116,131,182,190,122,173,111,111,182,179, +164,196,236, 51, 30, 96,213,179,104,121, 80,238, 31,189,196, 22,125,109,167,170,117,240,110,165,237,127,206,191,141,232,138,100, +230,238, 18,110,125,175,179,205,145,145,212,143, 63, 55, 15, 31, 54, 84, 86,199,213, 19,101, 8,158, 55, 91,221, 53,105, 8,224, + 27,113, 32,112,170,219,142,211,177,171,224, 99, 96, 60,178,164,123,210,225,228, 70,207, 42,172, 65,226,121,223, 18, 59,104, 6, + 48, 88, 48,181,236,120, 95,133,135, 94,248,251, 17,217,173, 57,192,254, 2, 97, 80, 47, 38, 56,195,232,254,109,190, 46,158,139, +218,222, 20,248, 24,221,180,152, 56,137,183,182,220,112, 68,246,194, 48,201,142, 98,245, 63, 23,246, 37, 90,221, 95,155,151,197, +206,128,243,125,211,212,227,238, 59,166, 68,104,241,193, 6,240, 49, 23,113, 76,135,215, 26, 29,190, 29, 56,190,159,130,152,221, +154,197,181,112,213,123, 87, 95, 46,253, 62,199,216, 88,219,164, 48, 73,149,147, 22,212, 39, 67,160,200,130, 72,241,132,129,167, +179, 43, 4,212, 56,155,214,214, 76, 29,188, 98,159,213, 29,191,165,234, 87,213,117, 31, 31, 79,172,208,154, 58,186,154,221,109, + 26, 45,127,138,214,246, 85, 13,179, 31,177,189, 38,227,252, 13,182, 83,131,211,255, 0,234,199, 14, 76, 62,151, 75, 75,255, 0, +226,186, 77,167, 70,157,127, 63, 11, 95,219, 64,101,238,155,148,153, 59,226,203,162,124, 72,142,199,185,183, 70,112, 99, 58,227, +151, 18,207,166,228, 92, 6, 54, 53, 75,116,202,220,113,182, 62,202,201,199,200,116,110,164, 29,120,128,185,152,141,190,121,116, + 57,230,110, 82,214,243, 55,230, 5,117, 91,254, 47,110, 52,112, 14,230,109,187,166, 25,142, 55,241, 9,113,192,184, 31, 30,142, +187,121,124,214,240,231, 71,220,241,246,159, 79,143,252, 84,225,122,126,180,126,151,213, 73, 6,142,191,247, 61, 46,171, 91, 95, +232,219,143,149, 1,207,246,150,247,186,230,206,216,251,158, 66,102, 9,118,236, 29,205, 38,142, 49, 24,141,179, 58,193,224,248, + 73, 5, 71, 72, 21, 39,141,188,235, 11, 35,188,247,168,240, 50,114, 81,162,234,197,183,239, 89,107,116,225,212,192,207, 92, 72, + 56, 95,151, 76,241,243, 53,219,108,248,155, 24, 92,143,224, 45,129,164,201,124,159, 69, 46, 57, 29, 66, 63,188,233, 55, 59,121, +214, 70,110,213,217,153,176,238,248, 99, 39,108,198,159, 34, 28,132,220,242, 49,178, 48,211, 34, 56,217,148,100,180,143,168,149, +179,233,215,168, 91, 85,175,198,169, 12,201,247,157,237,115,178, 59,127,214,198, 26, 60,217,160,109,200, 68,191, 28, 73,182,141, +196, 70, 18,250, 65,214,246, 36, 27,233, 30,124,106,174,211,220,123,172, 16,118,190, 44, 83,117,160,124, 93,154, 44,200,204,106, + 64,245,177, 16,205, 60,210, 56,145,164,109, 58,147,166, 8,224,117,115,174,177,113,187, 47,248, 81, 19, 29,163,248, 95,169, 45, +198, 92, 95, 79,234,172, 88,241,213,163,169,107,240,231,110, 28,168,141,143,217, 30,163, 21,152,236,254,163,163,140, 48,111, 38, + 38,174,134,161,233, 58, 35, 87,201,170,221, 45, 60, 63, 70,128,224,225,238, 78,232,219, 23, 55, 27, 14, 86,206,120, 50, 55,124, +166,103,244,232,182,198,206,244,235, 28,175,149, 52, 90, 33,226,111,162,236, 46,160,112, 28,123, 30,247,238, 12,238,218,197,198, +220, 96,210,113, 91,212,195, 50, 21,212,198,115,141, 36,184,150,247,203, 16, 79,235, 10,181,145,143,216,135, 39,252,217,217,189, + 82,229, 49,110,164,152,130, 79, 87,240, 7,213,118,185,151,228,189,248,252,190,202,179,220,155, 86, 14,124, 24,127,197,179, 99, +197,194,199,202,134,102, 71,150, 4,142,105, 81,195, 65, 27,188,167,198, 64, 56, 41, 26,185, 80, 28,172, 61,193,220,112,231, 71, +234,167,142, 69, 25,207,180,203,132,177, 0, 67, 69,183, 28,211,149,172,124, 92,100, 91,219,229,210, 71,190,133,143,222, 27,254, + 78, 22, 63, 74, 88, 99,200,200,199,237,182, 18, 24,131, 5,147,119,149,226,201,109, 58,133,197,128,210, 47,194,187, 53,199,216, + 63,141,179,106,192,254, 57,211,179,254,242, 15, 85,211,176,230, 53,117, 52,233,183,209, 85,246,200,123, 21, 98, 97,180,157,156, +199,212,198, 45,233,159, 16,142,169,145,189, 29,244, 55,205,213,191, 75,249,223, 45, 0,219,246,235,159,180,207,177, 97, 71, 42, +200,115, 30,120,179, 37,116, 0,191, 71, 10,124,128,192, 14, 11,121, 34, 4,219,221, 92,156, 61,223,191,105,217,247, 9,230,140, +226,229, 97, 96,203, 42, 66,137, 34, 28,156,140,118,158, 88,114, 2,183, 90, 23,127,135,162, 66,232,243,174,235,123,131, 98,120, + 34,255, 0, 82, 54, 8,199,234,169,135,215,188, 33, 58,193, 91, 78,142,179, 91, 86,157, 95, 69,234,156, 56,253,155,252, 67, 5, +177,219,106,254, 32, 33,140,109,189, 57, 49,122,189, 2,135,163,233,194,182,173, 29, 59,232,211,249,183,183, 10,203,117,124, 10, +142, 71, 3,186,251,170,125,176, 60,197, 32,159, 38,109,152, 99, 79, 50,227,177, 11,186, 77,210,150,208,226,207, 39,238,212, 88, +198,100, 33,141,248,242,174,163,185,115, 55, 60, 53,218, 54,204,108,197,134, 76,222,186,229,102,180,106, 75, 12,124, 73, 39, 33, + 83,130,175, 81,146,230,220,133,237,231, 86,118,232, 59, 49,113,152,109,103,106,244,199, 38, 18,222,157,241,140,126,172,186,156, +127,145,173,213,215,167,167,227,123,105,171,251,236, 59, 27, 97,160,238, 51,133,232,250,170, 99,245,239, 8,143,170, 3, 21,211, +214, 58,117,105,213,244, 95,194,158,192,121,238,201,221,155,244, 81,246,238, 30, 60,102, 92, 72,176,118, 52,203,146, 67, 0, 71, +245,201,162, 89, 37,146,121,146, 98,224, 11,198, 35, 70,187, 3,126,117,157, 7,114,111, 59, 4, 27,140,152,217,158,167, 35,215, +238, 89, 89, 41,208, 66, 93, 96,207, 24,129,167,146, 71, 93, 49,105,248, 66,199,241,130, 64, 31, 8,174,249,241,251, 77,179, 54, +198, 67,181,250,177, 12, 99,103,180,152,162, 79, 78, 65,233,122, 81,170,250, 45,125, 26, 56, 90,246,160,102, 99,118, 65, 96,119, + 38,217,245, 6,201,183, 94, 92, 79,155, 95,249,203,135,110, 39,169,253,175,243,190,110, 53,125,128,161, 63,119,238, 45,186,205, +183, 18,130, 3,186,229,224,112, 91, 55, 66, 45,164,103, 37,141,254,110,177,231,229,194,185,173,187,122,238, 12,113,183, 62, 6, +123, 59,203,219,219, 17, 24,174, 99, 50, 49,145,166, 19,156,111, 82,203, 27,228, 21,141,136,213,243,114, 60,133,119,126,155,180, +127,139,146, 91,106,254, 50,121,222, 76, 95, 85,194, 19,225,171, 95,246, 23,254,167,178,129,155,141,216,205, 30, 50,231,182,205, +160,226,198, 48,186,178, 98, 15,242,154,151,165,208, 44,223,217,106,211,167, 79,195,123, 90,167,176, 26, 93,181,191, 46,231,179, +226,228,205, 50,100,100,178, 94,102, 84, 49, 31,153,144, 23,136,146, 80,252, 4, 31, 11,131,110, 21,175,235, 99,242,172,141,179, + 31, 99,185,254, 12,216, 55,232,195,127, 73, 36, 31,248,127,143,211,255, 0,100,223,217,252,250, 60, 57,219,198,180,125, 57,253, + 36,255, 0,218, 39,251,212,167,128,168,111, 91, 31,149, 47, 91, 23,149, 3,211,159,210, 79,253,162,127,189, 75,211,159,210, 79, +253,162,127,189, 74, 10,150, 61,108,127,163, 75,214, 71,229, 64,232, 31,210, 79,215, 79,247,170, 66, 15,231, 39,235,167,219, 74, +120, 2,215,168, 78,158,171,127,119,127,163,169,166,149, 15, 64,211,211,184,191, 71,157,198,159,237,127, 75,149, 42, 3,255,217, +}; + +#endif diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c new file mode 100644 index 00000000000..41f1f5f0a43 --- /dev/null +++ b/source/blender/src/usiblender.c @@ -0,0 +1,533 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + + /* placed up here because of crappy + * winsock stuff. + */ +#include "BLO_signer_info.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#else +#include <unistd.h> /* getpid */ +#endif +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_linklist.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "DNA_object_types.h" +#include "DNA_space_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_blender.h" +#include "BKE_curve.h" +#include "BKE_displist.h" +#include "BKE_exotic.h" +#include "BKE_font.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_mball.h" +#include "BKE_packedFile.h" + +#include "BIF_fsmenu.h" +#include "BIF_gl.h" +#include "BIF_interface.h" +#include "BIF_usiblender.h" +#include "BIF_drawtext.h" +#include "BIF_editarmature.h" +#include "BIF_editlattice.h" +#include "BIF_editfont.h" +#include "BIF_editmesh.h" +#include "BIF_editsound.h" +#include "BIF_renderwin.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_toolbox.h" + +#include "BSE_drawview.h" +#include "BSE_headerbuttons.h" +#include "BSE_editipo.h" +#include "BSE_editaction.h" +#include "BSE_filesel.h" + +#include "BLO_readfile.h" +#include "BLO_writefile.h" + +#include "BDR_drawobject.h" +#include "BDR_editobject.h" +#include "BDR_vpaint.h" + +#include "BPY_extern.h" +#include "blendef.h" + +#include "interface.h" +#include "radio.h" +#include "render.h" +#include "license_key.h" +#include "datatoc.h" + +#include "SYS_System.h" + +#include "PIL_time.h" + +/***/ + +void BIF_read_file(char *name) +{ + extern short winqueue_break; /* editscreen.c */ + struct BLO_SignerInfo *info; + extern char datatoc_ton[]; + extern int datatoc_tonize; + extern char datatoc_splash_jpg[]; + extern int datatoc_splash_jpg_size; + char infostring[400]; + //hier misschien? + //sound_end_all_sounds(); + + // first try to read exotic file formats... + if (BKE_read_exotic(name) == 0) { /* throws first error box */ + // we didn't succeed, now try to read Blender file + BKE_read_file(name, NULL); /* calls readfile, calls toolbox, throws one more, on failure calls the stream, and that is stubbed.... */ + } + info = BLO_getSignerInfo(); + if (BLO_isValidSignerInfo(info)) { + sprintf(infostring, "File signed by: %s // %s", info->name, info->email); + if (LICENSE_KEY_VALID) { + splash((void *)datatoc_ton, datatoc_tonize, infostring); + } else { + splash((void *)datatoc_splash_jpg, datatoc_splash_jpg_size, infostring); + } + } + BLO_clrSignerInfo(info); + + sound_initialize_sounds(); + + winqueue_break= 1; /* overal uit queue's gaan */ + +} + +int BIF_read_homefile(void) +{ + char tstr[FILE_MAXDIR+FILE_MAXFILE], scestr[FILE_MAXDIR]; + char *home= BLI_gethome(); + int success; + + BLI_make_file_string(G.sce, tstr, home, ".B.blend"); + strcpy(scestr, G.sce); /* even bewaren */ + if (BLI_exists(tstr)) { + success = BKE_read_file(tstr, NULL); + } else { + success = BKE_read_file_from_memory(datatoc_B_blend, datatoc_B_blend_size, NULL); + } + strcpy(G.sce, scestr); + + if (success) { + G.save_over = 0; + + /* disable autoplay in .B.blend... */ + G.fileflags &= ~G_FILE_AUTOPLAY; + + /* holobutton */ + if (strcmp(G.scene->r.ftype, "*@&#")==0) G.special1= G_HOLO; + + if (BLI_streq(U.tempdir, "/")) { + char *tmp= getenv("TEMP"); + + strcpy(U.tempdir, tmp?tmp:"/tmp/"); + } + + if (G.main->versionfile <= 191) { + strcpy(U.plugtexdir, U.textudir); + strcpy(U.sounddir, "/"); + } + + /* patch to set Dupli Armature */ + if (G.main->versionfile < 220) { + U.dupflag |= DUPARM; + } + + /* userdef new option */ + if (G.main->versionfile <= 222) { + U.vrmlflag= USERDEF_VRML_LAYERS; + } + + space_set_commmandline_options(); + + reset_autosave(); + } + + return success; +} + +static void get_autosave_location(char buf[FILE_MAXDIR+FILE_MAXFILE]) +{ + char pidstr[32]; + + sprintf(pidstr, "%d.blend", abs(getpid())); + BLI_make_file_string("/", buf, U.tempdir, pidstr); +} + +void BIF_read_autosavefile(void) +{ + char tstr[FILE_MAXDIR+FILE_MAXFILE], scestr[FILE_MAXDIR]; + int save_over; + + strcpy(scestr, G.sce); /* even bewaren */ + + get_autosave_location(tstr); + + save_over = G.save_over; + BKE_read_file(tstr, NULL); + G.save_over = save_over; + strcpy(G.sce, scestr); +} + +/***/ + +static void readBlog(void) +{ + char name[FILE_MAXDIR+FILE_MAXFILE]; + LinkNode *l, *lines; + + BLI_make_file_string("/", name, BLI_gethome(), ".Blog"); + lines= BLI_read_file_as_lines(name); + + if (lines && !BLI_streq(lines->link, "")) { + strcpy(G.sce, lines->link); + } else { + BLI_make_file_string("/", G.sce, BLI_gethome(), "untitled.blend"); + } + + BLI_free_file_lines(lines); + +#ifdef WIN32 + /* Add the drive names to the listing */ + { + __int64 tmp; + char tmps[4]; + int i; + + tmp= GetLogicalDrives(); + + for (i=2; i < 26; i++) { + if ((tmp>>i) & 1) { + tmps[0]='a'+i; + tmps[1]=':'; + tmps[2]='\\'; + tmps[3]=0; + + fsmenu_insert_entry(tmps, 0); + } + } + + fsmenu_append_seperator(); + } +#endif + + BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs"); + lines= BLI_read_file_as_lines(name); + + for (l= lines; l; l= l->next) { + char *line= l->link; + + if (!BLI_streq(line, "")) { + fsmenu_insert_entry(line, 0); + } + } + + fsmenu_append_seperator(); + BLI_free_file_lines(lines); +} + + +static void writeBlog(void) +{ + char name[FILE_MAXDIR+FILE_MAXFILE]; + FILE *fp; + + BLI_make_file_string("/", name, BLI_gethome(), ".Blog"); + + fp= fopen(name, "w"); + if (fp) { + fprintf(fp, G.sce); + fclose(fp); + } +} + +static void do_history(char *name) +{ + char tempname1[FILE_MAXDIR+FILE_MAXFILE], tempname2[FILE_MAXDIR+FILE_MAXFILE]; + int hisnr= U.versions; + + if(U.versions==0) return; + if(strlen(name)<2) return; + + while( hisnr > 1) { + sprintf(tempname1, "%s%d", name, hisnr-1); + sprintf(tempname2, "%s%d", name, hisnr); + + if(BLI_rename(tempname1, tempname2)) + error("Unable to make version backup"); + + hisnr--; + } + + /* lijkt dubbelop: maar deze is nodig als hisnr==1 */ + sprintf(tempname1, "%s%d", name, hisnr); + + if(BLI_rename(name, tempname1)) + error("Unable to make version backup"); +} + +void BIF_write_file(char *target) +{ + Library *li; + char di[FILE_MAXDIR]; + char *err; + + if (BLI_streq(target, "")) return; + + for (li= G.main->library.first; li; li= li->id.next) { + if (BLI_streq(li->name, target)) { + error("Cannot overwrite used library"); + return; + } + } + + if (!BLO_has_bfile_extension(target)) { + sprintf(di, "%s.blend", target); + } else { + strcpy(di, target); + } + + if (BLI_exists(di)) { + if(!saveover(di)) + return; + } + + waitcursor(1); + + if(G.obedit) { + exit_editmode(0); /* 0 = geen freedata */ + } + if (G.fileflags & G_AUTOPACK) { + packAll(); + } + + do_history(di); + + if (BLO_write_file(di, G.fileflags, &err)) { + strcpy(G.sce, di); + strcpy(G.main->name, di); /* is gegarandeerd current file */ + + G.save_over = 1; + + writeBlog(); + } else { + error("%s", err); + } + + waitcursor(0); +} + +void BIF_write_homefile(void) +{ + char *err, tstr[FILE_MAXDIR+FILE_MAXFILE]; + int write_flags; + + BLI_make_file_string("/", tstr, BLI_gethome(), ".B.blend"); + + /* force save as regular blend file */ + write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN); + BLO_write_file(tstr, write_flags, &err); +} + +void BIF_write_autosave(void) +{ + char *err, tstr[FILE_MAXDIR+FILE_MAXFILE]; + int write_flags; + + get_autosave_location(tstr); + + /* force save as regular blend file */ + write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN); + BLO_write_file(tstr, write_flags, &err); +} + +static void delete_autosave(void) +{ + char tstr[FILE_MAXDIR+FILE_MAXFILE], pidstr[FILE_MAXFILE]; + + sprintf(pidstr, "%d", abs(getpid())); + BLI_make_file_string("/", tstr, U.tempdir, pidstr); + + if (BLI_exists(tstr)) { + char str[FILE_MAXDIR+FILE_MAXFILE]; + BLI_make_file_string("/", str, U.tempdir, "quit.blend"); + BLI_rename(tstr, str); + } +} + +/***/ + +static void initbuttons(void) +{ + uiDefFont(UI_HELVB, + BMF_GetFont(BMF_kHelveticaBold14), + BMF_GetFont(BMF_kHelveticaBold12), + BMF_GetFont(BMF_kHelveticaBold10), + BMF_GetFont(BMF_kHelveticaBold8)); + uiDefFont(UI_HELV, + BMF_GetFont(BMF_kHelvetica12), + BMF_GetFont(BMF_kHelvetica12), + BMF_GetFont(BMF_kHelvetica10), + BMF_GetFont(BMF_kHelveticaBold8)); + + BIF_resources_init(); + + glClearColor(.7, .7, .6, 0.0); + + G.font= BMF_GetFont(BMF_kHelvetica12); + G.fonts= BMF_GetFont(BMF_kHelvetica10); + G.fontss= BMF_GetFont(BMF_kHelveticaBold8); + + /* IKONEN INLADEN */ + + clear_matcopybuf(); +} + +void BIF_init(void) +{ + BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size); + + initscreen(); /* voor (visuele) snelheid, dit eerst, dan setscreen */ + initbuttons(); + init_draw_rects(); /* drawobject.c */ + init_gl_stuff(); /* drawview.c */ + + if (I_AM_PUBLISHER) checkhome(); + + BIF_read_homefile(); + + readBlog(); + strcpy(G.lib, G.sce); +} + +/***/ + +extern unsigned short fullscreen; +extern unsigned short borderless; +extern ListBase editNurb; +extern ListBase editelems; + +void exit_usiblender(void) +{ + extern char *fsmenu; /* filesel.c */ + + freeAllRad(); + BKE_freecubetable(); + + if (G.background == 0) + sound_end_all_sounds(); + + if(G.obedit) { + if(G.obedit->type==OB_FONT) { + free_editText(); + } + else if(G.obedit->type==OB_MBALL) BLI_freelistN(&editelems); + free_editMesh(); + } + + free_editLatt(); + free_editArmature(); + free_posebuf(); + + free_blender(); /* blender.c, doet hele library */ + free_hashedgetab(); + free_matcopybuf(); + free_ipocopybuf(); + freefastshade(); + free_vertexpaint(); + + /* editnurb kan blijven bestaan buiten editmode */ + freeNurblist(&editNurb); + + fsmenu_free(); + + RE_free_render_data(); + RE_free_filt_mask(); + + free_txt_data(); + + sound_exit_audio(); + + BPY_end_python(); + + if (!G.background) { + BIF_resources_free(); + + BIF_close_render_display(); + mainwindow_close(); + } + + if(totblock!=0) { + printf("Error Totblck: %d\n",totblock); + MEM_printmemlist(); + } + delete_autosave(); + + printf("\nBlender quit\n"); + +#ifdef WIN32 + // when debugging enter infinite loop to enable + // reading the printouts... + while(G.f & G_DEBUG) {PIL_sleep_ms(10);} +#endif + + + SYS_DeleteSystem(SYS_GetSystem()); + + exit(G.afbreek==1); +} diff --git a/source/blender/src/view.c b/source/blender/src/view.c new file mode 100644 index 00000000000..05a9de22620 --- /dev/null +++ b/source/blender/src/view.c @@ -0,0 +1,1095 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> + +#ifdef WIN32 +#include <io.h> +#include "BLI_winstuff.h" +#else +#include <unistd.h> +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_space_types.h" +#include "DNA_view3d_types.h" +#include "DNA_camera_types.h" +#include "DNA_lamp_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_utildefines.h" +#include "BKE_object.h" +#include "BKE_global.h" +#include "BKE_main.h" + +#include "BIF_gl.h" +#include "BIF_space.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_toolbox.h" + +#include "BSE_view.h" +#include "BSE_edit.h" /* For countall */ +#include "BSE_drawview.h" /* For inner_play_anim_loop */ + +#include "BDR_drawobject.h" /* For draw_object */ + +#include "mydevice.h" +#include "blendef.h" + +/* Modules used */ +#include "render.h" + +#define TRACKBALLSIZE (1.1) + +void persp3d(View3D *v3d, int a) +{ + ScrArea *area= v3d->area; + + /* oppasen met optimaliseren: dan laatste mode in area bewaren */ + /* only 3D windows */ + if(a== 0) { + bwin_get_winmatrix(area->win, area->winmat); + glMatrixMode(GL_MODELVIEW); + bwin_ortho2(area->win, -0.5, (float)(area->winx)-.05, -0.5, (float)(area->winy)-0.5); + glLoadIdentity(); + } + else if(a== 1) { + glMatrixMode(GL_PROJECTION); + bwin_load_winmatrix(area->win, area->winmat); + glMatrixMode(GL_MODELVIEW); + bwin_load_viewmatrix(area->win, v3d->viewmat); + } +} + +void persp_general(int a) +{ + /* for all window types, not 3D */ + + if(a== 0) { + glPushMatrix(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + + myortho2(-0.5, ((float)(curarea->winx))-0.5, -0.5, ((float)(curarea->winy))-0.5); + glLoadIdentity(); + } + else if(a== 1) { + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } +} + +void persp(int a) +{ + /* oppasen met optimaliseren: dan laatste mode in area bewaren */ + /* only 3D windows */ + + if(curarea->spacetype!=SPACE_VIEW3D) persp_general(a); + else if(a== 0) { + glMatrixMode(GL_PROJECTION); + mygetmatrix(curarea->winmat); + glMatrixMode(GL_MODELVIEW); + myortho2(-0.5, (float)(curarea->winx)-.05, -0.5, (float)(curarea->winy)-0.5); + glLoadIdentity(); + } + else if(a== 1) { + glMatrixMode(GL_PROJECTION); + myloadmatrix(curarea->winmat); + glMatrixMode(GL_MODELVIEW); + myloadmatrix(G.vd->viewmat); + } +} + + +float zfac=1.0; + +void initgrabz(float x, float y, float z) +{ + if(G.vd==0) return; + zfac= G.vd->persmat[0][3]*x+ G.vd->persmat[1][3]*y+ G.vd->persmat[2][3]*z+ G.vd->persmat[3][3]; +} + +void window_to_3d(float *vec, short mx, short my) +{ + /* altijd initzgrab aanroepen */ + float dx, dy; + float fmx, fmy, winx, winy; + + /* stupid! */ + winx= curarea->winx; + winy= curarea->winy; + fmx= mx; + fmy= my; + + dx= (2.0*fmx)/winx; + dx*= zfac; + dy= (2.0*fmy)/winy; + dy*= zfac; + + vec[0]= (G.vd->persinv[0][0]*dx + G.vd->persinv[1][0]*dy); + vec[1]= (G.vd->persinv[0][1]*dx + G.vd->persinv[1][1]*dy); + vec[2]= (G.vd->persinv[0][2]*dx + G.vd->persinv[1][2]*dy); +} + +void project_short(float *vec, short *adr) /* clipt */ +{ + float fx, fy, vec4[4]; + + adr[0]= 3200; + VECCOPY(vec4, vec); + vec4[3]= 1.0; + + Mat4MulVec4fl(G.vd->persmat, vec4); + + if( vec4[3]>0.1 ) { + fx= (curarea->winx/2)+(curarea->winx/2)*vec4[0]/vec4[3]; + + if( fx>0 && fx<curarea->winx) { + + fy= (curarea->winy/2)+(curarea->winy/2)*vec4[1]/vec4[3]; + + if(fy>0.0 && fy< (float)curarea->winy) { + adr[0]= floor(fx+0.5); + adr[1]= floor(fy+0.5); + } + } + } +} + +void project_short_noclip(float *vec, short *adr) +{ + float fx, fy, vec4[4]; + + adr[0]= 3200; + VECCOPY(vec4, vec); + vec4[3]= 1.0; + + Mat4MulVec4fl(G.vd->persmat, vec4); + + if( vec4[3]>0.1 ) { + fx= (curarea->winx/2)+(curarea->winx/2)*vec4[0]/vec4[3]; + + if( fx>-32700 && fx<32700) { + + fy= (curarea->winy/2)+(curarea->winy/2)*vec4[1]/vec4[3]; + + if(fy>-32700.0 && fy<32700.0) { + adr[0]= floor(fx+0.5); + adr[1]= floor(fy+0.5); + } + } + } +} + +int boundbox_clip(float obmat[][4], BoundBox *bb) +{ + /* return 1: afbeelden */ + + float mat[4][4]; + float vec[4], min, max; + int a, flag= -1, fl; + + if(bb==0) return 1; + + Mat4MulMat4(mat, obmat, G.vd->persmat); + + for(a=0; a<8; a++) { + VECCOPY(vec, bb->vec[a]); + vec[3]= 1.0; + Mat4MulVec4fl(mat, vec); + max= vec[3]; + min= -vec[3]; + + fl= 0; + if(vec[0] < min) fl+= 1; + if(vec[0] > max) fl+= 2; + if(vec[1] < min) fl+= 4; + if(vec[1] > max) fl+= 8; + if(vec[2] < min) fl+= 16; + if(vec[2] > max) fl+= 32; + + flag &= fl; + if(flag==0) return 1; + } + + return 0; + +} + +void fdrawline(float x1, float y1, float x2, float y2) +{ + float v[2]; + + glBegin(GL_LINE_STRIP); + v[0] = x1; v[1] = y1; + glVertex2fv(v); + v[0] = x2; v[1] = y2; + glVertex2fv(v); + glEnd(); +} + +void fdrawbox(float x1, float y1, float x2, float y2) +{ + float v[2]; + + glBegin(GL_LINE_STRIP); + + v[0] = x1; v[1] = y1; + glVertex2fv(v); + v[0] = x1; v[1] = y2; + glVertex2fv(v); + v[0] = x2; v[1] = y2; + glVertex2fv(v); + v[0] = x2; v[1] = y1; + glVertex2fv(v); + v[0] = x1; v[1] = y1; + glVertex2fv(v); + + glEnd(); +} + +void sdrawline(short x1, short y1, short x2, short y2) +{ + short v[2]; + + glBegin(GL_LINE_STRIP); + v[0] = x1; v[1] = y1; + glVertex2sv(v); + v[0] = x2; v[1] = y2; + glVertex2sv(v); + glEnd(); +} + +void sdrawbox(short x1, short y1, short x2, short y2) +{ + short v[2]; + + glBegin(GL_LINE_STRIP); + + v[0] = x1; v[1] = y1; + glVertex2sv(v); + v[0] = x1; v[1] = y2; + glVertex2sv(v); + v[0] = x2; v[1] = y2; + glVertex2sv(v); + v[0] = x2; v[1] = y1; + glVertex2sv(v); + v[0] = x1; v[1] = y1; + glVertex2sv(v); + + glEnd(); +} + +/* trackball: deze is t.o.v. een 100% bol formule wel zo mooi */ + +void calctrackballvecfirst(rcti *area, short *mval, float *vec) +{ + float x, y, radius, d, z, t; + + radius= TRACKBALLSIZE; + + /* x en y normaliseren */ + x= (area->xmax + area->xmin)/2 -mval[0]; + x/= (float)((area->xmax - area->xmin)/2); + y= (area->ymax + area->ymin)/2 -mval[1]; + y/= (float)((area->ymax - area->ymin)/2); + + d = sqrt(x*x + y*y); + if (d < radius*M_SQRT1_2) /* Inside sphere */ + z = sqrt(radius*radius - d*d); + else + { /* On hyperbola */ + t = radius / M_SQRT2; + z = t*t / d; + } + + vec[0]= x; + vec[1]= y; + vec[2]= -z; /* jawel! */ + + if( fabs(vec[2])>fabs(vec[1]) && fabs(vec[2])>fabs(vec[0]) ) { + vec[0]= 0.0; + vec[1]= 0.0; + if(vec[2]>0.0) vec[2]= 1.0; else vec[2]= -1.0; + } + else if( fabs(vec[1])>fabs(vec[0]) && fabs(vec[1])>fabs(vec[2]) ) { + vec[0]= 0.0; + vec[2]= 0.0; + if(vec[1]>0.0) vec[1]= 1.0; else vec[1]= -1.0; + } + else { + vec[1]= 0.0; + vec[2]= 0.0; + if(vec[0]>0.0) vec[0]= 1.0; else vec[0]= -1.0; + } +} + +void calctrackballvec(rcti *area, short *mval, float *vec) +{ + float x, y, radius, d, z, t; + + radius= TRACKBALLSIZE; + + /* x en y normaliseren */ + x= (area->xmax + area->xmin)/2 -mval[0]; + x/= (float)((area->xmax - area->xmin)/4); + y= (area->ymax + area->ymin)/2 -mval[1]; + y/= (float)((area->ymax - area->ymin)/2); + + d = sqrt(x*x + y*y); + if (d < radius*M_SQRT1_2) /* Inside sphere */ + z = sqrt(radius*radius - d*d); + else + { /* On hyperbola */ + t = radius / M_SQRT2; + z = t*t / d; + } + + vec[0]= x; + vec[1]= y; + vec[2]= -z; /* jawel! */ + +} + +void viewmove(int mode) +{ + float firstvec[3], newvec[3], dvec[3]; + float oldquat[4], q1[4], q2[4], si, phi; + int firsttime=1; + short mval[2], mvalo[2]; + + /* sometimes this routine is called from headerbuttons */ + areawinset(curarea->win); + curarea->head_swap= 0; + + initgrabz(-G.vd->ofs[0], -G.vd->ofs[1], -G.vd->ofs[2]); + + QUATCOPY(oldquat, G.vd->viewquat); + getmouseco_sc(mvalo); /* werk met screencoordinaten ivm trackball functie */ + calctrackballvec(&curarea->winrct, mvalo, firstvec); + + /* cumultime(0); */ + + while(TRUE) { + getmouseco_sc(mval); + + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || (G.f & G_PLAYANIM)) { + + if(firsttime) { + firsttime= 0; + /* wordt hier geroteerd, gezoomd of transleerd */ + if(mode==0) { + if(G.vd->view!=0) scrarea_queue_headredraw(curarea); /* voor button */ + G.vd->view= 0; + } + + if(G.vd->persp==2 || (G.vd->persp==3 && mode!=1)) { + G.vd->persp= 1; + scrarea_do_windraw(curarea); + scrarea_queue_headredraw(curarea); + } + } + + + if(mode==0) { /* viewroteer */ + + if(U.flag & TRACKBALL) { + calctrackballvec(&curarea->winrct, mval, newvec); + + VecSubf(dvec, newvec, firstvec); + + si= sqrt(dvec[0]*dvec[0]+ dvec[1]*dvec[1]+ dvec[2]*dvec[2]); + si/= (2.0*TRACKBALLSIZE); + + if(si<1.0) { + Crossf(q1+1, firstvec, newvec); + + Normalise(q1+1); + + phi= asin(si); + + si= sin(phi); + q1[0]= cos(phi); + q1[1]*= si; + q1[2]*= si; + q1[3]*= si; + + QuatMul(G.vd->viewquat, q1, oldquat); + } + } + else { + /* roteren om z-as (x beweging) en liggende as (y) */ + + phi= 2*(mval[0]-mvalo[0]); + phi/= (float)curarea->winx; + si= sin(phi); + q1[0]= cos(phi); + q1[1]= q1[2]= 0.0; + q1[3]= si; + + /* liggende as */ + VECCOPY(q2+1, G.vd->viewinv[0]); + Normalise(q2+1); + phi= (mvalo[1]-mval[1]); + phi/= (float)curarea->winy; + si= sin(phi); + q2[0]= cos(phi); + q2[1]*= si; + q2[2]*= si; + q2[3]*= si; + + QuatMul(q1, q1, q2); + QuatMul(G.vd->viewquat, G.vd->viewquat, q1); + } + } + else if(mode==1) { /* translate */ + if(G.vd->persp==3) { + /* zoom= 0.5+0.5*(float)(2<<G.vd->rt1); */ + /* dx-= (mval[0]-mvalo[0])/zoom; */ + /* dy-= (mval[1]-mvalo[1])/zoom; */ + /* G.vd->rt2= dx; */ + /* G.vd->rt3= dy; */ + /* if(G.vd->rt2<-320) G.vd->rt2= -320; */ + /* if(G.vd->rt2> 320) G.vd->rt2= 320; */ + /* if(G.vd->rt3<-250) G.vd->rt3= -250; */ + /* if(G.vd->rt3> 250) G.vd->rt3= 250; */ + } + else { + window_to_3d(dvec, mval[0]-mvalo[0], mval[1]-mvalo[1]); + VecAddf(G.vd->ofs, G.vd->ofs, dvec); + } + } + else if(mode==2) { + G.vd->dist*= 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0; + + /* deze limits ook in toets.c */ + if(G.vd->dist<0.001*G.vd->grid) G.vd->dist= 0.001*G.vd->grid; + if(G.vd->dist>10.0*G.vd->far) G.vd->dist=10.0*G.vd->far; + + mval[1]= mvalo[1]; /* blijft ie zoomen */ + mval[0]= mvalo[0]; + } + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + if(G.f & G_PLAYANIM) inner_play_anim_loop(0, 0); + if(G.f & G_SIMULATION) break; + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + } + else BIF_wait_for_statechange(); + + /* dit moet onderaan, anders pakt de get_mbut het niet op de PC... */ + if( !(get_mbut() & (L_MOUSE|M_MOUSE))) break; + } + + curarea->head_swap= WIN_FRONT_OK; +} + +short v3d_windowmode=0; + +void setwinmatrixview3d(rctf *rect) /* rect: voor picking */ +{ + Camera *cam=0; + float d, near, far, winx = 0.0, winy = 0.0; + float lens, dfac, tfac, fac, x1, y1, x2, y2; + short orth; + + lens= G.vd->lens; + near= G.vd->near; + far= G.vd->far; + + if(G.vd->persp==2) { + if(G.vd->camera) { + if(G.vd->camera->type==OB_LAMP ) { + Lamp *la; + + la= G.vd->camera->data; + fac= cos( M_PI*la->spotsize/360.0); + + x1= saacos(fac); + lens= 16.0*fac/sin(x1); + + near= la->clipsta; + far= la->clipend; + } + else if(G.vd->camera->type==OB_CAMERA) { + cam= G.vd->camera->data; + lens= cam->lens; + near= cam->clipsta; + far= cam->clipend; + + if(cam->type==CAM_ORTHO) { + lens*= 100.0; + near= (near+1.0)*100.0; /* otherwise zbuffer troubles. a Patch! */ + far*= 100.0; + } + } + } + } + + if(v3d_windowmode) { + winx= R.rectx; + winy= R.recty; + } + else { + winx= curarea->winx; + winy= curarea->winy; + } + + if(winx>winy) d= 0.015625*winx*lens; + else d= 0.015625*winy*lens; + + dfac= near/d; + + /* if(G.vd->persp==1 && G.vd->dproj>1.0) far= G.vd->dproj*far; */ + + if(G.vd->persp==0) { + /* x1= -winx*G.vd->dist/1000.0; */ + x1= -G.vd->dist; + x2= -x1; + y1= -winy*G.vd->dist/winx; + y2= -y1; + orth= 1; + } + else { + if(G.vd->persp==2) { + fac= (1.41421+( (float)G.vd->camzoom )/50.0); + fac*= fac; + } + else fac= 2.0; + + x1= -dfac*(winx/fac); + x2= -x1; + y1= -dfac*(winy/fac); + y2= -y1; + + if(G.vd->persp==2 && (G.special1 & G_HOLO)) { + if(cam && (cam->flag & CAM_HOLO2)) { + tfac= fac/4.0; /* de fac is 1280/640 gecorr voor obszoom */ + + if(cam->netend==0.0) cam->netend= EFRA; + fac= (G.scene->r.cfra-1.0)/(cam->netend)-0.5; + + fac*= tfac*(x2-x1); + fac*= ( cam->hololen1 ); + x1-= fac; + x2-= fac; + } + } + + orth= 0; + } + + if(rect) { /* picking */ + rect->xmin/= winx; + rect->xmin= x1+rect->xmin*(x2-x1); + rect->ymin/= winy; + rect->ymin= y1+rect->ymin*(y2-y1); + rect->xmax/= winx; + rect->xmax= x1+rect->xmax*(x2-x1); + rect->ymax/= winy; + rect->ymax= y1+rect->ymax*(y2-y1); + + if(orth) myortho(rect->xmin, rect->xmax, rect->ymin, rect->ymax, -far, far); + else mywindow(rect->xmin, rect->xmax, rect->ymin, rect->ymax, near, far); + + } + else { + if(v3d_windowmode) { + if(orth) i_ortho(x1, x2, y1, y2, -far, far, R.winmat); + else { + if(cam && cam->type==CAM_ORTHO) i_window(x1, x2, y1, y2, near, far, R.winmat); + else i_window(x1, x2, y1, y2, near, far, R.winmat); + } + } + else { + if(orth) myortho(x1, x2, y1, y2, -far, far); + else { + if(cam && cam->type==CAM_ORTHO) mywindow(x1, x2, y1, y2, near, far); + else mywindow(x1, x2, y1, y2, near, far); + } + } + } + + if(v3d_windowmode==0) { + glMatrixMode(GL_PROJECTION); + mygetmatrix(curarea->winmat); + glMatrixMode(GL_MODELVIEW); + } +} + + +void obmat_to_viewmat(Object *ob) +{ + float bmat[4][4]; + float tmat[3][3]; + + Mat4CpyMat4(bmat, ob->obmat); + Mat4Ortho(bmat); + Mat4Invert(G.vd->viewmat, bmat); + + /* viewquat berekenen, o.a. voor add object */ + Mat3CpyMat4(tmat, G.vd->viewmat); + Mat3ToQuat(tmat, G.vd->viewquat); +} + + +void setviewmatrixview3d() +{ + Camera *cam; +/* float bepaalphitheta(); */ + + if(G.special1 & G_HOLO) RE_holoview(); + + if(G.vd->persp>=2) { /* obs/camera */ + if(G.vd->camera) { + + where_is_object(G.vd->camera); + obmat_to_viewmat(G.vd->camera); + + if(G.vd->camera->type==OB_CAMERA) { + cam= G.vd->camera->data; + if(cam->type==CAM_ORTHO) G.vd->viewmat[3][2]*= 100.0; + } + } + else { + QuatToMat4(G.vd->viewquat, G.vd->viewmat); + G.vd->viewmat[3][2]-= G.vd->dist; + } + } + else { + + QuatToMat4(G.vd->viewquat, G.vd->viewmat); + if(G.vd->persp==1) G.vd->viewmat[3][2]-= G.vd->dist; + i_translate(G.vd->ofs[0], G.vd->ofs[1], G.vd->ofs[2], G.vd->viewmat); + } +} + +/* IGLuint-> GLuint*/ +short selectprojektie(unsigned int *buffer, short x1, short y1, short x2, short y2) +{ + rctf rect; + Base *base; + short mval[2], code, hits; + + G.f |= G_PICKSEL; + + if(x1==0 && x2==0 && y1==0 && y2==0) { + getmouseco_areawin(mval); + rect.xmin= mval[0]-7; + rect.xmax= mval[0]+7; + rect.ymin= mval[1]-7; + rect.ymax= mval[1]+7; + } + else { + rect.xmin= x1; + rect.xmax= x2; + rect.ymin= y1; + rect.ymax= y2; + } + setwinmatrixview3d(&rect); + Mat4MulMat4(G.vd->persmat, G.vd->viewmat, curarea->winmat); + + if(G.vd->drawtype > OB_WIRE) { + G.zbuf= TRUE; + glEnable(GL_DEPTH_TEST); + } + + glSelectBuffer( MAXPICKBUF, buffer); + glRenderMode(GL_SELECT); + glInitNames(); /* deze twee fies zijn waarvoor? Anders werkt het niet */ + glPushName(-1); + code= 1; + + if(G.obedit && G.obedit->type==OB_MBALL) { + draw_object(BASACT); + } + else if ((G.obedit && G.obedit->type==OB_ARMATURE)||(G.obpose && G.obpose->type==OB_ARMATURE)) { + draw_object(BASACT); + } + else { + base= G.scene->base.first; + while(base) { + if(base->lay & G.vd->lay) { + base->selcol= code; + glLoadName(code); + draw_object(base); + code++; + } + base= base->next; + } + } + glPopName(); /* zie boven (pushname) */ + hits= glRenderMode(GL_RENDER); + if(hits<0) error("Too many objects in selectbuf"); + + G.f &= ~G_PICKSEL; + setwinmatrixview3d(0); + Mat4MulMat4(G.vd->persmat, G.vd->viewmat, curarea->winmat); + + if(G.vd->drawtype > OB_WIRE) { + G.zbuf= 0; + glDisable(GL_DEPTH_TEST); + } + + return hits; +} + +float *give_cursor() +{ + if(G.vd && G.vd->localview) return G.vd->cursor; + else return G.scene->cursor; +} + +unsigned int free_localbit() +{ + unsigned int lay; + ScrArea *sa; + bScreen *sc; + + lay= 0; + + /* soms kunnen we een localview kwijtrijaken: als een area gesloten wordt */ + /* alle area's aflopen: welke localviews zijn in gebruik */ + sc= G.main->screen.first; + while(sc) { + sa= sc->areabase.first; + while(sa) { + SpaceLink *sl= sa->spacedata.first; + while(sl) { + if(sl->spacetype==SPACE_VIEW3D) { + View3D *v3d= (View3D*) sl; + lay |= v3d->lay; + } + sl= sl->next; + } + sa= sa->next; + } + sc= sc->id.next; + } + + if( (lay & 0x01000000)==0) return 0x01000000; + if( (lay & 0x02000000)==0) return 0x02000000; + if( (lay & 0x04000000)==0) return 0x04000000; + if( (lay & 0x08000000)==0) return 0x08000000; + if( (lay & 0x10000000)==0) return 0x10000000; + if( (lay & 0x20000000)==0) return 0x20000000; + if( (lay & 0x40000000)==0) return 0x40000000; + if( (lay & 0x80000000)==0) return 0x80000000; + + return 0; +} + + +void initlocalview() +{ + Base *base; + float size = 0.0, min[3], max[3], afm[3]; + unsigned int locallay; + int ok=0; + + if(G.vd->localvd) return; + + min[0]= min[1]= min[2]= 1.0e10; + max[0]= max[1]= max[2]= -1.0e10; + + locallay= free_localbit(); + + if(locallay==0) { + error("Sorry, no more than 8 localviews"); + ok= 0; + } + else { + if(G.obedit) { + minmax_object(G.obedit, min, max); + + ok= 1; + + BASACT->lay |= locallay; + G.obedit->lay= BASACT->lay; + } + else { + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + minmax_object(base->object, min, max); + base->lay |= locallay; + base->object->lay= base->lay; + ok= 1; + } + base= base->next; + } + } + + afm[0]= (max[0]-min[0]); + afm[1]= (max[1]-min[1]); + afm[2]= (max[2]-min[2]); + size= MAX3(afm[0], afm[1], afm[2]); + if(size<=0.01) size= 0.01; + } + + if(ok) { + G.vd->localvd= MEM_mallocN(sizeof(View3D), "localview"); + memcpy(G.vd->localvd, G.vd, sizeof(View3D)); + + G.vd->ofs[0]= -(min[0]+max[0])/2.0; + G.vd->ofs[1]= -(min[1]+max[1])/2.0; + G.vd->ofs[2]= -(min[2]+max[2])/2.0; + + G.vd->dist= size; + + if(G.vd->persp>1) { + G.vd->persp= 1; + + } + G.vd->near= 0.1; + G.vd->cursor[0]= -G.vd->ofs[0]; + G.vd->cursor[1]= -G.vd->ofs[1]; + G.vd->cursor[2]= -G.vd->ofs[2]; + + G.vd->lay= locallay; + + countall(); + scrarea_queue_winredraw(curarea); + } + else { + /* flags wissen */ + base= FIRSTBASE; + while(base) { + if( base->lay & locallay ) { + base->lay-= locallay; + if(base->lay==0) base->lay= G.vd->layact; + if(base->object != G.obedit) base->flag |= SELECT; + base->object->lay= base->lay; + } + base= base->next; + } + scrarea_queue_headredraw(curarea); + + G.vd->localview= 0; + } +} + +void centreview() /* localview zonder local! */ +{ + Base *base; + float size, min[3], max[3], afm[3]; + int ok=0; + + min[0]= min[1]= min[2]= 1.0e10; + max[0]= max[1]= max[2]= -1.0e10; + + if(G.obedit) { + minmax_object(G.obedit, min, max); + + ok= 1; + } + else { + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + minmax_object(base->object, min, max); + ok= 1; + } + base= base->next; + } + } + + if(ok==0) return; + + afm[0]= (max[0]-min[0]); + afm[1]= (max[1]-min[1]); + afm[2]= (max[2]-min[2]); + size= MAX3(afm[0], afm[1], afm[2]); + + if(size<=0.01) size= 0.01; + + + + G.vd->ofs[0]= -(min[0]+max[0])/2.0; + G.vd->ofs[1]= -(min[1]+max[1])/2.0; + G.vd->ofs[2]= -(min[2]+max[2])/2.0; + + G.vd->dist= size; + + if(G.vd->persp>1) { + G.vd->persp= 1; + + } + G.vd->near= 0.1; + G.vd->cursor[0]= -G.vd->ofs[0]; + G.vd->cursor[1]= -G.vd->ofs[1]; + G.vd->cursor[2]= -G.vd->ofs[2]; + + scrarea_queue_winredraw(curarea); + +} + + +void restore_localviewdata(View3D *vd) +{ + if(vd->localvd==0) return; + + VECCOPY(vd->ofs, vd->localvd->ofs); + vd->dist= vd->localvd->dist; + vd->persp= vd->localvd->persp; + vd->view= vd->localvd->view; + vd->near= vd->localvd->near; + vd->far= vd->localvd->far; + vd->lay= vd->localvd->lay; + vd->layact= vd->localvd->layact; + vd->drawtype= vd->localvd->drawtype; + vd->camera= vd->localvd->camera; + QUATCOPY(vd->viewquat, vd->localvd->viewquat); + +} + +void endlocalview(ScrArea *sa) +{ + View3D *v3d; + struct Base *base; + unsigned int locallay; + + if(sa->spacetype!=SPACE_VIEW3D) return; + v3d= sa->spacedata.first; + + if(v3d->localvd) { + + locallay= v3d->lay & 0xFF000000; + + restore_localviewdata(v3d); + + MEM_freeN(v3d->localvd); + v3d->localvd= 0; + v3d->localview= 0; + + /* als in ander window de layers zijn veranderd */ + if(v3d->scenelock) v3d->lay= G.scene->lay; + + base= FIRSTBASE; + while(base) { + if( base->lay & locallay ) { + base->lay-= locallay; + if(base->lay==0) base->lay= v3d->layact; + if(base->object != G.obedit) base->flag |= SELECT; + base->object->lay= base->lay; + } + base= base->next; + } + + countall(); + allqueue(REDRAWVIEW3D, 0); /* ivm select */ + + } +} + +void view3d_home(int centre) +{ + Base *base; + float size, min[3], max[3], afm[3]; + int ok= 1, onedone=0; + + if(centre) { + min[0]= min[1]= min[2]= 0.0; + max[0]= max[1]= max[2]= 0.0; + } + else { + min[0]= min[1]= min[2]= 1.0e10; + max[0]= max[1]= max[2]= -1.0e10; + } + + base= FIRSTBASE; + if(base==0) return; + while(base) { + if(base->lay & G.vd->lay) { + onedone= 1; + minmax_object(base->object, min, max); + } + base= base->next; + } + if(!onedone) return; + + afm[0]= (max[0]-min[0]); + afm[1]= (max[1]-min[1]); + afm[2]= (max[2]-min[2]); + size= MAX3(afm[0], afm[1], afm[2]); + if(size==0.0) ok= 0; + + if(ok) { + + G.vd->ofs[0]= -(min[0]+max[0])/2.0; + G.vd->ofs[1]= -(min[1]+max[1])/2.0; + G.vd->ofs[2]= -(min[2]+max[2])/2.0; + + G.vd->dist= size; + + if(G.vd->persp==2) G.vd->persp= 1; + + scrarea_queue_winredraw(curarea); + } +} + + +void view3d_align_axis_to_vector(View3D *v3d, int axisidx, float vec[3]) +{ + float alignaxis[3]; + float norm[3], axis[3], angle; + + alignaxis[0]= alignaxis[1]= alignaxis[2]= 0.0; + alignaxis[axisidx]= 1.0; + + norm[0]= vec[0], norm[1]= vec[1], norm[2]= vec[2]; + Normalise(norm); + + angle= acos(Inpf(alignaxis, norm)); + Crossf(axis, alignaxis, norm); + VecRotToQuat(axis, -angle, v3d->viewquat); + + v3d->view= 0; + if (v3d->persp>=2) v3d->persp= 0; /* switch out of camera mode */ +} + diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c new file mode 100644 index 00000000000..d6e8e9b2654 --- /dev/null +++ b/source/blender/src/vpaint.c @@ -0,0 +1,1169 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> + +#ifdef WIN32 +#include <io.h> +#include "BLI_winstuff.h" +#else +#include <unistd.h> +#endif + +#include "MEM_guardedalloc.h" + +#include "IMB_imbuf.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "MTC_matrixops.h" + +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_mesh.h" +#include "BKE_displist.h" +#include "BKE_global.h" + +#include "BIF_graphics.h" +#include "BIF_interface.h" +#include "BIF_mywindow.h" +#include "BIF_editview.h" +#include "BIF_space.h" +#include "BIF_screen.h" +#include "BIF_toolbox.h" +#include "BIF_gl.h" + +#include "BDR_vpaint.h" + +#include "BSE_drawview.h" +#include "BSE_trans_types.h" +#include "BSE_view.h" + +#include "mydevice.h" +#include "blendef.h" + +#include "BIF_editdeform.h" + + /* Gvp.mode */ +#define VP_MIX 0 +#define VP_ADD 1 +#define VP_SUB 2 +#define VP_MUL 3 +#define VP_FILT 4 + + /* Gvp.flag */ +#define VP_COLINDEX 1 +#define VP_AREA 2 +#define VP_SOFT 4 +#define VP_NORMALS 8 + +#define MAXINDEX 65336 + +VPaint Gvp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT}; +float vpimat[3][3]; +unsigned int *vpaintundobuf=0; +int totvpaintundo; +short *indexar= 0; + +int totwpaintundo; +MDeformVert *wpaintundobuf=NULL; + +/* Function prototypes */ +int calc_vp_alpha_dl(DispList *disp, MVert *mvert, int vert, short *mval); + +/* in tegenstelling tot cpack teken kleuren, zijn de MCOL kleuren (vpaint kleuren) per byte! + en dus endian ongevoelig. Mcol = ABGR!!! Oppassen met cpack functies */ + +unsigned int rgba_to_mcol(float r, float g, float b, float a) +{ + int ir, ig, ib, ia; + unsigned int col; + char *cp; + + ir= floor(255.0*r); + if(ir<0) ir= 0; else if(ir>255) ir= 255; + ig= floor(255.0*g); + if(ig<0) ig= 0; else if(ig>255) ig= 255; + ib= floor(255.0*b); + if(ib<0) ib= 0; else if(ib>255) ib= 255; + ia= floor(255.0*a); + if(ia<0) ia= 0; else if(ia>255) ia= 255; + + cp= (char *)&col; + cp[0]= ia; + cp[1]= ib; + cp[2]= ig; + cp[3]= ir; + + return col; + +} + +unsigned int vpaint_get_current_col(void) +{ + return rgba_to_mcol(Gvp.r, Gvp.g, Gvp.b, 1.0); +} + +void do_shared_vertexcol(Mesh *me) +{ + /* als geen mcol: niet doen */ + /* als tface: alleen de betreffende vlakken, anders alles */ + MFace *mface; + TFace *tface; + int a; + short *scolmain, *scol; + char *mcol; + + if(me->mcol==0 || me->totvert==0 || me->totface==0) return; + + scolmain= MEM_callocN(4*sizeof(short)*me->totvert, "colmain"); + + tface= me->tface; + mface= me->mface; + mcol= (char *)me->mcol; + for(a=me->totface; a>0; a--, mface++, mcol+=16) { + if(mface->v3) { + if(tface==0 || (tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) { + + scol= scolmain+4*mface->v1; + scol[0]++; scol[1]+= mcol[1]; scol[2]+= mcol[2]; scol[3]+= mcol[3]; + scol= scolmain+4*mface->v2; + scol[0]++; scol[1]+= mcol[5]; scol[2]+= mcol[6]; scol[3]+= mcol[7]; + scol= scolmain+4*mface->v3; + scol[0]++; scol[1]+= mcol[9]; scol[2]+= mcol[10]; scol[3]+= mcol[11]; + if(mface->v4) { + scol= scolmain+4*mface->v4; + scol[0]++; scol[1]+= mcol[13]; scol[2]+= mcol[14]; scol[3]+= mcol[15]; + } + } + } + if(tface) tface++; + } + + a= me->totvert; + scol= scolmain; + while(a--) { + if(scol[0]>1) { + scol[1]/= scol[0]; + scol[2]/= scol[0]; + scol[3]/= scol[0]; + } + scol+= 4; + } + + tface= me->tface; + mface= me->mface; + mcol= (char *)me->mcol; + for(a=me->totface; a>0; a--, mface++, mcol+=16) { + if(mface->v3) { + if(tface==0 || (tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) { + + scol= scolmain+4*mface->v1; + mcol[1]= scol[1]; mcol[2]= scol[2]; mcol[3]= scol[3]; + + scol= scolmain+4*mface->v2; + mcol[5]= scol[1]; mcol[6]= scol[2]; mcol[7]= scol[3]; + + scol= scolmain+4*mface->v3; + mcol[9]= scol[1]; mcol[10]= scol[2]; mcol[11]= scol[3]; + + if(mface->v4) { + scol= scolmain+4*mface->v4; + mcol[13]= scol[1]; mcol[14]= scol[2]; mcol[15]= scol[3]; + } + } + } + if(tface) tface++; + } + + MEM_freeN(scolmain); +} + +void make_vertexcol() /* single ob */ +{ + Object *ob; + Mesh *me; + DispList *dl; + + /* + * Always copies from shadedisplist to mcol. + * When there are tfaces, it copies the colors and frees mcol + */ + + if(G.obedit) { + error("Unable to perform function in EditMode"); + return; + } + + ob= OBACT; + me= get_mesh(ob); + if(me==0) return; + + if(me->flag & ME_TWOSIDED) { + me->flag &= ~ME_TWOSIDED; + } + + dl= ob->disp.first; + + if(dl==0 || dl->col1==NULL) { + shadeDispList(ob); + dl= ob->disp.first; + } + if(dl && dl->col1) { + int i; + + if(me->mcol) MEM_freeN(me->mcol); + + me->mcol= MEM_dupallocN(dl->col1); + if (me->mcol) { + for (i=0; i<me->totface*4; i++) { + MCol *mcol= &me->mcol[i]; + mcol->a= 255; + } + } + + if(me->tface) mcol_to_tface(me, 1); + } + freedisplist(&(ob->disp)); + + + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); +} + + + +void copy_vpaint_undo(unsigned int *mcol, int tot) +{ + if(vpaintundobuf) MEM_freeN(vpaintundobuf); + vpaintundobuf= 0; + + if(mcol==0 || tot==0) return; + + vpaintundobuf= MEM_mallocN(4*sizeof(int)*tot, "vpaintundobuf"); + memcpy(vpaintundobuf, mcol, 4*sizeof(int)*tot); + totvpaintundo= tot; + +} + +void vpaint_undo() +{ + Mesh *me; + Object *ob; + unsigned int temp, *from, *to; + int a; + + if((G.f & G_VERTEXPAINT)==0) return; + if(vpaintundobuf==0) return; + + ob= OBACT; + me= get_mesh(ob); + if(me==0 || me->totface==0) return; + + if(me->tface) tface_to_mcol(me); + else if(me->mcol==0) return; + + a= MIN2(me->totface, totvpaintundo); + from= vpaintundobuf; + to= (unsigned int *)me->mcol; + a*= 4; + while(a--) { + temp= *to; + *to= *from; + *from= temp; + to++; from++; + } + allqueue(REDRAWVIEW3D, 0); + if(me->tface) mcol_to_tface(me, 1); +} + +void clear_vpaint() +{ + Mesh *me; + Object *ob; + unsigned int *to, paintcol; + int a; + + if((G.f & G_VERTEXPAINT)==0) return; + + ob= OBACT; + me= get_mesh(ob); + if(me==0 || me->totface==0) return; + + if(me->tface) tface_to_mcol(me); + if(me->mcol==0) return; + + paintcol= vpaint_get_current_col(); + + to= (unsigned int *)me->mcol; + copy_vpaint_undo(to, me->totface); + a= 4*me->totface; + while(a--) { + *to= paintcol; + to++; + } + allqueue(REDRAWVIEW3D, 0); + if(me->tface) mcol_to_tface(me, 1); +} + +void clear_vpaint_selectedfaces() +{ + Mesh *me; + TFace *tf; + Object *ob; + unsigned int paintcol; + int i; + + ob= OBACT; + + me= get_mesh(ob); + tf = me->tface; + if (!tf) return; /* should not happen, but you never know */ + + if(me==0 || me->totface==0) return; + + paintcol= vpaint_get_current_col(); + + for (i = 0; i < me->totface; i++) { + if (tf[i].flag & TF_SELECT) { + tf[i].col[0] = paintcol; + tf[i].col[1] = paintcol; + tf[i].col[2] = paintcol; + tf[i].col[3] = paintcol; + } + } + allqueue(REDRAWVIEW3D, 0); +} + +void vpaint_dogamma() +{ + Mesh *me; + Object *ob; + float igam, fac; + int a, temp; + char *cp, gamtab[256]; + + if((G.f & G_VERTEXPAINT)==0) return; + + ob= OBACT; + me= get_mesh(ob); + if(me==0 || me->totface==0) return; + + if(me->tface) tface_to_mcol(me); + else if(me->mcol==0) return; + + copy_vpaint_undo((unsigned int *)me->mcol, me->totface); + + igam= 1.0/Gvp.gamma; + for(a=0; a<256; a++) { + + fac= ((float)a)/255.0; + fac= Gvp.mul*pow( fac, igam); + + temp= 255.9*fac; + + if(temp<=0) gamtab[a]= 0; + else if(temp>=255) gamtab[a]= 255; + else gamtab[a]= temp; + } + + a= 4*me->totface; + cp= (char *)me->mcol; + while(a--) { + + cp[1]= gamtab[ cp[1] ]; + cp[2]= gamtab[ cp[2] ]; + cp[3]= gamtab[ cp[3] ]; + + cp+= 4; + } + allqueue(REDRAWVIEW3D, 0); + + if(me->tface) mcol_to_tface(me, 1); +} + + +void sample_vpaint() /* frontbuf */ +{ + unsigned int col; + int x, y; + short mval[2]; + char *cp; + + getmouseco_areawin(mval); + x= mval[0]; y= mval[1]; + + if(x<0 || y<0) return; + if(x>=curarea->winx || y>=curarea->winy) return; + + x+= curarea->winrct.xmin; + y+= curarea->winrct.ymin; + + glReadBuffer(GL_FRONT); + glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); + glReadBuffer(GL_BACK); + + cp = (char *)&col; + + Gvp.r= cp[0]; + Gvp.r /= 255.0; + + Gvp.g= cp[1]; + Gvp.g /= 255.0; + + Gvp.b= cp[2]; + Gvp.b /= 255.0; + + allqueue(REDRAWBUTSGAME, 0); +} + +void init_vertexpaint() +{ + + indexar= MEM_mallocN(sizeof(short)*MAXINDEX + 2, "vertexpaint"); +} + + +void free_vertexpaint() +{ + + if(indexar) MEM_freeN(indexar); + indexar= NULL; + if(vpaintundobuf) MEM_freeN(vpaintundobuf); + vpaintundobuf= NULL; + if(wpaintundobuf) + free_dverts(wpaintundobuf, totwpaintundo); + wpaintundobuf= NULL; +} + + +static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac) +{ + char *cp1, *cp2, *cp; + int mfac; + unsigned int col=0; + + if(fac==0) return col1; + if(fac>=255) return col2; + + mfac= 255-fac; + + cp1= (char *)&col1; + cp2= (char *)&col2; + cp= (char *)&col; + + cp[0]= 255; + cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8; + cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8; + cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8; + + return col; +} + +static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac) +{ + char *cp1, *cp2, *cp; + int temp; + unsigned int col=0; + + if(fac==0) return col1; + + cp1= (char *)&col1; + cp2= (char *)&col2; + cp= (char *)&col; + + cp[0]= 255; + temp= cp1[1] + ((fac*cp2[1])>>8); + if(temp>254) cp[1]= 255; else cp[1]= temp; + temp= cp1[2] + ((fac*cp2[2])>>8); + if(temp>254) cp[2]= 255; else cp[2]= temp; + temp= cp1[3] + ((fac*cp2[3])>>8); + if(temp>254) cp[3]= 255; else cp[3]= temp; + + return col; +} + +static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac) +{ + char *cp1, *cp2, *cp; + int temp; + unsigned int col=0; + + if(fac==0) return col1; + + cp1= (char *)&col1; + cp2= (char *)&col2; + cp= (char *)&col; + + cp[0]= 255; + temp= cp1[1] - ((fac*cp2[1])>>8); + if(temp<0) cp[1]= 0; else cp[1]= temp; + temp= cp1[2] - ((fac*cp2[2])>>8); + if(temp<0) cp[2]= 0; else cp[2]= temp; + temp= cp1[3] - ((fac*cp2[3])>>8); + if(temp<0) cp[3]= 0; else cp[3]= temp; + + return col; +} + +static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac) +{ + char *cp1, *cp2, *cp; + int mfac; + unsigned int col=0; + + if(fac==0) return col1; + + mfac= 255-fac; + + cp1= (char *)&col1; + cp2= (char *)&col2; + cp= (char *)&col; + + /* eerstmullen, dan fac blenden */ + cp[0]= 255; + cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])>>8) )>>8; + cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])>>8) )>>8; + cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])>>8) )>>8; + + + return col; +} + +static void vpaint_blend( unsigned int *col, unsigned int paintcol, int alpha) +{ + + if(Gvp.mode==VP_MIX || Gvp.mode==VP_FILT) *col= mcol_blend( *col, paintcol, alpha); + else if(Gvp.mode==VP_ADD) *col= mcol_add( *col, paintcol, alpha); + else if(Gvp.mode==VP_SUB) *col= mcol_sub( *col, paintcol, alpha); + else if(Gvp.mode==VP_MUL) *col= mcol_mul( *col, paintcol, alpha); +} + + +static int sample_backbuf_area(int x, int y) +{ + unsigned int rect[129*129], *rt; + int x1, y1, x2, y2, size, a, tot=0, index; + + if(totvpaintundo>=MAXINDEX) return 0; + + if(Gvp.size>64.0) Gvp.size= 64.0; + + x1= x-Gvp.size; + x2= x+Gvp.size; + CLAMP(x1, 0, curarea->winx); + CLAMP(x2, 0, curarea->winx); + y1= y-Gvp.size; + y2= y+Gvp.size; + CLAMP(y1, 0, curarea->winy); + CLAMP(y2, 0, curarea->winy); + + glReadPixels(x1+curarea->winrct.xmin, y1+curarea->winrct.ymin, x2-x1+1, y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE, rect); + if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr( (int)(4*Gvp.size*Gvp.size), rect); + + rt= rect; + size= (y2-y1)*(x2-x1); + if(size<=0) return 0; + + memset(indexar, 0, 2*totvpaintundo+2); /* plus 2! first element is total */ + + while(size--) { + + if(*rt) { + index= framebuffer_to_index(*rt); + if(index>0 && index<=totvpaintundo) + indexar[index] = 1; + } + + rt++; + } + + for(a=1; a<=totvpaintundo; a++) { + if(indexar[a]) indexar[tot++]= a; + } + + return tot; +} + +static unsigned int sample_backbuf(int x, int y) +{ + unsigned int col; + + if(x>=curarea->winx || y>=curarea->winy) return 0; + + x+= curarea->winrct.xmin; + y+= curarea->winrct.ymin; + + glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); + if(G.order==B_ENDIAN) SWITCH_INT(col); + + return framebuffer_to_index(col); +} + +static int calc_vp_alpha(MVert *mvert, short *mval) +{ + float fac, dx, dy, nor[3]; + int alpha; + short vertco[2]; + + if(Gvp.flag & VP_SOFT) { + project_short_noclip(mvert->co , vertco); + dx= mval[0]-vertco[0]; + dy= mval[1]-vertco[1]; + + fac= sqrt(dx*dx + dy*dy); + if(fac > Gvp.size) return 0; + + alpha= 255.0*Gvp.a*(1.0-fac/Gvp.size); + } + else { + alpha= 255.0*Gvp.a; + } + if(Gvp.flag & VP_NORMALS) { + VECCOPY(nor, mvert->no); + + /* transpose ! */ + fac= vpimat[2][0]*nor[0]+vpimat[2][1]*nor[1]+vpimat[2][2]*nor[2]; + if(fac>0.0) { + dx= vpimat[0][0]*nor[0]+vpimat[0][1]*nor[1]+vpimat[0][2]*nor[2]; + dy= vpimat[1][0]*nor[0]+vpimat[1][1]*nor[1]+vpimat[1][2]*nor[2]; + + alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac); + } + else return 0; + } + + return alpha; + +} + +int calc_vp_alpha_dl(DispList *disp, MVert *mvert, int vert, short *mval) +/* Lets us do soft vertex painting onto a deformed mesh */ +{ + float fac, dx, dy, nor[3]; + int alpha; + short vertco[2]; + + /* For safety's sake !*/ + if (!disp || !disp->verts || !disp->nors) + return calc_vp_alpha (mvert+vert, mval); + +// make display list + if(Gvp.flag & VP_SOFT) { + project_short_noclip(disp->verts+(vert*3), vertco); + dx= mval[0]-vertco[0]; + dy= mval[1]-vertco[1]; + + fac= sqrt(dx*dx + dy*dy); + if(fac > Gvp.size) return 0; + + alpha= 255.0*Gvp.a*(1.0-fac/Gvp.size); + } + else { + alpha= 255.0*Gvp.a; + } + + if(Gvp.flag & VP_NORMALS) { + + VECCOPY(nor, disp->nors+(vert*3)); + +// transpose ! + fac= vpimat[2][0]*nor[0]+vpimat[2][1]*nor[1]+vpimat[2][2]*nor[2]; + if(fac>0.0) { + dx= vpimat[0][0]*nor[0]+vpimat[0][1]*nor[1]+vpimat[0][2]*nor[2]; + dy= vpimat[1][0]*nor[0]+vpimat[1][1]*nor[1]+vpimat[1][2]*nor[2]; + + alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac); + } + else return 0; + } + + return alpha; + +} + + +void wpaint_undo (void){ + Mesh *me; + + me = get_mesh(OBACT); + if (!me) + return; + + if (!wpaintundobuf) + return; + + if (!me->dvert) + return; + + if (totwpaintundo != me->totvert) + return; + + free_dverts(me->dvert, me->totvert); + + me->dvert= MEM_mallocN(sizeof(MDeformVert)*me->totvert, "deformVert"); + copy_dverts(me->dvert, wpaintundobuf, totwpaintundo); + + makeDispList(OBACT); + scrarea_do_windraw(curarea); + +}; + +void copy_wpaint_undo (MDeformVert *dverts, int dcount){ + if (wpaintundobuf) + free_dverts(wpaintundobuf, totwpaintundo); + + wpaintundobuf = MEM_mallocN (sizeof(MDeformVert)*dcount, "wpaintundo"); + totwpaintundo = dcount; + copy_dverts (wpaintundobuf, dverts, dcount); +}; + +void weight_paint(void) +{ + Object *ob; + Mesh *me; + MFace *mface; + TFace *tface; + float mat[4][4], imat[4][4]; + int index, totindex; + short mval[2], mvalo[2], firsttime=1; + MDeformWeight *dw, *uw; + extern float editbutvweight; + DispList *dl; + + + if((G.f & G_WEIGHTPAINT)==0) return; + if(G.obedit) return; + if(G.obpose) return; + + if(indexar==0) init_vertexpaint(); + + ob= OBACT; + me= get_mesh(ob); + if (!me->dvert){ + return; + } + if(me==0 || me->totface==0) return; + if(ob->lay & G.vd->lay); else error("Active object not in this layer!"); + +// if(me->tface==NULL && me->mcol==NULL) make_vertexcol(); + +// if(me->tface==NULL && me->mcol==NULL) return; + + /* imat voor normalen */ + Mat4MulMat4(mat, ob->obmat, G.vd->viewmat); + Mat4Invert(imat, mat); + Mat3CpyMat4(vpimat, imat); + + /* projektiematrix laden */ + mymultmatrix(ob->obmat); + mygetsingmatrix(mat); + myloadmatrix(G.vd->viewmat); + + getmouseco_areawin(mvalo); + + if(me->tface) tface_to_mcol(me); + copy_vpaint_undo( (unsigned int *)me->mcol, me->totface); + copy_wpaint_undo(me->dvert, me->totvert); + + getmouseco_areawin(mval); + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + while (get_mbut() & L_MOUSE) { + getmouseco_areawin(mval); + + if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + + if(firsttime) draw_sel_circle(mval, 0, Gvp.size, Gvp.size, 0); + else draw_sel_circle(mval, mvalo, Gvp.size, Gvp.size, 0); + + firsttime= 0; + + /* welke vlakken doen mee */ + if(Gvp.flag & VP_AREA) { + totindex= sample_backbuf_area(mval[0], mval[1]); + } + else { + indexar[0]= sample_backbuf(mval[0], mval[1]); + if(indexar[0]) totindex= 1; + else totindex= 0; + } + + MTC_Mat4SwapMat4(G.vd->persmat, mat); + + if(Gvp.flag & VP_COLINDEX) { + for(index=0; index<totindex; index++) { + if(indexar[index] && indexar[index]<=me->totface) { + + mface= ((MFace *)me->mface) + (indexar[index]-1); + + if(mface->mat_nr!=ob->actcol-1) { + indexar[index]= 0; + } + } + } + } + + if((G.f & G_FACESELECT) && me->tface) { + for(index=0; index<totindex; index++) { + if(indexar[index] && indexar[index]<=me->totface) { + + tface= ((TFace *)me->tface) + (indexar[index]-1); + + if((tface->flag & TF_SELECT)==0) { + indexar[index]= 0; + } + } + } + } + + dl= find_displist(&ob->disp, DL_VERTS); + for(index=0; index<totindex; index++) { + + if(indexar[index] && indexar[index]<=me->totface) { + mface= ((MFace *)me->mface) + (indexar[index]-1); + + + if (calc_vp_alpha_dl(dl, me->mvert, mface->v1, mval)){ + dw= verify_defweight(me->dvert+mface->v1, ob->actdef-1); + uw= verify_defweight(wpaintundobuf+mface->v1, ob->actdef-1); + if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a)); + } + + if (calc_vp_alpha_dl(dl, me->mvert, mface->v2, mval)){ + dw= verify_defweight(me->dvert+mface->v2, ob->actdef-1); + uw= verify_defweight(wpaintundobuf+mface->v2, ob->actdef-1); + if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a)); + } + + if (calc_vp_alpha_dl(dl, me->mvert, mface->v3, mval)){ + dw= verify_defweight(me->dvert+mface->v3, ob->actdef-1); + uw= verify_defweight(wpaintundobuf+mface->v3, ob->actdef-1); + if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a)); + } + + if(mface->v4) { + if (calc_vp_alpha_dl(dl, me->mvert, mface->v4, mval)){ + dw= verify_defweight(me->dvert+mface->v4, ob->actdef-1); + uw= verify_defweight(wpaintundobuf+mface->v4, ob->actdef-1); + if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a)); + } + } + } + } + + MTC_Mat4SwapMat4(G.vd->persmat, mat); + + } + else BIF_wait_for_statechange(); + + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { +// makeDispList(ob); + scrarea_do_windraw(curarea); + screen_swapbuffers(); + backdrawview3d(0); + draw_sel_circle(mval, 0, Gvp.size, Gvp.size, 0); + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + } + } + + if(me->tface) { + MEM_freeN(me->mcol); + me->mcol= 0; + } + + /* cirkel wissen */ + draw_sel_circle(0, mvalo, 0, Gvp.size, 1); + + makeDispList(ob); + + allqueue(REDRAWVIEW3D, 0); + +} + +void vertex_paint() +{ + Object *ob; + Mesh *me; + MFace *mface; + TFace *tface; + float mat[4][4], imat[4][4]; + unsigned int paintcol=0, *mcol, fcol1, fcol2; + int index, alpha, totindex, total; + short mval[2], mvalo[2], firsttime=1; + + if((G.f & G_VERTEXPAINT)==0) return; + if(G.obedit) return; + + if(indexar==0) init_vertexpaint(); + + ob= OBACT; + me= get_mesh(ob); + if(me==0 || me->totface==0) return; + if(ob->lay & G.vd->lay); else error("Active object not in this layer!"); + + if(me->tface==NULL && me->mcol==NULL) make_vertexcol(); + + if(me->tface==NULL && me->mcol==NULL) return; + + /* imat voor normalen */ + Mat4MulMat4(mat, ob->obmat, G.vd->viewmat); + Mat4Invert(imat, mat); + Mat3CpyMat4(vpimat, imat); + + /* projektiematrix laden */ + mymultmatrix(ob->obmat); + mygetsingmatrix(mat); + myloadmatrix(G.vd->viewmat); + + paintcol= vpaint_get_current_col(); + + getmouseco_areawin(mvalo); + + if(me->tface) tface_to_mcol(me); + copy_vpaint_undo( (unsigned int *)me->mcol, me->totface); + + getmouseco_areawin(mval); + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + while (get_mbut() & L_MOUSE) { + getmouseco_areawin(mval); + + if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + + if(firsttime) draw_sel_circle(mval, 0, Gvp.size, Gvp.size, 0); + else draw_sel_circle(mval, mvalo, Gvp.size, Gvp.size, 0); + + firsttime= 0; + + /* welke vlakken doen mee */ + if(Gvp.flag & VP_AREA) { + totindex= sample_backbuf_area(mval[0], mval[1]); + } + else { + indexar[0]= sample_backbuf(mval[0], mval[1]); + if(indexar[0]) totindex= 1; + else totindex= 0; + } + + MTC_Mat4SwapMat4(G.vd->persmat, mat); + + if(Gvp.flag & VP_COLINDEX) { + for(index=0; index<totindex; index++) { + if(indexar[index] && indexar[index]<=me->totface) { + + mface= ((MFace *)me->mface) + (indexar[index]-1); + + if(mface->mat_nr!=ob->actcol-1) { + indexar[index]= 0; + } + } + } + } + if((G.f & G_FACESELECT) && me->tface) { + for(index=0; index<totindex; index++) { + if(indexar[index] && indexar[index]<=me->totface) { + + tface= ((TFace *)me->tface) + (indexar[index]-1); + + if((tface->flag & TF_SELECT)==0) { + indexar[index]= 0; + } + } + } + } + + for(index=0; index<totindex; index++) { + + if(indexar[index] && indexar[index]<=me->totface) { + + mface= ((MFace *)me->mface) + (indexar[index]-1); + mcol= ( (unsigned int *)me->mcol) + 4*(indexar[index]-1); + + if(Gvp.mode==VP_FILT) { + fcol1= mcol_blend( mcol[0], mcol[1], 128); + if(mface->v4) { + fcol2= mcol_blend( mcol[2], mcol[3], 128); + paintcol= mcol_blend( fcol1, fcol2, 128); + } + else { + paintcol= mcol_blend( mcol[2], fcol1, 170); + } + + } + + total= 0; + + total+= alpha= calc_vp_alpha(me->mvert+mface->v1, mval); + if(alpha) vpaint_blend( mcol, paintcol, alpha); + + total+= alpha= calc_vp_alpha(me->mvert+mface->v2, mval); + if(alpha) vpaint_blend( mcol+1, paintcol, alpha); + + total+= alpha= calc_vp_alpha(me->mvert+mface->v3, mval); + if(alpha) vpaint_blend( mcol+2, paintcol, alpha); + + if(mface->v4) { + total+= alpha= calc_vp_alpha(me->mvert+mface->v4, mval); + if(alpha) vpaint_blend( mcol+3, paintcol, alpha); + } + + /* if(total==0) { */ + /* alpha= 25*Gvp.a; */ + /* vpaint_blend( mcol, paintcol, alpha); */ + /* vpaint_blend( mcol+1, paintcol, alpha); */ + /* vpaint_blend( mcol+2, paintcol, alpha); */ + /* if(mface->v4) vpaint_blend( mcol+3, paintcol, alpha); */ + /* } */ + } + } + + MTC_Mat4SwapMat4(G.vd->persmat, mat); + + } + else BIF_wait_for_statechange(); + + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + do_shared_vertexcol(me); + if(me->tface) { + mcol_to_tface(me, 0); + } + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + backdrawview3d(0); + draw_sel_circle(mval, 0, Gvp.size, Gvp.size, 0); + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + } + } + + if(me->tface) { + MEM_freeN(me->mcol); + me->mcol= 0; + } + + /* cirkel wissen */ + draw_sel_circle(0, mvalo, 0, Gvp.size, 1); + + allqueue(REDRAWVIEW3D, 0); +} + +void set_wpaint(void) /* toggle */ +{ + Object *ob; + Mesh *me; + + scrarea_queue_headredraw(curarea); + ob= OBACT; + me= get_mesh(ob); + + if(me && me->totface>=MAXINDEX) { + error("Maximum number of faces: %d", MAXINDEX-1); + G.f &= ~G_WEIGHTPAINT; + return; + } + +// if(me && me->tface==NULL && me->mcol==NULL) make_vertexcol(); + + if(G.f & G_WEIGHTPAINT) G.f &= ~G_WEIGHTPAINT; + else G.f |= G_WEIGHTPAINT; + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSGAME, 0); + + if(G.f & G_WEIGHTPAINT) { + setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT); + } + else { + freefastshade(); /* voor zekerheid */ + if (ob) + makeDispList(ob); + if(!(G.f & G_FACESELECT)) + setcursor_space(SPACE_VIEW3D, CURSOR_STD); + } +} + + +void set_vpaint(void) /* toggle */ +{ + Object *ob; + Mesh *me; + + scrarea_queue_headredraw(curarea); + ob= OBACT; + me= get_mesh(ob); + + if(me && me->totface>=MAXINDEX) { + error("Maximum number of faces: %d", MAXINDEX-1); + G.f &= ~G_VERTEXPAINT; + return; + } + + if(me && me->tface==NULL && me->mcol==NULL) make_vertexcol(); + + if(G.f & G_VERTEXPAINT){ + G.f &= ~G_VERTEXPAINT; + } + else { + G.f |= G_VERTEXPAINT; + /* Turn off weight painting */ + if (G.f & G_WEIGHTPAINT) + set_wpaint(); + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSGAME, 0); + + if(G.f & G_VERTEXPAINT) { + setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT); + } + else { + freefastshade(); /* voor zekerheid */ + if (ob) makeDispList(ob); + if((G.f & G_FACESELECT)==0) setcursor_space(SPACE_VIEW3D, CURSOR_STD); + } +} + diff --git a/source/blender/src/windows_creator_splash.jpg.c b/source/blender/src/windows_creator_splash.jpg.c new file mode 100644 index 00000000000..577ca6b0c83 --- /dev/null +++ b/source/blender/src/windows_creator_splash.jpg.c @@ -0,0 +1,989 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifdef _WIN32 +/* DataToC output of file <splash_jpg> */ + +int datatoc_splash_jpg_size= 30379; +char datatoc_splash_jpg[]= { +255,216,255,224, 0, 16, 74, 70, 73, 70, 0, + 1, 2, 0, 0,100, 0,100, 0, 0,255,236, 0, 17, 68,117, 99,107,121, 0, 1, 0, 4, 0, 0, 0, 50, 0, 0,255,238, 0, 14, + 65,100,111, 98,101, 0,100,192, 0, 0, 0, 1,255,219, 0,132, 0, 8, 6, 6, 6, 6, 6, 8, 6, 6, 8, 12, 8, 7, 8, 12, + 14, 10, 8, 8, 10, 14, 16, 13, 13, 14, 13, 13, 16, 17, 12, 14, 13, 13, 14, 12, 17, 15, 18, 19, 20, 19, 18, 15, 24, 24, 26, 26, + 24, 24, 35, 34, 34, 34, 35, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 1, 9, 8, 8, 9, 10, 9, 11, 9, 9, 11, 14, 11, 13, 11, + 14, 17, 14, 14, 14, 14, 17, 19, 13, 13, 14, 13, 13, 19, 24, 17, 15, 15, 15, 15, 17, 24, 22, 23, 20, 20, 20, 23, 22, 26, 26, 24, + 24, 26, 26, 33, 33, 32, 33, 33, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,255,192, 0, 17, 8, 1, 15, 1,244, 3, 1, 34, 0, 2, + 17, 1, 3, 17, 1,255,196, 0,194, 0, 0, 1, 5, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2, 4, 5, 6, + 0, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 16, 0, 2, 1, + 3, 2, 4, 2, 5, 7, 7, 8, 7, 4, 6, 11, 1, 1, 2, 3, 0, 17, 4, 18, 5, 33, 49, 19, 6, 65, 20, 81, 97,113, 34, 50, +129,145,161,209, 66, 21, 7,193,225, 82,146,178, 35, 51,177, 98,114,130, 67,115, 36, 22,240,210, 83, 99,131,195, 52,162,211, 84, + 54,147,163,179,132,196, 37,241,194,226, 68,100,116,148,164, 53, 69, 23, 38, 17, 0, 2, 2, 1, 2, 4, 4, 3, 5, 7, 4, 3, + 0, 0, 0, 0, 0, 1, 17, 2, 3, 33, 4, 49, 65, 81, 18, 97,113, 19, 5,129,145, 34,161,177,193,209, 50,240,225, 66, 82, 98, +146, 20,114, 35, 51, 21,241,147, 52,255,218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0,246, 67, 44,170,177,170,200,202, 58, +113,216, 2, 64,248, 22,157, 28,211, 27,222, 70, 63,214, 52, 39,251, 31,221,199,251, 11, 78,136,112,160, 31, 36,211,134, 22,145, +173,111,210, 52,195,147, 48, 63,196,127,214, 53,210, 94,255, 0, 37, 9,175,107,154, 16, 55,152,154,215, 18, 55,235, 26, 97,159, + 32,155,117, 92,127, 88,253,116,197,189,175,110, 52,224, 63, 61, 0, 65, 52,252,140,175,250,199,235,164,234, 77,225, 52,159,172, +105, 56, 87,112, 20, 2,153,114, 57,137, 95,245,141, 55,204,100,218,253, 86,253, 99, 93,198,247,240,166,158, 30,202, 0,121, 25, + 89, 74, 20,117, 93,110,111,112,198,132,217,153, 86,176,158, 75,255, 0, 77,190,186,102, 91, 19, 34,173,248, 1,113,242,159,205, + 64,191, 11,212,101, 14, 50,242,207, 60,137, 63, 93,190,186,119,155,202,183,241,228,253,118,250,232, 11,114, 44, 41,116,250,104, + 7,140,204,195,202,121, 63, 93,190,186,112,202,204, 60, 60,196,159,174,223, 93, 13, 0, 6,187, 80,185, 52, 4,129,147,148, 0, +253,252,159,174,223, 93,115,101,228,143,237,228,253, 99,245,212,114,215,181,171,135, 30, 38,128,145, 30,108,250,142,169,220,122, + 46,199,235,162,140,169,219,148,237,111, 78,179,245,208,225, 95,112,146, 1, 23, 63, 85,119, 78, 34, 73,208, 56,115, 60, 42, 0, +167, 43, 33, 64, 61, 71, 35,211,168,253,116,225,149, 63,140,175,234,247,143,215, 81, 66, 33, 54, 26,138,155,145,107,216, 91,217, + 74,177, 48,184, 12,126, 95, 69, 1, 32,100,228, 17,126,179,241,240,212,126,186,239, 49,147,199,247,175,250,199,235,168,218, 92, + 88,171, 2, 7,170,156, 76,136,190,242,131,236, 60,120,252,148, 1,252,196,246,254, 51,254,177,250,232, 47,147,144,150, 38,121, + 63, 93,143,229,166, 23, 60,244,145,235,166, 18, 30,192, 11, 91,159, 10,160, 41,204,200,182,161, 59,129,107,147,169,190,186,140, +217,217,142,196,137,229, 3,192, 7,111,174,147, 32, 16, 84,125,147, 77, 69,176, 44,220, 7, 59,250, 5, 80, 27,206,101,162,221, +178, 36, 62,129,173,184,159,158,155,231,115, 87,226,200,144,147,196,251,237, 97,244,208, 12,128,176, 39,151, 36, 20,215, 12,198, +224,216,122,104, 3, 28,204,208,110,114,165, 3,208, 29,190,186,112,206,203, 97,117,200,151,245,219,235,168,227, 73, 22, 62,245, +169, 1, 55,176, 22, 20, 1,198,102,117,253,236,153, 7,245,219,235,164,243,249,136,226,249, 50,144,124, 53,183,215, 64,144, 1, +196,154,116, 49,235, 58,156,112,160, 38,121,252,163,192, 79, 33,191,243,219,235,161,249,172,245,185,108,137,120,242, 29, 70,250, +235,128, 0,220, 10, 70, 26,143,178,128,107,102,231,248, 79, 47,235,183,215, 74, 50,183, 6, 23,243, 18,175,245,219,235,174, 0, + 6,231,242, 83, 76,161,156,170,142, 2,128, 42,207,153,194,249, 51, 31,248,140, 7,242,211,219, 59, 34, 62, 7, 34, 75,255, 0, + 77,190,186,134,229,239,197,172, 41, 27, 79,197,107,154, 2, 75,103,102, 91,221,158, 67,127,231,183,215, 76, 57,249,129,108,114, + 36,213,234,118,250,232, 58,137, 94, 60, 9,166,132, 0,223,153,160, 12,185,153,195,137,201,151,229,145,190,186, 47,222, 25, 96, + 91,175, 33, 62,146,237,245,212,106,235, 84,146,192,111, 61,154,127,251,196,191,174,223, 93,119,157,205,255, 0,196,203,250,237, +245,208,111,232,164,227, 64, 72,243,185,159,248,153,127, 93,190,186,239, 59,155,255, 0,136,151,245,219,235,160,172,108,223, 10, +147,110,118, 20, 79, 46,227,226,178,250,201, 31,146,133, 29,231, 51,127,241, 50,254,187,125,116,190,115, 51,255, 0, 17, 47,235, +183,215, 72, 34,140,115, 98,222,155, 15,202,105,193, 21, 69,194,113,254,113,164, 18, 81,222,115, 55,255, 0, 17, 47,235,183,215, + 79, 89,247, 6, 54, 19, 75,242,187, 15,229, 52,128,181,253,211,110, 87,210, 45, 78, 17,234,241, 39,211,122, 9, 30, 38,203, 6, +207,150,227,210, 3,177, 63,203, 68, 25, 50, 0, 15, 94,119, 60,254, 50, 1,254, 90, 8,143,222, 42, 71,174,244, 97, 21,215,135, + 46, 71,215, 64, 59,207,100,169, 10,142,194,231,237, 51, 55,237, 26, 70,200,203, 99,198,105, 7,177,136, 28, 61,149,205,208, 69, +247,217,111,127, 77, 50, 92,172,100, 85, 0,146, 0,240, 28,232, 65,195, 35, 36,139,137,228,229,250, 77,207,231,167,117,179, 47, +110,172,150,225,115,169,190,186,132,251,154, 14, 17,197,242,147, 76,243,243, 30, 54, 22,244, 85, 41,102, 95, 42,215, 19,200, 63, +174,126,186, 67,149, 36,100,106,201,111,149,201,252,181, 75, 36,211, 61,181, 57, 55,245,210, 69, 11, 59,129,233,160,130,236,231, + 11, 27,100,200,124, 88,130,198,195,242, 83, 27,118, 85, 28, 38,145,141,173,123,145,249,106,187,203,158, 94, 62, 52, 57, 97, 34, +192, 14,116, 5,199,222, 11,209,234,234,125, 93, 13, 90,238,111,110,190,142,124,235,170, 22,143,240,182,255, 0,240,182,255, 0, +247, 85,213, 6,165,131,253,143,238,227,253,133,162, 40, 54,181, 49,184,152,255, 0,161, 31,236, 45, 20,112,170, 64, 50, 41, 4, +113,240,166, 27,159, 11,218,137, 49, 26,135,178,134, 26,132, 20, 19,202,145, 89,174,111,202,148, 17, 92,109,202,244, 3,129,174, + 38,147,128, 28,107,174, 40, 5, 12, 24, 16, 60, 41,141,110, 84,183,183,133, 52,131,122, 2, 12,195, 84,204, 1,245,124,194,144, + 40,189,113,107,185,111, 79, 26, 75,159,158,161, 66, 92, 3, 76, 44, 77,112,231, 74,124, 40, 14, 0,215, 17,194,187, 87,133, 33, +185, 52, 7, 49, 84, 4,158, 0, 14, 53, 75, 38,251, 46,191,220,198,186, 7, 45, 87, 36,252,196, 85,222,128, 65,191, 26,163,207, +218, 26, 61, 83,226,141, 73,205,163,241, 30,207, 85,124,255, 0,114,123,165,142,182,219, 54,149,101,222, 63, 87,135,192,247,108, + 22,217,221,215,112,165,218, 21,103,244,151, 91,102,235,139,149, 24,140,251,147, 11,150, 67,198,255, 0,209,181, 75, 18, 70,110, +110, 1,245,240,172, 42,179, 35, 6, 82, 85,135, 16, 71, 2, 13, 95, 96,111, 34, 66,176,229,144, 30,218, 86, 94, 64,255, 0, 75, +215, 92, 54, 94,233, 92,145,143,112,213,109,193, 91,133,109,231,209,157,183,158,218,233, 57, 48, 77,171,206,188,235,229,213, 23, + 72,215, 3, 75,128, 9,185,227,225,234,163, 43,113,230,121, 80, 68,122,172, 56, 17,111,116,211, 66,139, 3,192, 88,219,135, 14, + 7,217, 95, 88,249, 97,253,210,120, 30, 39,141, 36,159,103,192,131,199,228,174, 88,199, 48,197, 84,241, 60,111,111,146,152,200, +111,118,114,125,100, 15, 26, 1,204, 65,227,202,144,128,110, 71, 42, 97, 18,223,152, 63, 37, 57,120, 11,183, 51,206,170, 0,166, + 82,197,111,198,198,214,168,242, 72, 28,233,251, 10,120,159, 73,165,200,155, 91, 21, 94, 67,133,232, 12,192, 91, 72,170, 7,190, +163,240,138, 65,196, 88,183,182,144, 51,178,218,213,203, 17,230, 79,205, 64, 38,181, 83,101, 30,218, 86, 12,255, 0, 8,176,167, + 5, 11,199,249,105,117,169, 54, 28, 77, 0,206,141,197,201,189, 17, 13,190, 74,102,167,191, 30, 2,145,130,252, 71,230,160, 15, +123,138, 65,207,143, 10, 21,201, 94, 0,131, 74,173,101,227,206,128,123, 58,134,210, 56,147,204,208,201, 32,216,123,162,184,146, + 79,162,184, 35, 55, 32, 77, 36,176, 35, 16,222, 23,165,227, 69, 88, 24,252, 76,171,237, 63, 85,233,235, 12, 66,218,153,154,254, + 10, 45,244,154,128,143, 93,196,240, 28,106, 72, 69, 31, 10, 3,111, 22, 55,250,133, 40, 12,120, 41,183,137, 0, 90,130, 64, 8, +164, 62, 22,246,240,254, 90,114,194,191,105,192,246,113, 52, 96,151,240,227,123, 18,104,130, 32, 1,191, 11, 85, 18, 5, 35,136, +125,150, 99,235, 54, 7,242,209, 5,144,141, 17,170,216,220,220,106, 35,229,107,211,129,133, 64,214,226,254,179, 77,108,204, 88, +197,133,216,248, 88, 84, 3,152, 72,222,243, 18, 86,153,211,244, 14,124,175, 77, 59,128, 96, 2, 71,192,122, 77, 71,151, 54,115, +192, 89,125,130,169, 9,162, 18, 71, 31,150,185,250, 72, 46,238, 61,119, 53, 94, 30,105, 5,203, 19,242,211, 26, 54, 45, 99,225, + 66,193, 60,100, 99,160, 54, 55,246, 10, 99,238, 1,108, 18, 63,158,131, 20, 62,230,170, 89, 32,211,102,240,229, 64, 39,156,157, +174, 69,151,217, 67,146, 89,223,226,114,126, 90,120, 64,139,115,227,198,164, 69, 18,206, 2,173,135,137, 53, 13, 70,132, 36,141, +139, 15, 93, 73,242,199,231,227, 82, 76, 35, 30,236,228, 30, 28, 45, 81,134, 85,223,151, 14, 66,169,146, 57,142,220, 45,198,142, + 35,210,160, 26,144, 52,223, 89, 30,241,226, 13, 68,152,179, 57, 81,200, 84, 52,180,212, 48,131,169, 98,190, 21, 33, 33,104, 13, +219,131,120, 15, 85, 7, 13,136, 58, 91,194,165, 78,196,198,204, 5,141, 8,220,185, 35,188,240,161,210, 26,199,213, 77,115, 27, +128, 3, 94,255, 0,106,162,178, 0, 47,226,105,208,130, 47,232,163, 21,227,169, 97,210,255, 0, 11,241, 11,121,107,120,255, 0, +226,111, 93, 79,176,242,218,124, 60,191,255, 0, 17, 93, 80,222,159,105, 36,124, 81,223,194, 56,255, 0, 97,104,151, 20,136,183, +210,127,221,199,251, 11, 79, 49, 3,225, 90, 57, 17,230,182,161,236,160, 26,145, 52, 87,111,146,130, 98, 54,161, 6,131, 75,171, +198,144,194, 71,137,167, 8,184,115,160, 18,254, 55,174,213,227, 74, 33, 35,198,184,163, 91,133, 0,151, 52,174,196, 35, 16,120, +128, 72,249,169, 44,195,194,133, 53,250,100,122,109,106, 2, 56,224, 41, 9, 23,246, 87,105,244,210,129, 80,162,113,168, 19,238, +248,145, 62,129,170, 82, 57,149,181,190,115, 83,229, 93,104,200, 13,139, 2,160,250, 46, 43, 50,251,118,100,108, 84,196, 77,188, + 87,136,175,159,238, 27,141,206, 37, 69,183,163,125,211, 54, 75,186, 60, 15,118,199, 6,223, 43,183,175,120,136,138,207,108,248, +150, 99,125,199, 31,217, 63,209, 75,247,238, 63,251, 39,250, 42,167,200,102,127,176,127,154,184,224,229,128, 73,133,128, 28, 73, + 35,149,124,207,243,253,199,249, 95,254,191,220,125, 15,240,182, 31,204,191,191,247,150,255, 0,127, 65,111,225, 63,209, 72, 55, +248, 71,246, 79,244, 85, 13,117,115,255, 0,182,221,255, 0, 50,254,212,116,255, 0,172,218,255, 0, 43,254,230, 76,205,159, 19, + 32,245, 32,137,162,147,237,114,210,125,126,218,135, 82, 49,240,115, 50,191,233,177,228,148,122, 81, 73, 31, 56,163,190,203,187, + 70,186,159, 10, 96, 61, 33, 9,254, 74,242,221,101,202,222, 95, 77,235,171,117,172, 87,236, 61, 52,120,177, 37,143,189,105,193, + 90,210,254,208,187,110,243, 46, 25, 17, 77,121, 32,228, 63, 73,125,149,162,139, 42, 9,149, 36,141,195, 33,227,122,197, 50,178, +146,172, 10,176,224, 65,224, 69, 72,194,206,159, 6, 77,113, 27,169,248,163, 63, 9,175,110,203,220,239,134, 49,230,155, 83,132, +255, 0, 21,127, 52,120,247,158,221, 76,179,147, 20, 86,252, 99,248,109,251,205,173,227, 63, 11, 94,244,209,107,241, 62,193,225, + 64,194,204,198,220, 98,234, 70, 61,241,241,198,109,117, 52,116,138, 38,213,238,218,191, 67, 75,214,245, 87,163, 86,171,213, 52, +124, 43,210,212,179,165,211,171, 92, 83, 22,196,113, 6,161,207, 41,227, 26,159,233, 26,172,220, 59,183,183,182,173,209,182,172, +249,228,199,153, 2,182,182, 86, 49,217,198,161,197,117,125, 34,164, 99,230, 97,231,171, 79,131,144,153, 16,150, 32, 73, 27, 6, + 28, 60, 56,120,215, 95, 78,233, 43, 58,180,158,169,198,135, 42,228,165,155,173,108,155, 92, 84,234,190, 1, 2,169,224,120,211, +186,104,188,105,108, 71, 30, 0, 83, 24,134, 62,161,202,161,177, 89,213, 71,166,184,179, 21,247,120,122,104, 51, 77, 20, 8,102, +157,214, 40,215,226,145,200, 85, 23,225,204,212,120,247, 93,182, 87, 17, 67,155, 4,146, 57,178,162,202,140, 73,244, 0, 13,234, +164,222,169, 50, 54,147,134,210, 37,139,114,102,185,174,226, 13,149,108, 60, 77, 32, 30, 35,157, 21, 23, 85,139, 15, 96,168, 81, +140, 3, 91,137,246, 10,122,199, 41, 22, 9,111,111,231,163,170,183, 33,194,212,253, 7,129, 38,212, 4,110,137,251, 76, 63,150, +148, 70,131,215, 69,115, 18,220,150, 22,166,117,225, 28,174,212, 7, 5, 0,216, 15,101, 16, 33, 35,249,106, 63,155,187,123,171, + 77,147, 38,126, 74,116,251, 40, 9,145,199,194,252,184,124,148,191,185, 93, 58,156, 95,219, 85,196,202,192,221,137,167, 69, 9, + 39,143, 42,133,100,183,202,198, 82,121,177,240, 0,125,116,195,154, 57,162,113,240,189, 2, 72,108, 69,133,239,202,153, 60,216, +184, 81, 25,179, 38, 72, 98, 79,138, 73, 24, 42,143, 14,102,175,130, 11,155,122, 37,212, 39,155,200,144,216, 27, 15, 80,164,148, +204, 69,217,137,170,124, 62,238,237,249,247, 24,118,204, 76,131,145, 60,196,170,180,104,116, 2, 1, 99,119,109, 62, 3,194,175, +153,210, 64, 64, 53,111, 91, 86, 59,234,235, 42,117,208,205, 47, 75,207,101,149,161,198,142, 72,136,132,147, 79,104, 72, 34,244, +247,180, 96,105,226,104,145,184,113,118, 91,241,172,155,112,180, 27, 28, 74,169,199,196,240,174,150, 50, 91,128,191, 10,108,206, +236,214, 6,192,113,181, 57, 28,244,248,243,189, 24,170,150,117,196, 75,164,243,163, 42, 35,141, 68,219,217, 81,153, 75, 57, 39, +194,141, 25,208,131,133, 3,124,134, 75, 35, 33, 10,188,135, 47,101, 18, 41, 25,214,231,195,133,169,179, 43, 94,246,231,202,150, + 52,101, 22,183,182,140,181,234,198, 78, 11, 16, 7, 0,105,216,247, 66,195,213,249,104,226, 30,167,168,142, 68,209,132, 40,138, + 1, 96, 90,220,104,137,103, 44, 12,247, 49,144, 56,240,168, 97, 53, 16, 5, 88, 42,198, 56, 51, 92,158, 20,210, 33, 78, 8,188, +252,104, 64, 44,126,205,248,242,174, 56,238,110,234, 46, 15,162,139,227,193,120,243,165, 15, 45,141,141,191, 61, 3, 98, 70,157, + 37, 55,226,198,158, 28, 50,216,129,236, 52,205, 45,127,120,218,230,215,174,233,134, 58,111,123,158,117, 96,146, 9,177,129, 35, +247,139,111, 27,158, 84, 81, 4,106,128, 9, 86,254, 39,143, 26,227, 26, 14, 23, 58,249, 48,240,245, 83,196, 11,164, 92,142, 28, + 77, 66,200,125, 43,229,237,212, 31,244,246,189,143, 46,191, 58,234,235, 15, 47,125, 6,222, 94,223,250,255, 0,244, 53,212, 18, + 78,140, 0,136,125, 41, 31,236, 45, 57,136,166, 14, 8,151,255, 0,102,159,178, 41, 65, 4, 94,169,144, 50,146, 15,201, 67,189, +233,114, 27,223, 30, 28, 40, 87,181, 0, 78, 20,160,129, 65, 12, 15,141, 62,244, 3,181, 3,234,174,166, 82,130, 5, 0,190, 55, + 34,163,229, 48,208, 20,122,111,243, 81,153,170, 30, 73, 37,213,124, 45, 70, 16, 32, 77,172, 43,133,207, 26, 81,192, 82,130, 0, +168, 81, 45,227, 73,107,181, 45,205,170, 22,102,124, 88, 99, 77,245,204,121, 32,240,254,149,115,203,150,152,168,239,146,202,181, + 92,217,188,120,239,146,202,152,234,236,223, 36, 74,155, 34, 28, 88,245,202,214, 30, 3,196,250,128,172,246,110,227, 46, 89, 42, + 61,200,175,193, 7,143,244,170, 60,249, 18,228,191, 82, 86,185,240, 30, 0,122,168, 85,249,221,239,185, 95, 60,211, 28,211, 31, + 78,118,255, 0, 87,228,125,237,159,183,211, 12, 94,241,123,253,149,242,252,206,173,174,195,218,145, 44,105,153,186, 38,185, 26, +204,152,231,225, 81,225,175,210,125, 85, 71,218,248, 73,155,187,196, 36, 23,142, 16,102, 97,233,211,109, 63,246,136,173, 15,226, + 7,113, 75,219, 93,181,145,155,138, 64,203,153,151, 31, 21,143,217,121, 47,239,255, 0, 85, 84,145,235,175, 87,179,108, 43,153, +250,183, 74,223, 87,109, 42,248, 79, 59, 51,205,238,219,231,134,175, 29, 91,172, 87,186,237,113,142,136,126,251,222,253,177,218, +228, 99,102,228,143, 48,163,134, 38, 58,235,117, 31,206, 85,224,191,214, 34,168,113,255, 0, 25,123, 74,105, 52, 75, 30, 94, 58, +223,248,146, 68,165,126, 94,155,187,125, 21,224,178,203, 36,210, 60,211, 59, 73, 44,132,179,187, 18, 89,152,241, 36,147,204,154, +101,126,206,190,223,137, 86, 44,219,125, 86,159, 36,126, 58,254,229,153,218,106,170,151, 71,175,205,159, 83,244,182, 30,234,194, + 25, 88,210, 71,149, 19,240,143, 42, 18, 53, 41,244, 95,152, 35,244, 90,176,187,190,211, 62,209,148, 96,151,222, 70,247,162,148, +114,101,250,199,141,121,239,225,255, 0,115,229,118,230,255, 0,141,105, 15,145,204,145, 32,204,132,159,116,171,157, 34, 75,126, +146, 19,123,252,149,239,125,211,132,185,123, 68,175,111,222, 99,254,245, 15,179,226, 31,171, 95,159,247,191,106,162,173,175, 85, +245, 36,236,172,180,118, 75,141,108,126,131,217,189,210,214,117,165,191, 75,106,182,175, 21, 86,248, 90,167,159, 97,229, 73,135, + 58,207, 25,229,241, 47,131, 15, 16,107,105,141,147, 28,177, 44,202,195, 76,158,240, 39,133, 97, 43, 75,219,179,179,227,201, 1, +254,201,131, 47,177,191, 56,175,143,236,251,135, 92,175, 3,127, 77,211,107,194,203,243, 71,213,247, 92, 10,216,214,100,190,170, + 52,159,141, 95,228,207, 42,252, 74, 32,247, 94, 65, 82, 8,233, 67,196,127, 64, 86,151,240,251, 51, 19, 7,182,230,159, 46,100, +130, 53,201,123,188,140, 20,124, 9,226,107, 53,248,148, 45,221,121, 3,253,212, 63,176, 42,143,106,218,247, 61,242, 65,131,132, + 11,164,119,118,212,214,142, 61, 86, 5,143,182,222,218,253,207,167, 92,155, 76,117,181,187, 82,173, 91,126, 9, 31,136, 89,109, +143,121,146,213,175,125,157,172,146,241,108,245,121, 59,223,182, 11,244,206,224, 61,100, 71, 33, 95,156, 37,170,207, 7,114,219, +183, 52, 47,129,145, 30, 64, 94, 97, 24, 18, 61,163,152,175, 56,151,240,215,120, 88, 12,144,228, 65, 52,128, 95,164, 11, 41, 62, +160, 88, 91,231,172,170, 73,159,179,230,146,140,248,185,152,236, 65,183,186,202,195,152, 53,197,109, 48,100, 79,209,202,219, 93, +127,100,122, 30,247,113,137,175, 95, 18, 73,244,211,243, 61,103,189,129, 29,179,159,171,209, 31, 15,248,169, 94,103,218,191,249, +139,110,183,251, 97,249,107,107,184,111, 75,191,118, 30, 94, 99, 0,185, 41,211,139, 37, 71, 32,226, 72,248,129,232, 96,111, 88, +190,212, 23,238, 45,184,127,190, 31,200,107,166,218,174,187,124,213,182,141, 59, 39,253,167, 61,213,235,125,206, 11,213,202,178, +163, 95,220,123,101,213, 84,179,184, 85, 81,118, 36,128, 0, 30,146,106,143, 51,191, 59,115, 6, 67, 24,201,235,184,224,122, 42, + 92, 15,235,124, 63, 77, 98,187,243,184,103,201,206,147,102,198,114,152,152,199, 76,224, 27,117, 36, 28,245,122,151,149,189, 53, + 23,181,123, 57,183,248,159, 51, 38, 99,143,134,141,211, 82,162,238,236, 5,206,155,240, 0, 95,157,112,166,211, 29,113,172,185, +236,234,158,169, 47, 30, 7,124,155,204,150,202,240,237,234,172,214,141,191, 14, 38,218, 63,196,109,138,103,210,102,146, 16,120, +106,120,205,191,236,234,171,220,108,232,119, 24,196,248,121, 11, 60, 71,237,198,193,133,253, 6,213,135,221,255, 0, 13,161,135, + 21,231,218,178,100,121,144, 22, 16, 77,164,235,176,189,149,148, 45,143,163,133, 99,246, 29,243, 47, 97,207, 76,184, 24,152,238, + 6, 68, 55,247, 93, 60, 65, 30,159, 65,240,170,182,184,114,209,219,111,103, 43,149,131,221,231,195,117, 77,205, 20, 91,248,170, +123,139,199,101,164, 10,136,132,185, 0, 0, 73, 39,128, 0, 87,155,254, 33,231,200,242,109,147, 99, 76,235, 28,208,188,138, 81, +138,220, 49, 82, 15, 15, 85,101,246,230,222,247, 73, 14,211,133, 44,178,156,162, 58,145,151, 54, 33, 46,110,228,158, 10, 47,198, +177,143,100,239,141,100,119, 85, 79,140,174, 16,245, 55,147,126,169,149,226, 88,221,154,225, 15,140,173, 52, 61, 79, 35,189, 59, +103, 6, 83, 19,230, 9, 92,112, 61, 21,105, 0,254,178,141, 63, 77, 75,219,187,155, 96,222, 28, 71,133,152,166, 99,202, 25, 1, +141,207,244, 67,129,127,146,176,173,248, 99,186,172, 58,252,228, 6, 91,127, 14,207,107,250, 53, 91,242, 86, 50,120, 50, 48,114, +100,199,152, 24,178, 32,114,172, 60, 85,148,248, 17, 93,105,180,219,100, 77, 99,200,221,151,237,192,227,125,238,235, 19, 86,203, +137, 42,190, 95,190, 79,161, 32,117, 50,105, 97,116, 52, 45,211,113,193,219, 99, 15,145, 60,120,200,222, 50, 48, 4,251, 47,206, +179, 56, 29,202,113,251, 42, 61,255, 0, 40,117, 50, 35, 6, 5, 7,251, 73,131, 20, 91,251, 64,212,107,203,115,115,183, 13,235, + 56,228,101, 59,228,101, 78,193, 84,115,226, 77,149, 17,124, 7,160, 10,227,131,101,107,218,221,207,182,180,110,173,245,107,161, +223,113,191,173, 43, 78,197,221,107,165,100,186, 39,212,245,244,239,190,216, 4, 35,103,141, 92,175,211,146,223, 62,139, 85, 95, +121,102,225,238, 61,173,149,145,133, 58,100, 71,174, 33,170, 54, 13,111,222, 47, 3,110, 85,157,196,252, 50,222,231,128, 75,145, + 60, 24,206,194,253, 38, 44,204, 63,165,160, 17,244,213, 14,243,177,238,253,185, 33,198,204,225, 14, 64,176,146, 38, 38, 41, 66, +155,250,185, 30, 54, 34,187,227,219,237,253, 74,250, 89,102,213,105,195,214, 99,161,231,203,186,221,122, 86, 89,112,197,109, 86, +165,105, 19,215,136,110,205,255, 0,204,219,127,244,219,255, 0,102,213,237, 0,164, 74,243, 72,193, 35, 81,118,118, 54, 80, 7, +164,154,241,142,202,255, 0,205, 59,111, 11,251,237,195,254, 27, 85,159,126,247, 36,251,134,227, 46,211,142,221, 60, 12, 54,208, +200,166,221, 73, 87,226,103,244,233, 60, 0,171,186,193,108,219,138,213, 56, 74,146,223,132,179, 59, 77,197,112,109,175,118,165, +187,194, 93, 92, 35,103,155,223, 61,183,139, 33, 79, 52,103, 97,123,244, 80,184,253,110, 10,126, 67, 76,197,252, 65,237,153, 24, + 35,205, 36, 58,143,197, 36,102,194,255, 0,208,213, 88,254,209,236, 86,238, 28,118,220, 51, 39, 56,216, 97,138, 71,160, 2,242, + 21,248,136, 45,192, 11,240,171,125,247,240,198, 44, 92, 41,114,246,140,153, 36,146, 21, 46,113,230, 10, 75,128, 46, 66,178, 5, +227,232,225, 92,222, 29,157,109,233,218,246,238,224,223, 41,249, 29, 86,125,245,235,234,214,148,237,226,151, 54,190,102,251, 30, + 92, 93,194, 37,202,194,158, 57,225,110, 79, 27, 6, 23,249, 42, 65,137, 71, 13, 92, 43,194,123,107,184, 50,123,127,113,143, 37, + 9,108,102, 33,114,160,191, 7, 79, 30, 31,164, 60, 13,105,255, 0, 19, 50,165, 77,203, 2, 76, 89,157, 34,151, 20, 58,148, 98, +161,129,118,179,112,245, 86, 45,177,107, 53,113,247,105,100,218,180,116,228,110,158,224,158, 27,100,237,250,170,210,117,158,188, +211, 61, 51, 35, 39, 15, 19, 29,167,201,117,138, 24,197,222, 87, 33, 64, 30,178,106,143, 7,188,246, 29,211,113, 77,179, 5,222, + 73,164, 45,211,109, 4, 33,208,165,207, 22,177,228,190,138,242, 28, 36,222,119,169, 83,105,196,121,114, 90,102, 14, 33, 46, 74, +221, 65,247,219, 81,176, 0, 30,102,189, 7,182, 63, 15,247, 29,147,119,197,221, 51,114,241,202,194, 31, 92, 49,150,102,247,227, +104,248, 29, 32,112, 45, 90,190,215, 14, 42, 91,212,201, 54,134,234,150,158, 70,113,239, 51,102,189,125, 60,113, 73, 74,237,235, +231,174,134,251, 84,151,225,254,150,167, 5,115,227,232,250,105, 86, 76,117,225,212,189,185,216, 94,187,204, 99,161,224,172,223, + 69,120, 79,160,118,146,110, 53,123,195,194,148, 71,195,222,230,108, 1,166,121,160, 9,211, 24,249, 77,119,156,155,146,133, 81, +236,168, 80,194, 19,112,192, 92,243, 2,138, 96, 32, 95, 73,185, 28,252, 42, 17,202,200, 63,218, 16, 61, 3,133, 6, 73, 37, 96, + 73,114,126, 90, 16,177, 49, 53,189,246, 80, 56, 11,220,114, 20,223,240,234,117, 52,160,219,192, 85,104,110, 28,121,240,162,129, +194,128,152,103,197, 3,137, 46,125,148, 35,151, 2, 15,118, 34,109,233, 53, 25,236, 1,245, 80,139,106,250, 42,200, 39, 12,212, + 22,211, 0, 30,214, 38,148,230,177, 55, 17, 32, 39,199,137,252,181, 4,177, 7,128,189,197,133, 61, 79, 1,126,126, 53, 1,107, +230,100,242,247,210,191,192,213,107,112,191,152,211,233,174,160,223,252, 55,254,237,255, 0,196,215, 80, 22,132,112, 79,232, 39, +236,138,234,226,126, 15,232, 39,236,138,235,213, 33, 31, 35,226, 23,244, 80, 8,191, 10, 52,237,239,129,234,161,139,223,128,160, + 24, 21, 84,159, 73,167,105, 62, 6,156, 45, 73,110, 52, 2, 0,108, 65,164,208, 65,189,249,248, 81, 64,189, 41, 20, 0,184,248, +212, 41,134,169, 88,142, 95, 80,169,236, 45, 85,197,193, 98,222,158, 54,163, 42, 20, 40,228,105,196, 1,234, 2,154, 26,168, 55, + 92,249, 36,149,241,144,233,141, 14,150,183,218, 35,157,235,203,187,221, 83,109,143,190,202, 91,113, 84,185,179,209,182,219, 95, +113,147,178,186, 37,171,111,146, 36,103,238,225,111, 22, 33,185,228,101,240, 31,209,170, 82, 75, 18,204,110, 79, 18, 79, 58, 74, +177,219,246,169, 50,136,150, 91,164, 62, 30,150,246, 87,231,111,147,115,190,204,151,234,124,170,191, 77, 87,237,204,251,213,166, +223,103,137,190, 11,157,159,234,179, 35, 99, 97,203,149,168,160,180,104, 9,103, 60,133,170, 61,108,150, 24,227,143,162,138, 21, + 45, 96, 7,174,178, 18,198, 98,145,227,110,104, 74,159,146,186,111,182, 43,109, 76, 90,247, 59, 79,115,229, 58, 66, 71, 61,158, +241,238, 47,151, 78,213, 88,237, 92,227, 89,108,208,246, 84,170,155,172,145,158,114, 66,193,125,160,171,127, 32,167,126, 46,109, +147,238, 29,164,211, 64,165,219, 6,116,201,117, 28,250, 96, 52,110,126, 77,119,170, 12, 60,169,112,114,162,203,135,227,137,131, + 15, 95,164, 31,104,175, 79,193,206,196,221,176,196,209, 89,227,144,105,150, 38,177,177, 35,222, 71, 21,244,253,139,117, 90,215, +211,254, 44,118,238, 75,173, 89,243,189,235,106,238,221,191,135, 37,123, 91,233,100,124,151, 93, 94,209,220,191,131, 81,100,206, +249,125,183,146,152,193,201, 99,133,145,126,154,147,254,205,212, 49, 3,212, 65,246,214,119, 31,240,103,186,100,148, 46, 68,216, +144, 71,227, 39, 81,156,219,212,170,149,251, 10,238,240, 90,179,222,151,131,226,126, 62,219, 45,197,109,219,216,223,138,224, 99, +123,115,108,159,120,223,112, 54,236,117, 44,211, 76,129,136,251, 40, 14,167,115,253, 21, 4,215,211,155,236,171, 14,207,154,238, +108, 12, 76,131,218,227, 64,250, 77, 82,246,127, 98,109, 93,161, 27, 73, 1, 57, 57,242,174,153,179, 36, 0, 29, 60,244, 70,188, +116,173, 65,238,237,238, 60,166, 27,110, 43,106,142, 54,213, 59,142, 69,135, 37, 30,207, 26,248,158,243,191,198,177, 89,167,167, +107,173, 39,141,173, 99,238,251, 54,195, 34,186, 79,139,178,181,227,133,107, 83, 43, 87, 93,186,204, 38,156, 0, 72, 42, 46, 7, +182,169,107, 71,219,144, 21,134, 89,200,254, 35, 5, 95, 98,254,115, 95,148,246,202,187,110,241,199,240,203,126, 80,126,155,220, +108,171,181,201, 60,225, 47, 57, 60,175,241, 32,223,186,178, 13,136,253,212, 60,255, 0,160, 43, 73,248,104,176,141,163, 36,168, +188,205,144, 68,135,199, 72, 69,211,252,166,179,159,137, 60,123,175, 35,251,184,191, 96, 85, 70,197,191,231,246,252,237, 62, 40, + 13, 20,195, 76,176,189,244,190,159,103,136,191, 58,254,132,241, 91, 38,206,148,175, 30,218,191, 56, 63, 3, 92,181,197,189,189, +236,180,238,178,126, 19,204,246,224, 74, 55,243, 77,121, 63,226, 42,194, 59,140,152,173,173,160,140,205,111,211,226, 63,100, 10, +177,155,241, 50,102,138,208,237,234,178,219,226,121, 11, 40, 63,209, 10,164,252,245,140,154,108,221,223, 57,165,147, 86, 70, 94, + 75,242, 81,114,204,120, 5, 80, 62,138,231,179,219,100,199,119,124,139,181, 67, 92, 78,187,221,214, 44,184,214, 60,111,185,182, +159, 15,204,187,217,139,255, 0,149, 59,136,127,102, 60,173,191,165,212,227, 80,251, 79,255, 0, 50,109,191,223, 15,203, 91, 28, +189,136,236, 61,129,155, 4,214,243, 83,116,230,201,183,131, 25, 16, 4,254,168,250,107, 27,218,127,249,147,109,254,248,127, 33, +174,213,186,190, 61,197,171,193,187,125,149, 72,225,122, 90,153, 54,212,183, 20,171, 63, 27,182, 68,222,117,253,239,184,117, 62, + 63, 51, 54,171,250,117,181, 78,219, 54, 94,231,204,196, 89,246,184,166,108, 86, 44, 20,199, 40, 85,184, 54,110, 26,197, 93,119, +247,110, 79,139,157, 38,243,140,133,241, 50, 78,169,200, 23,233,201,200,234,245, 55, 59,250,106, 31,106,119,156,221,186,143,137, + 44, 62, 99, 14, 70,215,164, 29, 46,140, 69,137, 91,240, 32,219,149,107,212,181,240, 86,248, 85,108,225,104,254,213,230,101,227, +173, 55, 22,166,119,106, 41,127, 82,251, 31,144,131,182,123,232,255, 0, 97,146,127,227,143,251,202,140,123, 35,186,185,157,185, +255, 0, 94, 63,245,235, 71,187,254, 38, 52,248,146, 99,237, 56,207, 4,178,130,167, 34, 86, 23, 64,120, 93, 21, 47,199,208,111, + 82,123, 23,186,119,221,203, 37,118,220,168, 78,108, 10, 61,252,210,116,180, 67,192,200,220,155,249,107,151,169,186,174, 55,145, +211, 29, 99,138,224,227,230,117,244,182,150,200,177,172,153, 45, 60, 26,213, 79,200,160,239, 12,108,156, 61,191, 96,199,204, 82, +153, 17,226,178, 72,132,130, 65, 86, 80, 7, 11,248, 85,167,225,100, 72,217, 91,148,164, 93,214, 56,213, 79,160, 49, 98,127,100, + 83,191, 21,130,140,189,182,198,255, 0,186,147,246,150,157,248, 84,200,178,238,133,191, 70, 27,124,242, 86,109,105,216,187,112, +157,126,119, 53, 90,165,238, 10,188, 99, 77,124, 40,122, 64,229,107, 94,188, 79,190, 84, 39,116,238, 0, 11,123,200, 79,180,198, +151,175,109, 19,198, 13,130,223,211, 94, 41,223, 68, 55,117,103,144, 44, 47, 31, 15,248, 73, 92, 61,187,254,107,127,161,253,232, +244,123,159,252, 53,255, 0, 90,251,152,124,195, 47,249, 7,109, 0,158,145,206,150,227,194,250, 90,223,150,135,216, 49, 65, 47, +116,225, 44,246,176,234, 52,119,253, 49, 27, 21,173, 46,197,181, 29,247,176, 78,218, 8, 89, 58,210, 75, 3, 31, 9, 21,184, 92, +250, 15, 42,243,226,185,219, 70,112,212, 31, 23, 55, 21,195, 11,240,101,101, 55, 6,189,148,106,245,207,137, 56,183,117,215,247, +115, 60, 57, 19,199,108, 25,154,154,246,209,255, 0,111, 35,232,190,139,126,141,173,226,107, 33,248,147, 20, 63,229,135,105,180, +245, 86,104,140, 60, 69,245, 19, 99,111,234,222,179, 56,223,138, 25, 75, 8, 92,204, 17, 52,160,127, 17, 36, 40, 9,244,149, 42, +255, 0,203, 89,206,225,238,109,195,184,221, 76,234, 34,198,135,222,142, 8,238, 64, 39,134,166, 39,153,240,175, 38, 13,158,106, +229,173,172,187, 85, 92,204,241,131,217,184,222,224,182, 27, 86,141,217,217, 68, 71, 9,234, 63,178, 72, 29,211,182,150, 54, 26, +218,231,254, 27,213, 62,126,175, 61,147,175,227,234,201,170,252,239,168,222,173,123, 59,255, 0, 50,237,255, 0,211,111,216,106, +179,239,158,221,200,193,207,151,117,130, 50,216, 89,109,173,202,143,225,200,223, 16,111, 83, 30, 32,215,185,228,173,119, 61,175, + 78,234, 40,243, 77,232,120, 22, 59, 91,107,222,181, 84,200,231,201,165,169, 91,183,108,221,213,149,135, 28,251,106, 78,113, 30, +253, 51, 28,161, 87,129, 32,217,117,143, 17, 82,191,203,253,238,110, 58,121, 39,211,251,241,255, 0,121, 78,237,142,243,155, 97, +132,225, 79, 17,200,196, 44, 89, 2,155, 58, 19,241,105,191, 2, 15,162,172,119,143,196, 87,201,197,124,109,170, 7,199,105, 65, + 86,200,118, 26,148, 31,208, 11,227,235,189,115,189,183, 62,163,173,113,209,214,116,179,233,227,169,214,149,218,250, 74,214,203, +145, 89, 45,106,186,248,104, 81,255, 0,146,251,156,255, 0,253,123,254,188,127,235,212,222,246, 76,168,147, 99,131, 52, 21,200, +135,111,142, 57, 20,155,144, 80,149,181,197,253, 21,161,236,142,230,223,183, 73,188,142, 76, 7, 46, 24,199,191,154, 61,214, 79, + 64,115,201,175,243,213, 87,226,110,163,186, 97, 22, 22,255, 0, 14,109,250,237, 89,174, 92,175,115, 92,121, 21,126,148,223,211, +228,106,216,177, 45,173,178,226,119,250,154, 77, 91,193,147,127, 11,113,227, 45,184,229,145,251,213, 17,196,173,232, 86,212,205, +243,149, 21,232, 78,108,121,251, 43, 5,248, 88,140,240,110,122,109,193,226,189,253,143, 94,130,113,143,218,113,242, 10,240,239, +127,250, 47,240,251,143,126,198, 22,218,159, 31,189,130, 78, 28,125, 38,141,107,211, 17, 60, 7, 26,144,177,147, 94, 99,212, 11, + 77,113, 22,163, 44, 58, 70,159,150,149,162,184, 32, 26, 16, 14,144, 86,226,152,226,192,212,149, 64,171,107,242,160, 73,164,142, + 7,137,189,232, 80, 75, 12,172, 65, 8,126, 90, 34,197, 43,122, 7,203, 68, 73, 2,128, 60,120, 0, 61,180,138,225, 61,226, 56, + 95,141, 1,195, 21,218,247,112, 62, 74,225,138, 60, 92,252,130,164,195,114,128,158, 4,211,180,208,132,111, 42,131,155, 63,250, +124,148,190, 90, 47, 75,159,150,164,145, 73,106, 0,157, 8,252,181,172,127,233,237,123,241,183,152,213, 93, 70,183,248,127, 87, + 71,254,117,117, 80, 25,139, 2,130,223, 97, 63,100, 82,234, 62,138,113,251, 39,249,137,251, 34,155,170,128,143, 63,198, 13,143, + 42, 17,146,222, 6,164, 74,120,220,122, 40, 54,212,120,208, 13,212,109,203,230,164, 89, 9, 60, 69,168,192, 91,217, 93, 64, 55, + 85,133, 46,160,124,105, 72, 28,141, 55, 72, 4,222,128,100,141,101, 37, 77,236, 9,249,170, 16, 21, 42,112, 4, 76, 71, 3,192, + 15,158,162,233, 54,231, 81,149, 28,109, 84,121,219, 84,239, 59,203, 5,157,100, 58,136,189,136, 39,159, 58,186, 35,198,187,144, + 21,231,220,237,113,238, 40,169,146,116,114,154,209,163,190,223,115,147, 5,157,177,198,170, 26,122,162,167, 11,104, 8,221, 76, +171, 49, 28,163, 28, 71,245,170,231,136, 28, 5,173,202,144, 14, 52, 94, 66,174,223,109,139, 5,123, 49, 86, 58,183,197,249,178, +103,220,100,205,110,236,142,122, 46, 75,201, 2, 37,141, 82,111, 24,100, 55,154, 65,112,120, 73,249, 13, 94, 83, 72, 86, 4, 48, +184, 60, 8, 53, 55, 91,122,238, 49, 91, 29,180,230,159, 75,114,101,219,103,182, 12,171, 37,117,228,215, 85,208,199, 84,172, 29, +195, 47,110,155,173,137, 41,141,185, 48,230,172, 61, 12, 15, 3, 82,115,182,167,136,153,113,134,184,249,148,241, 95,172, 85,101, +126, 95, 46, 28,219,108,145,100,233,101,194,203,239,171, 63, 71,143, 46, 45,198, 57,172, 90,175,138,127,115, 70,203, 23,190, 70, +144, 51,113, 78,175, 23,136,240, 63,213,111,174,164, 63,124, 96, 1,251,188,105,153,189, 13,165, 71,207,118,172, 45,117,122, 43, +238,187,196,163,189, 63, 23, 85, 39, 7,237,187, 86,231,177,175, 4,220, 23,187,159,117,110, 57,234, 97,142,216,208,183, 6, 88, +205,216,143, 65,127,170,168,171,168,248,216,115,229,190,136, 86,227,197,207, 5, 30,211, 94,107,228,207,184,200,187,157,178, 89, +232,151, 31,146, 61, 21,166, 28, 20,125,170,184,234,181,111,243, 99,113,177,228,202,153, 96,136, 93,152,243,240, 3,196,154,216, +195, 19, 99, 64,144, 69,109, 40, 44, 61, 39,210,104, 88, 27,124, 91,124,118, 95,122, 70, 30,252,135,153,245, 15, 85, 73, 39,157, +188,107,244, 30,221,178,255, 0, 30,142,215,255, 0,146,252,127,165,116,252,207,133,191,222,122,246, 85,167,232,167, 15,234,125, + 74, 13,223,182,246,125,203, 43,205,231, 96,164,153, 14, 0,105, 11, 61,200, 80, 0,228, 69, 70, 29,173,177,156, 51,128,216,105, +229,181, 25, 2,113,224,228, 0, 89, 88,157, 67,128,240, 53,123,146,236, 29, 84, 11,216, 80, 15,188, 57,251,109, 95, 85,100,201, + 9,119,218, 23, 13, 94,135,206,244,177,203,125,149,151,199, 69,169,150,111,195,222,219, 15,171, 68,193,127, 68, 72,109,245,213, +206,213,177,108,219, 71,189,183,226,172, 78, 69,140,166,236,228,127, 77,238,106,120,244, 91,135,164,210, 31,116,243, 39,212, 42, +219, 54, 91, 40,181,236,215, 70,201, 92, 24,170,230,184,234,159, 84,134,102, 98, 98,110, 56,239,135,150,130,104, 36,182,184,205, +192, 54, 33,135, 43, 30, 98,171,241,123, 87,183,240,242, 99,202,197,193, 72,230,136,234,141,195, 57, 32,250,120,181, 89,155,169, +212, 56,122,104,128,223,143,166,178,175,116,161, 89,164,248,164,244, 52,241,210,205, 90,213, 77,174, 13,169, 98,178,171, 41, 87, + 1,148,139, 21, 60, 65, 6,179,121,157,149,219,121,146, 51,156, 78,139, 30,102, 22,100, 31,170, 14,159,162,180,149,221, 11,155, +223,159, 26, 87, 37,233,173, 44,235,228,224, 95, 29, 47,165,234,173,230,164,202, 71,216, 61,183, 11, 6,104,100,150,222, 18, 72, +214,255, 0,179,166,180, 56, 88,216,184, 48,140,124, 56,146, 8,151,146, 32, 10, 62,138,152, 49,212,243, 52,166, 40,212,113, 20, +190, 92,151,253,118,181,188,217,154, 98,199, 79,209, 74,215,201, 21,123,142,203,180,238,205, 27,238, 56,203, 59, 68, 8,140,177, + 97, 96,121,252, 36, 82,109,251, 54,215,180,245, 14,219,140,176, 25,108, 36, 42, 88,223, 77,237,241, 19,233,166,111,251,254, 23, +110,225,249,156,132, 50,203, 33, 43, 4, 10,108, 93,135, 62, 62, 0,120,154,197,195,221,221,231,189, 59,157,159, 13,122,106,120, +244, 98,214, 23,212,207, 33, 34,245, 59,239,219,219,220,251,122, 78,159, 35, 94,157, 59,187,251,107,221,214, 53,249,158,138,128, +147, 85,217,157,175,176,238, 25, 47,151,153,132,178,228, 75, 98,242, 18,224,157, 32, 40,228,192,114, 21,139,139,190,187,135,104, +204, 24,251,246, 18,183, 34,232, 80,197, 37,185,106, 83,240,159,154,180,221,203,221, 45,131,219,248,123,206,202,209,200, 50,166, + 68, 6, 69, 44, 52, 50, 72,196, 88, 17,102, 12,150, 52,173,173, 87, 53,110,175,193,192,181,107,101, 22,170,178,241, 82, 93,225, +109,216,123, 94, 58,226,224,194, 33,128, 18, 68, 96,147,197,185,159,120,154, 14,235,177,237, 91,178,129,184, 98,164,197, 69,149, +248,135, 3,212,203, 99, 88,129,248,147,158,219, 98, 34, 65, 28,187,172,146, 48,184, 70, 17,164, 96, 13, 62,237,201,102, 60,124, +106,207,181,123,151,119,206,109,192,239,172, 35,143, 30, 53,144, 22,143,165,165,125,237, 71,144,225,238,211,186,201,247, 38,231, +172,235,243, 29,149,117,237,117, 93,189, 35, 79,145, 32,126, 28,246,233,253,225, 18,219,244, 58,134,223, 93, 92, 65,218, 59, 4, + 88,111,130,152,139,229,229,177,149,120,221,180,155,174,167,190,163, 99,235,172,118, 79,126,238,251,142, 96,193,237,204, 48,192, +155, 70, 93, 75,200,224,125,173, 32,133, 81,237,167,100,111,159,136,155, 28, 94,115,113,197, 70,198, 22,212, 89, 35,117, 3,151, +188,113,218,235,207,198,182,243,101,180, 77,236,227,196,194,193,134,179,219,142,170,116,224,141,134, 39,104,118,246, 14, 66,101, + 98,225, 44,115,196,110,143,169,238, 9, 22,241,111, 69, 91,182, 52, 18, 41, 71,141, 89, 24, 89,149,133,193, 7,210, 13, 83,118, +175,117, 98,247, 46, 59,217, 58, 25,144,219,175, 5,238, 44,121, 58, 31, 21,254, 74,161,238,158,253,201,219,247, 23,217,246, 88, + 22, 92,136,200,142, 73,164, 5,191,120,126,196,104,164, 92,139,219,143,143,133, 98,214,181,156,218,205,191, 23, 38,171, 74,213, + 69,106,170,159, 36,160,183,203,236, 14,216,203,114,254, 79,160,199,153,129,217, 7,234,220,175,209, 67,131,240,235,181,225,112, +231, 30, 73,173,225, 36,140, 71,204,186,106,168,205,248,166,168,114, 58, 49, 16, 6,174,136, 16,106,183,162,218,175,244,222,141, +218, 61,251,147,187,238, 11,180,110,176, 36,121, 18, 6, 16,205, 29,212, 22, 64, 88,163,163, 19, 98, 64, 60,111,234,181,116,245, +243, 68,122,150,143, 54, 99,252,124, 51, 62,157, 39,201, 22,187,198,251,179,246,124, 56,184,173,138,233, 12,193,250, 49,226,162, +105, 26, 52,234,213,169,147,244,169,144, 98,108, 29,221,137,139,186,228, 97, 25, 67,171, 36, 38,107,171, 42,164,140,172, 8,141, +237,204, 26,243,206,241,207,238, 28,233,113,198,251,137,229,150, 38,148, 98,158,155, 71,172, 18,154,190, 34,111,107, 45, 93,246, + 86,231,221, 40,155,110, 22, 62, 22,189,156,200, 85,178,122, 76,125,198,145,140,135, 93,237,193,137,240,174,106,214, 79,185, 89, +167,213, 61, 78,142,181,117,237,117, 77,116,107, 67,208,118,189,147,107,217,214, 69,219,113,151, 28, 76, 65,144, 41, 99,114,183, +183,196, 79,166,172, 10,222,176,221,213,248,132,187, 70, 83,237,187, 84, 43, 62, 84, 94,236,243, 73,126,154, 55,232, 5, 91, 22, + 35,199,143, 10,168, 29,195,248,146,241,121,213,195,126,133,181,105, 24,195,151,167, 73,247,237, 70,219,115,102,219,124,216,173, + 85, 84, 85, 36,151, 37,161,232,140, 89, 9, 3,133,248, 26, 47,152, 81, 88,126,218,252, 68,143,112,204,143,111,223, 49, 99,134, +105, 88, 36,121, 81,130, 20,185,224, 22, 68, 98,116,223,211,122, 94,240,239, 45,215,183, 55, 88,240,246,248,241,204, 82, 64,179, + 30,172,101,142,162,242, 39, 2, 24,112,178, 10,133, 54,199, 36,147,193, 73,246, 80,245,229, 57,247, 85,173,232,181,121,254,225, +248,149,188,100,152,241,246, 12,117, 46,177,161,200,156, 68, 93,140,133, 70,189, 9,201, 84, 53,249,222,182,221,161,187,238, 59, +166,199, 6, 94,230,223,226,153,228, 89, 61,221, 31, 3,149, 23, 81,107, 80, 18,140, 25,175,199, 67, 82,166, 30, 69,238,203, 96, + 57,220,213,145,118, 62, 60, 40, 76, 73,241,168, 36, 18,196, 47,123, 92,129,206,155, 10,134, 4, 17,227, 82, 7, 5, 63, 53, 7, + 31,129, 36,120, 26, 0,234, 52,138, 91, 87, 15, 77, 40, 62, 6,168, 27,110, 52,182,174, 62, 21,195,213, 64, 73,254,195,254, 15, +252,234,234,239,236,111,254,231,254,117,117, 0,118, 60, 22,223,160,159,178, 41,141,126, 6,212,164,181,146,252,244, 37,255, 0, + 84, 82, 30, 62, 20, 0,101,189,249,113,181, 32, 31, 39,166,150, 82,117,129,232, 20, 53,102,185,191, 42, 0,151,191,133,113,225, +225, 77, 7,211, 74, 79, 10, 3,185,241, 52,132,222,184, 49,212, 65, 22, 20,140,109,202,128,141,146,224,170,143, 93,199,201, 66, + 44, 0,167,101, 27,186,175,128, 23,191,183,255, 0,162,131,235,168,202,113, 55, 21,220,125, 20,170, 56, 94,151,194,128, 64,220, +105,197,137,224, 40, 96,243, 52,224, 64, 20, 7, 1,122, 80,162,185, 72,165,191, 26, 1, 81, 1,112, 60, 47,196, 31, 69, 55, 39, +107,194,200,247,158, 32, 63,156,188, 15,209, 68,140,141, 96,147,107,113,162,134, 91,115,252,213,139,210,151, 93,183,170,178,232, +212,154,165,239, 71,221, 75, 58,190,169,193, 71, 47,111,195,175, 76, 83, 50,223,193,148, 55,211,238,210,142,218, 91,219,205, 31, +212,255, 0,237, 85,211, 1,173,120,252,130,137,170,255, 0, 9,226, 43,200,253,183,102,220,250, 75,225,107, 47,196,244,175,112, +221,165, 30,171,249, 85,254, 5,108, 29,189,131, 29,139,234,149,191,156,108, 62, 97, 83, 4, 9, 24, 9, 31,186,163,192, 90,194, +164,107,241,231, 76, 33,124,121,215,163, 22, 12, 88,148, 99,165,107,228,181,249,156, 50,102,203,145,206, 75,187,121,189, 62, 64, +250,108,205,160,185,176, 30,170,227, 19,143,182, 72,246, 10,122, 31,120,211,197,129,244,138,234,115, 43,114, 56, 74, 81,141,237, +110, 63, 37,232, 23,210,120,114,241, 52,108,150,213, 51,176,229,123,113,245,112,160,131,126, 85,160, 41,177,227,207,213, 74, 13, +197,143, 3, 76, 38,198,151,219, 64,119, 1,195,159,164,154, 32,231,106, 8, 32,155, 15, 26, 58,142, 55,163, 2,170,220,138,145, +106, 26, 14, 34,141, 80,135, 1, 76,145,110, 45, 79, 20,143,107, 26,160,242,191,196,225, 40,205,192, 39,248, 70, 39,209,253, 45, + 94,247,209,166,182,125,140,113,143,108, 96,249,107,112, 12, 38,183, 62,166,163,175, 87,175,242, 84,157,251,183,113, 59,139, 4, + 98,228,147, 28,136,117,193, 58,128, 89, 27,216,121,131,226, 43, 15, 31, 98,119,134,211, 43, 29,167, 61, 21, 27,155, 67, 51,196, + 79,244,212,139,125, 38,128,214,119, 76,253,169,140,216,231,184, 81,100,149,195,249,117, 40, 92,128, 52,234,248, 65,176,172,223, +121, 54,205, 47,102,224,207,177,198, 99,194,108,209,211, 22,101, 28, 18,112,214, 86,254,112, 52, 40,127, 14,183,205,195, 36,100, +239,217,235, 98, 64,118, 14,211, 76, 69,249, 2,224, 40,249,207,178,180,253,207,218,178,110,123, 14, 38,203,180, 24,160, 92, 89, + 81,212, 76, 88, 46,132,142, 68,230,138,228,177, 47,122, 2,167,240,179, 3, 12,237,185,123,140,145, 43,228,153,204, 1,216, 92, +170, 42, 35,217,125, 23, 47,198,175,251,221, 88,118,182,227,229,208, 7,208,151,176,251, 61, 68,215,255, 0,102,244,222,203,216, +115, 59,119,107,155, 11, 53,226,146, 89, 50, 26,101,104, 75, 50,233,100,141, 44,117,170, 27,221, 42,250,104,163,200,137,224,153, + 67,197, 42,148,145, 27,136, 42,194,196, 31,109, 1,226,125,165, 31,112, 73,149, 58,246,244,209,195,145,161,122,157, 65, 25, 37, + 47,246,122,138,252, 47,206,213,173,200,193,252, 76,155, 30, 88,178,115,113,206, 59,163, 44,193,198, 56, 82,132, 89,174,122, 94, +138, 14,111,225,206,227,131,154, 51, 59,115, 56, 69,239, 22,137, 36,102, 71, 79,230,137, 16, 54,161,237,181, 38, 71,108,126, 32, +238,209,249, 61,199,112,143,203, 27,107, 86,146,202, 64,253, 37,137, 61,239,150,133, 23,178,123,107,116,217,247,197,202,154, 92, +119,133,162,120,229, 88,102, 87,107, 16, 8,247, 87,249,192, 84, 60,206,247,222,183,125,220, 96,246,252, 80,193,212,151, 70, 52, +134, 52,105, 27,143, 7,102,144, 21, 30,158, 92, 43,107,218,221,165,135,219, 49,187, 43,156,140,217,128, 89,178, 8,176,210, 56, +232, 65,198,195,211,233,172,158,231,248,113,186,227,238, 39, 59,183,242, 80, 32,147,171, 10, 51, 24,228,136,223, 80, 10, 64, 32, +129,225,202,132, 44,215, 99,252, 68,200, 4,229,111,176,194,167,139,116,248, 48,244,252, 17, 70, 62, 99, 88,174,206, 80,157,227, +130,138,253, 85, 89,164, 2, 65,201,128, 71,247,190, 90,216,255, 0,151,123,247,117,143,203,111, 27,194, 65,136,125,217, 22, 45, + 58,217,124, 71,238,146, 59,252,173, 64,217,127, 15,183,109,159,127,199,220,150,124,121, 49, 49,229, 98,170, 93,250,166, 50, 25, + 69,199, 72, 46,173, 39,211,107,208, 12,252, 90,255, 0,250,127,253,231,254, 77,104,255, 0, 15,255, 0,242,158,223,255, 0, 27, +255, 0,111, 37, 7,189,251,106,110,227,198,199, 56,178, 36,121, 24,140,229, 4,151, 10,194, 64, 53, 45,212, 27, 31,112, 85, 15, +111,246,191,122,237,185, 56,107,230,196, 91,116, 83,199, 36,216,235, 59,105, 49,235, 13, 34,132, 2,222,240,191, 10, 3, 39,182, + 24,151,188, 33, 59,157,180,140,227,215,215,203, 95, 80,252, 90,188, 53,115,189,123,189,171, 17,221, 31,135,240,239, 89, 47,184, +237,211, 46, 46, 92,156,102,141,193, 49,187,126,149,214,229, 73,241,224,106,141,123, 75,241, 5, 34,242, 73,185, 17,140, 6,144, +163, 42, 64,154,125, 3,133,237,234,160, 51,189,227,209,110,235,220, 60,135, 16,102, 93, 61, 63,246,186, 87,169,107,120,245, 47, + 86,127,137,122,190,253,198,215,109,126, 77, 53, 91,149,250,178,222,180,221,181,248,112,155, 94, 92,123,134,239, 58,100,207, 9, +215, 20, 49, 3,211, 87, 28, 67,179, 48, 5,173,225,192, 82,119,119,101,238,189,201,185,199,157,131, 54, 60,113, 71, 8,132,137, +153,213,181, 43,200,247, 26, 35,113,107, 63,166,128,209,246,134, 14, 54, 7,110,109,195, 29, 2, 25,241,227,158,102, 3,139, 60, +170, 36, 37,143,143, 59, 85,231,141, 68,218, 49, 36,193,218,240,112,102, 42,210, 98,227,197, 12,133, 46, 84,180,104,168,116,220, + 3,107,143, 69, 75,224, 40, 14, 38,155, 75, 92, 71,162,128,239, 11, 80,224, 28, 27,218,104,182,225, 66,128, 92, 55,180,208, 6, + 91,143, 26, 95, 10,101,233,192,248, 80, 29,235,165,191, 11, 82, 91,143,174,186,195,149, 1, 42,223,184,255, 0,131,255, 0, 58, +186,146,223,184,183,251,159,249,213,212, 1,156,252, 63,208, 79,217, 20,128,253, 53,207,127,119,250, 9,251, 34,153,127,158,128, +100,182,212, 61,156, 77, 48,129,233,231, 73, 49,247,199,178,153,171,141,232, 2, 94,194,187, 80,172,142, 95,226, 71,100,224,229, +207,135,151,188, 71, 22, 78, 52,143, 12,241,148,148,149,146, 50, 81,215,130, 17,192,138, 93,235,241, 7,182,182, 77,163, 31,125, +147, 32,230, 96,229, 72, 98,199,147, 12, 9,117, 56, 4,149,248,148, 2, 44,121,154, 3, 89,115, 73,107,243, 53, 19, 7, 50, 61, +195, 11, 27, 62, 16,203, 22, 84, 73, 58, 43,128, 24, 44,138, 29, 67, 88,145,123, 31, 77, 73,189,168, 8, 83,220,204,192,113,181, +128,249,169,150,110, 84,242, 67, 72, 91,192,155,213, 87,112,119, 14,221,219, 59,107,238,219,153,113,140,140,168,122, 75,173,181, + 55,194, 0,184,168, 82,208, 41,229, 75,167,194,162,109, 27,166, 62,241,182,226,238,184,202,233, 6, 92,107, 52, 75, 32, 1,194, +176,184,212, 20,176,191,203, 82,245, 80, 13, 84,191, 10, 93, 2,244,170,192, 19, 81,242, 55, 45,191, 9,213, 51, 50,225,199,121, + 8,233,172,210, 42, 22,191,232,134, 34,244, 4,160,160, 90,150,192, 10, 77, 96,216,142, 32,241, 6,163,101,238,123,126, 27,164, +121,121, 80,227,179,252, 11, 44,138,133,175,195,221, 12, 69,232, 9,136,160,176, 7,194,230,157,165,127, 68,124,212, 15, 53,141, + 2, 25,178, 37, 72,163, 22,253,227,176, 85,227,203,139,112,174,135,114,219,178, 92,199,143,151, 12,173,107,233,142, 69, 99, 97, +204,216, 26,128,148, 18, 51,246, 1, 53,194, 36,244,115,164, 46, 52, 93, 92, 82, 44,139,224,120,248,208, 10, 81, 53,124,156,171, +140,105,194,223,202,107,186,128,106,245,154,112,101, 39,217,196, 26, 1,130, 49,115,204,124,180,141, 31,243,155,231, 52,242, 71, + 18, 8, 20,214, 34,196,147,225,203,194,128,172, 99,239,177,183, 2, 73,185,166,146, 7, 27,223,213, 79,233,146, 61,243, 93,238, + 47, 33,198,180, 6,251,196,123,162,222,186, 80,131,237, 27,210,179,183,176, 83, 24,131,199,153,160, 28, 52,134, 10,163,157, 72, + 81, 81,163,185, 96, 79,133, 73, 6,163, 1, 23,194,158, 41,139,206,159, 84,135, 80,229,107, 88,122,104,134,154,224, 90,244, 2, +175, 5, 20,224,120,211, 11, 1, 96, 77, 45,252,111, 64,116,158, 3,210,194,136, 40, 46,224, 50,220,248,220,210,245,211,195,141, + 0, 66,124, 43,169,165,197,184,211, 90, 84, 83,227,243,212,145, 3,155,227, 65,237,167,212,115, 48,212, 8,240,191,211, 69, 15, + 73, 16, 19,157, 40, 20, 19, 42,129,123, 10, 27,100,128, 57, 85, 16, 75,177,183, 42,105, 54,231,194,129, 30, 73,118,181,172, 61, + 52, 66,246, 23,168,218, 44, 48,114, 71,197,158,254,202, 50, 88, 42,139,248, 80, 38,156, 1,164,113,191, 58,103,154, 96, 0,183, + 42, 32, 75,224, 43,129, 23,252,212, 24,101,103,226,121, 81,111,194,227,157, 71,100,135,107, 30, 77, 14, 27,105, 36, 27,241, 52, +201, 39, 10, 45,226,104, 75, 49, 81,101,170,156,146, 9,130,247,228,126,138, 86, 32,154,139, 22, 65, 98, 3, 81,193,189, 80, 61, +109,233,250, 41, 15, 62, 21,194,184,208, 11,225, 66,129,133,155,133,184,209,188, 47, 65,199,226, 24,122,232, 2,139,210,219,211, + 93,200,215, 27, 1,115, 66, 10, 69,112, 52, 62,170,218,215,229, 93,213, 90, 20,155,127,220,114,254,199,254,117,117, 51,170, 58, + 23,255, 0,115,127,253,117,171,168, 4,121,100,178,113,254,206, 50,120, 15, 20, 90,103, 81,253, 53,206, 63,135,253,220,127,176, +180,202, 20, 22, 68,146,107, 0, 55, 11,122, 5, 8, 75, 37,143, 27,159, 88,174,201, 39, 88,246,126, 83, 64,227, 84, 31, 53,102, +228, 77, 23,118,119,176,139,106, 27,169,159,239, 56,158,235,171,202,171,100,220,230, 1,165,184,197,110, 7,133,175,206,147, 54, + 93,191,255, 0,243, 28, 28,108, 57,222, 89,151,118,121,115, 18, 69,210, 99,145,241,202,133, 78, 45,116,210,130,199,211,122,219, +100,254, 26,247,180,123,238,251,186,109, 27,134, 6, 60, 91,203,229, 70,250,218, 67, 39,150,202,151,170, 80,142,131, 5,107, 1, +200,251, 13, 46, 79,224,230,226,157,177, 22,211,129,155,143, 38,224,249, 99, 47, 46,105,139,199, 22,149,141,163, 88,227,208,146, + 49,182,171,220,129, 80, 1,238, 94,251,221,112, 31,183,123,111, 15,116,251,147, 8,109,216,178,230,238, 43, 17,153,193,120,189, +209,165, 67, 54,145,164,124, 62,154,167,127,197, 30,241,155,179,214, 69,220, 12,121,216,249,171,143, 38, 82,199, 22,185, 33,146, + 38,145, 3, 18,134,204,173, 25,226, 44, 77,108,123,139,240,227,122,201,159,102,222,118, 28,184, 33,222, 54,204, 88, 49,166, 73, +174, 98,115, 2,233,214,132,163, 95,153, 91, 50,216,138, 22,253,216,157,235,220,219, 4,120,123,150, 78,220,185,233,152, 50, 0, +136, 52, 80,164, 34, 35, 30,139,199, 9, 37,245,177, 60, 71,203, 64, 83,118,247,120,119,118, 23,122,224,109,187,246,226, 50,176, +242,113, 82, 89, 98, 69, 26, 4,111,139,230,145,135,186,173,173,108, 46,124,120,214,107,184,187,155,186,187,187,100,220, 55,108, +188,164,139,101,139, 50, 40, 35,219,149, 84, 89,156, 60,137,239, 5,212,116, 5,226, 73,227,122,244, 40,255, 0, 13,247,143,243, +126,221,190, 79, 54, 43, 96, 99, 98,193,139,145, 16,121, 58,173,211,197,242,175,160,116,180,218,252,174,220,171, 63,255, 0,249, + 15,120, 71,131,157,179, 99,110, 88, 99,109,151, 33, 50, 34, 73, 11,222, 70,143, 82, 35, 57, 17, 49, 67,161,248,129,126, 63, 61, + 1, 27, 55,189,119, 28, 12, 46,215,237,204, 77,211,238, 76, 47,187,177,230,205,220, 86, 35, 51,130,234, 74,141, 10, 25,180,141, + 35,225,244,250,170, 43,126, 38,119,100,189,156, 37, 92,243, 30,116, 25,171,143, 38, 82,199, 22,169, 33,146, 39,117, 13,116, 54, +101,104,207,188, 44,107, 87,186,126, 25,111,161, 54, 29,207,100,204,199,135,122,218,113, 97,197,157,100,212, 97,144,194, 13,157, + 11, 70,215,224,197, 72,101,177, 20, 93,255, 0,177,123,219,185,182, 8,176,183, 60,157,185,115,215, 48,100, 40,136, 60, 80,164, + 34, 35, 30,139,199, 9, 37,245,177, 60, 71,203, 80, 26, 30,192,255, 0, 55,101, 46, 94,235,220,210,127,134,206,143, 26, 93,174, + 5,101, 97, 28,101, 92,182,160,188,117, 21,208, 77,235, 51,248,161,217,157,183,137,183,110,253,213,157,145, 48,220,242,158, 49, +136,165,192, 78,165,149, 22, 36, 77, 60,110,170, 73,185,175, 77,218,113,228,192,218,240,112,102, 33,164,198,199,138, 25, 25, 46, + 84,180,104,168, 74,146, 1,181,199,162,188,235,241, 3,177,187,203,188,119,104,230,131, 43, 6, 29,179, 16, 91, 11, 30, 89, 37, +189,205,139,201, 34,136, 25,117, 49, 28,184,139,124,180, 6,135,240,185,119, 37,236,141,183,239, 34,197,200,115,142, 36,190,161, + 1,115,210,189,252, 52,252, 63,205,181,101,191, 20, 59, 51,182,241,118,237,219,186,243,178, 38, 27,166, 83,198, 49, 20,184, 9, +212,178,162,196,137,167,141,213, 73, 55, 53,109, 47,111,254, 37, 55,109, 65,129, 22,247,142,155,196,121, 77, 36,153, 74,204,177, +156,110,158,148,137,116,227,248, 55, 27,104,249,106,191,190,187, 19,189,187,195,112,130, 68,204,192,143, 3, 13, 2,226,193, 36, +147, 18, 94,195,169, 44,138, 49,217,117, 49, 31, 55,203, 64, 65,125,191,184, 51,255, 0, 4,240,176, 70, 44,249,153,185, 51,160, +198,137, 17,164,151,203, 9, 90, 72,238, 0, 36, 40, 84,224, 79, 13, 54,174,252, 31,200,237,124,125,245,246,227,181,228,237,221, +203, 30, 43, 99,206,114, 36, 50, 36,133, 10, 25,237, 27, 42, 24,159, 82, 95, 77,141,133,197,235, 97, 6,203,248,145, 7,105,195, +137, 6,247,135,254, 96,131, 51,173,215, 63,192,108, 78,145,140, 99,144, 96, 28,117, 53,254, 15, 14,117, 7,177,191, 15,183,109, +175,184,114,187,191,186,179,160,202,221,103, 15,161, 32, 62,232,105,120, 59,177,211, 24,190,159,116, 5, 22,160, 61, 32, 0, 95, + 82, 32,177, 54, 55,244, 10,112,137, 73,226,163,141, 8, 21, 32,254,240, 40, 39,232,244, 81,122,145,223,152,183,180, 84, 2, 24, +210,250,116, 11,122,105, 76, 81,133,213,160,124,212,134, 85, 39, 72, 43,235,185,240,245, 87, 60,168, 23,221, 96,110, 57, 92, 80, + 13, 88,144,168,107, 15, 95, 10,107,196,130, 54,109, 32, 16, 15,209, 78,234, 32, 2,236, 61,151,161, 78,232,209, 16, 24, 27,219, +135,203, 84, 16,152,220,223,157, 33, 55,246,250,171,143, 3,233,164, 60, 56,255, 0, 37, 80,117,237, 74,136, 92,240,166,128, 93, +128, 2,228,242, 21, 57, 35, 88,198,145,242,154, 0,122, 52, 40,245,243,174, 20,249, 79, 5, 31, 45, 52, 84, 2,220,142, 66,245, +193,164,110, 75, 77,118, 43,203,209, 68,141,155, 65, 53, 72, 42, 22,189,152, 90,150, 67,101,161,164,156,110,220,233,175, 38,162, + 64,229,225, 64,112,187, 54,170, 43, 16,170, 73,229, 76, 30,234,129,227, 77,118, 4, 88,241,172,113,102,184, 0,212,204, 73,162, + 68,164,146,198,185, 64, 52,251,128,120,114,173, 62, 1, 15, 98, 21, 9, 34,162,234, 38,230,139, 33, 12, 0,227,235,161,133, 21, + 18,128,199,196,186,141,219,144,169, 41,202,244, 37,210,160, 11, 87, 51, 0,156, 47,168,253, 85, 28,182, 80, 82,200, 75,240,228, + 41,164,177,225,233,166, 26, 52, 74,163,222, 63, 37,107,130, 32, 88,215, 66,138,123,182,133,185,181, 15, 80,252,212, 41,157, 89, +180,142, 67,249,107, 17, 44,163, 47,168,146,105, 85,117, 48, 90, 96,169, 48, 40, 0,177, 28, 73,225, 91,110, 17, 3, 40, 10, 0, + 95, 10, 43, 54,133,185, 60, 0,160,221,125, 28, 56,208,242, 36, 83,238, 47,202,107,154, 82,202, 5,216,187,150, 53,220,128,227, + 77, 62,161, 70,133, 20,144,204, 56, 10,233,193, 25, 9, 4, 86, 23, 60,205, 25, 77,141,169,186,151,195,128,241,174, 98,128, 22, + 60,192,172, 38,231,204,211, 90, 7, 82, 56, 83,154,214,185, 60,170, 42,100, 32, 6,252, 79,162,134,243, 52,135,143, 5,244, 87, + 67, 16, 29,114, 67, 93, 88, 88,120, 26,176,198,219,127,114,178,245,127,136, 3,219, 79, 43,139,250,106,148,184,210, 82,223, 17, + 28,107, 89, 2,152,224,138, 38,230,136,170,109,203,128,181, 43,168,122, 34, 11, 96,219,143, 83,254,207,231,170,249,181,116,218, +222, 60, 42,246,110, 35,133,103,101,200, 75,201, 15,218, 86, 43,243, 27, 85,106, 32,139,130, 16,194,162, 61,125,102, 39, 77,213, + 71, 59,211, 63,115,162,226, 73, 11,248,175, 15,170,144, 72,209,178,200, 99,247, 84,105,185,228,105,145, 49,107,155,113, 38,245, +153, 53, 5,143, 77,124,135, 83, 91,107,232, 90,222,174,190,171,215, 82,220,249, 45, 55,254,195,159,252,123, 87, 85,145, 3,164, + 31,195,254,238, 63,216, 90, 29, 62, 79,236,255, 0,187,143,246, 22,153, 64, 69,201,182,177,236,252,166,128,121, 81,242,127,136, + 61,159,148,208,121, 85, 6, 68,119,246,220,168,141, 36, 14,165,176,114,183, 7,226, 8, 95, 40,210, 35,194, 79,233, 19, 11,219, +217, 87, 81,239,251,116,143,229, 76,161,115,150, 46,172,152,156,110,172, 35, 19, 52,122,172, 20,184, 86,185, 94,118,227,107, 86, + 63, 47,240,251,112,158, 92,214, 76,136, 21, 50, 55, 17, 52, 74, 75,251,184, 18, 28,150,200,199, 96, 19,226, 45,153, 33, 85, 28, + 57,113,171, 53,237, 76,193,220, 57, 27,129, 8,248,239, 60,249,112,204,249, 25, 23, 86,159, 27,202,244,198, 32, 61, 5, 96, 75, + 94, 78, 36,175, 11,122, 0,184,194,238,157,163, 38, 45,184,201, 58,227,228,110, 88,240,101, 67,142,247,186,174, 66,234,141, 93, +128,210, 11,113, 11,115,239, 17,194,137, 15,116,118,252,248,242,101,197,184, 70,208, 68,209,163,201,239, 1,121,206,152,109,113, +114, 36, 63, 9, 28, 15,133,103,112,251, 83,120,195,134, 12, 15,240,146,227,207,133,183, 98,231, 78,229,153,162,108, 24,218, 57, + 12, 8,201,239,150,184,233,177, 43,164,241,181,116, 61,167,187,200, 49,164,201,108,120,165,196, 27, 70, 58,172,110,236,143, 14, +215,144,114, 36,148,222, 48, 67,200, 24,133, 79, 15, 22,160, 52, 56,221,209,176,101,117, 12, 25,232,203, 12, 47,147, 41, 96,200, + 22, 40,206,153, 28,151, 85,248, 15, 6, 28,215,198,166,226,238,123,126,102, 36,153,216,211, 7,199,139, 80,149,172,192,161, 65, +118, 86, 70, 1,129, 3,141,136,172,116,157,147,185, 75,139, 38, 57,158, 5, 47,137,186, 99,171, 6,147,248,153,185,233,157, 7, + 37, 7, 72, 84,179,145,196, 30, 87,173, 23,108,237, 83,237, 88,217, 94, 98, 53,134, 92,188,150,201,104,198, 68,249,108, 46,145, +196, 58,147,229, 18,238,214,140,122, 7,135,174,163, 0,246,206,242,216, 55, 72,118,249, 23, 32, 65, 54,226,145,201, 14, 60,160, +135, 29, 86, 40,138,228, 2,160,179, 41, 85,227,239, 30, 87,165,238, 78,238,219,251,110, 65, 6, 76,111, 44,205,137,145,154,170, +131,129, 92,109, 55, 91,159, 22,212,109,236,227,225, 89,221,179,179, 55,172, 76, 76,125,186,118,198, 48,184,219, 83, 42,120,229, +114,200, 54,185,250,202, 99, 86,137,117,117,148, 40,226, 70,147,127,138,173,123,215,183,183, 46,224,233,253,220,240, 47,248, 44, +252, 41, 60,195,186, 91,205,136,116, 58,232,142, 75,233,104,120,142, 28, 15,201, 80, 22,201,220, 91,102, 68,152,227, 18,120,228, +138, 89,229,198,150, 70, 99, 25, 71,134, 22,201, 97,165,212,106,247, 84, 31, 15,116,234,229, 82, 54,253,231,107,221, 34,150,124, + 12,149,154, 56,108,101, 54,101, 42, 25,117,171, 89,192, 58, 89,120,169,228, 71, 42,207,201,219, 27,147,110, 82,103, 35,227,178, + 54,229,145,158,169, 38,182, 6, 57,182,207,187,213, 93, 66,139,158,167, 22, 23,248,124,111,194,141,219,123, 38,229,182,225,231, +227,229, 8,226, 73,213, 35,197,198, 73,164,200, 88,130,198, 81,128,154,100, 89, 58,122,190, 4, 55,210,191, 53, 1, 98,189,213, +219,175, 4, 51,174,124,102, 44,130, 68, 50, 0,218, 88, 13, 26,154,246,224,131,168,183, 99,238,130,109,122,228,238, 93,178, 47, + 62,115, 31,203, 46, 22, 97,192,187, 93,140,146, 8, 35,202, 37, 21, 1,107, 4,147,143, 14, 22, 39,149,102,115,251, 39, 63, 35, +110,217,240,143, 74,115,141,181, 38,211,152,158,103, 39, 30, 32, 64,139, 84,191,225,180, 52,233,238, 55,238,222,215,225, 82, 55, + 46,210,220,167,155, 43, 50, 38,142, 83, 38,229, 46,108,112, 12,169,241, 11, 69, 54, 20, 88, 86,121,241,128,117,101,120,245, 21, + 23, 12,188, 47,225, 64,106, 70,251,178,166, 86, 62, 9,204,143,205,100,170, 52, 74,164,176, 34, 80, 90, 43,186,130,163,168, 20, +233,185,247,188, 42, 57,238,142,223,213,145,108,216,255, 0,195, 89,101,176,110, 36,201,209,253,223,187,251,207,222,123,158,229, +253,238, 28,235, 61, 39,105,238,235,153,181,136, 95, 31,200,237,171,182,244,144, 79, 52, 74,167, 10,235, 50,244,130, 73,212, 44, +182,208,210, 49, 34,214,225,123,212,105,123, 55,120,153,167,107,227, 65, 26,203, 22, 68,120,152,249, 83,162, 75, 34,100,249,137, + 26, 25, 52,245,112,196,136,126, 24,216,141,124,125,116, 6,229, 55, 29,189,182,255, 0,189, 70, 68,127,119,172,109, 51,101, 19, +238, 42, 37,245,150, 39,150,155, 27,250, 42,155, 51,188,182,152, 83,111,242,108, 51, 27,112,204, 24, 49, 1,170, 62,155,132, 50, + 72,210, 6, 77, 67, 74,219,221, 34,230,227,195,141, 53, 59,117,191,201,179,118,222,184,160,200,153, 39, 35, 76,146,205, 18,203, + 52,175,144, 53, 73, 57, 50,184,212,222,243, 30, 39,137,176,229, 81,211, 96,220, 39,207,139,118,201,104, 33,200,147,120, 77,207, + 35, 25, 36,105, 17, 34,139, 1,182,245, 68,126,154,106,114,108,198,224, 15,155,136, 19,119, 94,245,218,182,141,205,246,156,148, +115, 60, 67, 12,200,225,108,161,115, 39,242,192,159,232,124, 71,212,120,113,169,239,220,253,187,208,198,203, 25,136,144,230, 23, +242,238, 67, 11,136,216, 69, 33, 96, 69,208, 43,251,172, 90,214, 60, 13, 83,239,221,189,159,185,119, 4, 91,158, 44,152,227, 22, +219,103, 88, 72,238,178, 41,219,243,155, 53,180,170,198,234,218,210, 66, 5,216,113, 30,187,138,108,206,197,207,154, 8, 96,102, +135, 32, 58,238, 16, 79, 31,154,202,199,141, 83, 55, 53,179, 35,145,134, 54,134,152, 8,219, 75, 70,214, 26,173,199,198,128,216, +111, 91,195,109,146, 96, 99, 67,136,114,178,119, 25, 94, 8, 81, 93, 99, 0,199, 12,153, 12, 89,159,135,195, 25,170,140,126,243, +219,115,224,150,103,141,241, 35,199,135, 22,121, 26, 82, 15, 28,151,158, 21,137, 4,122,181, 29,112, 16, 52,223, 85,197,170, 79, +117,236,210,111,111,181, 75, 14, 38, 30,225, 30, 6, 68,147,100, 96,238, 12,201, 12,170,240, 75, 2,241, 16,100,139,171, 72, 27, +138,120, 86,105,123, 11,115,143, 18,104,206, 68,114,145,228, 30, 8, 99,154,104, 63,233, 50,114,167,108,117,153, 87,169, 26,172, +121, 11, 28, 78,188,125,222, 32, 80, 26, 9,251,159, 97,198,130, 28,137,243, 99, 88,167, 70,150, 38,247,141,209, 24, 35,183,186, + 9, 1, 89,128,107,242,241,161,207,220, 91,124,123,198, 54,201, 27,245,114,167,149,225,145, 87,148, 69, 49,223, 47,223, 36, 91, +224, 81,192, 30, 23, 23,170,105,251, 23, 62, 77,180,225,194,216,240,187,237,123,142, 17, 83, 44,242, 40,200,206,201,143, 41, 79, + 82, 85,121, 29, 70,150,212,199,137, 63,103,209, 50, 94,212,220,164,222, 76,138,216,235,182,156,220,156,227, 62,183,235,255, 0, +138,193,124, 46,152,139, 70,155,163,182,171,235,226, 61,117, 65,113,143,220,125,188, 49, 36,206, 92,248,186, 17,178, 36,147, 27, +128, 12,166,209, 90,224, 18,175,246, 88,112,111, 10, 62,225,188, 54, 52, 88,146, 97, 98, 75,156,249,167,247, 41, 29,163, 80,154, + 12,165,229,121,116,170, 13, 34,220,120,220,218,178,187,103,101,238, 56,248,177,197, 40,134, 57,210,125,165,157,206, 86, 78, 81, +146, 45,182,110,171,182,172,128,116,106,187,116,227, 85, 0,120,159, 70,135,186, 48, 55,125,203, 18, 44, 61,179,164, 96,146, 79, +254, 99, 20,179,201,140,210,193,164,222, 20,154, 24,167,101,214,214,212, 64,190,155,128,120,212, 3,155,184, 34,159,102,195,222, +112,113,166,202, 92,229,133,177,177,213, 64,144,156,130,186,117,146,116,160, 91,221,152,155, 1,233,167,224,111,184,121, 91, 92, +219,180,255, 0,224,225,198,105,162,202, 19, 17,251,183,199,145,161,148,106, 82, 85,134,164, 54, 35,157, 67,220,113,123,146, 77, +177,240,182,184,240,240, 36,233, 99,199, 8,142,105, 0,141, 67, 17,145, 28,111,229,253,219, 70, 2,196,221, 63, 93,133,133, 56, +109, 19,255, 0,149,229,217,227,192,195,133,250,102, 36,194,105,101,159, 24,173,238,117,205,211,134, 82,206, 46, 75,105,190,174, + 60,104, 3,183,115,108, 26, 33,149,179,145, 86, 98,232,161,131, 43, 6, 66,170,253, 69,101, 13, 30,146,235,114,224, 90,227,211, + 79,151,184,246,200,103,108, 24,167,142, 92,184,231,135, 30,120, 75, 20,208,103,146, 56,197,219, 73, 26,191,122, 10,175,218,172, +126, 79, 99,111, 25, 42,163, 37,163,156, 77, 30, 70, 59,193, 46,110, 82,244,162,154, 72,221, 58,211, 64, 34,124,189, 42,140, 25, +100,181,248,113,225,122,191,155,182,179,159,207,105,146, 17,230,119,204, 61,217, 46, 91,132, 24,254, 83, 90, 55,185,241,159, 46, +214, 28,185,113,170, 66,203,252,197,177, 95, 48, 54,100,119,194, 12,217, 4,146, 2,172,109,161,200, 36, 89,180,176,210,116,222, +199,135, 58, 54,223,159,137,185, 66,114,176,164, 18,196, 24,161,224, 84,171,175,196,174,174, 3, 41, 30,130, 43, 27,143,217,185, +248,231, 61, 26, 28,108,146,240,228,227,227,182, 78, 78, 84,169, 50,100,228,140,157, 45, 13,194, 99,141, 42, 1,233,130,117,123, +222,219,254,223,192,222,118,172,111, 47,156, 98,120, 36,105,165,227, 43,205, 58, 22,100,232,198,210,188,105,213,178,106,212,237, +239, 94,195,136,227, 81,244, 42, 46, 36,145,175,194,132,100,127, 77, 25, 87,135, 26, 27,165,220,139,216, 10, 20,104,149,199,141, +119, 85,253, 52,189, 49,250, 66,151,162, 63, 76, 85, 32,206,163,250,105, 68,142, 60,105,253, 0, 73, 26,135,170,154, 98, 35,196, +124,244, 7,117,164,244,215, 9, 92,155, 19,194,155,211,106, 66,164,115, 20, 1, 29,130,219, 75,234,191, 62, 22,164,235, 63, 47, + 69, 36, 96, 51,128,121, 26,146, 49,227, 52, 4,110,171,210,107, 99, 82,252,170, 91,215, 93,229, 23,211, 64, 69,214,212,241, 60, +150,176,169, 39, 13, 7, 35, 73,229, 7,166,160, 1,215,147,213, 77,234, 57,230, 5, 24, 66, 10,145,232,185,189,119, 64, 90,254, +138, 64, 7,173,169,226,103, 3, 72, 2,150, 76,114,120,169,183,133, 71,112,232,218, 91,157, 32, 19,213,181, 1,127,244,245, 80, + 37,144,147,164,114, 20, 52,144,162,216,159,139,149,117, 69, 93, 75, 33,241,209, 37,107, 59, 21,244, 90,165,140, 8, 79, 30,179, +124,194,171,145,138,176,177,171, 40, 95, 82,250,235, 70, 89, 83, 54,243,218, 88,211,201,143,145,220, 56, 48,207, 19, 24,228,138, + 76,152, 17,149,212,217,149,213,156, 21, 32,243,189, 93,158,245,236,187, 15,255, 0,232,246,191,255, 0, 91,143,255, 0,121, 95, + 63, 99,118,254,215,157,189,119,214,251,151,180,205,220,121, 91,110,230,241,227,236,120,242, 73, 27, 50,207,145, 40,124,135,232, + 94, 82,169,166,222,239,203, 89,222,235,237, 77,163,109,239,156, 77,139, 21,159, 11, 11, 53,113, 37,155, 26,103, 15, 46, 27,100, +170,180,152,206,254, 44,151,230,106, 59, 42,213,217,240, 74, 95,192,170,174,205, 85,113,110, 23,196,250,121,251,215,179,111,195, +184,182,203,127,249,220,127,251,202,160,203,238, 62,208, 50,203, 42,247, 22,220, 75, 49, 96, 6, 92, 7,153,191,233,215,207,157, +197,177,237,208,237, 25,121,177,109,115,108,211, 96,229,174, 44, 34,105, 25,198, 82, 54,171,176, 18,125,165,211,114, 87,133,107, +251, 91,177,123,123, 51,107,237,216, 39,216,178,183,111,243, 12, 82,201,157,220, 48, 78,233, 30,220,200,204,154, 2, 32, 49,254, +239, 77,223,169,207,195,209, 89,197,158,185,169,221, 84,212, 56,214, 63, 9, 71, 76,184,173,138,202,173,167, 42,116,159,198, 25, +236, 27,110,231,182,111, 16,147,183,102,195,153, 20, 54, 89, 6, 60,169, 45,152,241, 26,140,108,214,169,139, 24, 11,170, 59,130, +124, 13,121, 55,224,135,151,195,198,238, 8,122,232,241,166, 92,113,199, 53,192, 14, 21, 92,106, 23,244,142, 53,235,170,203, 36, + 65,145,131, 7, 23, 86, 6,224,131,200,130, 43, 71, 50, 69,255, 0,193,127, 59,163,255, 0,196, 87, 82,244,207,150,211, 97,126, +133,191,245,247,174,160, 21,199, 8,255, 0,187,143,246, 22,155, 78,127,177,253,220,127,176,180,202,208, 34,228,252, 99,217,249, + 77, 0,222,244,124,145,239,143,103,229, 52, 43, 80, 30,107, 47,120,239,209,224,103,102, 99,202,153, 15, 2,110,109, 44,126, 93, +130, 98,249, 73,100,143, 29,140,163,220,109,122, 0, 42,120,159, 14, 70,180,131,188,240, 27,127,125,129, 80, 60,234,242, 64,129, + 37, 70,153,165,138, 15, 52,223,225,239,172, 38,144, 84, 57,224, 88, 91,215, 83,155,182,176, 91, 97,202,237,227, 36,222, 83, 47, +204,245, 36,212,189, 65,230,229,146,121, 52,157, 58,120, 52,135, 79,187,203,211, 73,254, 92,199, 25,249, 57,126,111, 37, 96,201, +105, 37,147, 9, 89, 68, 93,105,162, 24,242, 73,112,186,205,208,112, 82,214, 7,141,168, 10,136,251,239, 29,176,115, 50,155, 20, + 44,152,114, 99, 69, 34,137,227,104,147,205,112, 86,158,116,186,199,211, 55, 18,112, 58, 72,241,167, 14,253,192, 92,252, 44, 9, +224, 16,205,151,229,213,163,121,163,234, 7,203,118,138, 46,148, 96,222, 85,184, 5,153,120, 5, 32,251, 36, 97,246,108, 88, 56, +239, 22, 54,231,152,146, 20,199,140, 74, 12, 35,221,196, 12,145, 41, 69,136, 35, 41, 71,210,234,192,131,207,159, 26, 38, 23,103, + 97,109,210,227,182, 22, 94, 84, 81, 68, 33,235, 64,175, 24, 89,219, 29,222, 72,154, 82, 35, 4,123,210, 27,170, 21, 83,192, 90, +212, 4,141,219,125,147,111,205,139, 7, 23, 2, 92,249,140, 47,151, 58, 68, 64,100,134, 55, 72,201, 69, 35,247,142, 75,240, 81, +232,231, 84,187,127,124, 73, 22, 46, 75,238,248,196, 8, 34,220, 50,163,200,141,148, 9, 35,194,205, 56,157, 61, 6,218, 79,188, +130,228,241,226,120, 85,238,237,219,241,110,185, 17,101, 12,169,240,229, 88,155, 26,102,198,101, 83, 36, 14,201, 35, 70, 75, 43, + 21,247,163, 22,100,177,231,198,162,127,146,246,150,133,225,105, 39,100,120, 51,113,143,190,183, 11,159,144, 51,100, 96, 66,124, + 73, 34,141, 30,174,119,168,192, 12,126,246,139, 59, 26, 35,182,226, 12,220,217, 50,165,195, 16,193, 58, 60, 37,161,128,101, 59, +166, 66,130,172,189, 54, 22,176,248,141,189, 38,155,177,119, 99,238,155,206,102,206,240,183,152,142, 99, 32,133,128,141,241,177, + 60,190, 52,128,206, 13,206,179, 44,197, 0, 30,191, 69, 77,155,181,186,208, 71,171,115,203,243,241, 79, 38, 66,238, 23,139,168, + 26, 88,142, 60,136,169,211,233, 42,104, 60, 0, 94, 7,143, 58,236, 46,206,219,112, 50,227,207,198,146,113,149, 28,221,126,187, + 50,179,178,156,120,241, 26, 25, 25,144,150,141,150, 37, 99,126, 58,184,222,160, 43,119,254,231,222,182,237,245,182,204, 76,100, +108,117, 27, 89, 70, 36,106,115,153,152,216,210, 47, 19,195, 82,174,145,232, 34,254, 52,153, 63,136,219,118, 14, 22, 54, 86,100, + 2, 22,148,100,188,240,188,241,169, 81,137, 57,196,149, 97,215,167,172,229,212,149, 85, 28, 64,240,171,157,203,182, 49, 55, 61, +210, 61,214,105,231,142, 88,198, 40,104,163, 40, 35,127, 39,145,231, 33, 45,174, 54,110, 14, 72, 54, 97,112,125,134,163,158,205, +196, 68,133,113,179, 50,177,138,121,149,149,226,100, 15, 44, 89,121, 7, 50, 88,153,140,126,232, 18, 31,117,146,204, 7, 11,248, +208, 29,221,123,190, 78,215, 46,211, 20, 25, 30, 86, 44,204,137, 34,200,157, 96,108,150, 85, 76,121,102, 93, 49, 32, 36,221,163, + 28,135, 42,166,237,238,231,221,183,109,199, 27, 31, 43, 37,162, 71,198,195,157,124,166, 12,153, 41, 33,200,146,116, 45, 52,145, + 44,139,142, 25, 98, 83,239,145,166,231,244, 77,182, 57,123,116, 25,153,184, 25,178,179,137, 54,233, 94,104, 2,144, 20,180,144, +201,140, 67,220, 18, 70,153, 79, 43,113,170,189,179,180, 33,218,242,206, 78,219,186,102,226,235, 84, 73,226, 95, 44,233, 42,164, +179, 78,170,221, 92,103, 96, 47, 59,143,112,142, 30,190, 52, 5, 22,119,123,238, 80, 73,220,141, 11, 65,208,199,198,203,151,101, + 26, 46, 67,237,204,184,249, 26,205,253,237, 82, 61,199,170,141,220, 29,197,220,155, 76, 27,174,219,141, 44, 57, 59,158, 44,187, +111,146,201, 48,133, 12,155,132,175, 6,137, 35, 12, 65,101,104,143, 17,110, 4, 85,156,255, 0,135, 93,187, 54,223, 14, 8,105, + 97,104,163,158, 25,115, 34,232,174, 68,235,146,141, 28,167, 34, 78,145,214, 78,173, 92,190, 32, 61,149, 52,118,174, 3, 51, 73, +151,155,145,149,151, 46, 86, 46,100,185,147, 52, 66, 70,108, 23, 18,193, 30,152, 98,142, 53,140, 17,196, 42, 3,196,241,191, 26, + 3, 41,157,223,251,156,185, 59,174, 70,214, 98, 59,118, 62,200,249,248,132,166,163,230,145, 49, 39,185,111,180,161, 51, 20, 91, +211, 91,125,151, 42, 73,240,167,200,150,108,156,178,140,218, 68,248, 82, 96,203,238,168,109, 41, 14, 66, 68,205,123,240,107, 90, +252, 47,194,169, 19,240,255, 0,183, 96,196,155, 10, 41,230, 72,167,198,204,195,112,175, 29,250,121,178,199, 60,132,126,238,215, + 78,146,170,122, 20,113, 7,157, 95,193,136,209,225,207,139,151,185, 79,184,245,195, 43, 75,144, 49,209,213, 89,116,149, 95, 41, + 12, 11,243,130,104, 10, 44,110,252,199,201,198,158, 69,193, 39, 38, 12,156, 44, 79, 47, 20,241, 74, 53,231,186,197, 18,180,139, +238,171,163, 18, 29,126,201, 28,205, 65,221,187,251, 45, 54, 73,178,246,204, 13, 57,241,226,103,229, 74, 29,213,146, 3,133, 57, +195, 99,196, 14,173,229, 28, 7, 15,116,124,149, 99,135,217,123,110, 36, 41, 19,102,229, 79,211,108, 7, 82,221, 32, 47,182, 63, + 83, 24, 90, 56, 87,135, 0, 31,211,234, 60,105, 50,187, 23,107,203,197,108, 36,205,203,199,138, 72,243, 32,200,104,140,101,228, +135, 58,115,153, 44, 68,188, 46, 6,153, 79,186, 64,189,184,113,160, 46,183,205,230, 77,173,176,241,177,112,219, 55, 55, 58, 71, + 72, 32, 87, 17,139, 69, 27, 79, 35, 51,176,107,123,169, 96, 45,196,145,237,170,101,239, 88,231,203,142, 39,219,102,135, 17,229, + 56,107,145, 49, 85,113,148, 49,124,243, 66,240,252, 75,101, 82,183,253, 33,232,227, 86,251,214,213, 14,239,229,164, 92,169,240, +178,177, 29,159, 31, 43, 25, 87, 90,245, 35,104, 36, 91, 74,142,164, 50, 57,240,224,108, 69, 85, 30,209,193,142,113, 44, 25, 19, +180, 81,147, 52, 56,179, 48,104,252,215,150,242, 94,101,152,167, 80,177,143,157,218,215, 37,173,122, 32, 69,195,239,136, 39, 76, + 86,159,111,124,127, 56, 54,249,163,187,171,219, 31,115,103,138, 9,152,175, 43, 72,154, 89,125, 98,161,205,223, 71, 43,108,207, +203,195,193,150, 24,177,112, 6,224,249, 97,162, 37, 35,151,175,208, 40,142, 61,246,126,133,249, 91,141, 4,246, 62,108, 93,175, + 38,218,179,140,173,219, 39, 7, 11,110, 51, 75, 38,152,177,215, 16,106, 86,128,199, 18,177, 88,229,102,117,212, 53, 30, 28,120, + 85,235,246,118,212,248,121,216, 58,229, 72,115,240,113,246,201, 66, 50,141, 16,227, 44,137, 25,138,232,108,214,148,222,247, 28, +184, 85, 4,108,190,239,104,183, 7,195,139, 5,252,184,202,125,185, 51, 75,173,188,202, 99,182, 91, 14,151,197,164, 42,218,254, +159,166,154, 46,248,221,228,237,248,242, 70, 10,253,228,145,108,243, 74,197,215,167, 36,123,156,139, 25,117, 81,109, 36,149, 96, + 5,248, 92, 31, 72,169,217, 29,169,155,147,220,131, 44, 72, 34,218,151, 40,231,178, 44,215,213, 35, 98,190, 35, 90, 3, 15,186, +228,181,203,117, 74,216,112, 80, 73,169,195,178,118,193,132,248, 41,145,146,138,248,219,126, 32,148, 52,122,213,118,183, 50, 99, + 72,183,140,174,189, 70,237,117, 32,250, 5, 64, 39,113,119, 72,216,100, 43,228,155, 36,174, 36,187,132,218,100, 84, 9, 14, 59, +196,146,124, 64,234,111,222,240, 30, 52,167,186, 72,220,223, 1, 48, 93,225, 57, 79,183,195,148,100, 85, 15,150,152,231, 47,165, +160,241, 10, 85, 74,235,244,248, 91,141, 31,119,237,172, 45,233,229, 57,114,204, 12,184, 83,237,174, 99, 40, 63,117,144,209,187, +191, 20, 62,253,225, 22,240,231,194,158,157,183,136, 55, 65,185,245,165, 40, 50, 14,106,225,157, 29, 17,148,208,249, 83, 56,247, +117,223,167,126, 26,173,115,123, 94,128,204,236,221,239,157,147,135, 30, 86,102, 57,151, 54,108,125,180,197,137, 25, 68,137,165, +206,121,163, 86, 87,247,153, 65,233,234,109, 87,176, 28, 56,212,249, 59,251, 26, 45,195, 23,107,203,197,108, 92,169,158, 24,101, +130,105, 81,102, 89,114, 37,104, 35, 17, 68,125,233, 83, 82, 92,184,251, 36, 31, 97,177, 59, 31,110,194,129,177,113,242,242,181, +170,226, 46, 52,238, 98,103,135,200, 73, 36,216,250, 0,137, 84,219,170, 84,235, 6,235,235,227, 82, 98,237, 88, 48,242, 34,201, + 77,195, 48,155,196,217,106,206,135,204,201, 11,201, 52,111, 51,104,212, 61,233, 77,213, 10,169, 22, 22,176,170, 0,239, 93,196, +187, 38,100,146, 74,178, 73, 20, 27,110, 86,224,240, 32, 64, 27,161, 36, 9,241, 55,188, 27,247,156, 60, 40,111,221,179,185, 56, +145,237,140,251,146,230,203,130, 49, 58,171, 99,210,199, 92,198,147,171,166,223,195,112, 45,111,139,135, 46, 53, 59,118,237,188, + 29,237,230,124,185, 37, 67, 54, 20,251,115,116,138,139, 69,144,209,200,236, 53, 35,123,224,196, 45,225,234,160,100,118,182, 46, + 68,243,228, 99,229,228, 98,101, 75,148,249,195, 38, 35, 25,100,121, 49,215, 10, 68, 64,232,203,164,198,131,152, 36, 55, 27,214, +121,148,133,183,119,100,146,100, 77, 22, 92, 14,189,108,249, 49,113, 99,101, 17,188, 73, 30,221, 30,226, 86,101, 63,106,250,148, +250,234, 44,253,229, 62, 88,219,219,109,197, 43, 30, 75,237, 47,147, 52,165, 79, 77, 55, 57, 84, 8,130,253,163,211,189,216,114, + 36,124,147,165,236,236, 40,145, 60,190, 94, 76, 82, 46, 73,203, 89,181, 35,184,102,197, 27,123,173,229,141,238, 26, 37,230,110, +117,113,189, 38, 63,101,224, 3,135,210,202,201,142, 28, 53,193, 86,136, 24,200,153,182,214, 15,140,242,150,140,155,248, 54,141, + 55,249, 42,130, 26,119,246,214,239,184,170, 71,212, 56, 48,207,144,145,197, 42, 60,142,184,242,140,114,178, 34,155,196,206,236, +186, 3,115, 83,122,181,237,237,195, 59,114,125,213,115,226, 88, 95, 15, 56,227, 36, 74, 67,105, 65,143, 4,182,214, 62, 47,122, + 83,199,209, 77, 94,206,195, 48,230,226, 62, 86, 75,225,228,164,209, 71,141,173, 85, 32, 92,137, 12,239,210,210,128,150, 15,197, + 75,234,176,225,233,188,237,163,104,109,168,101,152,167,151, 46, 92,201,252,214, 84,211,244,193, 50,152,227,132,233, 17, 36,106, + 22,209, 14, 22,160, 39,232,247,173,106, 99, 1,126, 28, 42, 82, 47, 81, 11,218,204, 57,138, 3, 1, 98,104, 4,143,128,163, 69, +140,217, 74,120,133,183,137,160,170, 18, 11, 6,211, 92,131, 32, 11,197,123,122,170,144,146, 54,233, 98,253,233, 96, 66,113, 52, + 96, 99,189, 67, 47,150, 22,205,171, 73,224,111, 82, 0,191, 46, 30,186, 2, 66,152,248,222,147, 84,124,232,122, 52,139, 95, 81, +231, 75,110, 20, 1,109, 25,230,126, 90,126,152,239,207,149, 71, 55, 63, 39, 42, 66,121,222,128,145,210,142,222, 21,198, 4,229, +122, 5,200, 60,233,117,155,208, 15,120,213, 69,129,168, 89,145,251,161,188, 69, 29,174, 90,194,147,166, 39,117, 67,240,243,111, + 96,162, 4, 65,143, 43, 8,200, 70, 32,248,128,105,221, 9,255, 0,217, 63,234,154,186, 80, 0, 10, 5,128,224, 0,167, 0, 61, + 21,190,207, 18, 73, 81, 22, 44,164,234,104,154,195,195, 73,169, 48, 67, 50,220,116,152, 11,248,169,171, 36, 21, 33, 5,189,117, + 21, 20,241, 29,203,129,243,215,110,199, 2,247,135,120,102, 77,181,161, 56,123,150, 65,155,125,200,221,167,218, 34,198, 89, 38, +116, 88, 25,241,193, 44,100, 97,202,177, 61,241,180,207, 63,121,166,209,183,236,141,183,102,228,116,145, 49, 83, 50, 76,255, 0, + 51, 44,204, 89, 50, 19, 38,110, 44, 37, 14,191,233,122,182,220,251,159, 31,102,238, 94,243,218,183,173,167,239,125,135,114,221, +178, 30,104, 58,175,142,203, 60, 19,202,209,188, 83,160,107, 27, 55, 17,110, 34,161, 79,189,239,251,159,226, 6,209,185,249,120, + 59,127, 39, 28, 99, 13,166, 12,242,240,226,193,141,142,191,184, 89, 36,148, 6, 49,149, 83,118,241,189,100,164, 94,235,236,238, +231,218, 54,244,220, 55, 45,203, 31,118,196,197,148, 98,100, 54, 38, 89,202,242,147,145,126,132,192,252, 7,135,135, 10,223,246, +118, 22, 60,189,165,139, 2,118,220,122,183, 24,143, 79, 10, 78,224,202,194,155,117,104,134,153,101,135, 13, 6,131,114,188,143, +242, 85,127,126, 71,141,139,218,187,132, 91, 35,108, 56,144,103,100,197,153,188, 69,183,238,167, 63, 39, 34, 80,196, 34,195, 27, + 34,104,141, 26, 66,214, 21, 73,219,253,246,248,241,108,216,179,246,207,222,221,197,179, 70, 99,237,236,193, 36,202,202,141,170, + 88,250,152,209,169,235,104,212, 89, 56,143,203, 81, 36,148, 37, 11,192,173,182,229,185,243, 47,127, 12, 87, 22, 92, 13,232, 54, + 36,177, 67, 38,229, 26, 65,137, 27,130,209,179, 36,186, 33, 38, 81,119, 35,225,229,123,215,185, 97,225,228, 38, 44, 8,113,229, + 77, 49,168,208,224,150, 22, 3,131, 17,192,154,241,223,193,169,242, 14, 6,237, 38, 75, 50,229,201,187,226,180,177,149,109, 79, + 37,164,102, 70, 85, 43,167,222,253, 46, 0,215,208,227, 83, 42,179, 2,172, 64, 44,151, 6,199,209,113, 86, 8, 85,116,101,232, +219,166,215,233, 90,214, 60,250,183,183,205, 93, 86,190, 31, 39,229,174,171, 4, 40,223,236,127,119, 31,236, 45, 54,156,255, 0, +217,255, 0,119, 31,236, 45, 55,198,133, 35,100,143,124,123, 63, 45, 7,213, 70,200,248,199,179,242,208, 79, 19,194,128,243,103, +239, 45,250, 60,167,193,213, 17,145, 93,182,205, 90, 5,254,240,124,215,134, 19,110, 28, 60,186, 7,183,243,175,225, 85,123,230, +118,226,251, 82, 79, 14, 81,197,140,225,247, 30,168, 33, 5, 20,182, 62, 96,141, 94,250,175,171,136, 55,240,227,110,117,234, 95, +117,109,189, 67, 33,195,131,168,102, 25, 69,250, 73,171,174, 23, 64,158,246,191, 80, 47, 13, 92,237, 76,155,100,217,178, 97, 72, +178, 54,236,105, 99,136,202,209,163,193, 27, 42,153,201, 51, 21, 82,166,198, 77, 71, 87,166,252,104, 10,237,135, 51,113,203, 27, +214, 38, 86, 72,146,108, 44,215,197,131, 36, 70,170, 66,156,120, 39, 82, 80,112, 58, 90, 99,242,115,172, 31,109,110,187,222, 58, + 96,229,121,246,152, 73, 14,193, 22, 66, 74,161,245,174,102, 70, 68, 13,239, 49, 36, 50,171,124, 67,137, 32, 94,189, 86, 60,120, + 33,105, 30, 24,150, 54,153,250,147, 50, 40, 82,239,164, 38,183, 35,226,109, 42, 5,207,128,168,176,236,187, 54, 48, 43,143,183, + 99, 68,165,146, 66, 18, 24,212,107,137,204,177,183,186,188,209,216,178,159, 2,111, 64, 98, 23,127,221,177,176,177,102,198,146, + 44,124, 69,159, 56,229,116,145, 36,100, 43,184,201, 4,111, 60, 76,221, 81, 11, 0,192,188, 98,250,253, 85, 59,241, 3,113,220, + 99,198,207,219,241, 50,124,172, 41,180,229,102,200,193, 65,121, 25, 94, 56,149, 3,112, 43,109,100,221,120,220,143,151, 80,219, + 22,205, 51, 66,242,109,248,206,216,236,210, 64, 76, 73,116,103,126,171,178,251,188, 9,127,124,255, 0, 59,143, 58, 46,126,211, +181,238,130, 63,188,176,160,204, 17,106,233,140,136,214, 64,186,133,152, 0,224,243,183, 26, 3, 27,157,189,110,184,178,110,255, + 0,119, 50, 69,209,221, 37, 89,250, 43, 27,228,180, 49,224,227,203,212, 72,167, 96, 36, 10,238, 58,154,125,237, 28,184,212,125, +191,117,223,101,238, 9,113,113,247, 53, 41,185,231,195, 31, 83,165,169, 35,140,237, 43,157,251,132,144,251,160,144, 0,191,180, +241, 38,183, 25, 91, 30,205,154, 25,114,240, 49,231, 87,147,174,226, 72,145,181, 75,164, 70,100,107,142, 44, 81, 66,146,124, 56, +114,167,141,167,109, 92,177,158,184, 80, 12,193,107,100,136,147,170, 52,163, 68,191,188,182,174, 8,197, 71, 30, 70,213,150, 15, + 59,125,223,114,129, 62,242,194,200, 76, 57, 48,246,237,255, 0, 40, 70, 16, 52, 82, 28, 77,197,116,161, 71, 54,187,233,226,220, +248,155, 90,245,161,143,184,247, 92,173,217, 54,245,116,133, 37,221, 39,192, 91,160, 44,145, 38,214,185,201,207,155, 44,205,199, +213,194,180, 18,236, 91, 36,194, 46,190,219,139, 39, 69,153,225,213, 12,103, 67, 72,253,103, 43,238,240,212,254,243,122, 79, 19, + 68, 59, 86,214, 51,206,232, 48, 96,243,228,131,231, 58, 73,213,190,131, 21,250,150,213,125, 7, 79,179,133, 1,230,253,183,188, +238,241,237,176, 70,153, 10,217, 89, 56,219, 20, 39,112,145, 53,200,131, 50,108,152,216,190,162, 67,149, 3, 74,234,251, 71,141, +249, 84,204,222,234,238, 8,176,231,104,242, 35, 89,112, 49, 55,108,135,155,162,164,100, 54,219,155, 30, 44,100, 6,224,171, 34, +147,170,223, 37,171,110,155, 46,201, 20, 19, 99, 69,182,226,199, 6, 64, 11, 60, 73, 12,106,174, 21,153,212, 56, 85, 23,179, 59, + 48,245,146,106, 76, 59, 62,208,208, 8, 14, 6, 57,137, 97,108, 85,140,196,133, 68, 14, 67, 60, 54, 35,224, 98,160,149,228,109, + 64, 79, 78,131,107, 8, 85,180, 29, 46, 22,198,205, 96,108,109,200,216,211,194, 3,192, 14, 4, 80,227,131, 30, 22,149,160,137, + 34,105,223,171, 57, 69, 10, 94, 77, 42,154,222,223, 19,105, 64, 46,124, 5, 16, 58,175, 51,234,168, 5,210,188, 5,190,138, 69, + 77, 76,111,225,227, 74,100,140,243, 97,243,211, 86, 84,187, 29, 84, 1, 52,241, 35,194,184,175, 11, 40,246,208,218,112,111, 97, +242,216,210, 9,129, 23,227,126, 86,177,160, 8,160,120,241, 53, 25,210,236,108, 72, 30, 2,159,213,244, 3,127,101,168,122,152, +143,174,170, 3,116,145,195, 85, 57, 82,252, 73,164,247,200,191, 32,107,131, 58,242,249,234,129,190, 45, 78, 20,209,114, 73,244, +210,131,110,117, 0, 43,220,223,211, 68, 90, 24,167,131,106, 3,148,113, 39,214,105,100,177, 20,168, 56,123,107,159,145,170, 66, + 51, 61,148,129,204,210, 67,226,105,143,241, 26, 36, 60,141, 67, 72,108,252, 72,189, 44, 6,203,243,210,178, 23,126, 4, 11, 15, + 26,232,197,151,229, 52,228, 9, 74,150,141, 71,139, 18,110,125, 0, 84,116, 18, 16,116, 62,144,134,227,229,227, 70,149,191,134, +131,244,110,126, 94, 20,193,125, 46, 64,248,135, 15,146,161, 71, 98,222,236, 91,199,159,182,135, 34,129,112, 61, 52,171, 32,191, + 15, 27,112,166,187,112,227,226,104, 6, 88,104, 35,253, 56, 83,225,205,120, 23, 66,128, 65, 52,206,104,126, 90, 54, 57,195,208, + 4,160,234,246,218,180,100,123,238, 38, 72,250, 69, 0, 47,194,246,165, 95, 19,235,167, 76,152, 38, 48,209, 31,222, 92,105, 31, + 45, 37,133,173, 64, 56,159, 71,209, 74, 0, 42, 60, 79,141, 54,222,154,164,219,251,183,107,207,223,243, 59,114, 33, 44,121,216, + 96,150, 50, 42,136,228,211,167, 87, 73,131, 49, 54,212, 57,129, 64, 94,243,164, 2,231,213,232,170,248,119,156, 89,183,140,157, +141, 86, 65,149,139, 10,100, 73, 33, 3,166, 86, 66, 66,133, 58,181, 95,135,162,172,109,242,154, 3,136,224, 41, 45, 98,106, 36, +251,182, 22, 62,229,137,180,202,228,101,230,172,143,143, 30,146, 65, 88,134,167, 37,185, 11, 84,210, 9,160, 7,111,124, 31, 69, +207,209, 82,177,162, 42,190,247,196,120,154, 20, 75,119,191,128,163, 79, 58, 98,227,203,144,224,148,133, 26, 70, 11,206,202, 53, + 27, 94,213,170,245, 35, 97,194,250,233,224, 48,229, 84, 29,177,221,123,103,118,224,190,126,218, 36, 69,142, 67, 20,144,206,170, +178, 41,176, 96, 72, 70,113,102, 7,129,189, 76,216,183,220, 77,251, 17,243, 49, 22, 68,142, 57,165,199,101,152, 40,109, 80,182, +134, 35, 75, 48,181,199, 10,223,113, 30,188, 11, 80,214,240,162, 35,159, 1, 76, 12,180,245,101,168,186,150, 58,158, 35,129,147, +219,184,216, 63,137, 18,247, 86, 25,205,218, 91,184, 76,115,170, 91,169, 23, 86,105, 35, 19,197,226, 25, 53, 95,133,102,191, 17, + 38,217,115,255, 0, 17, 59,117,240,183, 28,127,186, 14, 30,222,145,238, 57, 10,179,192,177,163,186,235,158, 51, 96,214,183,188, +173,111, 93,171,220,166,252, 54,236, 93,195, 43, 35, 51, 51,102,134,105,242,164,105,178, 28,153, 6,185, 29,139,179,176, 14, 5, +201, 55,172,246,103, 98,246, 30, 55,120,237,221,184,189,181,134,113,179,113, 39,202,121,139, 77,212, 13, 11, 5, 10, 63,121,166, +198,245,134,161,137,131,204,191, 19, 27, 99,204,237, 92, 22,196,207,219,242,247, 77,191, 58,120, 38,154, 25,112,206, 76,216,231, +132, 79,163, 6, 56,147, 65,248,130,216,233, 28, 47,123,214,219,183,247, 30,203,194,198,252, 58, 94,225,143,202,238,131, 5, 38, +219, 55,123,133, 80,194,241,121,105,219,244, 27, 95, 13, 92, 1,244,120,217, 71,248, 93,177,166,113,135, 43,182,176,198, 39, 94, + 71, 92,128,198,253, 27,158,156,122, 68,183,189,173,225,245, 80,143,225,198,206,243, 97,200,189,171,139, 36,122,102, 92,172, 51, + 47, 16, 67,126,229,145,204,182,248, 69,200,189, 94,215, 18, 36,205,126, 26,162, 52,253,195, 38,149,214, 59,130, 16,178,149, 86, +176, 47, 45,199, 18, 56, 26,250, 8,130,121, 10,243,221,167,181,231,217, 4,152,187, 95,111, 99,226, 99,228, 60,114,203,229,231, + 40,161,227, 47,165,238,210,151,189,154,189, 6, 53,208,138,183, 39, 72, 2,228,146,120, 15, 18,120,154,133, 23,143,163,141,171, +169,124,107,168, 10, 7,229, 31,247,113,254,194,211,125,119,167,191,216, 31,238,227,253,133,166,113,229, 64, 70,200, 62,248,246, +126, 90, 21,232,153, 32,235, 28, 60, 62,186, 13, 0,251,139,130,105, 3, 0,107, 63, 7,116, 99, 78,155,115,152,140,105,184,101, +102, 97,171, 59, 11, 70,112,188,198,183,115,250, 45,229,141,189,180,120,251,155, 97,151, 21,243, 83, 54, 51,143, 19,199, 27,185, + 12, 61,233,173,210,176, 32, 18, 36,212, 52,145,192,248, 80,133,193, 97,196, 83,121,142, 85, 81, 39,116,108, 48,199, 4,210,103, + 70,177,228, 43, 60, 76, 67,124, 49,184,142, 70, 97,107,168, 70, 54,109, 86,211,227, 82,226,221,246,217,103, 92, 88,242, 85,166, +121,101,199, 88,197,238,101,128,106,149, 57,125,145, 66,147,128,183,203, 92, 61,117, 73, 15,117,109,178,231,102,237,108,198, 44, +204, 73,158, 4,137,191,181, 49,192,153, 76, 80,219, 72,247, 92,240, 38,254,233,167,225,119, 54,213,155, 6,218,207, 48,131, 35, +115,199,131, 38, 28,103,226,202,185, 11,174, 53,118, 3, 72, 45,196, 45,207,188, 65,181, 8, 92,131, 79, 22,170, 84,238,109,129, +219, 37, 87, 58, 50,113, 35,150,124,134, 58,128, 88,224,110,156,173,168,139, 29, 13,193,173,202,163, 97,119, 94, 22,225, 49, 76, +112, 22, 37,204,147, 4,201, 35,104, 44, 98,197, 25,172,233, 27, 46,163,193,172, 84,216,139, 19, 81,148,209, 27, 87, 90,226,168, +227,238,189,130, 92,105,243, 35,207,141,160,199, 17, 25, 92, 6,229,145,194, 29, 35, 77,223,168,120, 46,155,220,240,231, 79,198, +238, 93,191, 51, 51, 7, 19, 5,188,202,103, 71,149, 34,100, 33,247, 84,225,180, 81,200,140, 13,141,245, 77,244, 84, 5,185, 20, + 88,163, 75,106,110, 36,208,238, 42, 72, 26, 84, 88, 0, 42, 1, 22, 56,129,226, 7,170,137, 18, 71, 98,116,142,116,222, 22,191, +163,149, 62, 48, 2,131,127, 95, 26, 1,234,171,171,144, 20,134,250,128, 0,105,241, 52,161,214,220, 92, 47,203, 77,121, 96, 28, +156,124,244, 3,138,128, 57,241, 2,163,169, 82, 15, 11,216,211,204,201, 99,164,220,252,244, 62,170,129,240,155,143, 81,160, 28, + 72,229, 64, 60, 71, 5, 55,229, 78,105, 65,181,193,181, 52,184,245,252,213, 80, 56, 22, 30, 28,189,116,132,181,172, 41, 53, 11, + 30, 6,144,183,160,112,170, 4, 6,148,159,116,251, 41,164,240,164, 98,116,212, 2, 10,119,133, 32,167, 91,133, 0,241,192, 10, +108,166,200, 77, 62,212, 57,133,210,198,169, 8,128, 23,110, 30, 53, 33, 84, 11,138,100, 41,198,255, 0, 53, 45,200,144,159, 93, +103,139, 52, 56,175, 27,208,211,151, 26,120, 36,177,191,201, 76,244, 85, 1,228,177, 37,189, 8,191,203, 68, 73, 99, 86, 17,159, + 19,107,250,253, 20, 50,108,162, 66, 61,210, 52, 53, 8,151,208, 2,168,177,247,181,250, 42, 20,115, 42,130,204,162,214,125, 32, +143, 80,185,161,185,213,106, 40, 42,108,169,197, 99, 82, 75,122, 89,185,208,154,214,170, 67,136, 58, 57,115,161,178,113, 6,213, + 56,220, 32, 4, 2, 45, 77, 58, 77,189,218,164, 34, 0, 4,169,110, 92, 63,150,166,131,243,250,106, 33, 55,156,120,122, 42, 90, +113,176,160, 29,113, 94,103, 38,213,145,153,147,220, 59,166,212, 63,249,214,207,186,156,172, 32, 7, 23, 94,132, 98, 88, 15,243, +101, 81,107,120,154,244,221, 35,128,241,170,253,187,102,197,219, 50,247, 12,184, 30, 70,147,114,152,100, 78, 28,130,161,130,132, +178,105, 85,176,176,241,189, 3, 49,120,221,193, 22,110,231,188,247, 22,219,239, 91, 96,143, 38, 36, 54, 37,100,140,206,198, 54, +245,171, 46,147, 81,228,217, 34,135,177,151,186,147, 47, 35,239,225,136,155,143,222, 70,121, 53,245, 24, 9, 76,122,117,232,211, +199, 70,157, 54,173, 94, 7,106,236,155, 46,231,184,238, 56,218,245,110,128,140,140, 87, 42, 97, 80,196,179, 8,215, 72, 32, 49, + 39,133,205, 65, 94,200,219, 78, 58,237,199,115,206, 59, 48,109, 95,116,153, 87,163, 96,218,250,101,244,117, 76,119,251, 58,168, + 66,151,115,218,176,247,206,238,237,172,140,193, 50, 54,233,131, 44,217, 43, 28,210, 71,103, 72, 80,128,154, 88,104,245,219,159, +141,122, 30,227,149,143,183,224,100,230,229,185, 76,120, 34,121,101,101,230, 21, 65, 39, 77,188,125, 21, 85,188,118,230,221,188, +207,131,148,217, 25, 24, 89, 24, 26,198, 60,248, 82,116, 92, 36,128, 43,199,125, 45,238,144, 42,227, 43, 15, 31,113,197,159, 11, + 41,122,152,217, 49,180, 82,161,225,116,112, 85,133,199,168,209, 20,242,214, 92,140, 76,206,216,222,182,237,174,125,171, 27, 51, +115,197,198, 25,153, 25,210, 77,145,147, 14, 77,248, 77, 1, 46,170, 25, 5,248,181,197,122,166,237,255, 0,241,153,191,220, 75, +251, 6,179,176,126, 30,225, 70, 54,241,145,187,110, 89, 48,237, 89, 17,101, 96, 65, 44,200, 99, 67, 1,186, 33, 94,151,188, 60, + 61, 54,224, 8,227, 90,185,177,211, 39, 30, 88, 36, 36, 44,200,209,177, 94, 96, 48,210,109,123,250,107,117, 70, 79, 46,217,135, +249, 99, 7,183, 59,186, 14, 27,102,118, 38, 54, 14,254, 22,218, 87,128, 72, 50,219,250, 12,116, 49,244, 83, 94,121,161,236,233, +159, 30, 86,140,183,113, 58,150,141,138,221, 91, 48,220, 93,124, 13,122, 38, 55,110,109,184,221,190,189,180,202,211,237,235, 1, +198, 34, 98, 11,178, 16, 71, 18,161, 69,248,243, 2,171,113,187, 23,101,131,182,101,237, 78,166, 68,152, 50, 57,151,172,238,189, +117,114,226, 64,234,232,138, 1, 86, 28, 61,218,176,254,192, 3,186, 39,158, 62,234,236,248,210, 70, 68,151, 35, 40, 72,138, 72, + 12, 4, 23, 26,128,231, 85, 91,103,111,226,247, 46,247,221,113,110,217, 25,114,197, 6, 96,139, 26, 21,201,153, 35,143, 84, 65, +181,170, 35,168, 36, 19,192, 27,129,232,171,236, 94,199,198, 77,199,111,221,115,119, 93,195,112,204,219, 89,219, 29,178,102, 70, + 75, 58,232, 42, 80, 70, 7, 47, 17,196,248,154,186,218,246, 28, 77,175, 51,114,205,199,121, 30, 77,210, 97,145,144,178, 21, 42, +174, 20, 37,163,210,170, 64,176,241, 38,175,108,235, 0,242,204, 61,169,115,255, 0, 11, 63,205,249, 89,249,207,190,227, 69, 36, +184,153,126,106, 97,210,242,211,188, 40,145,162,184, 64, 52, 39, 19,107,223,141,235, 85,187,224, 99,119, 31,122,118,188, 27,155, + 74,209, 79,180, 77, 44,226, 25,100,128,185,253,219, 16,205, 3, 35,105, 36,242, 6,180, 56,125,149,182, 99,246,147,118,106, 75, + 57,219,154, 57, 34, 51, 22, 78,190,153,100,105,155,222,233,232,190,166,225,238, 81,183, 46,202,195,220,178,182,252,232,183, 28, +237,191, 43,109,198, 56,112, 77,135, 36, 72,198, 54,181,245,245, 33,147,137,211,225,106,195, 68,208,201, 99,203, 63,105,111, 61, +215,179,109, 83, 77,149,182,109,219, 95,222,184,184,211,200,211, 28,105,130,187,116, 17,164, 44,218, 94,218,172, 77, 80, 97,109, + 61,223,153,178, 96,111,187, 38,207,156,253,197, 42,195,152,155,228,155,140, 26, 38,214, 68,142,143, 3,100, 1,210,100, 37, 66, +105, 22,241,241,175, 90,217,123, 87,105,216,225,202, 76,100,121,229,207, 58,179,242,242,220,207, 62, 65,182,159,223, 72,252,192, + 7,128,229, 84,248,255, 0,135, 24,184, 95,225,176,119,173,211, 23,104,213,172,109, 17,100, 40,128, 93,181, 24,213,138, 25, 4, +103,197,117,124,181, 39, 72, 26,148,178,237, 95,230, 31,196,156,216, 55, 44,140,152,241,112,176,176,114,198, 4, 83, 17, 19, 76, + 28,144, 36, 3,131, 40,177,184, 28,235,210, 53,183,133, 86, 69,176,226, 99,239,217,125,194,143, 33,203,204,130, 44,105, 99, 98, +189, 32,144,146, 84,168,211,170,252,120,251,213, 99,111, 73,170,132, 91,144,253, 77,244, 95,233,174,164,176,183, 63, 15,203, 93, + 84,186,253,133, 51,219,220, 63,238,227,253,133,166,211,159,251, 49,254,238, 63,216, 90, 75,138,201,162, 38, 79,198, 56,120,126, + 83, 65, 22,191,133, 31, 36,251,227,217,245,208, 8,185,160, 49, 56,189,142,216,178,109,249,144,197,133, 30,229,143,151,184,228, +101,230, 42, 14,164,145,229,174, 90,192,165,204,122,159, 79, 94, 61, 74,220, 56,112,191, 10,172,255, 0, 45,247, 14,223,135,213, +150, 36,201,202,159, 47,102, 98,137, 52,211,157,120,153, 11,213,145,203, 69,238, 69,246,189,209,100, 95, 14, 21,233, 54,183, 42, + 78, 23,160, 60,219, 39,182,183,227, 43, 97, 71, 4, 70,109,207,111,222, 19, 42, 86,105, 60,190, 59,110, 89,145, 75,161,100, 17, +157, 76,138,247, 10, 64,213,164,213,182,205,180,186,119,174,231,152,129,254,239,197,140, 8, 89,209,144, 28,188,132,134, 44,134, + 66,192, 6,178, 98, 37,200,225,239,154,217,219,209, 93, 99,206,128,199,191,108,110,210,238,243, 72,205, 2,224, 62,227, 38,235, + 28,170,238,102,187, 96,125,222,176,178, 24,194,143,120,234, 36, 49,225, 81, 48,251, 35,112,199,201,218,186,221, 41,227,198,131, +107, 76,135,243, 57, 49,164,114,237,163,222, 41,143, 30,136,231,214, 66,148,105, 62, 30, 60, 60, 43,119,115, 93,126, 55,160, 48, +242,118, 62,231, 38, 44,144, 52,216,234,205,137,186, 64,166,238, 71, 83, 55, 61, 51,224,184,208, 61,208,169,103,244, 30, 87,163, +193,219, 59,196,185,163,112,203,242,208,188,155,150, 70,123,195, 28,175, 38,152,230,219,126,239, 68,212, 98, 75,176,147,137,225, +107,124,213,178,189,205,112,227,232,160, 60,250, 94,217,220,182,109,182, 60,199, 49, 77, 38, 6, 54,199, 26,199, 16,154, 64,210, +237,141, 32,155, 80,142, 38,144, 70,122,183, 12,168,196,115, 43,194,172,251, 75,107,204, 9,143,186,102, 99, 36,114, 25,183, 89, + 46,218,227,117, 92,220,181,153, 10, 67, 34,106,179,172,119,247,138,144, 45,195,143, 13,119, 16, 43,175,194,178, 14, 63, 13,232, +186,125, 44,222,203,154, 24,177, 0,123, 40,164,113,225, 80, 9,211, 83,207,143,168,154,120,141, 15, 13, 60,233, 0, 60,237,111, + 93, 56,159, 26, 1, 27, 66,139, 90,186,195, 72,240, 28,169,166,204, 5,205,248,211,153,213,121, 17,127, 71, 10, 1,224, 15, 30, + 21,196,218,152,101, 75, 3,170,231,209, 76,234, 3,204, 31,152,213, 3,139,112,183,133,233,183, 94, 28,105,174,117, 15,132,129, +233, 52,150, 30,138, 1,110,190,154, 75,171, 27,120,210,114, 97, 78,225,112,124,106,131,136, 20,201, 56, 39,180,211,137,227, 76, +147,144, 30,186,128, 65,206,156,125, 31,233,206,154, 57,211,193,247,128,246, 80,129, 40, 51,242,181, 20,155, 84,121, 13,200,170, + 7, 39, 1, 66,214, 53,216,248,209, 9,178,218,134,138, 15, 18, 47, 81, 35, 76,117,199,188, 69, 51,192, 94,152, 24, 45,212, 11, + 10,123, 47,187,106, 48,137,145,176, 10,200,220, 65,181,233,100,137, 12,122, 69,244,248, 84,117,146,194,214,255, 0, 64, 43,186, +231,144, 38,164, 20,115,105, 85,208,156, 5, 4,155,159,101, 56,176, 43,206,145,172, 5,199,160,213, 32,248,229, 19, 3,194,214, +231, 93,135, 23, 84,190,162,109,225,199,219, 76,198, 26, 81,175,227,245, 84,188, 53, 68, 13,160, 30, 32, 94,254,154,164, 26,216, + 54,117,117,107,219,211,236,162, 24, 28,120, 94,142,205,101,225,225, 76, 73, 46, 53, 17,107,248, 80, 72, 34,172,188,233, 23,213, +198,149,231, 13,164, 41,224,198,198,149,108, 57, 80, 21,217,127,198, 52, 1,206,143,146, 47, 59, 91,149, 34,161,189,232, 5, 88, +156,184, 78, 32,240,229,232,171,104, 80, 40, 0,120, 80, 21, 65,148,191,176,124,213, 46, 49, 85, 1,228,120, 82,210,129,115,106, +121, 90,218, 48,216,206, 38,148, 45, 45,173,227, 79, 75,214,144,153, 26, 1, 28,168,170, 79,141, 56, 2,124, 40,138,131,198,150, +158, 66, 96,114, 15, 27,209, 65,181, 32, 81,106,112, 28,107, 1,161,193,169, 25,155,236,211,173, 93,102,169,161,164, 12,177,241, + 20,195,110,116,109, 55,231, 77, 40, 42,166,138, 51,134,159,234,255, 0,245,171,169,250, 69,190, 79,203, 93, 86,126,240, 82, 73, +127,221,255, 0,119, 31,236, 45, 55,209, 79,113,193, 63,187,143,246, 22,154,121, 86, 1, 23, 39,248,163,217,249,104, 86,183,170, +139,147,109, 99,217, 66,249, 62, 90, 2, 52, 57,216,153, 57, 19,226,193, 50,201, 54, 49, 2,120,212,220,161, 62, 13,235,169, 45, + 97,202,188,254, 45,162, 85,203,120,149, 50, 82, 9,247,185, 22,109, 50, 76, 3, 99,172, 90,148,177,213,240,150, 60, 91,199,211, + 78,218,176,247, 44,108,157,174,104,188,207, 86, 73,119, 8,166, 51, 60,172,157, 56,209,134, 50,184,114, 64, 91,168,183,166,189, + 22,193, 88,109, 95,148,234,188, 27,252, 15, 45,119, 23,148,173, 78,113,163,241, 75,241, 55,151,227, 66, 57, 80, 12,175, 37,212, + 30,100,199,214, 17,125,174,152,109, 26,189,151, 54,175, 59, 81,186,249,108,127,186,188,247,223, 30, 95, 43,239,126,175, 90,218, +180, 54,159,226,123,154,245,255, 0, 15, 69, 91,118,220, 56,199,184,210,108, 20,202, 56,227,108,209, 52,153, 43, 45,186,230, 88, +217,148, 52,255, 0,106,220,192,225,232,163,219,164,155,118,152, 79,151, 78,190,124,133,119, 46,214,170, 85,137,105,106,250,244, +242,231,208,218,114,225, 73,237,172,198, 70,223,149, 54, 86, 76,238,153, 36,157,210, 40,227, 42,242,168,242,166, 40,150, 77, 1, + 72, 26, 13,219, 81, 31,146,135,143,231, 54,220,214,234, 71,147,228,194,231,195,142,170,146,203,239, 25, 98,120,120, 0,199,138, +134,208, 77, 99,210, 77,105,109, 99,135,194, 77,250,205, 61,107, 10, 98,103,198, 13,109,189,116, 56,165,142,104,250,144,176,116, +187, 45,199,165, 88,163, 15,144,138,198,244,179,226, 27,100,178,174, 76,217, 30, 83, 8, 28,118, 89,213,196,138, 7, 80,199, 52, +100,162,183,251, 69,149,126, 91, 81,213,103,233,193,247,188,121,111,136, 60,249, 11, 16,152,191, 84,228,183, 71, 80,139,222,227, + 23,240,201,225,244, 85,120, 87,243, 78,188,191, 2, 44,239,249, 99, 78,111,203,139,228,107,101,154, 44,120, 95, 35, 33,196,113, + 68,165,228,118, 54, 1, 71, 50,105,184,185, 88,217,176,245,241, 92, 73, 29,202,147, 98, 8,101,224, 85,131, 88,130, 61, 6,170, + 55, 69,200,126,222, 88, 22, 57, 79, 89, 34,139, 36,200,189,105,163,137,244,172,146, 50,167,199, 34, 14, 60, 60,120,208, 59, 74, + 76,212,243,120,153,113,200, 99, 86,234, 99,229,188, 82, 33,200, 12,205,170,103,105, 62,217,247, 70,158, 30,145,194,176,241,174, +203, 94,117, 78, 35,192,223,170,253, 74,210, 52,106,103,196,210, 36,122,206,155,218,194,244, 78,137,191, 23, 63, 69, 98, 18, 61, +214, 41,119, 4,192, 25, 51,100,180,121, 86,156,137,226,116, 36,234, 69,125,101,224,145,188, 34,100, 35,217,107,212,137,132,203, + 47, 95,104,143, 53, 54,232, 78, 20,153, 73, 34,207,172,178,100,169,151, 66, 77,251,198, 34, 43,245, 52,142, 62,219,213,244, 63, +171,143,135,237,240, 51,235,255, 0, 79, 15, 31,187,241, 53,197, 20,178,168, 36,250, 69,232,157, 24,137,181,137,245, 19, 89, 24, +225,204,220, 55, 53,234, 71,148,184, 50,238,114,147,168, 77, 16, 56,227, 4, 5,189,244,145, 27, 74, 60,120, 19, 76,130, 57,226, + 92, 21,221,147, 49,176,162, 25,177,196,145,137,217,196,131, 36,174, 63, 83,163,251,207,224, 15,221,147,195,229,181, 79, 71,135, +213,172,112, 75, 94,127,145,125,103,252,186, 76, 75,122,114,251, 53, 54, 24,167, 19, 42, 4,200,198, 42,241, 72, 46,142, 57, 17, +202,135,153,147,137,131, 24,151, 38, 69,137, 11, 4, 12,124, 89,141,130,128, 56,147, 89,180,139,114,139,179, 48,224,129, 37,142, +101, 17, 12,152,153, 95,172, 33, 50,254,244, 21,140,172,132,233,230, 20,222,215,181, 69,139, 2,108,152, 49, 58,226,105, 96, 77, +208, 60, 30,236,208,132,132,197,239,148, 15, 35, 73,211,215,200,189,173,225,194,213, 86, 42,203,110,218, 43, 53,227,161, 30,107, + 66, 74,186,186,167,225, 44,214,193,149,139,147, 52,176,227,200,174,248,231, 76,225,126,203, 91,225, 39,211, 82,136,213,194,213, +131,147, 11, 39, 18, 39, 16,164,137,139, 38,229, 59,101,135, 19,203,120,134,190,139, 20,141,196,134, 61, 86,185, 94,124, 47,194, +141, 31, 89,113,176, 83,120, 25,147,224,172, 57, 61, 49, 28,115, 44,157, 83, 40, 16,117, 22, 54,121, 47,210,225, 25,115,127,210, +179, 81,225,175, 21,111,179, 82, 44,214,225,106,235, 19, 51,167, 19, 93, 59,197,212, 24,253, 65,214, 11,172,198, 8,213,164,155, + 6,211,206,215, 28,233,154, 86,246,185,172,166,110, 28,146,229,180,225, 51,162,146,109,169, 99, 73,212, 73, 44,171, 42,223, 82, +191, 76,136,250,154,124, 46, 46,126, 30, 53, 55,183,227,156,227,102,161, 89, 17, 46, 58, 82,168,153, 21,201, 79,120,195, 22, 95, +190,150, 60,197,200,191,143, 58,143, 18, 85,238, 86,158, 28,141, 87, 43,118,237,117,142, 60,255, 0, 2,255, 0, 66,240, 54,166, +216, 2, 45, 88,120, 34,207,131, 11, 38, 88, 14, 67, 73,129, 28, 89,125,118, 19,192, 36,120, 28,180,145, 77, 22, 65, 97,212,120, +238, 24,163, 16,126,106, 73,227,203,155, 22, 13,210, 71,200,145,179,132,249, 49,227,105,200,100, 11, 33, 83,142,145,190, 49, 45, + 20,162, 53, 93, 36,169, 28, 79,141,111,208,215,245,115,142, 26,204, 79, 3, 63,228, 56,253, 26,196,241,210, 38, 56,155,110,172, +110,239, 26, 58,180,145,216, 72,160,130, 84,145,168,106, 30, 23, 21,207,225, 88,252,156, 92,216,228,220,228,199,131, 34, 57,178, + 14, 36,146,146, 38,144, 24, 72, 65,144,170,209,144, 25,129,189,194, 29, 86,190,154,118, 46, 38,100,239,135, 12,166,119,193,108, +217, 73, 1, 38,133, 4, 62, 89,200, 30,251,180,157, 35, 47, 45,118,227,192,112,181,101,225, 81, 61,220,167,135,132,149,102,115, + 29,156,227,143,140, 26,209,241, 83,255, 0,180,172,118, 46, 30, 70, 60,120,114,202,185,160, 52, 57,145,229,152,218,102,151, 66, +176, 16,129,196,144,218, 71,185,110, 53, 43,186,206,225,143,183,225,238, 91, 95, 89,230,195,117,102,132,106, 46,241,200,189, 51, +173, 71, 22, 96, 72, 60,105,233, 46,234,213, 91,245, 54,167,148,173, 7,172,251,109,103, 95,210,147,133,198, 30,166,165,207, 10, +142,109,168,122,235, 7,180,109,157,195,152,153,219,126,100,217, 9,228, 49, 36,135, 22, 98,238,189, 73,231, 99, 42, 62,171,251, +218,109,167,213, 81, 48, 63,204,217,217,248,135, 45,114, 34,131,114,150, 57, 39,191, 81, 4, 73,137,168, 58,248,105,234, 91,229, +173,255, 0,140,190,175,247, 43,244,255, 0,231,238, 48,183, 79,233,255, 0,110,223, 86,159, 30, 14,126, 58, 30,146,124,104, 51, +100,193,137, 4,153, 25, 50, 44, 80,196, 53, 73, 35, 27, 0, 61,117,231, 89,223,230,124, 44,188,161,142, 50,101,135,109,146, 81, + 5,140,141,213, 76,205, 66, 63, 78,174,157,199,179,213, 86,219,196, 18, 73,218,249,123, 72, 76,137,178,240, 34,131,168,196, 73, +251,201, 90,197,138, 55,246,131,157,249,138,127,142,147,164,221, 53,102,150,156,147,231,246,162,173,203,106,241, 70,157, 83,106, +121,181,203,236,102,186, 25, 98,202,137,103,132,135,138, 64, 26, 55, 30, 32,248,209,154,228,124,130,188,251, 43,111,201, 57, 25, +130, 63, 55,251,188,220, 88, 49,202,203, 63, 8, 25, 85,101,210,117,113, 4, 30, 45, 82,122, 89,120,240, 73, 4,254,105,118,152, +183,137, 18,112,134, 83, 32,196,208, 10, 89,150,242, 24,181,158, 54,168,240, 39, 13, 95,143, 40,248,252,202,183, 22, 83, 52,225, +206,116,227, 29, 56,104,109,175,195,228, 52, 12,124,172,124,184, 87, 35, 26, 65, 44, 46, 24, 43,175, 34, 84,149, 63, 49, 21,137, +135, 81,201, 67,184,121,239,242,224,155, 47,201, 91,175,174,214, 78,142,189, 31,189,211,241,244,245, 85,207,107,179,227,108, 59, +118,222,240,206,153,153, 11,148,208,245, 99,107, 41, 89,101,117,235, 53,172,183,225,207,157, 75,224,237,172,204,185, 92,180,141, +103,226,163, 83, 84,220,247, 94, 29,123, 84, 62,122,207,211, 31, 7, 58,117, 52, 66,215,227,202,158,214,211,195,209,106,243,121, + 19,112,242, 80,249, 17,159,247,167,151,202,251,228, 72, 39,182,173, 13,163,226,247,117,107,248, 52, 85,158,102, 8,193,251,170, + 28,145,153, 46,222,240,201, 38, 64,133,230,121, 91, 41,149, 44,210,116,206,191, 78,159, 0,106,189,186, 77, 46,253, 92,233, 26, +253, 63, 30,124,140,173,211,105,190,205, 20,107, 58,125, 95, 14, 92,205,192,225, 25, 63,233,202,137,183,179, 24,216,158, 62,247, +228,172,247,102,203, 36,189,171,139, 36,206,242, 72,122,224,188,164,179,144, 38,144, 13, 68,250,171, 67,129,194, 38,245,181,114, +181,123,111,106,241,237,109,124,142,212,183,125, 43,120,142,228,156,121,146,143,133, 33,174,249,107,171, 37, 35, 74,161, 94, 48, + 57, 94,230,136, 46, 79,170,153, 63,241,163, 95,109, 20, 3,110, 28,232, 82, 4,214,235, 55,162,255, 0,146,159, 26,234, 54,246, + 19, 76,146,230, 86,246,212,136,150,220,124,104, 9, 17,138,150,130,194,163, 68, 42, 90,142, 66,180,145, 7, 14, 2,254, 52,151, + 62,154, 82, 69,117,175,202,183, 84,103,137,220, 60, 77, 61, 28, 47, 42, 25, 90,224, 42,179, 13, 52,228,146, 28,159, 26, 34,159, + 93, 71, 91, 10,112,110, 53,121, 26, 77,115, 36,134, 52, 64,104, 43,196,115,167,105, 97,198,178,210, 47,116,135, 86, 20,237, 99, +194,163,106, 52,224,198,178,234, 84, 26,247,231, 73,238,138,104, 52,140,125, 20,131, 77, 33,220, 45,242,126, 90,234,109,206,159, +234,254, 90,234, 71,222, 72, 69, 51,158, 9,253,220,127,176,180,219,211,156,124, 31,221,199, 99,253, 69,166,129,207,209, 89, 41, + 27, 32,251,227,143,133, 4,241, 21, 45,225,234, 27,234,183,133,185,254, 90,104,197,254,125,254, 74, 2, 45,141, 45,184, 90,245, + 39,202,139,124, 95, 45,171,134, 47,243,190,143,207, 64, 70, 3,215, 92, 42, 79,150, 32,252,127, 71,231,174,242,195,244,254,138, + 2, 57, 96, 71,164,210, 11,243,181, 72, 24,188,126, 63,163,243,210,140,113,200,183,209, 64, 3,228, 20,156,109,206,143,229,255, + 0,157,244,126,122,239, 44,111,241,125, 31,158,128, 0,227,198,157, 97,107,209,188,189,190,223,209, 75,229,255, 0,157,244, 84, + 96, 18, 7, 0,133,181,185,241,167,251,228,139,176,191,141,133, 26, 60,114, 20,141, 92,205,249,126,122,119,151,254,119, 31,101, +100, 0,233,241,212,206,111,242,114,165, 17, 90,254,241,227,235,163,244,180,143,138,254,209, 74, 34, 35,155, 95,209,194,168, 35, + 24,215, 87, 30, 86,228, 77, 41, 68, 0, 88, 15,154,140, 34, 3, 85,219,159,171,243,210,244, 1,225,171,215,202,128, 6,145,123, + 88, 87, 48, 94, 70,212,102,137,124, 92, 95,217,249,233,157, 52,225,239,106,244,112,227, 64, 71, 47,102, 60, 47, 77,214, 91,128, + 31, 61, 28,192, 9, 39, 95,209, 77, 16, 0, 62, 47,163,243,208, 16,242,176,225,206,129,241,114,148, 60, 50,124,113,220,128, 71, +160,233, 35,135,170,158, 20, 37,145, 0, 10,160, 40, 0, 88, 0, 60, 0,169, 99, 28,158, 77,244,126,122, 79, 45,196,251,223, 69, + 89,113, 4,133, 51, 26,145,238, 65,166, 49, 36,241,169,126, 90,255, 0,107,232,252,244,198,198,185, 62,247,209,249,234, 20,142, +188,233,147, 18, 24, 88,112,183,242,212,193,141,111,181,244,126,122, 81, 0, 13, 98,220,199,162,128,131, 28,186, 65, 21,204,250, +184,250,106,123, 97,196,120,147,244, 84,102,195, 26,236,175,195,217,249,232, 0,128, 72,249,105,207,197, 26,222, 0,212,159, 41, + 96, 61,255, 0, 31, 71,231,164,147, 23,220,111,126,215, 30,143,207, 66,149,177,113,113,122, 59,143,116,159, 93, 26, 60, 45, 50, + 15,127,194,252,189, 94,218, 43, 97,234, 83,102,176,191,163,243,209,132, 70,198,107, 49, 7,145, 31,201, 82,137, 54,165,135, 11, + 72,185,126, 62,207,207, 69,242,220,126, 59,252,159,158,163, 41, 22, 66,124, 42,179,114,218,176, 55, 46,147,102, 68, 93,225,191, + 74, 69,119,141,151, 85,131, 0,209,178,181,143,141, 94, 62, 63,243,173,126, 28,191, 61, 71,147, 18,246, 26,252,125, 31,158,173, + 91, 78, 83,105,245, 68,178, 86, 81,100,154,232,200,184,248,208, 98,226,166, 22, 36, 98, 40, 99, 26, 99, 69,228, 5, 74,128,116, + 96, 98,220,108,121, 10,120,197,183,219,250, 63, 61, 35,193,112, 84, 63, 63, 87,231,171, 60,217, 33, 45, 22,144, 52,102,192,120, + 88,131,235,167, 28,172,114,164, 18, 69,252,106, 47,147, 55, 54,127,163,243,215,121, 54,253, 63,163,243,208, 10,142, 30,100, 23, +213, 96,110,106,106,159,174,129,139,132, 67,235,213,203,213,249,234,103,151,227,125, 95, 69, 10, 87, 20,253,243, 95,192,255, 0, + 45, 29, 71, 42, 51, 99,234, 98,197,185,250,191, 61, 62, 60,110, 63, 23,209, 66, 14,141,120, 81,199, 5,165, 72, 0, 28, 91,128, +231, 72, 89, 47,110, 36, 15, 80,250,235, 73,165,196,144,249, 29,110, 21,192,218,148, 21,245,252,195,235,174,178,159, 79,204, 62, +186,189,235,169,143,175,160,224,194,156, 56,242,166,133, 30,191,152,125,116, 64, 84,120, 31,152,125,117,123,235,213, 22, 45,208, + 75, 53, 40, 94, 60,169, 67, 1,224,126, 97,245,211,132,163,244, 79,204, 62,186,189,245,234, 29, 95, 64,137, 97, 71, 15,194,213, + 20, 72,191,162,223, 48,250,233,226,116, 31,101,190, 97,245,212,118,175, 82,170,248, 7,226,124, 41, 66,154, 15,154, 79,209,111, +152,125,117,222,109,127, 69,190, 97,245,214,123,151, 81, 85,101,197, 7,181,233, 52,208,134, 90, 15,178,223, 48,250,235,142, 92, +127,160,223, 48,250,234,119, 46,165,178,111,128,109, 63,201,249,107,168, 94, 97,116,234,179,124, 58,188, 63, 75, 79,166,186,175, +114,234, 72,127, 97, 86,224,123,151,230, 99,143,246, 22,153,196, 30, 20, 83, 19,176,141,129, 91,116,227,230,234, 15,192,190, 4, +138, 78,139,255, 0, 51,245,211,253,106,134,129,243,227, 93,113,199,249, 40,157, 23,191, 52,253,116,250,233,122, 15,127,137, 57, +113,247,215,253,106, 3,204, 54, 21,203,203,222,251,109,166,202,103,133, 31,184,100, 16,184,213,239,195,184,116,149,181, 19,207, + 68,154, 87,244, 64,225,206,141,187,247,126,255, 0,129,157,188,109,208,152,204,219, 90,230,101,179, 58, 93, 70, 41,139, 24,225, +179,123, 31, 37,175,233,233,154,219,226,195,177,245,160,242, 71, 7,171,254, 43,202,116, 95, 31, 95,241, 71,157,233,104,107,255, + 0, 22,221, 91,125,175,139,141, 68,131,106,218,113,247,141,227, 59, 39, 54, 12,140,236,168, 34, 25,120,243,203,143,104,112,208, + 73,161, 90, 49, 98, 35, 37,158,236,252,254, 74, 3, 58,189,199,189,226,110, 99,104,200,157, 50,132, 59,132,216,143,152, 98, 84, +234,198,187, 81,220,148, 89, 61,208,201, 37,129,183,133, 77,147,124,221, 37,237, 30,223,220, 99,149, 33,206,222, 62,236,142,108, +128,128,172,103, 51,167,213,116, 70,247,111,239, 16,160,248,154,158,216,221,146, 54,168, 21,206,211,247, 64,156,156, 98,210,226, +156,127, 49,102, 39, 65,103,209,212,182,171,248,218,245, 59, 34, 13,141,182, 53, 92,143, 35,247, 9,138, 48,133,229,199, 24,157, + 19,167,163,164,234,233,133,248,116, 91,213,106,128,243,204, 93,255, 0,126,194,216,216,226,230,170,182, 22, 54,247,186, 73, 44, +177,137, 60,203,226,110, 18, 70,144, 13,109,238,165,141,189,211,113,117,183,174,239, 19,184,183,169,251,154, 44,105, 37, 85,193, +147,115,155,110, 56,157, 33,168, 34,109,139,184,134, 50,124, 90,132,156, 61,149,116,240,118,115, 97,237,247, 27, 64,193, 18,185, +219, 63,123,138, 33,235,117, 15, 83,203,217,130,234,234,124, 90,126,215, 62, 53, 56, 67,179,156,209,163,200, 12,239, 50,246,210, +248,253,111, 55,208, 26,254,214,174,175,151,231,246,180,127, 54,128,206,108, 24,155,134,219,221, 71,105,159,113,124,184, 48,182, + 61,189, 52,186,216, 59,172,153, 16, 52,214, 44,214,102, 49,106, 38,228,241,181,248, 10,164,126,246,238, 20,203,124, 13, 81, 25, + 21,219,106, 13,160, 95,239, 25, 51,164,130, 3,110, 28, 60,178, 43,219,249,215,228, 43,208, 94, 13,184,238,209,245, 14, 31,223, + 61, 6,233, 93,224, 25, 94, 95, 87,189,167,222,234,116,245,243,240,189, 68, 56,253,187,230, 14,163,182,249,143, 58,186,175, 38, + 54,191, 63,211, 58, 47,239, 95,204,116,239,111,181,167,213, 64, 99, 37,239, 61,242, 24,119,201,210, 85,153, 49,246,252,188,236, + 41, 90, 20, 72,132,152,217, 13,142, 4, 74, 28,200,209,248, 30,168, 4,176, 54,225, 71,159,113,222,242, 55, 28, 28, 89,183, 47, +250, 62,228, 56, 45, 34, 70,169,213,132,237,199, 44, 43,170,155, 16, 11,178,219,216,121,138,191, 76,110,200, 86,203,208,219, 54, +162,179,156,239,222,225,147,163, 80,243, 61,111,123,225,213,110,165,248, 95,157, 77,201,199,237,219, 63,156, 59,109,188,226,117, + 58,178, 99,127,215,232, 78,158,173, 77,252,125, 26,116,253,171, 90,128,204,239,123,158,247,133,221,243,195,129,154, 99,139, 39, + 27,106,199, 68,100, 14,144,121,172,217,224,105, 66,147, 98,254,237,129, 60,203, 0,121, 1, 87, 24,187,198,247, 55,104,231,230, +172,152,227,115,196,155, 51, 14, 12,169,202,195, 12,175,143,147, 38, 44,114,123,196, 32,215,160,120,233,213,234,169,155,166, 55, +109,156,134, 27,201,219,124,209,199, 33,188,212,184,194, 95, 45,172, 95,248,141,171,167,174,222,173, 94,186,152,177,237, 43,178, + 21, 97,130,219, 15, 68,139,153, 32,242,157, 15,110,174,158,143,162,160, 48, 25, 29,233,221, 11, 17,199,196, 15, 62, 70, 28,121, +115,228, 44,209,226,192,224,227,201, 20,107, 14,107, 77, 60, 81, 42,175, 80,234,104, 11,115, 82, 60,106,243, 11,184, 55,236,158, +239,125,191,166, 70,214, 51,103,192, 44,254, 93, 80, 8,113, 6, 72,100,188,190, 97,229, 47,204,116,244,232, 62,171,213,175,151, +236, 49,139,183,245, 14,207,229,210, 87,251,187, 84,184,157, 62,182,165, 18,116,125,235, 51,235,211,170,220,117, 90,252,106,198, + 56,123,112,111,238,241,157,191,252,193,162,210, 0,240, 28,205, 1, 87,226, 23,234, 91, 70,159,146,222, 22,160, 48,125,220,251, +154,247,107, 65, 6,227, 36, 80,176,216,122,112,129,238,163, 75,185,201, 19, 53,131, 11,252, 30,247,233, 3, 99,192, 82,227,239, +219,196,171, 20,226, 76, 87,220,215,109,222, 18, 44,188,157, 49, 43, 75,139,185,195,131, 14,162, 74,198,186,197,184,114, 45,111, + 10,221,110, 49,118,207,222,120,255, 0,122,157,187,239,107, 71,229, 60,203, 99,249,155,117,151,165,210,234, 29,118,235,233,211, +111,183,107,113,161,201, 23,105,116, 28, 72,118,190,129,135, 43,169,169,241,180,116, 58,195,206,234,185,182,142,189,186,190, 26, +254, 46, 52, 6,120,119, 14,229, 15, 99,239,123,199, 80,182,227,182, 12,144,131, 34, 21,142, 88,222, 21,212,177,228, 36,100,196, + 88, 95,137,140,233, 34,212, 4,222,123,134,108,217, 54, 79, 62,145, 75,247,182, 70, 23,222, 70, 4,184,134, 28, 4,220, 21, 4, +103,220,185,119, 34,231,236,143, 79, 26,212,227, 65,219, 75,177, 74,184,231,110,251,128, 44,131, 35, 75,227,156, 77, 55, 61, 94, +169,212, 99,231,125, 90,190, 90,102,227, 7,106,182, 46, 88,221, 14,219,229,188,200,243,189,121, 49,194,121,174,154,219,172, 93, +173,213,233,105,248,189,237, 54,240,160, 60,240,111,155,182,118,231,182,110,121, 82, 13, 25,248,157,187, 59,224, 50, 30,146, 62, + 86,123,198,242, 70, 47,192,240, 44, 15,172,122, 5, 79,151,186,187,129, 49, 34,204,143, 46, 41,164,220,242, 30, 12,125,186, 36, +139,204,227,170,231,249, 32, 97,235, 52,113,191,185,238,147, 43, 91,168, 71,135, 10,217,101, 67,218,222,119, 19,206,157,179,207, +232,139,200,117,159, 27,173,211,234,175, 71,161,173,181,105,235,105,209,167,237, 90,220,106, 51,226,246, 65,109,211,168,219, 78, +183, 35,239,139,203,139,123,245, 44, 60,207,189,238,158,175,233,125,191, 93, 80, 68,131,126,220, 87,178,103,222,115,158, 44, 76, +248, 83, 32, 52,140,171, 58,169,134,103,129, 29,147, 21,221, 11,144,160,149, 87,176,110, 21, 66,187,182,249,184,201,179, 9,242, +164,198,147, 31,184,100,192,152, 50, 68,178, 73, 26,226, 77, 50,172,226, 7,104,174, 56,169, 10,109,200,243, 21,184,242,251, 9, +216,200,213,131,247, 15, 68,131,105, 32,242,125, 11,113,227,171,167,162,223, 37, 65,139, 31,179, 23, 21, 68, 71,104,242,131, 38, + 32,182,147, 16,199,230,244,142,143, 29, 86,235,105,182,159,181,110, 84, 5, 94,239,188,111, 56,253,203, 22, 12, 57, 73, 6,223, + 43, 65,140,142,145,199, 58,172,211, 9, 9, 76,161,171,173, 28,141,238,152,184,104, 63,106,178,253,181,220,219,220, 56,189,187, +142,115, 27, 50, 57, 19,110,139, 44, 52,106,116,140,222,160,253,252,210, 63, 81,164,247,125,205, 0,252, 39, 95, 58,244, 89,177, +251,107,239,184, 91, 37,182,239,191, 64, 2, 14,164,152,254,110,196, 54,157, 1,155,169,203, 85,173,225,127, 93, 86, 99, 99,126, + 31,117,227,108,102,216,250,247, 81, 23, 78, 76, 45, 90,186,199, 70,144,173,207,173,123, 91,237, 95,198,128,205,100,238,125,193, +151,143,178,238,178,110, 93, 53,151,123,203,198, 76,120,162, 10,162, 60, 85,220, 35, 85,118,213,119,212, 32,226, 15, 14, 71,152, +167,193,221,251,222, 78, 38, 59, 9,162,138, 89,241,251,113,204,189, 48, 66, 62,237, 43,197,146,218, 73,183, 32, 10,143, 10,218, + 79, 7,109,121, 24,124,193,219,124,135,154, 62, 91,168,248,221, 31, 57,213,123,244,245, 54,158,183, 87, 95, 47,123, 85,252,106, +149,246,206,195,202,193,120,241,114, 54,168, 48, 99,159, 14,124,150,196,159, 13, 81,140, 83, 25,113,163,156,130, 84,163,184,101, + 10,121,241, 11, 64, 89,118,222,233, 62,229,183, 48,205,149,100,202,135, 39, 51, 23,168,160, 47, 89, 49, 50,100,198, 19, 4, 30, +144,162,246,225,122,197,205,222, 59,254, 46, 14,102,119, 94, 57,153,241, 55,153,224,143,164, 0,129,246,204,181,198,136,181,141, +216, 58,191,189,127, 27, 90,183, 88, 24, 59, 7, 95, 6,109,166, 76, 59,199,139, 52, 88, 49,226,205, 6,147,140,210,196,102,104, +196,109,239, 40,145, 18,228,112, 7,214,106,179,107,218,251, 43, 6, 29,194, 24,242, 54,220,146, 70, 67,238,114,205, 62, 36,143, +210,146,121, 38,153,114, 72, 35,247,105, 35,149,247,135, 11, 0,121, 84, 97, 21,153, 59,239,114, 97,247, 4, 59, 80,111, 53, 6, + 52,152, 17,229,206, 87, 30, 24,152,103, 75, 34,187, 55, 82,101,148, 21, 65,104,150, 53,107,149, 58,175,122,130,253,201,220,204, +249, 88,163, 38, 38,201,149,213,241, 98,140, 99,145, 44, 7, 36,199,171,108,152,201,210,149,186, 66,218, 38, 58,181,223,194,182, +249,120,253,190,119,172, 70,207, 59,127,223, 1,109,133,214,147, 31,204,233, 37,173,210, 14,218,249,234,181,189,126,186,174,147, + 19,176,204,121,131, 86,205,161,229, 67,184,126,247, 16, 89,245,182,158,169,215,193,186,151,181,254,213,252,111, 68, 82,167, 55, +112,147,115,237,125,158,108,140,142,164,121,249,184,120,249,178,162,182, 62,168,155, 40, 68,241,186,222,233,171, 72, 71, 0,219, +137, 3,133, 70,220,118,157,141, 95, 3, 27, 1,229,149, 35,222,151, 15, 34, 54,121, 85, 98, 15, 19,206,248,145,219, 64, 49,130, +193,133,175, 99,194,252, 44, 53,239,143,177, 29,154,211,156, 15,184, 76, 42, 5,228,199, 24,125, 31,179,111,123,167,162,246,183, +133, 46, 6, 55,109, 38, 14, 34,109,237,183, 28, 17, 61,176,140, 50, 99,152,188,207,189,252, 18,173,110,175,197,203,222,231, 64, +121,190,233,230,113,247, 29,211, 34, 52,120,224,131,120, 24,139,184,166, 67,235,141, 14,223, 14,156, 95, 47,193, 76,110,205, 98, +218,184,106,189,171, 95, 46,253, 62,199,216, 88,219,164, 48, 73,149,147, 22,212, 39, 67,160,200,130, 72,241,132,129,167,179, 43, + 4,212, 56,155,213,214, 76, 29,188, 98,159,205, 29,191,165,230, 87,205,117, 31, 31, 79,156,208,154, 58,186,154,221,109, 26, 45, +127,122,214,245, 84, 13,179, 31,177,188,166,227,247, 27,108,167, 7,167,255, 0,205,142, 28,152,125, 46,150,151,255, 0,170,233, + 54,157, 26,117,252,124, 45,127, 93, 1, 87,186,110, 82,100,239,139, 46,137,241, 34, 59, 30,230,221, 25,193,140,235,142, 92, 75, + 62,155,145,112, 24,216,212, 45,211, 43,113,198,216,251, 43, 39, 31, 33,209,186,144,117,226, 2,230, 98, 54,249,229,208,231,153, +185, 75, 91,210,111,204, 10,213,111,248,189,184,209,192, 59,153,182,238,152,102, 56,223,120, 75,142, 5,192,247,244,117,219,209, +241, 91,195,157, 31,115,199,218,124,190, 63,222,167, 11,203,245,163,242,190,106, 72, 52,117,255, 0,177,233,117, 90,218,255, 0, + 70,220,125, 20, 6,127,180,183,189,215, 54,118,199,220,242, 19, 48, 75,183, 96,238,105, 52,113,136,196,109,153,214, 15, 7,186, + 72, 42, 58, 64,169, 60,109,233,170, 44,142,243,222,163,192,201,201, 70,139,171, 22,223,189,101,173,211,135, 83, 3, 61,113, 32, +225,126, 93, 51,199,210,107,109,179,226,108, 97,114, 62,225,108, 13, 38, 75,228,249, 41,113,200,234, 17,253,167, 73,185,219,211, + 85, 25,187, 87,102,102,195,187,225,140,157,179, 26,124,136,114, 19,115,200,198,200,195, 76,136,227,102, 81,146,210, 62,162, 86, +207,167, 94,161,109, 86,191, 26,164, 43, 39,222,119,181,206,200,237,255, 0, 59, 24,104,243,102,129,183, 33, 18,251,241, 38,218, + 55, 17, 24, 75,233, 7, 91,216,144,111,164,122,120,212, 93,167,184,247, 88, 32,237,124, 88,166,235, 64,248,187, 52, 89,145,152, +212,129,231, 98, 33,154,121,164,113, 35, 72,218,117, 39, 76, 17,192,234,231, 90,197,198,236,191,186,136,152,237, 31,117,249,146, +220,101,197,242,254,106,197,143, 29, 90, 58,150,191, 14,118,225,202,136,216,253,145,230, 49, 89,142,207,230, 58, 56,195, 6,242, + 98,106,232,106, 30, 83,162, 53,124, 26,173,210,211,195,244,104, 12, 28, 61,201,221, 27, 98,230,227, 97,202,217,207, 6, 70,239, +148,204,254, 93, 22,216,217,222, 93, 99,149,242,166,139, 68, 60, 77,244, 93,133,212, 14, 3,142,199,189,251,131, 59,182,177,113, +183, 24, 52,156, 86,243, 48,204,133,117, 49,156,227, 73, 46, 37,189,178,196, 19,250,194,165,100, 99,246, 33,201,255, 0, 22,118, +111, 52,185, 76, 91,169, 38, 32,147,205,251,129,245, 93,174,101,248, 47,126, 63, 15,170,164,247, 38,213,131,159, 6, 31,222,217, +177,226,225, 99,229, 67, 51, 35,203, 2, 71, 52,168,225,160,141,222, 83,227, 32, 28, 20,141, 92,168, 12,172, 61,193,220,112,231, + 71,230,167,142, 69, 25,207,180,203,132,177, 0, 67, 69,183, 28,211,149,172,123,220,100, 91,219,225,210, 71,182,133,143,222, 27, +254, 78, 22, 63, 74, 88, 99,200,200,199,237,182, 18, 24,131, 5,147,119,149,226,201,109, 58,133,197,128,210, 47,194,182,107,143, +176,125,246,205,171, 3,239,206,157,159,247,144,121,174,157,135, 49,171,169,167, 77,190, 74,143,182, 67,216,171, 19, 13,164,236, +230, 62,166, 49,111, 44,248,132,117, 76,141,228,239,161,190, 46,173,250, 95,206,248,104, 4,223,183, 92,253,166,125,139, 10, 57, + 86, 67,152,243,197,153, 43,160, 5,250, 56, 83,228, 6, 0,112, 91,201, 16, 38,222,202,201,195,221,251,246,157,159,112,158,104, +206, 46, 86, 22, 12,178,164, 40,146, 33,201,200,199,105,229,135, 32, 43,117,161,119,247,122, 36, 46,143, 77,110,183,184, 54, 39, +130, 47,243, 35, 96,140,126,170,152,124,251,194, 19,172, 21,180,232,235, 53,181,105,213,242, 94,161,195,143,217,191,120, 96,182, + 59,109, 95,120, 8, 99, 27,111, 78, 76, 94,175, 64,161,232,249,112,173,171, 71, 78,250, 52,253,155,219,133,101,185,124, 10,140, +142, 7,117,247, 84,251, 96,121,138, 65, 62, 76,219, 48,198,158,101,199, 98, 23,116,155,165, 45,161,197,158, 79,221,168,177,140, +200, 67, 27,241,229, 90,142,229,204,220,240,215,104,219, 49,179, 22, 25, 51,122,235,149,154,209,169, 44, 49,241, 36,156,133, 78, + 10,189, 70, 75,155,114, 23,183,166,164,237,208,118, 98,227, 48,218,206,213,229,142, 76, 37,188,187,227, 24,252,217,117, 56,255, + 0, 3, 91,171,175, 79, 79,198,246,211, 83,247,216,118, 54,195, 65,220,103, 11,201,245, 84,199,231,222, 17, 31, 84, 6, 43,167, +172,116,234,211,171,228,191,133, 62, 0,243,221,147,187, 55,232,163,237,220, 60,120,204,184,145, 96,236,105,151, 36,134, 0,143, +231,147, 68,178, 75, 36,243, 36,197,192, 23,140, 70,141,118, 6,252,234,186, 14,228,222,118, 8, 55, 25, 49,179, 60,206, 71,159, +220,178,178, 83,160,132,186,193,158, 49, 3, 79, 36,142,186, 98,211,238,133,143,223, 4,128, 61,209, 91,231,199,237, 54,204,219, + 25, 14,215,230,196, 49,141,158,210, 98,137, 60,185, 7,165,229, 70,171,232,181,244,104,225,107,218,129,153,141,217, 5,129,220, +155,103,212, 27, 38,221,121,113, 62, 45,127,227, 46, 29,184,158,167,241,127,157,241,113,171,240, 4, 9,251,191,113,109,214,109, +184,148, 16, 29,215, 47, 3,130,217,186, 17,109, 35, 57, 44,111,241,117,143, 63, 71, 10,205,109,219,215,112, 99,141,185,240, 51, +217,222, 94,222,216,136,197,115, 25,145,140,141, 48,156,227,121,150, 88,223, 32,172,108, 70,175,139,145,228, 43,119,229,187, 71, +239,114, 75,109, 95,124,158,119,147, 23,205,112,132,248,106,215,252, 11,255, 0, 83,213, 64,205,198,236,102,143, 25,115,219,102, +208,113, 99, 24, 93, 89, 49, 7,248, 77, 75,210,232, 22,111,225,106,211,167, 79,187,123, 90,167,192, 22, 93,181,191, 46,231,179, +226,228,205, 50,100,100,178, 94,102, 84, 49, 31,137,144, 23,136,146, 80,251,132, 31, 11,131,110, 21,111,231, 99,244, 85, 70,217, +143,177,220,253,204,216, 55,232,195,127, 41, 36, 31,244,254,255, 0,151,254, 19,127, 15,227,209,225,206,222, 53, 99,229,207,233, + 39,254,145, 63,214,164,120, 9, 13,231, 99,244, 87,121,216,189, 20, 15, 46,127, 73, 63,244,137,254,181,119,151, 63,164,159,250, + 68,255, 0, 90,144, 36,145,231, 99,253, 26,239, 57, 31,162,129,208, 63,164,159,174,159,235, 83,132, 31,206, 79,215, 79,174,145, +224, 9, 94, 97, 58,122,173,253,157,254, 78,166,154,234, 30,129,167,167,113,126,143, 59,141, 63,197,253, 46, 85,212, 7,255,217, +}; + +#endif diff --git a/source/blender/src/winlay.h b/source/blender/src/winlay.h new file mode 100644 index 00000000000..4cf19bc23cd --- /dev/null +++ b/source/blender/src/winlay.h @@ -0,0 +1,74 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +/* Abstract window operations */ + +typedef struct _Window Window; +typedef void (*WindowHandlerFP) (Window *win, void *user_data, short evt, short val, char ascii); + +Window* window_open (char *title, int x, int y, int width, int height, int start_maximized); +void window_set_handler (Window *win, WindowHandlerFP handler, void *user_data); +void window_destroy (Window *win); + +void window_set_timer (Window *win, int delay_ms, int event); + +void window_make_active (Window *win); +void window_swap_buffers (Window *win); + +void window_raise (Window *win); +void window_lower (Window *win); + +short window_get_qual (Window *win); +short window_get_mbut (Window *win); +void window_get_mouse (Window *win, short *mval); + +void window_get_position (Window *win, int *posx_r, int *poxy_r); + +void window_get_size (Window *win, int *width_r, int *height_r); +void window_set_size (Window *win, int width, int height); + +char* window_get_title (Window *win); +void window_set_title (Window *win, char *title); + +void window_set_cursor (Window *win, int cursor); +void window_set_custom_cursor (Window *win, unsigned char mask[16][2], unsigned char bitmap[16][2]); + +void window_warp_pointer (Window *win, int x, int y); + +void window_queue_redraw (Window *win); + + /* Global windowing operations */ + +Window* winlay_get_active_window(void); + +void winlay_process_events (int wait_for_event); + +void winlay_get_screensize (int *width_r, int *height_r); diff --git a/source/blender/src/writeavicodec.c b/source/blender/src/writeavicodec.c new file mode 100644 index 00000000000..6c19dfaac4e --- /dev/null +++ b/source/blender/src/writeavicodec.c @@ -0,0 +1,799 @@ +/** + * Functions for writing windows avi-format files. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * + */ + +#ifdef _WIN32 + +#define INC_OLE2 +#include <windows.h> +#include <windowsx.h> +#include <memory.h> +#include <mmsystem.h> +#include <vfw.h> + +#include <string.h> + +#include "MEM_guardedalloc.h" +#include "BLI_blenlib.h" + +#include "render_types.h" +#include "render.h" + +#include "BKE_global.h" +#include "BKE_scene.h" +#include "BKE_writeavi.h" + +#include "BIF_toolbox.h" + +// this defines the compression type for +// the output video stream + +AVICOMPRESSOPTIONS opts; + +static int sframe; +static PAVIFILE pfile = NULL; +static int avifileinitdone = 0; +static PAVISTREAM psUncompressed = NULL, psCompressed = NULL; + +// function definitions +static void init_bmi(BITMAPINFOHEADER *bmi); +static void opts_to_acd(AviCodecData *acd); +static void acd_to_opts(AviCodecData *acd); +static void free_opts_data(); +static int open_avi_codec_file(char * name); + +/////////////////////////////////////////////////////////////////////////// +// +// silly default parameters +// +/////////////////////////////////////////////////////////////////////////// + +#define DEFAULT_WIDTH 240 +#define DEFAULT_HEIGHT 120 +#define DEFAULT_LENGTH 100 +#define DEFAULT_SIZE 6 +#define DEFAULT_COLOR RGB(255,0,0) +#define XSPEED 7 +#define YSPEED 5 + +/////////////////////////////////////////////////////////////////////////// +// +// useful macros +// +/////////////////////////////////////////////////////////////////////////// + +#define ALIGNULONG(i) ((i+3)&(~3)) /* ULONG aligned ! */ +#define WIDTHBYTES(i) ((unsigned)((i+31)&(~31))/8) /* ULONG aligned ! */ +#define DIBWIDTHBYTES(bi) (int)WIDTHBYTES((int)(bi).biWidth * (int)(bi).biBitCount) +#define DIBPTR(lpbi) ((LPBYTE)(lpbi) + \ + (int)(lpbi)->biSize + \ + (int)(lpbi)->biClrUsed * sizeof(RGBQUAD) ) + +/////////////////////////////////////////////////////////////////////////// +// +// custom video stream instance structure +// +/////////////////////////////////////////////////////////////////////////// + +typedef struct { + + // + // The Vtbl must come first + // + IAVIStreamVtbl * lpvtbl; + + // + // private ball instance data + // + ULONG ulRefCount; + + DWORD fccType; // is this audio/video + + int width; // size in pixels of each frame + int height; + int length; // length in frames of the pretend AVI movie + int size; + COLORREF color; // ball color + +} AVIBALL, * PAVIBALL; + +/////////////////////////////////////////////////////////////////////////// +// +// custom stream methods +// +/////////////////////////////////////////////////////////////////////////// + +HRESULT STDMETHODCALLTYPE AVIBallQueryInterface(PAVISTREAM ps, REFIID riid, LPVOID * ppvObj); +HRESULT STDMETHODCALLTYPE AVIBallCreate (PAVISTREAM ps, LONG lParam1, LONG lParam2); +ULONG STDMETHODCALLTYPE AVIBallAddRef (PAVISTREAM ps); +ULONG STDMETHODCALLTYPE AVIBallRelease (PAVISTREAM ps); +HRESULT STDMETHODCALLTYPE AVIBallInfo (PAVISTREAM ps, AVISTREAMINFOW * psi, LONG lSize); +LONG STDMETHODCALLTYPE AVIBallFindSample (PAVISTREAM ps, LONG lPos, LONG lFlags); +HRESULT STDMETHODCALLTYPE AVIBallReadFormat (PAVISTREAM ps, LONG lPos, LPVOID lpFormat, LONG *lpcbFormat); +HRESULT STDMETHODCALLTYPE AVIBallSetFormat (PAVISTREAM ps, LONG lPos, LPVOID lpFormat, LONG cbFormat); +HRESULT STDMETHODCALLTYPE AVIBallRead (PAVISTREAM ps, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, LONG * plBytes,LONG * plSamples); +HRESULT STDMETHODCALLTYPE AVIBallWrite (PAVISTREAM ps, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, DWORD dwFlags, LONG *plSampWritten, LONG *plBytesWritten); +HRESULT STDMETHODCALLTYPE AVIBallDelete (PAVISTREAM ps, LONG lStart, LONG lSamples); +HRESULT STDMETHODCALLTYPE AVIBallReadData (PAVISTREAM ps, DWORD fcc, LPVOID lp,LONG *lpcb); +HRESULT STDMETHODCALLTYPE AVIBallWriteData (PAVISTREAM ps, DWORD fcc, LPVOID lp,LONG cb); + +IAVIStreamVtbl AVIBallHandler = { + AVIBallQueryInterface, + AVIBallAddRef, + AVIBallRelease, + AVIBallCreate, + AVIBallInfo, + AVIBallFindSample, + AVIBallReadFormat, + AVIBallSetFormat, + AVIBallRead, + AVIBallWrite, + AVIBallDelete, + AVIBallReadData, + AVIBallWriteData +}; + + +// +// This is the function an application would call to create a PAVISTREAM to +// reference the ball. Then the standard AVIStream function calls can be +// used to work with this stream. +// +PAVISTREAM WINAPI NewBall(void) +{ + static AVIBALL ball; + PAVIBALL pball = &ball; + + // + // Fill the function table + // + pball->lpvtbl = &AVIBallHandler; + + // + // Call our own create code to create a new instance (calls AVIBallCreate) + // For now, don't use any lParams. + // + pball->lpvtbl->Create((PAVISTREAM) pball, 0, 0); + + return (PAVISTREAM) pball; +} + +/////////////////////////////////////////////////////////////////////////// +// +// This function is called to initialize an instance of the bouncing ball. +// +// When called, we look at the information possibly passed in <lParam1>, +// if any, and use it to determine the length of movie they want. (Not +// supported by NewBall right now, but it could be). +// +/////////////////////////////////////////////////////////////////////////// +HRESULT STDMETHODCALLTYPE AVIBallCreate(PAVISTREAM ps, LONG lParam1, LONG lParam2) +{ + PAVIBALL pball = (PAVIBALL) ps; + + // + // what type of data are we? (audio/video/other stream) + // + pball->fccType = streamtypeVIDEO; + + // + // We define lParam1 as being the length of movie they want us to pretend + // to be. + // + if (lParam1) + pball->length = (int) lParam1; + else + pball->length = DEFAULT_LENGTH; + + switch (pball->fccType) { + + case streamtypeVIDEO: + pball->color = DEFAULT_COLOR; + pball->width = DEFAULT_WIDTH; + pball->height = DEFAULT_HEIGHT; + pball->size = DEFAULT_SIZE; + pball->ulRefCount = 1; // note that we are opened once + return AVIERR_OK; // success + + case streamtypeAUDIO: + return ResultFromScode(AVIERR_UNSUPPORTED); // we don't do audio + + default: + return ResultFromScode(AVIERR_UNSUPPORTED); // or anything else + } +} + + +// +// Increment our reference count +// +ULONG STDMETHODCALLTYPE AVIBallAddRef(PAVISTREAM ps) +{ + PAVIBALL pball = (PAVIBALL) ps; + return (++pball->ulRefCount); +} + + +// +// Decrement our reference count +// +ULONG STDMETHODCALLTYPE AVIBallRelease(PAVISTREAM ps) +{ + PAVIBALL pball = (PAVIBALL) ps; + if (--pball->ulRefCount) + return pball->ulRefCount; + + // Free any data we're keeping around - like our private structure + GlobalFreePtr(pball); + + return 0; +} + + +// +// Fills an AVISTREAMINFO structure +// +HRESULT STDMETHODCALLTYPE AVIBallInfo(PAVISTREAM ps, AVISTREAMINFOW * psi, LONG lSize) +{ + PAVIBALL pball = (PAVIBALL) ps; + + if (lSize < sizeof(AVISTREAMINFO)) + return ResultFromScode(AVIERR_BUFFERTOOSMALL); + + _fmemset(psi, 0, (int)lSize); + + // Fill out a stream header with information about us. + psi->fccType = pball->fccType; + psi->fccHandler = mmioFOURCC('B','a','l','l'); + psi->dwScale = 1; + psi->dwRate = 15; + psi->dwLength = pball->length; + psi->dwSuggestedBufferSize = pball->height * ALIGNULONG(pball->width); + psi->rcFrame.right = pball->width; + psi->rcFrame.bottom = pball->height; + CopyMemory((PVOID)psi->szName, + (PVOID)L"Bouncing ball video", + sizeof(L"Bouncing ball video")); + + return AVIERR_OK; +} + +/////////////////////////////////////////////////////////////////////////// +// +// AVIBallReadFormat: needs to return the format of our data. +// +/////////////////////////////////////////////////////////////////////////// +HRESULT STDMETHODCALLTYPE AVIBallReadFormat (PAVISTREAM ps, LONG lPos,LPVOID lpFormat,LONG *lpcbFormat) +{ + PAVIBALL pball = (PAVIBALL) ps; + LPBITMAPINFO lpbi = (LPBITMAPINFO) lpFormat; + + if (lpFormat == NULL || *lpcbFormat == 0) { + *lpcbFormat = sizeof(BITMAPINFOHEADER); + return AVIERR_OK; + } + + if (*lpcbFormat < sizeof(BITMAPINFOHEADER)) + return ResultFromScode(AVIERR_BUFFERTOOSMALL); + + // This is a relatively silly example: we build up our + // format from scratch every time. + + /* + lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + lpbi->bmiHeader.biCompression = BI_RGB; + lpbi->bmiHeader.biWidth = pball->width; + lpbi->bmiHeader.biHeight = pball->height; + lpbi->bmiHeader.biBitCount = 8; + lpbi->bmiHeader.biPlanes = 1; + lpbi->bmiHeader.biClrUsed = 2; + lpbi->bmiHeader.biSizeImage = pball->height * DIBWIDTHBYTES(lpbi->bmiHeader); + */ + + //init_bmi(&lpbi->bmiHeader); + + memset(&lpbi->bmiHeader, 0, sizeof(BITMAPINFOHEADER)); + lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + lpbi->bmiHeader.biWidth = pball->width; + lpbi->bmiHeader.biHeight = pball->height; + lpbi->bmiHeader.biPlanes = 1; + lpbi->bmiHeader.biBitCount = 24; + lpbi->bmiHeader.biSizeImage = pball->width * pball->height * sizeof(RGBTRIPLE); + + /* + lpbi->bmiColors[0].rgbRed = 0; + lpbi->bmiColors[0].rgbGreen = 0; + lpbi->bmiColors[0].rgbBlue = 0; + lpbi->bmiColors[1].rgbRed = GetRValue(pball->color); + lpbi->bmiColors[1].rgbGreen = GetGValue(pball->color); + lpbi->bmiColors[1].rgbBlue = GetBValue(pball->color); + */ + + *lpcbFormat = sizeof(BITMAPINFOHEADER); + + return AVIERR_OK; +} + +/////////////////////////////////////////////////////////////////////////// +// +// AVIBallRead: needs to return the data for a particular frame. +// +/////////////////////////////////////////////////////////////////////////// +HRESULT STDMETHODCALLTYPE AVIBallRead (PAVISTREAM ps, LONG lStart,LONG lSamples,LPVOID lpBuffer,LONG cbBuffer,LONG * plBytes,LONG * plSamples) +{ + PAVIBALL pball = (PAVIBALL) ps; + LONG lSize = pball->height * ALIGNULONG(pball->width); // size of frame + // in bytes + int x, y; + HPSTR hp = lpBuffer; + int xPos, yPos; + + // Reject out of range values + if (lStart < 0 || lStart >= pball->length) + return ResultFromScode(AVIERR_BADPARAM); + + // Did they just want to know the size of our data? + if (lpBuffer == NULL || cbBuffer == 0) + goto exit; + + // Will our frame fit in the buffer passed? + if (lSize > cbBuffer) + return ResultFromScode(AVIERR_BUFFERTOOSMALL); + + // Figure out the position of the ball. + // It just bounces back and forth. + + xPos = 5 + XSPEED * (int) lStart; // x = x0 + vt + xPos = xPos % ((pball->width - pball->size) * 2); // limit to 2xwidth + if (xPos > (pball->width - pball->size)) // reflect if + xPos = 2 * (pball->width - pball->size) - xPos; // needed + + yPos = 5 + YSPEED * (int) lStart; + yPos = yPos % ((pball->height - pball->size) * 2); + if (yPos > (pball->height - pball->size)) + yPos = 2 * (pball->height - pball->size) - yPos; + + // + // Build a DIB from scratch by writing in 1's where the ball is, 0's + // where it isn't. + // + // Notice that we just build it in the buffer we've been passed. + // + // This is pretty ugly, I have to admit. + // + for (y = 0; y < pball->height; y++) + { + if (y >= yPos && y < yPos + pball->size) + { + for (x = 0; x < pball->width; x++) + { + *hp++ = (BYTE) ((x >= xPos && x < xPos + pball->size) ? 1 : 0); + } + } + else + { + for (x = 0; x < pball->width; x++) + { + *hp++ = 0; + } + } + + hp += pball->width - ALIGNULONG(pball->width); + } + +exit: + // We always return exactly one frame + if (plSamples) + *plSamples = 1; + + // Return the size of our frame + if (plBytes) + *plBytes = lSize; + + return AVIERR_OK; +} + + +HRESULT STDMETHODCALLTYPE AVIBallQueryInterface(PAVISTREAM ps, REFIID riid, LPVOID * ppvObj) +{ + PAVIBALL pball = (PAVIBALL) ps; + + // We support the Unknown interface (everybody does) and our Stream + // interface. + + if (_fmemcmp(riid, &IID_IUnknown, sizeof(GUID)) == 0) + *ppvObj = (LPVOID)pball; + + else if (_fmemcmp(riid, &IID_IAVIStream, sizeof(GUID)) == 0) + *ppvObj = (LPVOID)pball; + + else { + *ppvObj = NULL; + return ResultFromScode(E_NOINTERFACE); + } + + AVIBallAddRef(ps); + + return AVIERR_OK; +} + +LONG STDMETHODCALLTYPE AVIBallFindSample (PAVISTREAM ps, LONG lPos, LONG lFlags) +{ + // The only format change is frame 0 + if ((lFlags & FIND_TYPE) == FIND_FORMAT) { + if ((lFlags & FIND_DIR) == FIND_NEXT && lPos > 0) + return -1; // no more format changes + else + return 0; + + // FIND_KEY and FIND_ANY always return the same position because + // every frame is non-empty and a key frame + } else + return lPos; +} + +HRESULT STDMETHODCALLTYPE AVIBallReadData (PAVISTREAM ps, DWORD fcc, LPVOID lp, LONG *lpcb) +{ + return ResultFromScode(AVIERR_UNSUPPORTED); +} + +HRESULT STDMETHODCALLTYPE AVIBallSetFormat (PAVISTREAM ps, LONG lPos, LPVOID lpFormat, LONG cbFormat) +{ + return ResultFromScode(AVIERR_UNSUPPORTED); +} + +HRESULT STDMETHODCALLTYPE AVIBallWriteData (PAVISTREAM ps, DWORD fcc, LPVOID lp, LONG cb) +{ + return ResultFromScode(AVIERR_UNSUPPORTED); +} + +HRESULT STDMETHODCALLTYPE AVIBallWrite (PAVISTREAM ps, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, DWORD dwFlags, LONG *plSampWritten, LONG *plBytesWritten) +{ + return ResultFromScode(AVIERR_UNSUPPORTED); +} + +HRESULT STDMETHODCALLTYPE AVIBallDelete (PAVISTREAM ps, LONG lStart, LONG lSamples) +{ + return ResultFromScode(AVIERR_UNSUPPORTED); +} + + +////////////////////////////////////// +static void init_bmi(BITMAPINFOHEADER *bmi) +{ + memset(bmi, 0, sizeof(BITMAPINFOHEADER)); + bmi->biSize = sizeof(BITMAPINFOHEADER); + bmi->biWidth = R.rectx; + bmi->biHeight = R.recty; + bmi->biPlanes = 1; + bmi->biBitCount = 24; + bmi->biSizeImage = bmi->biWidth * bmi->biHeight * sizeof(RGBTRIPLE); +} + + +static void opts_to_acd(AviCodecData *acd) +{ + acd->fccType = opts.fccType; + acd->fccHandler = opts.fccHandler; + acd->dwKeyFrameEvery = opts.dwKeyFrameEvery; + acd->dwQuality = opts.dwQuality; + acd->dwBytesPerSecond = opts.dwBytesPerSecond; + acd->dwFlags = opts.dwFlags; + acd->dwInterleaveEvery = opts.dwInterleaveEvery; + acd->cbFormat = opts.cbFormat; + acd->cbParms = opts.cbParms; + + if (opts.lpFormat && opts.cbFormat) { + acd->lpFormat = MEM_mallocN(opts.cbFormat, "avi.lpFormat"); + memcpy(acd->lpFormat, opts.lpFormat, opts.cbFormat); + } + + if (opts.lpParms && opts.cbParms) { + acd->lpParms = MEM_mallocN(opts.cbParms, "avi.lpParms"); + memcpy(acd->lpParms, opts.lpParms, opts.cbParms); + } +} + + +static void acd_to_opts(AviCodecData *acd) +{ + memset(&opts, 0, sizeof(opts)); + if (acd) { + opts.fccType = acd->fccType; + opts.fccHandler = acd->fccHandler; + opts.dwKeyFrameEvery = acd->dwKeyFrameEvery; + opts.dwQuality = acd->dwQuality; + opts.dwBytesPerSecond = acd->dwBytesPerSecond; + opts.dwFlags = acd->dwFlags; + opts.dwInterleaveEvery = acd->dwInterleaveEvery; + opts.cbFormat = acd->cbFormat; + opts.cbParms = acd->cbParms; + + if (acd->lpFormat && acd->cbFormat) { + opts.lpFormat = malloc(opts.cbFormat); + memcpy(opts.lpFormat, acd->lpFormat, opts.cbFormat); + } + + if (acd->lpParms && acd->cbParms) { + opts.lpParms = malloc(opts.cbParms); + memcpy(opts.lpParms, acd->lpParms, opts.cbParms); + } + } +} + +static void free_opts_data() +{ + if (opts.lpFormat) { + free(opts.lpFormat); + opts.lpFormat = NULL; + } + if (opts.lpParms) { + free(opts.lpParms); + opts.lpParms = NULL; + } +} + +static int open_avi_codec_file(char * name) +{ + HRESULT hr; + WORD wVer; + BITMAPINFOHEADER bmi; + AVISTREAMINFO strhdr; + int ret_val = 0; + + wVer = HIWORD(VideoForWindowsVersion()); + if (wVer < 0x010a){ + // this is probably an obsolete check... + ret_val = 1; + } else { + AVIFileInit(); + avifileinitdone++; + + hr = AVIFileOpen(&pfile, // returned file pointer + name, // file name + OF_WRITE | OF_CREATE, // mode to open file with + NULL); // use handler determined + + if (hr != AVIERR_OK) { + ret_val = 1; + } else { + // initialize the BITMAPINFOHEADER + init_bmi(&bmi); + // and associate a stream with the input images + memset(&strhdr, 0, sizeof(strhdr)); + strhdr.fccType = streamtypeVIDEO; // stream type + if (G.scene->r.avicodecdata) { + strhdr.fccHandler = G.scene->r.avicodecdata->fccHandler; + } + strhdr.dwScale = 1; + strhdr.dwRate = R.r.frs_sec; + strhdr.dwSuggestedBufferSize = bmi.biSizeImage; + SetRect(&strhdr.rcFrame, 0, 0, // rectangle for stream + (int) bmi.biWidth, + (int) bmi.biHeight); + + // And create the stream + hr = AVIFileCreateStream( + pfile, // file pointer + &psUncompressed,// returned stream pointer + &strhdr); // stream header + + if (hr != AVIERR_OK) { + ret_val = 1; + } else { + acd_to_opts(G.scene->r.avicodecdata); + } + } + } + + return(ret_val); +} + + +void end_avi_codec(void) +{ + free_opts_data(); + + if (psUncompressed) { + AVIStreamClose(psUncompressed); + psUncompressed = NULL; + } + + if (psCompressed) { + AVIStreamClose(psCompressed); + psCompressed = NULL; + } + + if (pfile) { + AVIFileClose(pfile); + pfile = NULL; + } + + if (avifileinitdone > 0) { + AVIFileExit(); + avifileinitdone--; + } +} + + +void start_avi_codec(void) +{ + HRESULT hr; + BITMAPINFOHEADER bmi; + char name[2048]; + char bakname[2048]; + + makeavistring(name); + sframe = (G.scene->r.sfra); + + strcpy(bakname, name); + strcat(bakname, ".bak"); + + if (BLI_exists(name)) { + BLI_move(name, bakname); + } + + // initialize the BITMAPINFOHEADER + init_bmi(&bmi); + + if (open_avi_codec_file(name)) { + error("Can not open file %s", name); + G.afbreek = 1; + } else { + // now create a compressed stream from the uncompressed + // stream and the compression options + hr = AVIMakeCompressedStream( + &psCompressed, // returned stream pointer + psUncompressed, // uncompressed stream + &opts, // compression options + NULL); // Unknown... + if (hr != AVIERR_OK) { + error("Codec is locked or not supported."); + G.afbreek = 1; + } else { + hr = AVIStreamSetFormat(psCompressed, 0, + &bmi, // stream format + bmi.biSize + // format size + bmi.biClrUsed * sizeof(RGBQUAD)); // plus size of colormap + if (hr != AVIERR_OK) { + error("Codec is locked or not supported."); + G.afbreek = 1; + } + } + } + + if (G.afbreek != 1) { + printf("Created win avi: %s\n", name); + if (BLI_exists(bakname)) { + BLI_delete(bakname, 0, 0); + } + } else { + // close the darn thing and remove it. + end_avi_codec(); + if (BLI_exists(name)) { + BLI_delete(name, 0, 0); + } + if (BLI_exists(bakname)) { + BLI_move(bakname, name); + } + } +} + + +void append_avi_codec(int frame) +{ + HRESULT hr; + BITMAPINFOHEADER bmi; + RGBTRIPLE *buffer, *to; + int x, y; + unsigned char *from; + + if (psCompressed) { + // initialize the BITMAPINFOHEADER + init_bmi(&bmi); + + // copy pixels + buffer = MEM_mallocN(bmi.biSizeImage, "append_win_avi"); + to = buffer; + from = (unsigned char *) R.rectot; + for (y = R.recty; y > 0 ; y--) { + for (x = R.rectx; x > 0 ; x--) { + to->rgbtRed = from[0]; + to->rgbtGreen = from[1]; + to->rgbtBlue = from[2]; + to++; from += 4; + } + } + + hr = AVIStreamWrite( + psCompressed, // stream pointer + frame - sframe, // frame number + 1, // number to write + (LPBYTE) buffer,// pointer to data + bmi.biSizeImage,// size of this frame + AVIIF_KEYFRAME, // flags.... + NULL, + NULL); + + MEM_freeN(buffer); + + if (hr != AVIERR_OK) { + G.afbreek = 1; + } else { + printf ("added frame %3d (frame %3d in avi): ", frame, frame-sframe); + } + } +} + + +int get_codec_settings(void) +{ + char name[2048]; + int ret_val = 0; + AVICOMPRESSOPTIONS *aopts[1] = {&opts}; + AviCodecData *acd = G.scene->r.avicodecdata; + static PAVISTREAM psdummy; + + acd_to_opts(G.scene->r.avicodecdata); + + psdummy = NewBall(); + + if (psdummy == NULL) { + ret_val = 1; + } else { + if (!AVISaveOptions(NULL, + ICMF_CHOOSE_KEYFRAME | ICMF_CHOOSE_DATARATE, + 1, + &psdummy, + (LPAVICOMPRESSOPTIONS *) &aopts)) + { + ret_val = 1; + } else { + if (acd) { + free_avicodecdata(acd); + } else { + acd = G.scene->r.avicodecdata = MEM_callocN(sizeof(AviCodecData), "AviCodecData"); + } + + opts_to_acd(acd); + + AVISaveOptionsFree(1, aopts); + memset(&opts, 0, sizeof(opts)); + } + } + + return(ret_val); +} + +#endif // _WIN32 diff --git a/source/blender/src/writeimage.c b/source/blender/src/writeimage.c new file mode 100644 index 00000000000..d107347598d --- /dev/null +++ b/source/blender/src/writeimage.c @@ -0,0 +1,110 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" // ImBuf{} +#include "DNA_scene_types.h" +#include "DNA_texture_types.h" // EnvMap{} +#include "DNA_image_types.h" // Image{} +#include "render.h" +#include "license_key.h" // LICENSE_KEY_VALID +#include "BKE_utildefines.h" // ELEM + +#include "BIF_writeimage.h" + +int BIF_write_ibuf(ImBuf *ibuf, char *name) +{ + int ok; + + /* to be used for e.g. envmap, not rendered images */ + + if(R.r.imtype== R_IRIS) ibuf->ftype= IMAGIC; + else if ((R.r.imtype==R_PNG) && (LICENSE_KEY_VALID)) { + ibuf->ftype= PNG; + } + else if ((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) { + // fall back to Targa if PNG writing is not supported + ibuf->ftype= TGA; + } + else if(R.r.imtype==R_RAWTGA) { + ibuf->ftype= RAWTGA; + } + else if(R.r.imtype==R_HAMX) { + ibuf->ftype= AN_hamx; + } + else if ELEM(R.r.imtype, R_JPEG90, R_MOVIE) { + if(R.r.quality < 10) R.r.quality= 90; + + ibuf->ftype= JPG|R.r.quality; + } + else ibuf->ftype= TGA; + + RE_make_existing_file(name); + + ok = IMB_saveiff(ibuf, name, IB_rect); + if (ok == 0) { + perror(name); + } + + return(ok); +} + + +/* ------------------------------------------------------------------------- */ + +void BIF_save_envmap(EnvMap *env, char *str) +{ + ImBuf *ibuf; +/* extern rectcpy(); */ + int dx; + + /* all interactive stuff is handled in buttons.c */ + + dx= env->cuberes; + ibuf= IMB_allocImBuf(3*dx, 2*dx, 24, IB_rect, 0); + + IMB_rectop(ibuf, env->cube[0]->ibuf, + 0, 0, 0, 0, dx, dx, IMB_rectcpy, 0); + IMB_rectop(ibuf, env->cube[1]->ibuf, + dx, 0, 0, 0, dx, dx, IMB_rectcpy, 0); + IMB_rectop(ibuf, env->cube[2]->ibuf, + 2*dx, 0, 0, 0, dx, dx, IMB_rectcpy, 0); + IMB_rectop(ibuf, env->cube[3]->ibuf, + 0, dx, 0, 0, dx, dx, IMB_rectcpy, 0); + IMB_rectop(ibuf, env->cube[4]->ibuf, + dx, dx, 0, 0, dx, dx, IMB_rectcpy, 0); + IMB_rectop(ibuf, env->cube[5]->ibuf, + 2*dx, dx, 0, 0, dx, dx, IMB_rectcpy, 0); + + BIF_write_ibuf(ibuf, str); + IMB_freeImBuf(ibuf); +} diff --git a/source/blender/src/writemovie.c b/source/blender/src/writemovie.c new file mode 100644 index 00000000000..f71156f5131 --- /dev/null +++ b/source/blender/src/writemovie.c @@ -0,0 +1,514 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifdef __sgi + +#include <unistd.h> +#include <movie.h> +#include <cdaudio.h> +#include <dmedia/cl.h> +#include <dmedia/cl_cosmo.h> +#include <sys/file.h> /* flock */ +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "BKE_global.h" +#include "BKE_utildefines.h" + +#include "BIF_gl.h" +#include "BIF_writemovie.h" +#include "BIF_toolbox.h" + +#include "render.h" + +#define error(str) {perror(str) ; error("%s", str); G.afbreek= 1;} +#define QUIT(str) {error(str); return;} + +#define DIR_UP 1 +#define DIR_DOWN 2 +#define DIR_BOTH (DIR_UP | DIR_DOWN) + +#define MAXQUAL R.r.quality +#define MINQUAL 30 + +/* globals */ + +static CL_Handle compr, soft_compr; +static MVid movie, image; +static DMparams *movie_params, *image_params; +static int compr_params[64]; +static int myindex, qualindex, qualnow, mv_outx, mv_outy, numfields= 2; +static char *comp_buf; +static int sfra, efra, first = TRUE, maxbufsize; +static int ntsc = FALSE; + +#define FIRST_IMAGE "FIRST_IMAGE" +#define BLENDER_FIRST_IMAGE "BLENDER_1ST_IMG" + + +static void report_flock(void) +{ + static int flock_reported = FALSE; + + if (flock_reported) return; + flock_reported = TRUE; + + error("WriteMovie: couldn't flock() moviefile. Ignoring."); +} + + +static void make_movie_name(char *string) +{ + int len; + char txt[64]; + + if (string==0) return; + + strcpy(string, G.scene->r.pic); + BLI_convertstringcode(string, G.sce, G.scene->r.cfra); + len= strlen(string); + + RE_make_existing_file(string); + + if (strcasecmp(string + len - 3, ".mv")) { + sprintf(txt, "%04d_%04d.mv", sfra, efra); + strcat(string, txt); + } +} + +static int my_Compress(uint * rect, int *bufsize) +{ + int err = 0; + + compr_params[qualindex] = qualnow; + clSetParams(compr, compr_params, myindex); + + while (clCompress(compr, numfields, rect, bufsize, comp_buf) != numfields) { + if (compr == soft_compr) { + error("clCompress (software)"); + return 1; + } + + /* hardware opnieuw initialiseren */ + clCloseCompressor(compr); + clOpenCompressor(CL_JPEG_COSMO, &compr); + + qualnow--; + compr_params[qualindex] = qualnow; + clSetParams(compr, compr_params, myindex); + printf("retrying at quality %d\n", qualnow); + + err= TRUE; + } + + return (err); +} + +static void set_sfra_efra(void) +{ + sfra = (G.scene->r.sfra); + efra = (G.scene->r.efra); +} + +static void open_compressor(void) +{ + int cosmo = FAILURE; + + /* initialiseren van de compressor */ + + if (clOpenCompressor(CL_JPEG_SOFTWARE, &soft_compr) != SUCCESS) QUIT("clOpenCompressor"); + + if (G.scene->r.mode & R_COSMO) { + cosmo = clOpenCompressor(CL_JPEG_COSMO, &compr); + if (cosmo != SUCCESS && first) error("warning: using software compression"); + first = FALSE; + } + + if (cosmo != SUCCESS) compr = soft_compr; + + myindex = 0; + + compr_params[myindex++]= CL_IMAGE_WIDTH; + compr_params[myindex++]= mv_outx; + + compr_params[myindex++]= CL_IMAGE_HEIGHT; + compr_params[myindex++]= mv_outy / numfields; + + compr_params[myindex++]= CL_JPEG_QUALITY_FACTOR; + qualindex = myindex; + compr_params[myindex++]= R.r.quality; + + compr_params[myindex++]= CL_ORIGINAL_FORMAT; + compr_params[myindex++]= CL_RGBX; + + compr_params[myindex++]= CL_ORIENTATION; + compr_params[myindex++]= CL_TOP_DOWN; + + compr_params[myindex++]= CL_INTERNAL_FORMAT; + compr_params[myindex++]= CL_YUV422; + + /* this parameter must be set for non-queueing mode */ + compr_params[myindex++]= CL_ENABLE_IMAGEINFO; + compr_params[myindex++]= 1; + + /* enable stream headers */ + compr_params[myindex++]= CL_STREAM_HEADERS; + compr_params[myindex++]= TRUE; + + clSetParams(compr, compr_params, myindex); + if (compr != soft_compr) clSetParams(soft_compr, compr_params, myindex); + + maxbufsize = 2 * clGetParam(compr, CL_COMPRESSED_BUFFER_SIZE); + comp_buf = MEM_mallocN(maxbufsize, "cosmo_buffer"); +} + +static void close_compressor(void) +{ + MEM_freeN(comp_buf); + comp_buf = 0; + + clCloseCompressor(compr); + if (soft_compr != compr) clCloseCompressor(soft_compr); +} + +void end_movie(void) +{ +} + +static void new_movie(int fd) +{ + char string[120]; + + if (dmParamsCreate(&movie_params) != DM_SUCCESS) QUIT("dmParamsCreate"); + if (dmParamsCreate(&image_params) != DM_SUCCESS) QUIT("dmParamsCreate"); + + if (mvSetMovieDefaults(movie_params, MV_FORMAT_SGI_3) != DM_SUCCESS) QUIT("mvSetMovieDefaults"); + if (dmSetImageDefaults(image_params, mv_outx, mv_outy, DM_PACKING_RGBX) != DM_SUCCESS) QUIT("dmSetImageDefaults"); + + mvAddUserParam(BLENDER_FIRST_IMAGE); + sprintf(string, "%04d", sfra); + dmParamsSetString(image_params, BLENDER_FIRST_IMAGE, string); + + if (ntsc) dmParamsSetFloat(image_params, DM_IMAGE_RATE, 29.97); + else dmParamsSetFloat(image_params, DM_IMAGE_RATE, 25.0); + + if (numfields == 2) { + if (ntsc) dmParamsSetEnum(image_params, DM_IMAGE_INTERLACING, DM_IMAGE_INTERLACED_ODD); + else dmParamsSetEnum(image_params, DM_IMAGE_INTERLACING, DM_IMAGE_INTERLACED_EVEN); + } else dmParamsSetEnum(image_params, DM_IMAGE_INTERLACING, DM_IMAGE_NONINTERLACED); + + dmParamsSetEnum(image_params, DM_IMAGE_ORIENTATION, DM_TOP_TO_BOTTOM); + dmParamsSetString(image_params, DM_IMAGE_COMPRESSION, DM_IMAGE_JPEG); + + if (mvCreateFD(fd, movie_params, NULL, &movie) != DM_SUCCESS) QUIT("mvCreateFile"); + if (mvAddTrack(movie, DM_IMAGE, image_params, NULL, &image)) QUIT("mvAddTrack");; + if (mvSetLoopMode(movie, MV_LOOP_CONTINUOUSLY) != DM_SUCCESS) QUIT("mvSetMovieDefaults"); + + if (mvWrite(movie) != DM_SUCCESS) QUIT("mvWrite"); + if (mvClose(movie) != DM_SUCCESS) QUIT("mvClose"); + + dmParamsDestroy(image_params); + dmParamsDestroy(movie_params); +} + + +void start_movie(void) +{ + char name[FILE_MAXDIR+FILE_MAXFILE]; + char bak[sizeof(name) + 4]; + int fd; + + first = TRUE; + + set_sfra_efra(); + + /* naam bedenken voor de movie */ + make_movie_name(name); + + ntsc = FALSE; + + switch (R.recty) { + case 480: case 360: case 240: case 120: + ntsc = TRUE; + } + + if (ntsc) { + switch (R.rectx) { + case 360: case 320: case 720: case 640: + mv_outx = R.rectx; + break; + default: + if (R.rectx <= 320) mv_outx = 320; + else if (R.rectx <= 640) mv_outx = 640; + else mv_outx = 720; + } + } else { + switch (R.rectx) { + case 360: case 384: case 720: case 768: + mv_outx = R.rectx; + break; + default: + if (R.rectx < 384) mv_outx = 384; + else mv_outx = 768; + } + } + + if (ntsc) { + if (R.recty <= 240) { + mv_outy = 240; + numfields = 1; + } else { + mv_outy = 480; + numfields = 2; + } + } else { + if (R.recty <= 288) { + mv_outy = 288; + numfields = 1; + } else { + mv_outy = 576; + numfields = 2; + } + } + + if(R.r.mode & R_MOVIECROP) { + if (ntsc) { + if (R.rectx > 640) mv_outx = 720; + else mv_outx = 640; + mv_outy = 480; + numfields = 2; + } else { + if (R.rectx > 720) mv_outx = 768; + else mv_outx = 720; + mv_outy = 576; + numfields = 2; + } + } + + qualnow = R.r.quality; + + + fd = open(name, O_BINARY|O_RDWR); + if (fd != -1) { + if (flock(fd, LOCK_EX) == -1) report_flock(); + + if (mvOpenFD(fd, &movie) == DM_SUCCESS) { + if (mvFindTrackByMedium(movie, DM_IMAGE, &image) == DM_SUCCESS) { + if (mvGetImageWidth(image) == mv_outx) { + if (mvGetImageHeight(image) == mv_outy) { + mvClose(movie); + close(fd); + return; + } + } + } + strcpy(bak, name); + strcat(bak, ".bak"); + BLI_rename(name, bak); + mvClose(movie); + } + + close(fd); + } + fd = open(name, O_BINARY|O_RDWR | O_CREAT | O_EXCL, 0664); + if (fd != -1) { + if (flock(fd, LOCK_EX) == -1) report_flock(); + new_movie(fd); + printf("Created movie: %s\n", name); + close(fd); + } +} + +void append_movie(int cfra) +{ + ImBuf *ibuf, *tbuf; + int err, ofsx, ofsy, bufsize, rate, lastqual, qualstep, direction, first_image, num_images; + char name[FILE_MAXDIR+FILE_MAXFILE]; + const char *string; + int fd; + + set_sfra_efra(); + make_movie_name(name); + open_compressor(); + + rate = 1024 * R.r.maximsize; + + /* veranderd: kopie van rectot maken */ + ibuf= IMB_allocImBuf(R.rectx, R.recty, 32, IB_rect, 0); + memcpy(ibuf->rect, R.rectot, 4*R.rectx*R.recty); + + if (ibuf->x != mv_outx || ibuf->y != mv_outy) { + tbuf = IMB_allocImBuf(mv_outx, mv_outy, 32, IB_rect, 0); + IMB_rectoptot(tbuf, 0, IMB_rectfill, 0x00); + + ofsx = (tbuf->x - ibuf->x) / 2; + ofsy = (tbuf->y - ibuf->y) / 2; + if (numfields == 2) ofsy &= ~1; + + IMB_rectop(tbuf, ibuf, ofsx, ofsy, 0, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_freeImBuf(ibuf); + strcpy(tbuf->name, ibuf->name); + ibuf = tbuf; + } + IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + + if (numfields == 2) { + if (ntsc) { + IMB_rectop(ibuf, ibuf, 0, 0, 0, 1, 32767, 32767, IMB_rectcpy, 0); + IMB_flipy(ibuf); + IMB_de_interlace(ibuf); + if (ntsc) IMB_rectop(ibuf, ibuf, 0, 0, 0, 1, 32767, 32767, IMB_rectcpy, 0); + } else { + IMB_flipy(ibuf); + IMB_rectop(ibuf, ibuf, 0, 0, 0, 1, 32767, 32767, IMB_rectcpy, 0); + IMB_de_interlace(ibuf); + } + } + else { + /* kleine movies anders op de kop */ + IMB_flipy(ibuf); + } + + if (rate == 0) { + qualnow = R.r.quality; + my_Compress(ibuf->rect, &bufsize); + } else { + qualstep = 4; + direction = 0; + + do { + if (qualnow > MAXQUAL) qualnow = MAXQUAL; + if (qualnow < MINQUAL) qualnow = MINQUAL; + + compr_params[qualindex] = qualnow; + clSetParams(compr, compr_params, myindex); + + lastqual = qualnow; + err = my_Compress(ibuf->rect, &bufsize); + + printf(" tried quality: %d, size %d\n", qualnow, bufsize); + + if (bufsize < 0.9 * rate) { + if (err) { + /* forget about this frame, retry next frame at old quality settting */ + qualnow = lastqual; + break; + } + if (qualnow == MAXQUAL) break; + direction |= DIR_UP; + if (direction == DIR_BOTH) qualstep /= 2; + qualnow += qualstep; + } else if (bufsize > 1.1 * rate) { + if (qualnow == MINQUAL) break; + direction |= DIR_DOWN; + if (direction == DIR_BOTH) qualstep /= 2; + qualnow -= qualstep; + } else break; + + if (qualstep == 0) { + /* this was the last iteration. Make sure that the buffer isn't to big */ + if (bufsize < 1.1 * rate) break; + else qualnow--; + } + } while (1); + + printf("used quality: %d\n", qualnow); + + if (bufsize < rate) qualnow++; + else qualnow--; + + } + + fd = open(name, O_BINARY|O_RDWR); + + if (fd != -1) { + if (flock(fd, LOCK_EX) == -1) report_flock(); + if (mvOpenFD(fd, &movie) == DM_SUCCESS){ + if (mvFindTrackByMedium(movie, DM_IMAGE, &image) == DM_SUCCESS) { + image_params = mvGetParams(image); + + first_image = 1; + + string = dmParamsGetString(image_params, FIRST_IMAGE); + if (string) { + first_image = atoi(string); + } + string = dmParamsGetString(image_params, BLENDER_FIRST_IMAGE); + if (string) { + first_image = atoi(string); + } + + num_images = mvGetTrackLength(image); + + if (cfra >= first_image && cfra <= (first_image + num_images - 1)) { + if (mvDeleteFrames(image, cfra - first_image, 1) != DM_SUCCESS) { + mvDestroyMovie(movie); + error("mvDeleteFrames"); + G.afbreek = 1; + } + } + + if (G.afbreek != 1) { + if (mvInsertCompressedImage(image, cfra - first_image, bufsize, comp_buf) == DM_SUCCESS) { + printf("added frame %3d (frame %3d in movie): length %6d: ", cfra, cfra - first_image + 1, bufsize); + mvClose(movie); + } else { + mvDestroyMovie(movie); + error("mvInsertCompressedImage"); + G.afbreek = 1; + } + } + } else { + mvDestroyMovie(movie); + error("mvFindTrackByMedium"); + G.afbreek = 1; + } + }else { + error("mvOpenFD"); + G.afbreek = 1; + } + close(fd); + } else { + error("open movie"); + G.afbreek = 1; + } + + IMB_freeImBuf(ibuf); + + close_compressor(); +} + +#endif /* __sgi */ |