/// Aqsis
// Copyright (c) 1997 - 2001, Paul C. Gregory
//
// Contact: pgregory@aqsis.com
//
// This library 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.
//
// This library 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 library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

/**
 * Copyright (C) 2006-2007  NTT DATA CORPORATION
 * 
 * Version: 1.0.0 2007/04/01
 *  
 */
package net.cellcomputing.himawari.library;

import static net.cellcomputing.himawari.library.CqStats.STATS_INC;
import static net.cellcomputing.himawari.library.EqDisplayMode.ModeA;
import static net.cellcomputing.himawari.library.EqDisplayMode.ModeRGB;
import static net.cellcomputing.himawari.library.EqDisplayMode.ModeZ;
import static net.cellcomputing.himawari.library.EqIntIndex.GEO_prc_created_dra;
import static net.cellcomputing.himawari.library.EqIntIndex.GPR_created;
import static net.cellcomputing.himawari.library.EqModeBlock.Attribute;
import static net.cellcomputing.himawari.library.EqModeBlock.BeginEnd;
import static net.cellcomputing.himawari.library.EqModeBlock.Frame;
import static net.cellcomputing.himawari.library.EqModeBlock.Motion;
import static net.cellcomputing.himawari.library.EqModeBlock.Object;
import static net.cellcomputing.himawari.library.EqModeBlock.Outside;
import static net.cellcomputing.himawari.library.EqModeBlock.Solid;
import static net.cellcomputing.himawari.library.EqModeBlock.Transform;
import static net.cellcomputing.himawari.library.EqModeBlock.World;
import static net.cellcomputing.himawari.library.EqProjection.ProjectionOrthographic;
import static net.cellcomputing.himawari.library.EqProjection.ProjectionPerspective;
import static net.cellcomputing.himawari.library.EqShaderType.Type_Displacement;
import static net.cellcomputing.himawari.library.EqShaderType.Type_Lightsource;
import static net.cellcomputing.himawari.library.EqShaderType.Type_Surface;
import static net.cellcomputing.himawari.library.EqShaderType.Type_Volume;
import static net.cellcomputing.himawari.library.EqVariableClass.class_facevarying;
import static net.cellcomputing.himawari.library.EqVariableClass.class_uniform;
import static net.cellcomputing.himawari.library.EqVariableClass.class_varying;
import static net.cellcomputing.himawari.library.EqVariableClass.class_vertex;
import static net.cellcomputing.himawari.library.EqVariableType.type_bool;
import static net.cellcomputing.himawari.library.EqVariableType.type_color;
import static net.cellcomputing.himawari.library.EqVariableType.type_float;
import static net.cellcomputing.himawari.library.EqVariableType.type_hpoint;
import static net.cellcomputing.himawari.library.EqVariableType.type_integer;
import static net.cellcomputing.himawari.library.EqVariableType.type_invalid;
import static net.cellcomputing.himawari.library.EqVariableType.type_last;
import static net.cellcomputing.himawari.library.EqVariableType.type_matrix;
import static net.cellcomputing.himawari.library.EqVariableType.type_normal;
import static net.cellcomputing.himawari.library.EqVariableType.type_point;
import static net.cellcomputing.himawari.library.EqVariableType.type_sixteentuple;
import static net.cellcomputing.himawari.library.EqVariableType.type_string;
import static net.cellcomputing.himawari.library.EqVariableType.type_triple;
import static net.cellcomputing.himawari.library.EqVariableType.type_vector;
import static net.cellcomputing.himawari.library.EqVariableType.type_void;
import static net.cellcomputing.himawari.library.RIL_POINTS.RIL_NONE;
import static net.cellcomputing.himawari.library.RIL_POINTS.RIL_P;
import static net.cellcomputing.himawari.library.RIL_POINTS.RIL_Pw;
import static net.cellcomputing.himawari.library.RIL_POINTS.RIL_Pz;
import static net.cellcomputing.himawari.library.RiGlobal.CheckMinMax;
import static net.cellcomputing.himawari.library.RiGlobal.Lightsource_stack;
import static net.cellcomputing.himawari.library.RiGlobal.QGetRenderContext;
import static net.cellcomputing.himawari.library.RiGlobal.QSetRenderContext;
import static net.cellcomputing.himawari.library.RiGlobal.RI_EPSILON;
import static net.cellcomputing.himawari.library.RiGlobal.RI_FALSE;
import static net.cellcomputing.himawari.library.RiGlobal.RI_INFINITY;
import static net.cellcomputing.himawari.library.RiGlobal.RI_NULL;
import static net.cellcomputing.himawari.library.RiGlobal.RI_PI;
import static net.cellcomputing.himawari.library.RiGlobal.RI_TRUE;
import static net.cellcomputing.himawari.library.ShadingInterpolation.ShadingConstant;
import static net.cellcomputing.himawari.library.ShadingInterpolation.ShadingSmooth;
import static net.cellcomputing.himawari.library.types.PublicFunctions.CLAMP;
import static net.cellcomputing.himawari.library.types.PublicFunctions.RAD;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Vector;

import javax.imageio.ImageIO;

import net.cellcomputing.himawari.accessory.STLVector;
import net.cellcomputing.himawari.accessory.primitive.p_String;
import net.cellcomputing.himawari.accessory.primitive.p_float;
import net.cellcomputing.himawari.accessory.primitive.p_int;
import net.cellcomputing.himawari.display.ZFileRequest;
import net.cellcomputing.himawari.exception.XqException;
import net.cellcomputing.himawari.library.cache.RiAreaLightSourceCache;
import net.cellcomputing.himawari.library.cache.RiAtmosphereCache;
import net.cellcomputing.himawari.library.cache.RiAttributeBeginCache;
import net.cellcomputing.himawari.library.cache.RiAttributeCache;
import net.cellcomputing.himawari.library.cache.RiAttributeEndCache;
import net.cellcomputing.himawari.library.cache.RiBasisCache;
import net.cellcomputing.himawari.library.cache.RiBlobbyCache;
import net.cellcomputing.himawari.library.cache.RiBoundCache;
import net.cellcomputing.himawari.library.cache.RiClippingCache;
import net.cellcomputing.himawari.library.cache.RiColorCache;
import net.cellcomputing.himawari.library.cache.RiColorSamplesCache;
import net.cellcomputing.himawari.library.cache.RiConcatTransformCache;
import net.cellcomputing.himawari.library.cache.RiConeCache;
import net.cellcomputing.himawari.library.cache.RiCoordinateSystemCache;
import net.cellcomputing.himawari.library.cache.RiCropWindowCache;
import net.cellcomputing.himawari.library.cache.RiCurvesCache;
import net.cellcomputing.himawari.library.cache.RiCylinderCache;
import net.cellcomputing.himawari.library.cache.RiDeclareCache;
import net.cellcomputing.himawari.library.cache.RiDeformationCache;
import net.cellcomputing.himawari.library.cache.RiDepthOfFieldCache;
import net.cellcomputing.himawari.library.cache.RiDetailCache;
import net.cellcomputing.himawari.library.cache.RiDetailRangeCache;
import net.cellcomputing.himawari.library.cache.RiDiskCache;
import net.cellcomputing.himawari.library.cache.RiDisplacementCache;
import net.cellcomputing.himawari.library.cache.RiDisplayCache;
import net.cellcomputing.himawari.library.cache.RiErrorHandlerCache;
import net.cellcomputing.himawari.library.cache.RiExposureCache;
import net.cellcomputing.himawari.library.cache.RiExteriorCache;
import net.cellcomputing.himawari.library.cache.RiFormatCache;
import net.cellcomputing.himawari.library.cache.RiFrameAspectRatioCache;
import net.cellcomputing.himawari.library.cache.RiFrameBeginCache;
import net.cellcomputing.himawari.library.cache.RiFrameEndCache;
import net.cellcomputing.himawari.library.cache.RiGeneralPolygonCache;
import net.cellcomputing.himawari.library.cache.RiGeometricApproximationCache;
import net.cellcomputing.himawari.library.cache.RiGeometryCache;
import net.cellcomputing.himawari.library.cache.RiHiderCache;
import net.cellcomputing.himawari.library.cache.RiHyperboloidCache;
import net.cellcomputing.himawari.library.cache.RiIdentityCache;
import net.cellcomputing.himawari.library.cache.RiIlluminateCache;
import net.cellcomputing.himawari.library.cache.RiImagerCache;
import net.cellcomputing.himawari.library.cache.RiInteriorCache;
import net.cellcomputing.himawari.library.cache.RiLightSourceCache;
import net.cellcomputing.himawari.library.cache.RiMakeBumpCache;
import net.cellcomputing.himawari.library.cache.RiMakeCubeFaceEnvironmentCache;
import net.cellcomputing.himawari.library.cache.RiMakeLatLongEnvironmentCache;
import net.cellcomputing.himawari.library.cache.RiMakeOcclusionCache;
import net.cellcomputing.himawari.library.cache.RiMakeShadowCache;
import net.cellcomputing.himawari.library.cache.RiMakeTextureCache;
import net.cellcomputing.himawari.library.cache.RiMatteCache;
import net.cellcomputing.himawari.library.cache.RiMotionBeginVCache;
import net.cellcomputing.himawari.library.cache.RiMotionEndCache;
import net.cellcomputing.himawari.library.cache.RiNuPatchCache;
import net.cellcomputing.himawari.library.cache.RiObjectBeginCache;
import net.cellcomputing.himawari.library.cache.RiObjectEndCache;
import net.cellcomputing.himawari.library.cache.RiObjectInstanceCache;
import net.cellcomputing.himawari.library.cache.RiOpacityCache;
import net.cellcomputing.himawari.library.cache.RiOptionCache;
import net.cellcomputing.himawari.library.cache.RiOrientationCache;
import net.cellcomputing.himawari.library.cache.RiParaboloidCache;
import net.cellcomputing.himawari.library.cache.RiPatchCache;
import net.cellcomputing.himawari.library.cache.RiPatchMeshCache;
import net.cellcomputing.himawari.library.cache.RiPerspectiveCache;
import net.cellcomputing.himawari.library.cache.RiPixelFilterCache;
import net.cellcomputing.himawari.library.cache.RiPixelSamplesCache;
import net.cellcomputing.himawari.library.cache.RiPixelVarianceCache;
import net.cellcomputing.himawari.library.cache.RiPointsCache;
import net.cellcomputing.himawari.library.cache.RiPointsGeneralPolygonsCache;
import net.cellcomputing.himawari.library.cache.RiPointsPolygonsCache;
import net.cellcomputing.himawari.library.cache.RiPolygonCache;
import net.cellcomputing.himawari.library.cache.RiProceduralCache;
import net.cellcomputing.himawari.library.cache.RiProjectionCache;
import net.cellcomputing.himawari.library.cache.RiQuantizeCache;
import net.cellcomputing.himawari.library.cache.RiReadArchiveCache;
import net.cellcomputing.himawari.library.cache.RiRelativeDetailCache;
import net.cellcomputing.himawari.library.cache.RiReverseOrientationCache;
import net.cellcomputing.himawari.library.cache.RiRotateCache;
import net.cellcomputing.himawari.library.cache.RiScaleCache;
import net.cellcomputing.himawari.library.cache.RiScreenWindowCache;
import net.cellcomputing.himawari.library.cache.RiShadingInterpolationCache;
import net.cellcomputing.himawari.library.cache.RiShadingRateCache;
import net.cellcomputing.himawari.library.cache.RiShutterCache;
import net.cellcomputing.himawari.library.cache.RiSidesCache;
import net.cellcomputing.himawari.library.cache.RiSkewCache;
import net.cellcomputing.himawari.library.cache.RiSolidBeginCache;
import net.cellcomputing.himawari.library.cache.RiSolidEndCache;
import net.cellcomputing.himawari.library.cache.RiSphereCache;
import net.cellcomputing.himawari.library.cache.RiSubdivisionMeshCache;
import net.cellcomputing.himawari.library.cache.RiSurfaceCache;
import net.cellcomputing.himawari.library.cache.RiTextureCoordinatesCache;
import net.cellcomputing.himawari.library.cache.RiTorusCache;
import net.cellcomputing.himawari.library.cache.RiTransformBeginCache;
import net.cellcomputing.himawari.library.cache.RiTransformCache;
import net.cellcomputing.himawari.library.cache.RiTransformEndCache;
import net.cellcomputing.himawari.library.cache.RiTransformPointsCache;
import net.cellcomputing.himawari.library.cache.RiTranslateCache;
import net.cellcomputing.himawari.library.cache.RiTrimCurveCache;
import net.cellcomputing.himawari.library.cache.RiWorldBeginCache;
import net.cellcomputing.himawari.library.cache.RiWorldEndCache;
import net.cellcomputing.himawari.library.types.CqColor;
import net.cellcomputing.himawari.library.types.CqMatrix;
import net.cellcomputing.himawari.library.types.CqRandom;
import net.cellcomputing.himawari.library.types.CqVector3D;
import net.cellcomputing.himawari.library.types.CqVector4D;
import net.cellcomputing.himawari.parser.Parser;
import net.cellcomputing.himawari.parser.keywords.AbstractKeywordParser;
import net.cellcomputing.himawari.util.HimawariLogger;

/**
 * 
 * 
 * 
 * @author NTT DATA Corporation
 */
public strictfp class RendermanInterface {
			
//	---------------------------------------------------------------------
//	 This file contains the interface functions which are published as the
//		Renderman Interface SPECification (C) 1988 Pixar.
	//

	static CqRandom worldrand = new CqRandom();
	static HimawariLogger logger = HimawariLogger.getLogger();
//	---------------------------------------------------------------------
//	 Interface parameter token strings.
	
	public static final String 	RI_FRAMEBUFFER	= "framebuffer";
	public static final String	RI_FILE	= "file";
	public static final String	RI_RGB	= "rgb";
	public static final String	RI_RGBA	= "rgba";
	public static final String	RI_RGBZ	= "rgbz";
	public static final String	RI_RGBAZ	= "rgbaz";
	public static final String	RI_A	= "a";
	public static final String	RI_Z	= "z";
	public static final String	RI_AZ	= "az";
	public static final String	RI_MERGE	= "merge";
	public static final String	RI_ORIGIN	= "origin";
	public static final String	RI_PERSPECTIVE	= "perspective";
	public static final String	RI_ORTHOGRAPHIC	= "orthographic";
	public static final String	RI_HIDDEN	= "hidden";
	public static final String	RI_PAINT	= "paint";
	public static final String	RI_CONSTANT	= "constant";
	public static final String	RI_SMOOTH	= "smooth";
	public static final String	RI_FLATNESS	= "flatness";
	public static final String	RI_FOV	= "fov";

	public static final String	RI_AMBIENTLIGHT	= "ambientlight";
	public static final String	RI_POINTLIGHT	= "pointlight";
	public static final String	RI_DISTANTLIGHT	= "distantlight";
	public static final String	RI_SPOTLIGHT	= "spotlight";
	public static final String	RI_INTENSITY	= "intensity";
	public static final String	RI_LIGHTCOLOR	= "lightcolor";
	public static final String	RI_FROM	= "from";
	public static final String	RI_TO	= "to";
	public static final String	RI_CONEANGLE	= "coneangle";
	public static final String	RI_CONEDELTAANGLE	= "conedeltaangle";
	public static final String	RI_BEAMDISTRIBUTION	= "beamdistribution";
	public static final String	RI_MATTE	= "matte";
	public static final String	RI_METAL	= "metal";
	public static final String	RI_PLASTIC	= "plastic";
	public static final String	RI_PAINTEDPLASTIC	= "paintedplastic";
	public static final String	RI_KA	= "ka";
	public static final String	RI_KD	= "kd";
	public static final String	RI_KS	= "ks";
	public static final String	RI_ROUGHNESS	= "roughness";
	public static final String	RI_SPECULARCOLOR	= "specularcolor";
	public static final String	RI_DEPTHCUE	= "depthcue";
	public static final String	RI_FOG	= "fog";
	public static final String	RI_BUMPY	= "bumpy";
	public static final String	RI_MINDISTANCE	= "mindistance";
	public static final String	RI_MAXDISTANCE	= "maxdistance";
	public static final String	RI_BACKGROUND	= "background";
	public static final String	RI_DISTANCE	= "distance";

	public static final String	RI_RASTER	= "raster";
	public static final String	RI_SCREEN	= "screen";
	public static final String	RI_CAMERA	= "camera";
	public static final String	RI_WORLD	= "world";
	public static final String	RI_OBJECT	= "object";
	public static final String	RI_INSIDE	= "inside";
	public static final String	RI_OUTSIDE	= "outside";
	public static final String	RI_LH	= "lh";
	public static final String	RI_RH	= "rh";
	public static final String	RI_P	= "P";
	public static final String	RI_PZ	= "Pz";
	public static final String	RI_PW	= "Pw";
	public static final String	RI_N	= "N";
	public static final String	RI_NP	= "Np";
	public static final String	RI_CS	= "Cs";
	public static final String	RI_OS	= "Os";
	public static final String	RI_S	= "s";
	public static final String	RI_T	= "t";
	public static final String	RI_ST	= "st";
	public static final String	RI_BILINEAR	= "bilinear";
	public static final String	RI_BICUBIC	= "bicubic";
	public static final String	RI_CUBIC	= "cubic";
	public static final String	RI_LINEAR	= "linear";
	public static final String	RI_PRIMITIVE	= "primitive";
	public static final String	RI_INTERSECTION	= "intersection";
	public static final String	RI_UNION	= "union";
	public static final String	RI_DIFFERENCE	= "difference";
	public static final String	RI_WRAP	= "wrap";
	public static final String	RI_NOWRAP	= "nowrap";
	public static final String	RI_PERIODIC	= "periodic";
	public static final String	RI_NONPERIODIC	= "nonperiodic";
	public static final String	RI_CLAMP	= "clamp";
	public static final String	RI_BLACK	= "black";
	public static final String	RI_IGNORE	= "ignore";
	public static final String	RI_PRINT	= "print";
	public static final String	RI_ABORT	= "abort";
	public static final String	RI_HANDLER	= "handler";
	public static final String	RI_IDENTIFIER	= "identifier";
	public static final String	RI_NAME	= "name";
	public static final String	RI_CURRENT	= "current";
	public static final String	RI_SHADER	= "shader";
	public static final String	RI_EYE	= "eye";
	public static final String	RI_NDC	= "ndc";
	public static final String	RI_AMPLITUDE	=	"amplitude";
	public static final String	RI_COMMENT	=	"comment";
	public static final String	RI_CONSTANTWIDTH	=	"constantwidth";
	public static final String	RI_KR	=	"kr";
	public static final String	RI_SHINYMETAL	=	"shinymetal";
	public static final String	RI_STRUCTURE	=	"structure";
	public static final String	RI_TEXTURENAME	=	"texturename";
	public static final String	RI_VERBATIM	=	"verbatim";
	public static final String	RI_WIDTH	=	"width";
	
	public static final float RiBezierBasis[][] = {
			{ -1,  3, -3,  1 },
	        {  3, -6,  3,  0 },
	        { -3,  3,  0,  0 },
	        {  1,  0,  0,  0 }
        };
	public static final float RiBSplineBasis[][] = {
			{ -1f / 6f,  3f / 6f, -3f / 6f,  1f / 6f },
	        {  3f / 6f, -6f / 6f,  3f / 6f,  0f / 6f },
	        { -3f / 6f,  0f / 6f,  3f / 6f,  0f / 6f },
	        {  1f / 6f,  4f / 6f,  1f / 6f,  0f / 6f } 
        };
	public static final float RiCatmullRomBasis[][] = { 
			{ -1f / 2f,  3f / 2f, -3f / 2f,  1 / 2f },
	        {  2f / 2f, -5f / 2f,  4f / 2f, -1 / 2f },
	        { -1f / 2f,  0f / 2f,  1f / 2f,  0 / 2f },
	        {  0f / 2f,  2f / 2f,  0f / 2f,  0 / 2f } 
        };
//	public static final float RiHermiteBasis[][] = {
//			{  2,  1, -2,  1 },
//	        { -3, -2,  3, -1 },
//	        {  0,  1,  0,  0 },
//	        {  1,  0,  0,  0 }
//		};
	public static final float RiHermiteBasis[][] = {
		//Aqsisオリジナル
        {  2,  1, -2,  1 },
        { -3, -2,  3, -1 },
        {  0,  1,  0,  0 },
        {  1,  0,  0,  0 }
		//サイトに載っていたHermite
//        {  2, -2,  1,  1 },
//        { -3,  3, -2, -1 },
//        {  0,  0,  1,  0 },
//        {  1,  0,  0,  0 }
		//↑の転置行列
//        {  2, -3, 0, 1 },
//        { -2,  3, 0, 0 },
//        {  1, -2, 1, 0 },
//        {  1, -1, 0, 0 }
		//オリジナルの転置
//		{  2, -3, 0, 1 },
//        {  1, -2, 1, 0 },
//        { -2,  3, 0, 0 },
//        {  1, -1, 0, 0 }

	};
	public static final float RiPowerBasis[][]	= {
			{1, 0, 0, 0},
	        {0, 1, 0, 0},
	        {0, 0, 1, 0},
	        {0, 0, 0, 1}
        };

	public static long RIH_S = RI_S.hashCode();
	public static long RIH_T = RI_T.hashCode();
	public static long RIH_ST = RI_ST.hashCode();
	public static long RIH_CS = RI_CS.hashCode();
	public static long RIH_OS = RI_OS.hashCode();
	public static long RIH_P = RI_P.hashCode();
	public static long RIH_PZ = RI_PZ.hashCode();
	public static long RIH_PW = RI_PW.hashCode();
	public static long RIH_N = RI_N.hashCode();
	public static long RIH_NP = RI_NP.hashCode();
	public static long RIH_DEPTHFILTER = "depthfilter".hashCode();
	public static long RIH_JITTER = "jitter".hashCode();
	public static long RIH_RENDER = "render".hashCode();
	public static long RIH_INDIRECT = "indirect".hashCode();
	public static long RIH_LIGHT = "light".hashCode();
	public static long RIH_VISIBILITY = "visibility".hashCode();

	public static int	RiLastError = 0;


//	----------------------------------------------------------------------
//	 CreateGPrim
//	 Helper function to build a GPrim from any boost::shared_ptr<> type..
//	
//	public static <T> void CreateGPrim( final T pSurface )
//	{
//	    CreateGPrim( boost::static_pointer_cast<CqBasicSurface,T>( pSurface ) );
//	}

//	----------------------------------------------------------------------
//	 BuildParameterList
//	 Helper function to build a parameter list to pass on to the V style functions.
//	 Vスタイル機能を通るためにパラメータ・リストを造る機能を助けます。
//	 returns a parameter count.

	public static int BuildParameterList( Object[] pArgs, STLVector<String> aTokens, STLVector<Object> aValues )
	{
		 int count = 0;
		 aTokens.clear();
		 aValues.clear();
	    
		 if(pArgs != null)
		 {
			 while( count < (pArgs.length / 2 ))
			 {
				 aTokens.add((String)pArgs[2 * count]);
				 aValues.add(pArgs[2 * count + 1]);
				 count++;
			 }
		 }
	    return ( count );
	}
//	----------------------------------------------------------------------
//	 ValidateState
//	 Check that the currect graphics state is one of those specified.
//	 現在のグラフィックスがそれらの指定の1つであると述べるチェックする。
	
	public static boolean	ValidateState(int count, int... STATE)
	{

		int currentState = Outside;
		if(  QGetRenderContext() != null && QGetRenderContext().pconCurrent() != null)
			currentState = QGetRenderContext().pconCurrent().Type().getValue();

		int i;
		for(i=0; i<count; i++)
		{
			//int state = va_arg( pArgs, int );
			int state = STATE[i];
			if( currentState == state )
				return(true);
		}
		return(false);
	}


//	----------------------------------------------------------------------
//	 GetStateAsString
//	 Get a string representing the current state.
//	 現状のstringを表示させてください。
	//
	public final static  String	GetStateAsString()
	{
		int currentState = Outside;
		if( QGetRenderContext() != null && QGetRenderContext().pconCurrent() != null)//条件がこの順番でないといけません。
			currentState = QGetRenderContext().pconCurrent().Type().getValue();
		switch( currentState )
		{
			case Outside:
				return("Outside");
//				break;

			case BeginEnd:
				return("BeginEnd");
//				break;

			case Frame:
				return("Frame");
//				break;

			case World:
				return("World");
//				break;

			case Attribute:
				return("Attribute");
//				break;

			case Transform:
				return("Transform");
//				break;

			case Solid:
				return("Solid");
//				break;

			case Object:
				return("Object");
//				break;

			case Motion:
				return("Motion");
//				break;
		}
		return("");
	}	
	

//	----------------------------------------------------------------------
//	 RiDeclare
//	 Declare a new variable to be recognised by the system.
//	 新しい変数がシステムによって認識されると宣言してください。
	//
	public static String RiDeclare( String name, String declaration )
	{

		if(name == null || declaration == null) return null;// Aqsisにないが、危険だから追加。意味は変わらず
		
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
			QGetRenderContext().pCurrentObject().AddCacheCommand( 
					new RiDeclareCache(name, declaration) ); 
			return null;
		}

//		Validate_RiDeclare
		if(!ValidateState(9, Outside, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiDeclare [" + GetStateAsString() + "]\n");
			return null;
		}

	    String strName = name ;
	    String strDecl =  declaration ;
	    QGetRenderContext().AddParameterDecl( strName, strDecl );
	    return ( null );
	}


//	----------------------------------------------------------------------
//	 SetDefaultRiOptions
//	 Set some Default Options.
//	 いくつかのDefault Optionsを設定してください。
	//
	public static void SetDefaultRiOptions()
	{
		    String g_shader_path ;
		    String g_archive_path ;
		    String g_texture_path ;
		    String g_display_path ;
		    String g_dso_path ;
		    String g_procedural_path ;
		    String g_plugin_path ;
	
		    String acPath ;
		    String rootPath ;
		    
		    File tmp = new File( "." );
		    acPath = tmp.getAbsoluteFile().getParentFile().getPath(); 
		    rootPath = acPath.substring(0, acPath.lastIndexOf("\\")+1 );
		    
		    g_shader_path = rootPath;
		    g_archive_path = rootPath;
		    g_texture_path = rootPath;
		    g_display_path = rootPath;
		    g_dso_path = rootPath;
		    g_procedural_path = rootPath;
		    g_plugin_path = rootPath;
	
		    g_shader_path = g_shader_path.concat( "shaders" );
		    g_archive_path = g_archive_path.concat( "archives" );
		    g_texture_path = g_texture_path.concat( "textures" );
		    g_display_path = g_display_path.concat( "bin" );
		    g_dso_path = g_dso_path.concat( "dsos" );
		    g_procedural_path = g_procedural_path.concat( "procedures" );
		    g_plugin_path = g_plugin_path.concat( "plugins" );
		
	
		    // Apply environment-variable overrides to default paths ...
		    p_String[] popt = new p_String[1];//パラメータで処理する関係でp_String
		    popt[0] = new p_String();
		    String[] pOption;
	
		    pOption = QGetRenderContext().optCurrent().GetStringOption( "searchpath", "shader" );
		    if ( pOption == null ){
		        // If the calling application has not already set a shader path then we provide one here.
		        if( System.getenv("HIMAWARI_SHADER_PATH") != null){
		            popt[0].value = System.getenv("HIMAWARI_SHADER_PATH");
		        }else{
		        	popt[0].value = g_shader_path;
		        };
		        RiOption( "searchpath" ,"shader", popt, null );
		    } ;
	
		    pOption = QGetRenderContext() .optCurrent().GetStringOption( "searchpath", "archive" );
		    if ( pOption == null ){
		        // If the calling application has not already set a shader path then we provide one here.
		        if( System.getenv("HIMAWARI_ARCHIVE_PATH") != null ){
		        	popt[0].value = System.getenv("HIMAWARI_ARCHIVE_PATH");
		        }else{
		        	popt[0].value = g_archive_path;
		        };
		        RiOption( "searchpath", "archive", popt, null );
		    } ;
	
		    pOption = QGetRenderContext() .optCurrent().GetStringOption( "searchpath", "texture" );
		    if ( pOption == null ){
		        // If the calling application has not already set a shader path then we provide one here.
		        if( System.getenv("HIMAWARI_TEXTURE_PATH") != null ){
		        	popt[0].value = System.getenv("HIMAWARI_TEXTURE_PATH");
		        }else{
		        	popt[0].value = g_texture_path;
		        };
		        RiOption( "searchpath", "texture", popt, null );
		    } ;
	
		    pOption = QGetRenderContext() .optCurrent().GetStringOption( "searchpath", "display" );
		    if ( pOption == null ){
		        // If the calling application has not already set a shader path then we provide one here.
		        if(System.getenv("HIMAWARI_DISPLAY_PATH") != null){
		        	popt[0].value = System.getenv("HIMAWARI_DISPLAY_PATH");
		        }else{
		        	popt[0].value = g_display_path;
		        };
		        RiOption( "searchpath", "display", popt, null );
		    } ;
	
		    pOption = QGetRenderContext() .optCurrent().GetStringOption( "searchpath", "dsolibs" );
		    if ( pOption == null ){
		        // If the calling application has not already set a shader path then we provide one here.
		        if( System.getenv("HIMAWARI_DSO_PATH" ) != null ){
		        	popt[0].value = System.getenv("HIMAWARI_DSO_PATH");
		        }else{
		        	popt[0].value = g_dso_path;
		        };
		        RiOption( "searchpath", "dsolibs", popt, null );
		    } ;
	
	
		    pOption = QGetRenderContext() .optCurrent().GetStringOption( "searchpath", "procedural" );
		    if ( pOption == null ){
		        // If the calling application has not already set a shader path then we provide one here.
		        if( System.getenv("HIMAWARI_PROCEDURAL_PATH") != null ){
		        	popt[0].value = System.getenv("HIMAWARI_PROCEDURAL_PATH");
		        }else{
		        	popt[0].value = g_procedural_path;
		        };
		        RiOption( "searchpath", "procedural", popt, null );
		    } ;
	
		    pOption = QGetRenderContext() .optCurrent().GetStringOption( "searchpath", "plugin" );
		    if ( pOption == null ){
		        // If the calling application has not already set a shader path then we provide one here.
		        if( System.getenv("HIMAWARI_PLUGIN_PATH") != null){
		        	popt[0].value = System.getenv("HIMAWARI_PLUGIN_PATH");
		        }else{
		        	popt[0].value = g_plugin_path;
		        };
		        RiOption( "searchpath", "plugin", popt, null );
		    } ;
	
		    // Setup a default Displac
		    RiDisplay( "ri.pic", "file", "rgba", (Object)null );
}

//	----------------------------------------------------------------------
//	 RiBegin
//	 Begin a Renderman render phase.
//	 レンダーマンフェーズを始めます。
//	extern "C" char *StandardParameters[][2];
	public static String[][] StandardParameters =  
	 {
            {"Ka", "uniform float" },
            {"Kd", "uniform float" },
            {"Ks", "uniform float" },
            {"Kr", "uniform float" },
            {"roughness", "uniform float" },
            {"texturename", "uniform string" },
            {"specularcolor", "uniform color" },
            {"intensity", "uniform float" },
            {"lightcolor", "uniform color" },
            {"from", "uniform point" },
            {"to", "uniform point" },
            {"coneangle", "uniform float" },
            {"conedeltaangle", "uniform float" },
            {"beamdistribution", "uniform float" },
            {"mindistance", "uniform float" },
            {"maxdistance", "uniform float" },
            {"distance", "uniform float" },
            {"background", "uniform color" },
            {"fov", "uniform float" },
            {"P", "vertex point" },
            {"Pz", "vertex point" },
            {"Pw", "vertex hpoint" },
            {"N", "varying normal" },
            {"Ng", "varying normal" },
            {"Np", "uniform normal" },
            {"Cs", "varying color" },
            {"Os", "varying color" },
            {"s", "varying float" },
            {"t", "varying float" },
            {"st", "varying float[2]" },
            {"gridsize", "uniform integer" },
            {"texturememory", "uniform integer" },
            {"bucketsize", "uniform integer[2]" },
            {"eyesplits", "uniform integer" },
            {"shader", "uniform string" },
            {"archive", "uniform string" },
            {"texture", "uniform string" },
            {"display", "uniform string" },
            {"dsolibs", "uniform string" },
            {"plugin", "uniform string" },
            {"auto_shadows", "uniform string" },
            {"endofframe", "uniform integer" },
			{"offset", "uniform float"},
            {"renderinfo", "uniform integer" },
            {"sphere", "uniform float" },
            {"coordinatesystem", "uniform string" },
            {"shadows", "uniform string" },
            {"shadowmapsize", "uniform integer[2]" },
            {"shadowangle", "uniform float" },
            {"shadowmapname", "uniform string" },
            {"shadow_shadingrate", "uniform float" },
            {"name", "uniform string" },
            {"shadinggroup", "uniform string" },
            {"sense", "uniform string" },
            {"compression", "uniform string" },
            {"quality", "uniform integer" },
            {"bias0", "uniform float" },
            {"bias1", "uniform float" },
            {"bias", "uniform float" },
            {"jitter", "uniform integer" },
            {"depthfilter", "uniform string" },
            {"width", "varying float" },
            {"constantwidth", "constant float" },
            {"binary", "uniform integer" },
            {"procedural", "uniform string" },
            {"quantize", "uniform float[4]" },
            {"dither", "uniform float" },
            {"interpolateboundary", "uniform integer" },
            {"zthreshold", "uniform color" },
            { null , null }
        };
	
	public static void	RiBegin( String name )
	{
		
		if(!ValidateState(1, Outside) )
		{
			logger.error("Invalid state for RiBegin [" + GetStateAsString() + "]\n" );
			return;
		}

	    // Create a new renderer
		// 新しいレンダを作成する。
		QSetRenderContext( new CqRenderer() );

	    QGetRenderContext().Initialise();
	    QGetRenderContext().BeginMainModeBlock();
	    QGetRenderContext().ptransSetTime( new CqMatrix() );
	    QGetRenderContext().SetCameraTransform( QGetRenderContext().ptransCurrent() );
	    // Clear the lightsources stack.
	    //　ライトソースのスタックをクリアする。
	    Lightsource_stack.clear();

	    // Clear any options.
	    //　全てのオプションをクリアする。
	    QGetRenderContext().optCurrent().ClearOptions();

	    // Include the standard options (how can we opt out of this).
	    int param = 0;
	    while( StandardParameters[param][0] != null )
	    {
	        RiDeclare(
	            StandardParameters[param][0],
	            StandardParameters[param][1]
	        );
	        param++;
	    };

	    SetDefaultRiOptions();

	    // Setup a default surface shader
	    // デフォルトのサーフェースシェーダをセットアップする。
	    IqShader pDefaultSurfaceShader = 
	        QGetRenderContext().getDefaultSurfaceShader();
	    QGetRenderContext().pattrWriteCurrent().SetpshadSurface( pDefaultSurfaceShader, QGetRenderContext().Time() );

		// Setup the initial transformation.
	    //　最初のトランスフォーメーションをセットアップする。
		//QGetRenderContext().ptransWriteCurrent() .SetHandedness( TqFalse );
		QGetRenderContext().pattrWriteCurrent().GetIntegerAttributeWrite( "System", "Orientation" )[ 0 ].value = 0;

	    return ;
	}

//	----------------------------------------------------------------------
//	 RiEnd
//	 End the rendermam render stage.
//	 レンダーマンの　レンダーステージの最後
	//
	public static void	RiEnd()
	{
//		Validate_RiEnd
		if(!ValidateState(1, BeginEnd) )
		{
			logger.error("Invalid state for RiEnd [" + GetStateAsString() + "]\n");
//			std::cerr << "Invalid state for RiEnd [" << GetStateAsString() << "]\n" << std::endl; \
			return;
		}

	    QGetRenderContext().EndMainModeBlock();

	    // Flush the image cache.
	    CqTextureMap.FlushCache();

	    // Clear the lightsources stack.
	    Lightsource_stack.clear();

	    // Delete the renderer
//	    delete( QGetRenderContext() );
	    QGetRenderContext().destruct();
	    
	    QSetRenderContext( null );

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiFrameBegin
//	 Begin an individual frame, options are saved at this point.
//	 個々のフレームを始めてください、そして、オプションはここに保存されます。
	//
	public static void	RiFrameBegin( int number )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiFrameBeginCache(number) );
			return;
		}

		{
			if(!ValidateState(1, BeginEnd) )
			{
				logger.error("Invalid state for RiFrameBegin [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    // Initialise the statistics variables. If the RIB doesn't contain
	    // a Frame-block the initialisation was previously done in CqStats::Initilise()
	    // which has to be called before a rendering session.
	    QGetRenderContext() .Stats().InitialiseFrame();
	    // Start the timer. Note: The corresponding call of StopFrameTimer() is
	    // done in WorldEnd (!) not FrameEnd since it can happen that there is
	    // not FrameEnd (and usually there's not much between WorldEnd and FrameEnd).
	    QGetRenderContext() .Stats().StartFrameTimer();

	    QGetRenderContext() .BeginFrameModeBlock();
	    QGetRenderContext() .SetCurrentFrame( number );
	    CqCSGTreeNode.SetRequired( false );


	    worldrand.Reseed('a'+'q'+'s'+'i'+'s');

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiFrameEnd
//	 End the rendering of an individual frame, options are restored.
//	 個々のフレームの終り、そして、オプションはここに保存されます。
	//
	public static void	RiFrameEnd()
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiFrameEndCache() );
			return;
		}

		{
			if(!ValidateState(1, Frame) )
			{
				logger.error("Invalid state for RiFrameEnd [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    QGetRenderContext() .EndFrameModeBlock();
	    QGetRenderContext() .ClearDisplayRequests();

	    return ;
	}

//	----------------------------------------------------------------------
//	 RiWorldBegin
//	 Start the information for the world, options are now frozen.  The world-to-camera
//	 transformation is set to the current transformation, and current is set to identity.
//	 worldの情報を始めてください。オプションは現在は凍結します。そのワールドカメラの位置を現在の位置に設定します。
//	 そして、現在の存在を設定します。
	//

	public static void RiWorldBegin()
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiWorldBeginCache() );
			return;
		}

		{ 
			if(!ValidateState(2, BeginEnd, Frame) )
			{ 
				logger.error("Invalid state for RiWorldBegin [" + GetStateAsString() + "]\n");
				return; 
			} 
		}

	    // Call any specified pre world function.
	    if ( QGetRenderContext().pPreWorldFunction() != null )
	    {
	    	try {
				(QGetRenderContext().pPreWorldFunction()).invoke( null );
			} catch (Exception e) {
				HimawariLogger.outputException( e );
			}
	    }
	    // Start the frame timer (just in case there was no FrameBegin block. If there
	    // was, nothing happens)
	    QGetRenderContext() .Stats().StartFrameTimer();
	    QGetRenderContext() .Stats().MakeParse().Start();

	    // Now that the options have all been set, setup any undefined camera parameters.
	    if ( !QGetRenderContext() .optCurrent().FrameAspectRatioCalled() )
	    {
	        // Derive the FAR from the resolution and pixel aspect ratio.
	        float PAR = QGetRenderContext() .optCurrent().GetFloatOptionIndex( "System", "PixelAspectRatio" , 0 ).value;
	        float resH = QGetRenderContext() .optCurrent().GetIntegerOptionIndex( "System", "Resolution" , 0 ).value;
	        float resV = QGetRenderContext() .optCurrent().GetIntegerOptionIndex( "System", "Resolution" , 1 ).value;
	        QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "FrameAspectRatio" , 0 ).value = ( resH * PAR ) / resV ;
	    }

	    if ( !QGetRenderContext() .optCurrent().ScreenWindowCalled() )
	    {
	        float fFAR = QGetRenderContext() .optCurrent().GetFloatOptionIndex( "System", "FrameAspectRatio" , 0 ).value;

	        if ( fFAR >= 1.0 )
	        {
	            QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 0 ).value = -fFAR ;
	            QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 1 ).value = + fFAR ;
	            QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 2 ).value = + 1 ;
	            QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 3 ).value = -1 ;
	        }
	        else
	        {
	            QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 0 ).value = -1 ;
	            QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 1 ).value = + 1 ;
	            QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 2 ).value =(float)( + 1.0 / fFAR );
	            QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 3 ).value =(float)( -1.0 / fFAR );
	        }
	    }

	    // Set the world to camera transformation matrix to the current matrix.

	    CqTransform current = QGetRenderContext().ptransCurrent();
		CqTransform camera = new CqTransform();
	    QGetRenderContext() .SetCameraTransform( camera );
		// clear the camera transform to a single state, all camera motion is now transferred to the objects.
		QGetRenderContext().GetCameraTransform().ResetTransform( current.matObjectToWorld( current.Time(0) ), 
																   current.GetHandedness(QGetRenderContext().Time()) );
	    QGetRenderContext() .BeginWorldModeBlock();
	    // and then reset the current matrix to identity, ready for object transformations.
		if ( current.cTimes() > 1 )//多分入らないでしょう。モーションブラーの時だけ？
		{
			int i;
			CqMatrix matOpenShutterInverse = current.matObjectToWorld( current.Time( 0 ) );
			matOpenShutterInverse = matOpenShutterInverse.Inverse();
			current.SetCurrentTransform( current.Time( 0 ), new CqMatrix() );
			for ( i = 1; i < current.cTimes(); ++i )
			{
				current.SetCurrentTransform( current.Time( i ), matOpenShutterInverse.multiply( current.matObjectToWorld( current.Time( i ) ) ) );
			}
			QGetRenderContext().pconCurrent().ptransSetCurrent(current);

			// Store the initial object transformation (including imparted camera motion).
			CqTransform newTrans =  new CqTransform( current ) ;
			QGetRenderContext().SetDefObjTransform( newTrans );
		}
		else
		{
			QGetRenderContext() .ptransSetTime( new CqMatrix() );

			// Store the initial object transformation
			CqTransform newTrans = new CqTransform();
			QGetRenderContext().SetDefObjTransform( newTrans );
		}

		QGetRenderContext().SetWorldBegin();

	    QGetRenderContext() .optCurrent().InitialiseCamera();
	    QGetRenderContext() .pImage() .SetImage();

//	    worldrand.Reseed('h'+'i'+'m'+'a'+'w'+'a'+'r'+'i');//2006/03/08 nttdata 修正
	    worldrand.Reseed('a'+'q'+'s'+'i'+'s');
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiWorldEnd
//	 End the specifying of world data, options are released.
//	 ワールドデータの指定を終了します。オプションを開放します。
	//

	public static void	RiWorldEnd()
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiWorldEndCache() );
			return;
		}

		{
			if(!ValidateState(1, World) )
			{
				logger.error("Invalid state for RiWorldEnd [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    boolean fFailed = false;
	    // Call any specified pre render function.
	    if ( QGetRenderContext().pPreRenderFunction() != null )
	    {
	    	try
	    	{
	         QGetRenderContext().pPreRenderFunction().invoke(null);
	    	}
	    	catch( Exception e)
	    	{
	    		HimawariLogger.outputException( e );
	    	}
	    }
	    // Stop the parsing counter
	    QGetRenderContext() .Stats().MakeParse().Stop();


	    final int[] poptVerbose = QGetRenderContext() .optCurrent().GetIntegerOption( "statistics", "renderinfo" );
	    if ( poptVerbose != null )
	    {
	        QGetRenderContext() . Stats().PrintInfo();
	    }

	    final int[] poptGridSize = QGetRenderContext() .optCurrent().GetIntegerOption( "limits", "gridsize" );
	    if( null != poptGridSize ){
	    	if(poptGridSize[0] <= 0){
	    		HimawariLogger.getLogger().warning("WARNING: BucketSize under 0 cast to 256\n");
	    		poptGridSize[0] = 256;
	    	}
	    	///--
	        QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "SqrtGridSize" , 0 ).value = (float)Math.sqrt( poptGridSize[0] );
	    }
		// Finalise the raytracer database now that all primitives are in.
		if( QGetRenderContext().pRaytracer() != null )
			QGetRenderContext().pRaytracer().Finalise();

	    // Render the world
	    try
	    {
	        QGetRenderContext().RenderWorld();
	    }
	    catch ( Exception e )
	    {
	    	HimawariLogger.outputException( e );
	    	logger.error( e.toString() );
	        fFailed = true;
	    }

	    // Delete the world context
	    QGetRenderContext() .EndWorldModeBlock();

	    // Stop the frame timer
	    QGetRenderContext() .Stats().StopFrameTimer();

	    if ( !fFailed )
	    {
	        // Get the verbosity level from the options...
	        int verbosity = 0;
	        final int[] poptEndofframe = QGetRenderContext() .optCurrent().GetIntegerOption( "statistics", "endofframe" );
	        if ( poptEndofframe != null )
	            verbosity = poptEndofframe[ 0 ];

	        // ...and print the statistics.
	        QGetRenderContext() .Stats().PrintStats( verbosity );
	    }

		QGetRenderContext().SetWorldBegin(false);

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiFormat
//	 Specify the setup of the final image.
//	 最終的なイメージをセットアップして指定する。
	//
	public static void	RiFormat( int xresolution, int yresolution, float pixelaspectratio )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiFormatCache(xresolution, yresolution, pixelaspectratio) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiFormat [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    QGetRenderContext() .optCurrent().GetIntegerOptionWriteIndex( "System", "Resolution" , 0 ).value = xresolution ;
	    QGetRenderContext() .optCurrent().GetIntegerOptionWriteIndex( "System", "Resolution" , 1 ).value = yresolution ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "PixelAspectRatio" , 0 ).value = (float) (( pixelaspectratio < 0.0 ) ? 1.0 : pixelaspectratio) ;

	    // Inform the system that RiFormat has been called, as this takes priority.
	    QGetRenderContext() .optCurrent().CallFormat();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiFrameAspectRatio
//	 Set the aspect ratio of the frame irrespective of the display setup.
//	 フレームの画面の比をディスプレイの設定に関わらずに設定してください。
	//
	public static void	RiFrameAspectRatio( float frameratio )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiFrameAspectRatioCache(frameratio) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiFrameAspectRatio [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    CqLogRangeCheckCallback rc = new CqLogRangeCheckCallback();

	    boolean valid = true;

	    rc.set( "frameratio");
	    if( !CheckMinMax( frameratio, 0.0f, RI_INFINITY, rc ) )
	    {
	        valid = false;
	    }

	    if( !valid )
	    {
	    	logger.error( "RiFrameAspectRatio: Invalid RiFrameAspectRatio, aborting\n" );
	        return;
	    }

	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "FrameAspectRatio" , 0 ).value = frameratio ;

	    // Inform the system that RiFrameAspectRatio has been called, as this takes priority.
	    QGetRenderContext() .optCurrent().CallFrameAspectRatio();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiScreenWindow
//	 Set the resolution of the screen window in the image plane specified in the screen
//	 coordinate system.
//	 スクリーン座標系で指定された画像平面における、スクリーンの窓の解決を設定してください。
	//
	//

	public static void	RiScreenWindow( float left, float right, float bottom, float top )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiScreenWindowCache(left, right, bottom, top) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiScreenWindow [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 0 ).value = left ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 1 ).value = right ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 2 ).value = top ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "ScreenWindow" , 3 ).value = bottom ;

	    // Inform the system that RiScreenWindow has been called, as this takes priority.
	    QGetRenderContext() .optCurrent().CallScreenWindow();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiCropWindow
//	 Set the position and size of the crop window specified in fractions of the raster
//	 window.
//	 ラスタウィンドウの部分で指定されたクロップウィンドウの位置とサイズを設定してください。
	//
	public static void	RiCropWindow( float left, float right, float top, float bottom )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiCropWindowCache(left, right, top, bottom) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiCropWindow [" + GetStateAsString() + "]\n");
				return;
			}
		}


	    CqLogRangeCheckCallback rc = new CqLogRangeCheckCallback();

	    boolean valid = true;

	    rc.set( "left");
	    if( !CheckMinMax( left, 0.0f, 1.0f, rc ) )
	    {
	        valid = false;
	    }

	    rc.set( "right" );
	    if( !CheckMinMax( right, 0.0f, 1.0f, rc ) )
	    {
	        valid = false;
	    }

	    rc.set( "top" );
	    if( !CheckMinMax( top, 0.0f, 1.0f, rc ) )
	    {
	        valid = false;
	    }

	    rc.set( "bottom" );
	    if( !CheckMinMax( bottom, 0.0f, 1.0f, rc ) )
	    {
	        valid = false;
	    }

	    if( !valid )
	    {
	    	logger.error("Invalid RiCropWindow, aborting \n");
	        return;
	    }
	    
	    // Check width > 0 and height > 0. If we found error, convert 0-1. 
	    if( left >= right ){
	    	logger.error("Invalid Value for left. Value exceeded upper right \n");
	    	left = 0f;
	    	right = 1f;
	    }
	    if( top >= bottom ){
	    	logger.error("Invalid Value for top. Value exceeded upper bottom \n");
	    	top = 0f;
	    	bottom = 1f;
	    }

	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "CropWindow" , 0 ).value = left ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "CropWindow" , 1 ).value = right ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "CropWindow" , 2 ).value = top ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "CropWindow" , 3 ).value = bottom ;

	    return ;
	}


	
//	----------------------------------------------------------------------
//	 RiProjection
//	 Set the camera projection to be used.
//	 カメラ映像に使用されるように設定してください。
	//
	public static void	RiProjection( String name, Object... pArgs)
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiProjectionV( name, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiProjectionV
//	 List mode version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiProjectionV( String name, int count, String[] tokens, Object[] values )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiProjectionCache(name, count, tokens, values) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiProjection [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    if ( name.compareTo( RI_PERSPECTIVE ) == 0 )
	        QGetRenderContext() .optCurrent().GetIntegerOptionWriteIndex( "System", "Projection" , 0 ).value = ProjectionPerspective ;
	    else if	( name.compareTo( RI_ORTHOGRAPHIC ) == 0 )
	        QGetRenderContext() .optCurrent().GetIntegerOptionWriteIndex( "System", "Projection" , 0 ).value = ProjectionOrthographic ;
	    else if( name != RI_NULL )
	    {
			logger.error("RiProjection: Invalid projection: \"" + name + "\"\n");
	        return ;
	    }

	    int i;
	    for ( i = 0; i < count; ++i )
	    {
	        String	token = tokens[ i ];
	        Object	value = values[ i ];

	        if ( token.compareTo( RI_FOV ) == 0 )
	        		QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "FOV" , 0 ).value = (( p_float[] )value )[0].value ;
	    }
	    // TODO: need to get the current transformation so that it can be added to the screen transformation.
	    QGetRenderContext().ptransSetTime( new CqMatrix() );

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiClipping
//	 Set the near and far clipping planes specified as distances from the camera.
//	 距離としてカメラから指定された近くて遠いクリッピング面を設定してください。
	//
	public static void	RiClipping( float cnear, float cfar )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiClippingCache(cnear, cfar) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiClipping [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    CqLogRangeCheckCallback rc = new CqLogRangeCheckCallback();

	    boolean valid = true;

	    rc.set( "near");
	    if( !CheckMinMax( cnear, RI_EPSILON, cfar, rc ) )
	    {
	        valid = false;
	    }

	    rc.set( "far" );
	    if( !CheckMinMax( cfar, cnear, RI_INFINITY, rc ) )
	    {
	        valid = false;
	    }

	    if( !valid )
	    {
	    	logger.error("RiClipping: Invalid RiClipping, clipping planes set to RI_EPSILON, RI_INFINITY\n");
	    	
	        cnear	= RI_EPSILON;
	        cfar	= RI_INFINITY;
	    }

	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "Clipping" , 0 ).value = cnear ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "Clipping" , 1 ).value = cfar ;

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiDepthOfField
//	 Specify the parameters which affect focal blur of the camera.
//	 カメラの焦点のぼやけに影響するパラメタを指定してください。
	//
	public static void	RiDepthOfField( float fstop, float focallength, float focaldistance )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiDepthOfFieldCache(fstop, focallength, focaldistance) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiDepthOfField [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    CqLogRangeCheckCallback rc = new CqLogRangeCheckCallback();

	    boolean valid = true;

	    rc.set( "fstop" );
	    if( !CheckMinMax( fstop, 0.0f, RI_INFINITY, rc ) )
	    {
	        valid = false;
	    }

	    rc.set( "focallength" );
	    if( !CheckMinMax( focallength, 0.0f, RI_INFINITY, rc ) )
	    {
	        valid = false;
	    }

	    rc.set( "focaldistance" );
	    if( !CheckMinMax( focaldistance, 0.0f, RI_INFINITY, rc ) )
	    {
	        valid = false;
	    }

	    if( !valid )
	    {
	    	logger.warning("RiDepthOfField: Invalid DepthOfField, DepthOfField ignored\n");
	        return;
	    }

	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "DepthOfField" , 0 ).value = fstop ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "DepthOfField" , 1 ).value = focallength ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "DepthOfField" , 2 ).value = focaldistance ;

	    QGetRenderContext() .SetDepthOfFieldData( fstop, focallength, focaldistance );
	}


//	----------------------------------------------------------------------
//	 RiShutter
//		Set the times at which the shutter opens and closes, used for motion blur.
//	  シャッターが開く回とモーションブラーに使用される閉鎖を設定してください。
	//
	public static void	RiShutter( float opentime, float closetime )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiShutterCache(opentime, closetime) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiShutter [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "Shutter" , 0 ).value = opentime;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "Shutter" , 1 ).value = closetime;

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiPixelVariance
//	 Set the upper bound on the variance from the true pixel color by the pixel filter
//	 function.
	//
	public static void	RiPixelVariance( float variance )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiPixelVarianceCache(variance) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiPixelVariance [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    CqLogRangeCheckCallback rc = new CqLogRangeCheckCallback();

	    boolean valid = true;

	    rc.set( "variance" );
	    if( !CheckMinMax( variance, 0.0f, RI_INFINITY, rc ) )
	    {
	        valid = false;
	    }

	    if( !valid )
	    {
	    	logger.warning("RiPixelVariance: Invalid PixelVariance, PixelVariance set to 0\n");
	        variance = 0;
	    }

	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "PixelVariance" , 0 ).value = variance ;

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiPixelSamples
//	 Set the number of samples per pixel for the hidden surface function.
//	 隠された表面機能に1画素あたりのサンプルの数を設定してください。
	//
	public static void	RiPixelSamples( float xsamples, float ysamples )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiPixelSamplesCache(xsamples, ysamples) ); 
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiPixelSamples [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    CqLogRangeCheckCallback rc = new CqLogRangeCheckCallback();

	    boolean valid = true;

	    rc.set( "xsamples" );
	    //Aqsisからの仕様変更Sampleの数を大きくしてしまうとメモリーエラーが出るので1000でストップします。
	    //if( !CheckMinMax( xsamples, 1.0f, RI_INFINITY, rc ) )
	    if( !CheckMinMax( xsamples, 1.0f, 1000.0f, rc ) )
	    {
	        valid = false;
	    }

	    rc.set( "ysamples" );
	    //Aqsisからの仕様変更Sampleの数を大きくしてしまうとメモリーエラーが出るので1000でストップします。
	    //if( !CheckMinMax( ysamples, 1.0f, RI_INFINITY, rc ) )
	    if( !CheckMinMax( ysamples, 1.0f, 1000.0f, rc ) )
	    {
	        valid = false;
	    }

	    if( !valid )
	    {
	    	logger.warning("RiPixelSamples: Invalid PixelSamples, PixelSamples set to 1, 1\n");
	        xsamples = 1;
	        ysamples = 1;
	    }

	    QGetRenderContext() .optCurrent().GetIntegerOptionWriteIndex( "System", "PixelSamples" , 0 ).value = (int)( xsamples ) ;
	    QGetRenderContext() .optCurrent().GetIntegerOptionWriteIndex( "System", "PixelSamples" , 1 ).value = (int)( ysamples ) ;

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiPixelFilter
//	 Set the function used to generate a final pixel value from supersampled values.
//	 「スーパー-標本抽出」の値から最終的なピクセル値を発生させるのに使用される機能を設定してください。
	//
	public static void	RiPixelFilter( Method function, float xwidth, float ywidth )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiPixelFilterCache(function, xwidth, ywidth) );
			return;	
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiPixelFilter [" + GetStateAsString() + "]\n");
				return;
			}
		}
		
		 CqLogRangeCheckCallback rc = new CqLogRangeCheckCallback();

		boolean valid = true;

	    rc.set( "xwidth" );
	    //Aqsisからの仕様変更Sampleの数を大きくしてしまうとメモリーエラーが出るので1000でストップします。
	    //if( !CheckMinMax( xsamples, 1.0f, RI_INFINITY, rc ) )
	    if( !CheckMinMax( xwidth, 1.0f, 1000.0f, rc ) )
	    {
	        valid = false;
	    }

	    rc.set( "ywidth" );
	    //Aqsisからの仕様変更Sampleの数を大きくしてしまうとメモリーエラーが出るので1000でストップします。
	    //if( !CheckMinMax( ysamples, 1.0f, RI_INFINITY, rc ) )
	    if( !CheckMinMax( ywidth, 1.0f, 1000.0f, rc ) )
	    {
	        valid = false;
	    }

	    if( !valid )
	    {
	    	logger.warning("RiPixelFilter: Invalid RiPixelFilter, RiPixelFilter set to 1, 1\n");
	    	xwidth = 1;
	        ywidth = 1;
	    }
		
		
	    QGetRenderContext() .optCurrent().SetfuncFilter( function );
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "FilterWidth" , 0 ).value = xwidth ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "FilterWidth" , 1 ).value = ywidth ;

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiExposure
//		Set the values of the exposure color modification function.
//	  露出色の値を変更し設定する機能
	//
	public static void	RiExposure( float gain, float gamma )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiExposureCache(gain, gamma) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiExposure [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "Exposure" , 0 ).value = gain ;
	    QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "Exposure" , 1 ).value = gamma ;

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiImager
//	 Specify a prepocessing imager shader.
//	 prepocessingイメージシェーダを指定する。
	//
	public static void	RiImager( String name, Object... pArgs)
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiImagerV( name, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiImagerV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiImagerV( String name, int count, String tokens[], Object values[]
 )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiImagerCache(name, count, tokens, values) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiImager [" + GetStateAsString() + "]\n");
				return; 
			}
		}

	    int i;

	    if ( name.length() != 0 )
	    {
	        QGetRenderContext() .optCurrent().GetStringOptionWriteIndex( "System", "Imager" , 0 ).value = name ;
	        QGetRenderContext() .optCurrent().LoadImager( name );
	        for ( i = 0; i < count; ++i )
	        {
	            String	token = tokens[ i ];
	            Object	value = values[ i ];

	            QGetRenderContext() .optCurrent().SetValueImager( token, value );
	        }
	    }
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiQuantize
//	 Specify the color quantization parameters.
//	 色の量子化パラメタを指定してください。
	//
	public static void	RiQuantize( String type, int one, int min, int max, float ditheramplitude )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiQuantizeCache(type, one, min, max, ditheramplitude) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiQuantize [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    if ( type.compareTo( "rgba" ) == 0 )
	    {
	        p_float[] pColorQuantize = QGetRenderContext() .optCurrent().GetFloatOptionWrite( "Quantize", "Color" );
	        pColorQuantize [ 0 ].value = (float)( one );
	        pColorQuantize [ 1 ].value = (float)( min );
	        pColorQuantize [ 2 ].value = (float)( max );
	        pColorQuantize [ 3 ].value = (float)( ditheramplitude );
	    }
	    else if (  type.compareTo( "z" ) == 0 )
	    {
	        p_float[] pDepthQuantize = QGetRenderContext() .optCurrent().GetFloatOptionWrite( "Quantize", "Depth" );
	        pDepthQuantize [ 0 ].value = (float)( one );
	        pDepthQuantize [ 1 ].value = (float)( min );
	        pDepthQuantize [ 2 ].value = (float)( max );
	        pDepthQuantize [ 3 ].value = (float)( ditheramplitude );
	    }
	    else
	    {
	        CqNamedParameterList pOption = QGetRenderContext() .optCurrent().pOptionWrite( "Quantize" );
	        if( pOption != null )
	        {
	            CqParameterTypedUniformArray<p_float,p_float> pQuant = new CqParameterTypedUniformArray<p_float,p_float>(type,4,new EqVariableType(type_float),p_float.class,p_float.class);
	            pQuant.pValue_get( 0,0).value = (float)( one );
	            pQuant.pValue_get( 0,1).value = (float)( min );
	            pQuant.pValue_get( 0,2).value = (float)( max );
	            pQuant.pValue_get( 0,3).value = (float)( ditheramplitude );
	            pOption.AddParameter( pQuant );
	        }
	    }

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiDisplay
//	 Set the final output name and type.
//	 最後に出力されるアウトプットの名前とタイプを指定する。
	//
	public static void	RiDisplay( String name, String type, String mode, Object... pArgs)
	{
	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiDisplayV( name, type, mode, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiDisplayV
//	 List based version of above.
	//
	public static void	RiDisplayV( String name, String type, String mode, int count, String[] tokens, Object[] values )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiDisplayCache(name, type, mode, count, tokens, values) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiDisplay [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    String strName = name ;
	    String strType =  type ;

	    //nttdata 高速化
//	    QGetRenderContext() .optCurrent().GetStringOptionWrite( "System", "DisplayName" ) [ 0 ].value = strName ;
//	    QGetRenderContext() .optCurrent().GetStringOptionWrite( "System", "DisplayType" ) [ 0 ].value = strType ;
	    QGetRenderContext() .optCurrent().GetStringOptionWriteIndex( "System", "DisplayName" , 0 ).value = strName ;
	    QGetRenderContext() .optCurrent().GetStringOptionWriteIndex( "System", "DisplayType" , 0 ).value = strType ;
	    
	    // Append the display mode to the current setting.
	    int eValue = 0;
	    int index = 0;
	    int dataOffset = 0;
	    int dataSize = 0;
	    if( index < mode.length() && mode.startsWith(RI_RGB, index) )
	    {
	        eValue |= ModeRGB;
	        dataSize += 3;
	        index += RI_RGB.length();
	    }
	    if( index < mode.length() && mode.startsWith(RI_A, index) )
	    {
	        eValue |= ModeA;
	        dataSize += 1;
	        index += RI_A.length();
	    }
	    if( index < mode.length() && mode.startsWith(RI_Z, index))
	    {
	        eValue |= ModeZ;
	        dataSize += 1;
	        index += RI_Z.length();
	    }

	    // If none of the standard "rgbaz" strings match, then it is an alternative 'arbitrary output variable'
	    if( eValue == 0 )
	    {
	        try {
				dataOffset = QGetRenderContext().RegisterOutputData( mode );
			} catch (XqException e) {
				HimawariLogger.outputException( e );
			}
	        dataSize = QGetRenderContext().OutputDataSamples( mode );
	    }

	    // Gather the additional arguments into a map to pass through to the manager.
	    HashMap<String, Object> mapOfArguments = new HashMap<String, Object>();
	    int i;
	    for( i = 0; i < count; ++i )
	    {
	        mapOfArguments.put( tokens[ i ] , values[ i ] );
	    }
	    // Check if the request is to add a display driver.
	    //--nttdata追加 アルファベットと数字、-_.以外ははじく 2005/11/30 + (/,\,:) 2006/03/16 nttdata add
		if(!strName.matches("\\+?[A-Za-z0-9\\.\\-_ :\\/\\\\]+")){
			HimawariLogger.getLogger().warning("Invalid Display name:\""+ strName  +"\".\n" );
			return;
		}
		
	    if ( strName.charAt(0) == '+' )
	    {
	        int iMode = QGetRenderContext() .optCurrent().GetIntegerOptionIndex( "System", "DisplayMode" , 0 ).value | eValue;
	        QGetRenderContext() .optCurrent().GetIntegerOptionWriteIndex( "System", "DisplayMode" , 0 ).value = iMode;
	        strName = strName.substring( 1 );
	    }
	    else
	    {
	        QGetRenderContext() .ClearDisplayRequests();
	        QGetRenderContext() .optCurrent().GetIntegerOptionWriteIndex( "System", "DisplayMode", 0 ).value = eValue ;
	    }
	    // Add a display driver to the list of requested drivers.
	    QGetRenderContext() .AddDisplayRequest( strName, strType, mode, eValue, dataOffset, dataSize, mapOfArguments );

	    return ;
	}

//	----------------------------------------------------------------------
//	 RiGaussianFilter
//	 Gaussian filter used as a possible value passed to RiPixelFilter.
//	 ガウシアンフィルターはRiPixelFilterを通過できる値を使用する。
	//
	public static float	RiGaussianFilter( float x, float y, float xwidth, float ywidth )
	{
	    /*
	     *  d = distance from origin
	     *  w = filterwidth ([COOK84a] article used 1.5)
	     *      For here use sqrt( (xwidth/2)*(xwidth/2) + (ywidth/2)*(ywidth/2) ).
	     *      Simplifying:
	     *
	     *          w = sqrt( (xwidth*xwidth)/2 + (ywidth*ywidth)/2 )
	     *          w = sqrt( (xwidth*xwidth + ywidth*ywidth)/2 )
	     *        w*w = (xwidth*xwidth + ywidth*ywidth)/2
	     *
	     *  if (d < filterwidth) then 0
	     *  else  exp(-d*d) - exp(-w*w)
	     *
	     */ 
	    //float d,d2,w,w2;
	    //
	    ///* d = sqrt(x*x+y*y), d*d = (x*x+y*y)  */
	    //d2 = (x*x+y*y);
	    //d = sqrt(d2);
	    //
	    //w2 = 0.5*(xwidth*xwidth + ywidth*ywidth);
	    //w = sqrt(w2);
	    //
	    //if(d>w)
	    //	return(0.0);
	    //else
	    //	return(exp(-d2) - exp(-w2));

	    // The above version falls faster than the one used by the 3.2 spec
	    //   PRMan and RenderDotC.  Since all three match exactly, might as
	    //   well change to the code below:
	    x *= 2.0 / xwidth;
	    y *= 2.0 / ywidth;

	    return (float)Math.exp( -2.0 * ( x * x + y * y ) );
	}


//	----------------------------------------------------------------------
//	 RiBoxFilter
//	 Box filter used as a possible value passed to RiPixelFIlter.
//	 boxのフィルタはRiPixelFIlterを通ることができる値を使用しました。
	//
	public static float	RiBoxFilter( float x, float y, float xwidth, float ywidth )
	{
	    /* [UPST89] -- (RC p. 178) says that x and y will be in the
	     *    following intervals:
	     *           -xwidth/2 <= x <= xwidth/2
	     *           -ywidth/2 <= y <= ywidth/2
	     *    These constraints on x and y really simplifies the
	     *       the following code to just return (1.0).  
	     *
	     */
	    return (float)Math.min( ( Math.abs( x ) <= xwidth / 2.0 ? 1.0 : 0.0 ),
	                ( Math.abs( y ) <= ywidth / 2.0 ? 1.0 : 0.0 ) );
	}


//	----------------------------------------------------------------------
//	 RiTriangleFilter
//	 Triangle filter used as a possible value passed to RiPixelFilter
//	 Triangle filter はRiPixelFilterを通過する可能な値を使用する。
	//
	public static float	RiTriangleFilter( float x, float y, float xwidth, float ywidth )
	{
	    float	hxw = (float)( xwidth / 2.0 );
	    float	hyw = (float)( ywidth / 2.0 );
	    float	absx = Math.abs( x );
	    float	absy = Math.abs( y );

	    /* This function can be simplified as well by not worrying about
	     *    returning zero if the sample is beyond the filter window.
	     */ 
	    return (float) Math.min( ( absx <= hxw ? ( hxw - absx ) / hxw : 0.0 ),
	                ( absy <= hyw ? ( hyw - absy ) / hyw : 0.0 ) );
	}


//	----------------------------------------------------------------------
//	 RiCatmullRomFilter
//	 Catmull Rom filter used as a possible value passed to RiPixelFilter.
//	 Catmull RomフィルタはRiPixelFIlterを通ることができる値を使用しました。
	//
	public static float	RiCatmullRomFilter( float x, float y, float xwidth, float ywidth )
	{
	    /*
	     * From page 223 of [MITC88] 
	     *
	     * if abs(d) < 1
	     *    f(d) = 1/6*(  (12-9*B-9*C)*abs(d*d*d)
	     *                + (-18 + 12*B + 6*C)*d*d + (6-2*B) )
	     *
	     * if 1 <= abs(d) < 2
	     *    f(d) = 1/6*(  (-B-6*C)*abs(d*d*d)
	     *                + (6*B + 30*C)*d*d
	     *                + (-12*B - 48*C)*d
	     *                + (8*B + 24*C) )
	     *
	     * otherwise  f(d)=0
	     *
	     * -------------------------------------------------------------
	     *  When B = 0.0 and C = 0.5 the filter is a Catmull-Rom cubic spline.
	     *
	     * if abs(d) < 1
	     *    f(d) = 1/6*[  (12-3)*abs(d*d*d) + (-18 + 3)*d*d + (6) ]
	     *
	     * if 1 <= abs(d) < 2
	     *    f(d) = 1/6*[  (-3)*abs(d*d*d) + (15)*d*d + (-24)*d + (12) ]
	     *
	     * otherwise  f(d)=0
	     * -------------------------------------------------------------
	     * Simplifying:
	     *
	     * if abs(d) < 1
	     *    f(d) = (3/2)*abs(d*d*d) - (5/2)*d*d + 1
	     *
	     * if 1 <= abs(d) <2
	     *    f(d) = (-0.5)*abs(d*d*d) + (5/2)*d*d - 4*abs(d) + 2
	     *
	     * otherwise  f(d)=0
	     *
	     */
	/*    float d, d2;

	    d2 = x * x + y * y; // d*d 
	    d = sqrt( d2 ); // distance from origin 

	    if ( d < 1 )
	        return ( 1.5 * d * d2 - 2.5 * d2 + 1.0 );
	    else if ( d < 2 )
	        return ( -d * d2 * 0.5 + 2.5 * d2 - 4.0 * d + 2.0 );
	    else
	        return 0.0;*/

	   /* RI SPec 3.2 */
	   float r2 = (x*x+y*y);
	   float r = (float)Math.sqrt(r2);
	   return (float) ((r>=2.0)?0.0:
					   (r<1.0)?(3.0*r*r2-5.0*r2+2.0):(-r*r2+5.0*r2-8.0*r+4.0));
	}


//	----------------------------------------------------------------------
//	 RiSincFilter
//	 Sinc filter used as a possible value passed to RiPixelFilter.
//	 sinc filter はRiPixelFilterを通過する可能な値を使用する。
	//
	public static float	RiSincFilter( float x, float y, float xwidth, float ywidth )
	{
	    //float d;
	    //
	    //d = sqrt(x*x+y*y);
	    //
	    //if(d!=0)
	    //	return(sin(RI_PI*d)/(RI_PI*d));
	    //else
	    //	return(1.0);

	    // The above is an un-windowed sinc, below is a windowed sinc
	    //   function similar in shape to what PRMan 3.9 uses.
	    // tburge 5-28-01

	    /* Modified version of the RI Spec 3.2 sinc filter to be
	     *   windowed with a positive lobe of a cosine which is half
	     *   of a cosine period.  
	     */

	    /* Uses a -PI to PI cosine window. */
	    if ( x != 0.0 )
	    {
	        x *= RI_PI;
	        x = (float) (Math.cos( 0.5 * x / xwidth ) * Math.sin( x ) / x);
	    }
	    else
	    {
	        x = 1.0f;
	    }
	    if ( y != 0.0 )
	    {
	        y *= RI_PI;
	        y = (float) (Math.cos( 0.5 * y / ywidth ) * Math.sin( y ) / y);
	    }
	    else
	    {
	        y = 1.0f;
	    }

	    /* This is a square separable filter and is the 2D Fourier
	     * transform of a rectangular box outlining a lowpass bandwidth
	    * filter in the frequency domain.
	    */ 
	    return x*y;
	}


//	----------------------------------------------------------------------
//	 RiDiskFilter -- this is in Pixar's ri.h
//	 Disk filter used as a possible value passed to RiPixelFilter
//	 DiskフィルタはRiPixelFIlterを通ることができる値を使用しました。 
	//
	public static float	RiDiskFilter( float x, float y, float xwidth, float ywidth )
	{
	    double d, xx, yy;

	    xx = x * x;
	    yy = y * y;
	    xwidth *= 0.5;
	    ywidth *= 0.5;

	    d = ( xx ) / ( xwidth * xwidth ) + ( yy ) / ( ywidth * ywidth );
	    if ( d < 1.0 )
	        return 1.0f;
	    else
	        return 0.0f;
	}


//	----------------------------------------------------------------------
//	 RiBesselFilter -- this is in Pixar's ri.h
//	 Besselj0 filter used as a possible value passed to RiPixelFilter
//	 beseel filter はRiPixelFilterを通過する可能な値を使用する。
	//
	public static float	RiBesselFilter( float x, float y, float xwidth, float ywidth )
	{
	    double d, w, xx, yy;

	    xx = x * x;
	    yy = y * y;

	    xwidth *= 0.5;
	    ywidth *= 0.5;

	    w = ( xx ) / ( xwidth * xwidth ) + ( yy ) / ( ywidth * ywidth );
	    if ( w < 1.0 )
	    {
	        d = Math.sqrt( xx + yy );
	        if ( d != 0.0 ) {
	            /* Half cosine window. */
	            w = Math.cos( 0.5 * RI_PI * Math.sqrt( w ) );
	            return (float) (w * 2*j1( RI_PI * d ) / d);
	        }else{
	            return RI_PI;
	        }
	    }
	    else{
	        return 0.0f;
	    }
	}
/*
	private static double j1(double x)
	{
		int n=1, k, sign;
		double x2, x22, deltaJ, j, epsilon;
		
		// マシンイプシロン
		epsilon = Double.longBitsToDouble(0x3ca0000000000000L);
		
		// nが負の奇数の場合、結果の符号を反転
		if(n % 2 == -1){
			sign = -1;
		}
		else{
			sign = 1;
		}
		n = Math.abs(n);
		
		x2 = x / 2;
		x22 = x2 * x2;
		
		deltaJ = 1;
		for(k = 1; k <= n; k++){
			deltaJ *= x2 / k;
		}
		
		j = deltaJ;
		k = 1;
		
		// 値の変化が十分小さくなるまで計算
		while(Math.abs(deltaJ) > Math.abs(j) * epsilon){
			deltaJ *= -x22 / k / (n + k);
			j += deltaJ;
			k = k + 1;
		}
		
		j *= sign;
		//System.out.println(df.format(j));
		return j;
	}
*/
	static public double j1(double x) {

	    double ax;
	    double y;
	    double ans1, ans2;

	    if ( (ax = Math.abs(x)) < 8.0) {
	      y = x * x;
	      ans1 = x * (72362614232.0 + y * ( -7895059235.0 + y * (242396853.1
	          + y * ( -2972611.439 + y * (15704.48260 + y * ( -30.16036606))))));
	      ans2 = 144725228442.0 + y * (2300535178.0 + y * (18583304.74
	          + y * (99447.43394 + y * (376.9991397 + y * 1.0))));
	      return ans1 / ans2;
	    } else {
	      double z = 8.0 / ax;
	      double xx = ax - 2.356194491;
	      y = z * z;

	      ans1 = 1.0 + y * (0.183105e-2 + y * ( -0.3516396496e-4
	                                           +
	                                           y * (0.2457520174e-5 + y * ( -0.240337019e-6))));
	      ans2 = 0.04687499995 + y * ( -0.2002690873e-3
	                                  + y * (0.8449199096e-5 + y * ( -0.88228987e-6
	          + y * 0.105787412e-6)));
	      double ans = Math.sqrt(0.636619772 / ax) *
	          (Math.cos(xx) * ans1 - z * Math.sin(xx) * ans2);
	      if (x < 0.0) ans = -ans;
	      return ans;
	    }
	  }


//	----------------------------------------------------------------------
//	 RiHider
//	 Specify a hidden surface calculation mode.
//	 陰面消去のモードを指定してください。
	//
	public static void	RiHider( String name, Object... pArgs)
	{

	   STLVector<String> aTokens = new STLVector<String>(String.class);
	   STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiHiderV( name, count, aTokens.toArray(), aValues.toArray() );

	}

//	----------------------------------------------------------------------
//	 RiHiderV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiHiderV( String name, int count, String tokens[], Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiHiderCache(name, count, tokens, values) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiHider [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    if ( name.compareTo( "hidden" ) == 0 || name.compareTo( "painter" ) == 0 )
	    {
	    	//nttdata 高速化
	        //QGetRenderContext() .optCurrent().GetStringOptionWrite( "System", "Hider" ) [ 0 ].value = name ;
	        QGetRenderContext() .optCurrent().GetStringOptionWriteIndex( "System", "Hider" , 0 ).value = name ;
	    }

	    // Check options.
	    int i;
	    for ( i = 0; i < count; ++i )
	    {
	        SqParameterDeclaration Decl;
	        try
	        {
	            Decl = QGetRenderContext().FindParameterDecl( tokens[ i ] );
	        }
	        catch( XqException e )
	        {
	            logger.error(e.strReason());
	            continue;
	        }
			long hash = Decl.m_strName.hashCode();
			if ( hash == RIH_DEPTHFILTER )		//↓Javaだと必要ない
	            RiOption( "Hider", "depthfilter", /*( String[] ) */values[ i ], null );
			else if ( hash == RIH_JITTER )
	            RiOption( "Hider", "jitter", /*( p_int[] )*/ values[ i ], null );
	    }

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiColorSamples
//	 Specify the depth and conversion arrays for color manipulation.
//	 色の操作に深さと変換アレイを指定してください。
	//
	public static void	RiColorSamples( int N, float[] nRGB, float[] RGBn )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiColorSamplesCache(N, nRGB, RGBn) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiColorSamples [" + GetStateAsString() + "]\n");
				return;
			}
		}

		logger.warning("RiColorSamples not supported\n" );
		
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiRelativeDetail
//	 Set the scale used for all subsequent level of detail calculations.
//	 すべてのその後のレベルの詳細計算に使用されるスケールを設定してください。
	//
	public static void	RiRelativeDetail( float relativedetail )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiRelativeDetailCache(relativedetail) );
			return;
		}

		{
			if(!ValidateState(2, BeginEnd, Frame) )
			{
				logger.error("Invalid state for RiRelativeDetail [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    if ( relativedetail < 0.0f )
	    {
	    	logger.error("RiRelativeDetail < 0.0\n");
	    }
	    else
	    {
	        QGetRenderContext() .optCurrent().GetFloatOptionWriteIndex( "System", "RelativeDetail" , 0 ).value = relativedetail;
	    }
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiOption
//	 Specify system specific option.
//	 システムの特定のオプションを指定してください。
	//
	public static void	RiOption( String name , Object... pArgs  )
	{
		STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues= new STLVector<Object>(Object.class);
		
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiOptionV( name, count,aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiOptionV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiOptionV( String name, int count, String[] tokens, Object[] values )
	{
		if( QGetRenderContext().pCurrentObject() != null ) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiOptionCache(name, count, tokens, values) ); 
			return;	
		}

		{ 
			if(!ValidateState(2, BeginEnd, Frame) ) 
			{ 
				logger.error("Invalid state for RiOption [" + GetStateAsString() + "]\n");
				return; 
			} 
		}

	    // Find the parameter on the current options.
	    CqNamedParameterList pOpt = QGetRenderContext() .optCurrent().pOptionWrite( name );

	    int i;
	    for ( i = 0; i < count; ++i )
	    {
	        String	token = tokens[ i ];
	        Object	value = values[ i ];

	        // Search for the parameter in the declarations.
	        // Note Options can only be uniform.
	        SqParameterDeclaration Decl;
	        try
	        {
	            Decl = QGetRenderContext().FindParameterDecl( token );
	        }
	        catch( XqException e )
	        {
	        	logger.error( e.strReason() );
	            continue;
	        }
	        int Type = Decl.m_Type.getValue();
//	        int Class = Decl.m_Class.getValue();
	        boolean bArray = Decl.m_Count > 1;
	        CqParameter pParam = pOpt.pParameter( Decl.m_strName );
	        if ( pParam == null )
	        {
//	            if ( Decl.m_strName != "" && ( Decl.m_Class ).getValue() == class_uniform )
	            if ( (!Decl.m_strName.equals("")) && ( Decl.m_Class ).getValue() == class_uniform )
	            {
	                try {
	                	pParam = createParameter( Decl );
					} catch ( Exception e) {
						HimawariLogger.outputException( e );
					}
	                pOpt.AddParameter( pParam );
	            }
	            else
	            {
//	                if ( Decl.m_strName == "" )
	                if ( Decl.m_strName.equals( "" ))
	                	logger.warning("Unrecognised declaration : " + token + "\n" );
	                else
	                	logger.warning("Options can only be uniform [" + token + "]\n");
	                return ;
	            }
	        }
	        else
	        {
	            Type = pParam.Type().getValue();
//	            Class = pParam.Class().getValue();
//	            bArray = pParam.Count() > 0;//仕様変更
	            bArray = pParam.Count() > 1;
	        }

	        switch ( Type )
	        {
	        case type_float:
	            {
	        		Object pf[] = (Object[])( value );
	                if ( bArray )
	                {
	                    int j;
	                    for ( j = 0; j < pParam.Count(); ++j )
	                    {
	                    	if(pf[ j ] instanceof p_float)
	                    	{
	                    		( (p_float)((CqParameterTypedUniformArray<p_float, p_float>)( pParam )).pValue_get( 0 , j )).value = ((p_float)pf[ j ]).value;
	                    	}
	                    	else
	                    	{
	                    		( (p_float)((CqParameterTypedUniformArray<p_float, p_float>)( pParam )).pValue_get( 0 , j )).value = (float)((p_int)pf[ j ]).value;
	                    	}
	                        
	                    }
	                }
	                else
	                {
	                	if(pf[ 0 ] instanceof p_float)
                    	{
                    		( (p_float)((CqParameterTypedUniform<p_float, p_float>)( pParam )).pValue_get( 0 , 0 )).value = ((p_float)pf[ 0 ]).value;
                    	}
	                	else
	                	{
	                		( (p_float)((CqParameterTypedUniform<p_float, p_float>)( pParam ) ).pValue_get( 0 , 0 )).value = (float)((p_int)pf[ 0 ]).value;
	                	}
	                }
	            }
	            break;

	        case type_integer:
	            {
	                Object pi[] =  (Object[])( value ); ;
	                if ( bArray )
	                {
	                    int j;
	                    for ( j = 0; j < pParam.Count(); ++j )
	                    {
	                    	if( pi[ j ] instanceof p_int)
	                    	{
	                    		( (p_int)((CqParameterTypedUniformArray<p_int, p_float>)( pParam ) ).pValue_get( 0 , j )).value = ((p_int)pi[ j ]).value;
	                    	}
	                    	else
	                    	{
	                    		( (p_int)((CqParameterTypedUniformArray<p_int, p_float>)( pParam ) ).pValue_get( 0 , j )).value = (int)((p_float)pi[ j ]).value;
	                    	}
	                    }
	                }
	                else
	                {
	                	if( pi[ 0 ] instanceof p_int)
                    	{
	                		( (p_int)( (CqParameterTypedUniform<p_int, p_float> )( pParam ) ).pValue_get( 0, 0 )).value = ((p_int)pi[ 0 ] ).value;
                    	}
	                	else
	                	{
	                		( (p_int)((CqParameterTypedUniform<p_int, p_float>)( pParam ) ).pValue_get( 0 , 0 )).value = (int)((p_float)pi[ 0 ]).value;
	                	}
	                }
	            }
	            break;

	        case type_string:
	            {
	        		p_String[] ps = (p_String[])( value );
	                if ( bArray )
	                {
	                    int j;
	                    for ( j = 0; j < pParam.Count(); ++j )
	                    {
	                        String str = "" ;
	                        if (  name.compareTo( "searchpath" ) == 0 )
	                        {
	                            // Get the old value for use in escape replacement
	                        	//Cソース：CqParameterTypedUniform　ではないと思うのでここでは変えている。
	                        		p_String str_old = (p_String)(( CqParameterTypedUniformArray<p_String, p_String> )( pParam ) ).pValue_get( 0 , j );
	                        	
	                        		// Build the string, checking for & character and replace with old string.
	                            int strt = 0;
	                            int len = 0;
	                            while ( true )
	                            {
//	                                if ( ( len = strcspn( ps[ j ][ strt ], "&" ) ) < strlen( ps[ j ][ strt ] ) )
	                                if ( ( len = ps[ j ].value.indexOf( "&" , strt ) ) <  ps[ j ].value.length()- strt && len != -1)
	                                {
	                                    str += ps[ j ].value.substring( strt, len );
	                                    str += str_old;
	                                    strt += len + 1;
	                                }
	                                else
	                                {
	                                    str += ps[ j ].value.substring( strt );
	                                    break;
	                                }
	                            }
	                        }
	                        else
	                            str = new String( ps[ j ].value );

	                        ((p_String)( (CqParameterTypedUniformArray<p_String, p_String> )( pParam ) ).pValue_get( 0 , j )).value = str;
	                    }
	                }
	                else
	                {
	                    String str = "";
	                    if ( name.compareTo( "searchpath" ) == 0 )
	                    {
	                        // Get the old value for use in escape replacement
	                    	//nttdata 高速化
	                        //p_String str_old = (p_String)( (CqParameterTypedUniform<p_String, p_String> )( pParam ) ).pValue() [ 0 ];
	                    	p_String str_old = (p_String)( (CqParameterTypedUniform<p_String, p_String> )( pParam ) ).pValue_get(0 , 0 );
	                        // Build the string, checking for & character and replace with old string.
	                        int strt = 0;
	                        int len = 0;
	                        while ( true )
	                        {
//	                            if ( ( len = strcspn( ps[ 0 ][ strt ], "&" ) ) < strlen( ps[ 0 ][ strt ] ) )
	                        	if ( ( len = ps[ 0 ].value.indexOf( "&" ,  strt ) ) <  ps[ 0 ].value.length()- strt && len != -1 )
	                            {
	                                str +=  ps[ 0 ].value.substring( strt, len );
	                                str += str_old;
	                                strt += (len-strt) + 1;
	                            }
	                            else
	                            {
	                                str += ps[ 0 ].value.substring( strt );
	                                break;
	                            }
	                        }
	                    }
	                    else
	                        str = new String( ps[ 0 ].value );

	                    //nttdata 高速化
	                    //((p_String)( ( CqParameterTyped<p_String, p_String> )( pParam ) ).pValue() [ 0 ]).value = str;
	                    ((p_String)( ( CqParameterTyped<p_String, p_String> )( pParam ) ).pValue_get( 0, 0 )).value = str;
	                }
	            }
	            break;

	        case type_color:
	            {
	                p_float[] pc = (p_float[])( value );
	                if ( bArray )
	                {
	                    int j;
	                    for ( j = 0; j < pParam.Count() * 3; j+=3 )
	                    	( (CqColor)( ( CqParameterTypedUniformArray<CqColor, CqColor> )( pParam ) ).pValue_get( 0 ,  (int)(j/3)) ).assignment( new CqVector3D(pc[ j ].value, pc[ j+1 ].value, pc[ j+2 ].value) );
	                }
	                else
	                	( (CqColor)( ( CqParameterTypedUniform<CqColor, CqColor> )( pParam )) .pValue_get( 0 , 0 ) ).assignment( new CqVector3D(pc[ 0 ].value, pc[ 1 ].value, pc[ 2 ].value) );
	            }
	            break;

	        case type_point:
	            {
	        		p_float[] pv = (p_float[])( value );
	                if ( bArray )
	                {
	                    int j;
	                    for ( j = 0; j < pParam.Count() * 3 ; j+=3 )
	                        ( (CqVector3D)( ( CqParameterTypedUniformArray<CqVector3D, CqVector3D> )( pParam ) ).pValue_get( 0 , (int)(j/3) )).assignment( new CqVector3D(pv[ j ].value, pv[ j+1 ].value, pv[ j+2 ].value) );
	                }
	                else
	                	( (CqVector3D)( ( CqParameterTypedUniform<CqVector3D, CqVector3D> )( pParam ) ).pValue_get( 0 , 0 )).assignment( new CqVector3D(pv[ 0 ].value, pv[ 1 ].value, pv[ 2 ].value) );
	            }
	            break;

	        case type_normal:
	            {
	        		p_float pv[] = (p_float[])( value );
	                if ( bArray )
	                {
	                    int j;
	                    for ( j = 0; j < pParam.Count() * 3 ; j+=3 )
	                    	 ( (CqVector3D)( ( CqParameterTypedUniformArray<CqVector3D, CqVector3D> )( pParam ) ).pValue_get( 0 , (int)(j/3) )).assignment( new CqVector3D(pv[ j ].value, pv[ j+1 ].value, pv[ j+2 ].value) );
	                }
	                else
	                	 ( (CqVector3D)(( CqParameterTypedUniform<CqVector3D, CqVector3D> )( pParam ) ).pValue_get( 0 , 0 ) ).assignment( new CqVector3D(pv[ 0 ].value, pv[ 1 ].value, pv[ 2 ].value) );
	            }
	            break;

	        case type_vector:
	            {
	                p_float pv[] = (p_float[])( value );
	                if ( bArray )
	                {
	                    int j;
	                    for ( j = 0; j < pParam.Count() * 3; j+=3 )
	                    	( (CqVector3D)( ( CqParameterTypedUniformArray<CqVector3D, CqVector3D> )( pParam ) ).pValue_get( 0 , (int)(j/3) ) ).assignment( new CqVector3D(pv[ j ].value, pv[ j+1 ].value, pv[ j+2 ].value) );
	                }
	                else
	                	( (CqVector3D)( ( CqParameterTypedUniform<CqVector3D, CqVector3D> )( pParam ) ).pValue_get( 0 , 0 ) ).assignment( new CqVector3D(pv[ 0 ].value, pv[ 1 ].value, pv[ 2 ].value) );
	            }
	            break;

	        case type_hpoint:
	            {
	        		p_float pv[] = (p_float[])( value );
	                if ( bArray )
	                {
	                    int j;
	                    for ( j = 0; j < pParam.Count() * 4; j+=4 )
	                    	( (CqVector4D) ( ( CqParameterTypedUniformArray<CqVector4D, CqVector3D> )( pParam ) ).pValue_get( 0 , (int)(j/4) ) ).assignment( new CqVector4D(pv[ j ].value, pv[ j+1 ].value, pv[ j+2 ].value, pv[ j+3 ].value) );
	                }
	                else
	                	( (CqVector4D)( ( CqParameterTypedUniform<CqVector4D, CqVector3D>)( pParam ) ).pValue_get( 0 , 0 ) ).assignment( new CqVector4D(pv[ 0 ].value, pv[ 1 ].value, pv[ 2 ].value, pv[ 3 ].value) );
	            }
	            break;

	        case type_matrix:
	            {
	        		p_float pm[] = (p_float[])( value );
	                if ( bArray )
	                {
	                    int j;
	                    for ( j = 0; j < pParam.Count() * 16; j+=16 )
	                    	( (CqMatrix)( ( CqParameterTypedUniformArray<CqMatrix,CqMatrix> )( pParam ) ).pValue_get( 0 , (int)(j/16) ) ).assignment( new CqMatrix(pm[ j    ].value, pm[ j+1  ].value, pm[ j+2  ].value, pm[ j+3  ].value,
																																			  pm[ j+4  ].value, pm[ j+5  ].value, pm[ j+6  ].value, pm[ j+7  ].value,
																																			  pm[ j+8  ].value, pm[ j+9  ].value, pm[ j+10 ].value, pm[ j+11 ].value,
																																			  pm[ j+12 ].value, pm[ j+13 ].value, pm[ j+14 ].value, pm[ j+15 ].value) );
	                }
	                else
	                	( (CqMatrix)( ( CqParameterTypedUniform<CqMatrix, CqMatrix> )( pParam ) ).pValue_get( 0 , 0 ) ).assignment( new CqMatrix(pm[ 0  ].value, pm[ 1  ].value, pm[ 2  ].value, pm[ 3  ].value,
																																		 pm[ 4  ].value, pm[ 5  ].value, pm[ 6  ].value, pm[ 7  ].value,
																																		 pm[ 8  ].value, pm[ 9  ].value, pm[ 10 ].value, pm[ 11 ].value,
																																		 pm[ 12 ].value, pm[ 13 ].value, pm[ 14 ].value, pm[ 15 ].value) );
	            }
	            break;
	        }
	    }
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiAttributeBegin
//	 Begin a ne attribute definition, pushes the current attributes.
//	 属性定義を始めて、現在の属性をpushします。
	//
	public static void	RiAttributeBegin()
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiAttributeBeginCache() );
			return;
		}

		{
			if(!ValidateState(5, World, Attribute, Transform, Solid, Object) )
			{
				logger.error("Invalid state for RiAttributeBegin [" + GetStateAsString() + "]\n");
				return;
			}
		}

	    QGetRenderContext() .BeginAttributeModeBlock();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiAttributeEnd
//	 End the current attribute defintion, pops the previous attributes.
//	 現在の属性を終わらせて前の属性をpopしてきます。
	//
	public static void	RiAttributeEnd()
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiAttributeEndCache() );
			return;
		}

		if(!ValidateState(1, Attribute) )
		{
			logger.error("Invalid state for RiAttributeEnd [" + GetStateAsString() + "]\n");
			return;
		}

	    QGetRenderContext() .EndAttributeModeBlock();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiColor
//		Set the current color for use by the geometric primitives.
//	  幾何学上基関数で使用のための現在の色を設定してください。
	//
	public static void	RiColor( float[] Cq )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiColorCache(Cq) );
			return;
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiColor [" + GetStateAsString() + "]\n");
			return;
		}

	    QGetRenderContext() .pattrWriteCurrent() .GetColorAttributeWrite( "System", "Color" ) [ 0 ].assignment( new  CqColor( Cq ) );
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiOpacity
//	 Set the current opacity, for use by the geometric primitives.
//	 幾何学のプリミティブで使用するために現在の不透明度を設定してください。
	//
	public static void	RiOpacity( float[] Os )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiOpacityCache(Os) );
			return;
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiOpacity [" + GetStateAsString() + "]\n");
			return; 
		}

	    QGetRenderContext() .pattrWriteCurrent() .GetColorAttributeWrite( "System", "Opacity" ) [ 0 ].assignment( new CqColor( Os ) );
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiTextureCoordinates
//	 Set the current texture coordinates used by the parametric geometric primitives.
//	 パラメトリックの幾何学上基関数によって使用される現在の織地座標を設定してください。
	//
	public static void	RiTextureCoordinates( float s1, float t1,
	                             float s2, float t2,
	                             float s3, float t3,
	                             float s4, float t4 )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiTextureCoordinatesCache(s1, t1, s2, t2, s3, t3, s4, t4) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{ 
			logger.error("Invalid state for RiTextureCoordinates [" + GetStateAsString() + "]\n");
			return;
		}

	    p_float[] pTC = QGetRenderContext() .pattrWriteCurrent() .GetFloatAttributeWrite( "System", "TextureCoordinates" );

	    assert( null != pTC );

	    pTC[ 0 ].value = s1;
	    pTC[ 1 ].value = t1;
	    pTC[ 2 ].value = s2;
	    pTC[ 3 ].value = t2;
	    pTC[ 4 ].value = s3;
	    pTC[ 5 ].value = t3;
	    pTC[ 6 ].value = s4;
	    pTC[ 7 ].value = t4;
	    QGetRenderContext() .AdvanceTime();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiLightSource
//	 Create a new light source at the current transformation.
//	 現在の変形から新しい光源を作成する。
	//
	Object	RiLightSource( String name, Object... pArgs)
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    return ( RiLightSourceV( name, count, aTokens.toArray(), aValues.toArray() ) );
	}


//	----------------------------------------------------------------------
//	 RiLightSourceV
//	 List based version of above.
	//
	public static Object	RiLightSourceV( String name, int count, String tokens[], Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiLightSourceCache(name, count, tokens, values) );
			return null;
		}

		if(!ValidateState(7, BeginEnd, Frame, World, Attribute, Transform, Solid, Motion) ) 
		{ 
			logger.error("Invalid state for RiLightSource [" + GetStateAsString() + "]\n");
			return null; 
		}

	    // Find the lightsource shader.
	    //IqShader * pShader = static_cast<CqShader*>( QGetRenderContext() .CreateShader( name, Type_Lightsource ) );
	    IqShader pShader = QGetRenderContext().CreateShader( name, new EqShaderType( Type_Lightsource ) );

	    // TODO: Report error.
	    if ( pShader == null ) return ( null );

	    pShader.matCurrent().assignment( QGetRenderContext() .ptransCurrent().matObjectToWorld(QGetRenderContext().Time()) );
	    CqLightsource pNew = new CqLightsource( pShader, RI_TRUE ) ;
	    Lightsource_stack.add(pNew);

	    // Execute the intiialisation code here, as we now have our shader context complete.
	    pShader.PrepareDefArgs();

	    if ( pNew != null )
	    {
	        int i;
	        for ( i = 0; i < count; ++i )
	        {
	            String	token = tokens[ i ];
	            Object	value = values[ i ];

	            SetShaderArgument( pShader, token,  value );
	        }
	        QGetRenderContext() .pattrWriteCurrent() .AddLightsource( pNew );

	        // Add it as a Context light as well in case we are in a context that manages it's own lights.
	        QGetRenderContext() .pconCurrent() .AddContextLightSource( pNew );
	        return ( pNew );
	    }
	    return null;
	}


//	----------------------------------------------------------------------
//	 RiAreaLightSource
//	 Create a new area light source at the current transformation, all
//	 geometric primitives until the next RiAttributeEnd, become part of this
//	 area light source.
//	 変化の時に新しい面光源を作成する。すべての幾何学的プリミティブは次のRiAttributeEndまで面光源の一部になるでしょう。
//	 
	//
	Object	RiAreaLightSource( String name, Object... pArgs)
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    return ( RiAreaLightSourceV( name, count, aTokens.toArray(), aValues.toArray() ) );
	}


//	----------------------------------------------------------------------
//	 RiAreaLightSourceV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static Object	RiAreaLightSourceV( String name, int count, String tokens[], Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiAreaLightSourceCache(name, count, tokens, values) ); 
			return null ;	
		}

		if(!ValidateState(7, BeginEnd, Frame, World, Attribute, Transform, Solid, Motion) ) 
		{ 
			logger.error("Invalid state for RiAreaLightSource [" + GetStateAsString() + "]\n");
			return null;
		}

		logger.warning("RiAreaLightSource not supported, will produce a point light\n" );
		
	    return ( RiLightSourceV( name, count, tokens, values ) );
	}


//	----------------------------------------------------------------------
//	 RiIlluminate
//	 Set the current status of the specified light source.
//	 現在の指定された光源のステータスを設定する。
	//
	public static void	RiIlluminate( Object light, boolean onoff )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiIlluminateCache(light, onoff) );
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiIlluminate [" + GetStateAsString() + "]\n" );
			return; 
		} 

	    CqLightsource pL = (CqLightsource)( light );

	    // Check if we are turning the light on or off.
	    if ( light == null ) return ;
	    if ( onoff )
	        QGetRenderContext() .pattrWriteCurrent() .AddLightsource( pL );
	    else
	        QGetRenderContext() .pattrWriteCurrent() .RemoveLightsource( pL );
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiSurface
//	 Set the current surface shader, used by geometric primitives.
//	 幾何学プリミティブによって使用される現在の表面シェーダを設定してください。
	//
	public static void	RiSurface( String name, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiSurfaceV( name, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiSurfaceV
//	 List based version of above.
//
	public static void	RiSurfaceV( String name, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiSurfaceCache(name, count, tokens, values) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiSurface [" + GetStateAsString() + "]\n");
			return; 
		}

	    // Find the shader.
	    //IqShader * pshadSurface = QGetRenderContext() .CreateShader( name, Type_Surface );
	    IqShader pshadSurface = QGetRenderContext().CreateShader( name, new EqShaderType( Type_Surface ));

	    if ( pshadSurface != null)
	    {
	        float time = QGetRenderContext().Time();
			pshadSurface.matCurrent().assignment( QGetRenderContext() .matCurrent(time) );
	        // Execute the intiialisation code here, as we now have our shader context complete.
	        pshadSurface.PrepareDefArgs();
	        int i;
	        for ( i = 0; i < count; ++i )
	        {
	            String	token = tokens[ i ];
	            Object	value = values[ i ];

	            SetShaderArgument( pshadSurface, token,  value );
	        }
	        QGetRenderContext() .pattrWriteCurrent() .SetpshadSurface( pshadSurface, QGetRenderContext() .Time() );
	    }
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiAtmosphere
//	 Set the current atrmospheric shader.
//	 現在のatrmosphericシェーダを設定してください。
//	 
	//
	public static void	RiAtmosphere( String name, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiAtmosphereV( name, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiAtmosphereV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiAtmosphereV( String name, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null ) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiAtmosphereCache(name, count, tokens, values) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiAtmosphere [" + GetStateAsString() + "]\n");
			return;
		} 

	    // Find the shader.
	    IqShader pshadAtmosphere = QGetRenderContext().CreateShader( name, new EqShaderType( Type_Volume ));

	    if ( pshadAtmosphere != null )
	    {
	        pshadAtmosphere.matCurrent().assignment( QGetRenderContext() .matCurrent(QGetRenderContext().Time()) );
	        // Execute the intiialisation code here, as we now have our shader context complete.
	        pshadAtmosphere.PrepareDefArgs();
	        int i;
	        for ( i = 0; i < count; ++i )
	        {
	            String	token = tokens[ i ];
	            Object	value = values[ i ];

	            SetShaderArgument( pshadAtmosphere, token, value );
	        }
	    }

	    QGetRenderContext() .pattrWriteCurrent() .SetpshadAtmosphere( pshadAtmosphere, QGetRenderContext() .Time() );
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiInterior
//	 Set the current interior volumetric shader.
//	 現在の内部の体積のシェーダを設定してください。
	//
	public static void	RiInterior( String name, Object... pArgs )
	{
		logger.warning("RiInterior not supported\n" );
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiInteriorV
//	 List based version of above.
	//
	public static void	RiInteriorV( String name, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiInteriorCache(name, count, tokens, values) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiInterior [" + GetStateAsString() + "]\n");
			return; 
		}

		logger.warning("RiInterior not supported\n" );
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiExterior
//	 Set the current exterior volumetric shader.
//	 現在の外の体積のシェーダを設定する。
	//
	public static void	RiExterior( String name, Object... pArgs )
	{
		logger.warning("RiExterior not supported\n");
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiExteriorV
//	 List based version of above.
	//
	public static void	RiExteriorV( String name, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiExteriorCache(name, count, tokens, values) ); 
			return;
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{ 
			logger.error("Invalid state for RiExterior [" + GetStateAsString() + "]\n");
			return; 
		} 

	    logger.warning( "RiExterior not supported\n" );
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiShadingRate
//	 Specify the size of the shading area in pixels.
//	 画素の陰影領域のサイズを指定してください。
	//
	public static void	RiShadingRate( float size )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiShadingRateCache(size) );
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiShadingRate [" + GetStateAsString() + "]\n");
			return; 
		} 

	    CqLogRangeCheckCallback rc = new CqLogRangeCheckCallback();

	    boolean valid = true;

	    rc.set( "size" );
	    if( !CheckMinMax( size, 0.0f, RI_INFINITY, rc ) )
	    {
	        valid = false;
	    }

	    if( !valid )
	    {
	    	logger.warning("Invalid ShadingRate, ShadingRate set to 1\n");
	        size = 1;
	    }

	    QGetRenderContext() .pattrWriteCurrent() .GetFloatAttributeWrite( "System", "ShadingRate" ) [ 0 ].value = size;
	    QGetRenderContext() .pattrWriteCurrent() .GetFloatAttributeWrite( "System", "ShadingRateSqrt" ) [ 0 ].value = (float)Math.sqrt( size );
	    QGetRenderContext() .AdvanceTime();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiShadingInterpolation
//	 Specify the method of shading interpolation.
//	 挿入に陰影をつけるメソッドを指定してください。
	//
	public static void	RiShadingInterpolation( String type )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiShadingInterpolationCache(type) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiShadingInterpolation [" + GetStateAsString() + "]\n");
			return; 
		}

	    if ( type.compareTo( RI_CONSTANT ) == 0 )
	        QGetRenderContext() .pattrWriteCurrent() .GetIntegerAttributeWrite( "System", "ShadingInterpolation" ) [ 0 ].value = ShadingConstant;
	    else
	        if ( type.compareTo( RI_SMOOTH ) == 0 )
	            QGetRenderContext() .pattrWriteCurrent() .GetIntegerAttributeWrite( "System", "ShadingInterpolation" ) [ 0 ].value = ShadingSmooth;
	        else
	            logger.error( "RiShadingInterpolation unrecognised value \"" + type + "\"\n" );

	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiMatte
//	 Set the matte state of subsequent geometric primitives.
//	 その後の幾何学上基関数のマット状態を設定してください。
	//
	public static void	RiMatte( boolean onoff )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiMatteCache(onoff) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error( "Invalid state for RiMatte [" + GetStateAsString() + "]\n" ); 
			return; 
		}

	    QGetRenderContext() .pattrWriteCurrent() .GetIntegerAttributeWrite( "System", "Matte" ) [ 0 ].value = ( onoff != false ? 1 : 0 );
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiBound
//	 Set the bounding cube of the current primitives.
//	 現在プリミティブのバウンドされた立方体を設定してください。
	//
	public static void	RiBound( float[] bound )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiBoundCache(bound) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiBound [" + GetStateAsString() + "]\n" );
			return; 
		} 

	    // TODO: Need to add a "Bound" attribute here, and fill it in.
	    QGetRenderContext() .AdvanceTime();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiDetail
//	 Set the current bounding cube for use by level of detail calculation.
//	 演算の詳細レベルに使用される現在のバウンドされた立方体を設定する。
	//
	public static void	RiDetail( float[] bound )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiDetailCache(bound) );
			return;
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{ 
			logger.error("Invalid state for RiDetail [" + GetStateAsString() + "]\n" );
			return; 
		} 

	    CqBound Bound = new CqBound( bound );

	    Bound.Transform( QGetRenderContext() .matSpaceToSpace( "object", "raster",new CqMatrix(), QGetRenderContext() .matCurrent( QGetRenderContext() .Time() ), QGetRenderContext().Time() ) );

	    float ruler = Math.abs( Math.max( Bound.vecMax().x - Bound.vecMin().x, Bound.vecMax().y - Bound.vecMin().y ) );

	    ruler *= QGetRenderContext() .optCurrent().GetFloatOptionIndex( "System", "RelativeDetail" , 0 ).value;

	    QGetRenderContext() .pattrWriteCurrent() .GetFloatAttributeWrite( "System", "LevelOfDetailRulerSize" ) [ 0 ].value = ruler;
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiDetailRange
//	 Set the visible range of any subsequent geometric primitives.
//	 幾何学プリミティブによって派生した、見える長さを設定してください。
	//
	public static void	RiDetailRange( float offlow, float onlow, float onhigh, float offhigh )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiDetailRangeCache(offlow, onlow, onhigh, offhigh) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiDetail [" + GetStateAsString() + "]\n");
			return; 
		}

	    if ( offlow > onlow || onhigh > offhigh )
	    {
	        logger.error( "RiDetailRange invalid range\n" );
	        return ;
	    }

	    p_float ruler = QGetRenderContext() .pattrWriteCurrent() .GetFloatAttributeWrite( "System", "LevelOfDetailRulerSize" ) [ 0 ];

	    float minImportance;
	    if ( onlow == offlow )
	    {
	        minImportance = ruler.value < onlow ? 1.0f : 0.0f;
	    }
	    else
	    {
	        minImportance = CLAMP( ( onlow - ruler.value ) / ( onlow - offlow ), 0, 1 );
	    }

	    float maxImportance;
	    if ( onhigh == offhigh )
	    {
	        maxImportance = ruler.value < onhigh ? 1.0f : 0.0f;
	    }
	    else
	    {
	        maxImportance = CLAMP( ( offhigh - ruler.value ) / ( offhigh - onhigh ), 0, 1 );
	    }

	    if ( minImportance >= maxImportance )
	    {
	        // Geometry is culled.  Use the special value -1 to represent this.
	        minImportance = maxImportance = -1.0f;
	    }

	    QGetRenderContext() .pattrWriteCurrent() .GetFloatAttributeWrite( "System", "LevelOfDetailBounds" ) [ 0 ].value = minImportance;
	    QGetRenderContext() .pattrWriteCurrent() .GetFloatAttributeWrite( "System", "LevelOfDetailBounds" ) [ 1 ].value = maxImportance;
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiGeometricApproximation
//	 Specify any parameters used by approximation functions during rendering.
//	 レンダリングの間に近似機能によって使用されるあらゆるパラメタを指定してください。
	//

	public static void	RiGeometricApproximation( String type, float value )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiGeometricApproximationCache(type, value) );
			return;
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiGeometricApproximation [" + GetStateAsString() + "]\n");
			return;
		}

		logger.warning("RiGeometricApproximation not supported\n");
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiOrientation
//	 Set the handedness of any subsequent geometric primitives.
//	 どんなその後の幾何学上基関数の利き手も設定してください。
	//
	public static void	RiOrientation( String orientation )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiOrientationCache(orientation) );
			return;
		}
		
		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error( "Invalid state for RiOrientation [" + GetStateAsString() + "]\n" );
			return;
		}

	    if ( orientation != null )
	    {
	    
	        if ( orientation.indexOf( RI_RH )!=-1 && orientation.substring(orientation.indexOf( RI_RH )) != null )
	            QGetRenderContext() .pattrWriteCurrent() .GetIntegerAttributeWrite( "System", "Orientation" ) [ 0 ].value = ( QGetRenderContext() .ptransCurrent().GetHandedness(QGetRenderContext().Time()) ) ? 0 : 1;
	        if ( orientation.indexOf( RI_LH )!=-1 && orientation.substring(orientation.indexOf( RI_LH )) != null )
	            QGetRenderContext() .pattrWriteCurrent() .GetIntegerAttributeWrite( "System", "Orientation" ) [ 0 ].value = ( QGetRenderContext() .ptransCurrent().GetHandedness(QGetRenderContext().Time()) ) ? 1 : 0;
	        if ( orientation.indexOf( RI_INSIDE )!=-1 && orientation.substring(orientation.indexOf( RI_INSIDE )) != null )
	            QGetRenderContext() .pattrWriteCurrent() .GetIntegerAttributeWrite( "System", "Orientation" ) [ 0 ].value = 1;
	        if ( orientation.indexOf( RI_OUTSIDE )!=-1 && orientation.substring(orientation.indexOf( RI_OUTSIDE )) != null )
	            QGetRenderContext() .pattrWriteCurrent() .GetIntegerAttributeWrite( "System", "Orientation" ) [ 0 ].value = 0;
	    }
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiReverseOrientation
//	 Reverse the handedness of any subsequent geometric primitives.
//	 どんなその後の幾何学上基関数の利き手も逆にしてください。
	//
	public static void	RiReverseOrientation()
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiReverseOrientationCache() );
			return;
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiReverseOrientation [" + GetStateAsString() + "]\n" );
			return;
		}

	    QGetRenderContext() .pattrWriteCurrent() .FlipeOrientation( QGetRenderContext() .Time() );
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiSides
//	 Set the number of visibles sides for any subsequent geometric primitives.
//	 あらゆるその後の幾何学上基関数にvisibles側の数を設定してください。
	//
	public static void	RiSides( int nsides )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiSidesCache(nsides) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiSides [" + GetStateAsString() + "]\n" ); 
			return; 
		} 

	    QGetRenderContext() .pattrWriteCurrent() .GetIntegerAttributeWrite( "System", "Sides" ) [ 0 ].value = nsides;
	    QGetRenderContext() .AdvanceTime();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiIdentity
//	 Set the current transformation to the identity matrix.
//	 
	//
	public static void	RiIdentity()
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiIdentityCache() );
			return;
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{
			logger.error( "Invalid state for RiIdentity [" + GetStateAsString() + "]\n");
			return;
		}

	    QGetRenderContext() .ptransSetTime( new CqMatrix() );
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 Set the current transformation to the specified matrix.
//	 指定されたマトリクスに変形を設定してください。
	//
	public static void	RiTransform( float[][] transform )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiTransformCache(transform) );
			return;
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiTransform [" + GetStateAsString() + "]\n");
			return; 
		}

//	    CqMatrix matTrans = new CqMatrix( transform );
//	    if ( matTrans.Determinant() < 0 && ( QGetRenderContext().pconCurrent().Type() != Motion || QGetRenderContext().pconCurrent().TimeIndex() == 0 ) )
//	        QGetRenderContext() .ptransWriteCurrent() .FlipHandedness( QGetRenderContext() .Time() );

		if( QGetRenderContext().IsWorldBegin() )
		{
			CqTransform newTrans =  new CqTransform( QGetRenderContext().GetDefObjTransform() ) ;
			QGetRenderContext() .pconCurrent().ptransSetCurrent( newTrans );
			QGetRenderContext() .ptransConcatCurrentTime( new CqMatrix( transform ) );
		}
		else
			QGetRenderContext() .ptransSetCurrentTime( new CqMatrix( transform ) );
	    QGetRenderContext() .AdvanceTime();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiConcatTransform
//	 Concatenate the specified matrix into the current transformation matrix.
//	 特別なマトリックスを現在の変異マトリックスに連結します。
	//
	public static void	RiConcatTransform( float[][] transform )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiConcatTransformCache(transform) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{ 
			logger.error("Invalid state for RiConcatTransform [" + GetStateAsString() + "]\n");
			return;
		} 

	    // Check if this transformation results in a change in orientation.
//	    CqMatrix matTrans = new CqMatrix( transform );
//	    if ( matTrans.Determinant() < 0 && ( QGetRenderContext().pconCurrent().Type() != Motion || QGetRenderContext().pconCurrent().TimeIndex() == 0 ) )
//	        QGetRenderContext() .pattrWriteCurrent() .FlipeCoordsysOrientation( QGetRenderContext() .Time() );

	    QGetRenderContext() .ptransConcatCurrentTime( new CqMatrix( transform ) );
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiPerspective
//	 Concatenate a perspective transformation into the current transformation.
//	 現在の変化をパースぺクティブに結合してください。
	//
	public static void	RiPerspective( float fov )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiPerspectiveCache(fov) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error( "Invalid state for RiPerspective [" + GetStateAsString() + "]\n" ); 
			return; 
		} 

	    if ( fov <= 0 )
	    {
	    	logger.error("RiPerspective invalid FOV\n" );
	        return ;
	    }

	    fov = (float) Math.tan( RAD( fov / 2 ) );

	    // This matches PRMan 3.9 in testing, but not BMRT 2.6's rgl and rendrib.
	    CqMatrix matP = new CqMatrix( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, fov, fov, 0, 0, -fov, 0 );

	    // Check if this transformation results in a change in orientation.
//	    if ( matP.Determinant() < 0 && ( QGetRenderContext().pconCurrent().Type() != Motion || QGetRenderContext().pconCurrent().TimeIndex() == 0 ) )
//	        QGetRenderContext() .pattrWriteCurrent() .FlipeCoordsysOrientation( QGetRenderContext() .Time() );

	    QGetRenderContext() .ptransConcatCurrentTime( matP );
	    QGetRenderContext() .AdvanceTime();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiTranslate
//	 Concatenate a translation into the current transformation.
//	 現在の変形へ移動を結合してください。
	//
	public static void	RiTranslate( float dx, float dy, float dz )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiTranslateCache(dx, dy, dz) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiTranslate [" + GetStateAsString() + "]\n"); 
			return; 
		}

	    CqMatrix	matTrans = new CqMatrix( new CqVector3D( dx, dy, dz ) );
	    // Check if this transformation results in a change in orientation.
//	    if ( matTrans.Determinant() < 0 && ( QGetRenderContext().pconCurrent().Type() != Motion || QGetRenderContext().pconCurrent().TimeIndex() == 0 ) )
//	        QGetRenderContext() .pattrWriteCurrent() .FlipeCoordsysOrientation( QGetRenderContext() .Time() );

		QGetRenderContext() .ptransConcatCurrentTime( matTrans );
	    QGetRenderContext() .AdvanceTime();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiRotate
//	 Concatenate a rotation into the current transformation.
//	 現在の変形に回転を連結する。
	//
	public static void	RiRotate( float angle, float dx, float dy, float dz )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiRotateCache(angle, dx, dy, dz) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiRotate [" + GetStateAsString() + "]\n"); 
			return;
		} 

	    CqMatrix	matRot = new CqMatrix( RAD( angle ), new CqVector3D( dx, dy, dz ) );
	    // Check if this transformation results in a change in orientation.
//	    if ( matRot.Determinant() < 0 && ( QGetRenderContext().pconCurrent().Type() != Motion || QGetRenderContext().pconCurrent().TimeIndex() == 0 ) )
//	        QGetRenderContext() .pattrWriteCurrent() .FlipeCoordsysOrientation( QGetRenderContext() .Time() );

	    QGetRenderContext() .ptransConcatCurrentTime( matRot );
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiScale
//	 Concatenate a scale into the current transformation.
//	 現在の変形にスケールを連結する。
	//
	public static void	RiScale( float sx, float sy, float sz )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiScaleCache(sx, sy, sz) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiScale [" + GetStateAsString() + "]\n"); 
			return; 
		} 

	    CqMatrix	matScale = new CqMatrix( sx, sy, sz );
	    // Check if this transformation results in a change in orientation.
//	    if ( matScale.Determinant() < 0 && ( QGetRenderContext().pconCurrent().Type() != Motion || QGetRenderContext().pconCurrent().TimeIndex() == 0 ) )
//	        QGetRenderContext() .pattrWriteCurrent() .FlipeCoordsysOrientation( QGetRenderContext() .Time() );

	    QGetRenderContext() .ptransConcatCurrentTime( matScale );
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiSkew
//	 Concatenate a skew into the current transformation.
//	 現在の変形に斜行を連結してください。
	//
	public static void	RiSkew( float angle, float dx1, float dy1, float dz1,
	               float dx2, float dy2, float dz2 )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiSkewCache(angle, dx1, dy1, dz1, dx2, dy2, dz2) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error( "Invalid state for RiSkew [" + GetStateAsString() + "]\n" ); 
			return; 
		} 

	    CqMatrix	matSkew = new CqMatrix( RAD( angle ), dx1, dy1, dz1, dx2, dy2, dz2 );

	    // This transformation can not change orientation.

	    QGetRenderContext() .ptransConcatCurrentTime( matSkew );
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiDeformation
//	 Specify a deformation shader to be included into the current transformation.
//	 変形シェーダを指定して、現在のトランスフォーメーションに含まれてください。
	//
	public static void	RiDeformation( String name, Object... pArgs )
	{
		logger.warning( "RiDeformation not supported\n" );
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiDeformationV
//	 List based version of above.
	//
	public static void	RiDeformationV( String name, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiDeformationCache(name, count, tokens, values) ); 
			return;
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error( "Invalid state for RiDeformation [" + GetStateAsString() + "]\n" ); 
			return; 
		} 

	    logger.warning( "RiDeformation not supported\n" );
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiDisplacement
//	 Specify the current displacement shade used by geometric primitives.
//	 現在の幾何学プリミティブで使われている変異シェーダを指定してください。
	//
	public static void	RiDisplacement( String name, Object... pArgs )
	{

 	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiDisplacementV( name, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiDisplacementV
//	 List based version of above.
	//
	public static void	RiDisplacementV( String name, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiDisplacementCache(name, count, tokens, values) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error( "Invalid state for RiDisplacement [" + GetStateAsString() + "]\n" ); 
			return; 
		}

	    // Find the shader.
	    IqShader pshadDisplacement = QGetRenderContext() .CreateShader( name, new EqShaderType(Type_Displacement ));

	    if ( pshadDisplacement != null )
	    {
	        pshadDisplacement.matCurrent().assignment( QGetRenderContext() .matCurrent(QGetRenderContext().Time()) );
	        // Execute the intiialisation code here, as we now have our shader context complete.
	        pshadDisplacement.PrepareDefArgs();
	        int i;
	        for ( i = 0; i < count; ++i )
	        {
	            String	token = tokens[ i ];
	            Object	value = values[ i ];

	            SetShaderArgument( pshadDisplacement, token,  value );
	        }
	    }

	    QGetRenderContext() .pattrWriteCurrent() .SetpshadDisplacement( pshadDisplacement, QGetRenderContext() .Time() );
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiCoordinateSystem
//	 Save the current coordinate system as the specified name.
//	 現在のコーディネートシステムを指定された名前で保存してください。
	//
	public static void	RiCoordinateSystem( String space )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiCoordinateSystemCache(space) ); 
			return;	
		}

		if(!ValidateState(7, BeginEnd, Frame, World, Attribute, Transform, Solid, Object) ) 
		{ 
			logger.error("Invalid state for RiCoordinateSystem [" + GetStateAsString() + "]\n" );
			return; 
		} 

	    // Insert the named coordinate system into the list help on the renderer.
	    QGetRenderContext() .SetCoordSystem( space, QGetRenderContext() .matCurrent( QGetRenderContext() .Time() ) );
	    QGetRenderContext() .AdvanceTime();

	    return ;
	}


//	----------------------------------------------------------------------
//	 ---Additional to spec. v3.1---
//	 RiCoordSysTransform
//	 Replace the current transform with the named space.
//	 現在の形をnamespaceとともに移動させる。

	public static void	RiCoordSysTransform( String space )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiCoordinateSystemCache(space) ); 
			return;	
		}

		if(!ValidateState(7, BeginEnd, Frame, World, Attribute, Transform, Solid, Object) ) 
		{ 
			logger.error( "Invalid state for RiCoordinateSystem [" + GetStateAsString() + "]\n" );
			return; 
		} 

	    // Insert the named coordinate system into the list help on the renderer.
	    QGetRenderContext() .ptransSetTime( QGetRenderContext() .matSpaceToSpace( space, "world", new CqMatrix(),new CqMatrix(), QGetRenderContext().Time() ) );
	    QGetRenderContext() .AdvanceTime();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiTransformPoints
//	 Transform a list of points from one coordinate system to another.
//	 ポイントのリストを1個の座標系から別のものに変えてください。
	//
	public static Object	RiTransformPoints( String fromspace, String tospace, int npoints, float[][] points )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiTransformPointsCache(fromspace, tospace, npoints, points) ); 
			return(null);
		}

		if(!ValidateState(7, BeginEnd, Frame, World, Attribute, Transform, Solid, Object) ) 
		{ 
			logger.error("Invalid state for RiTransformPoints [" + GetStateAsString() + "]\n" );
			return(null);
		} 

		logger.warning("RiTransformPoints not supported\n" );
	    return ( null );
	}


//	----------------------------------------------------------------------
//	 RiTransformBegin
//	 Push the current transformation state.
//	 現在の変形状態をpushしてください。
	//
	public static void	RiTransformBegin()
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiTransformBeginCache() ); 
			return;	
		}

		if(!ValidateState(7, BeginEnd, Frame, World, Attribute, Transform, Solid, Object) ) 
		{
			logger.error("Invalid state for RiTransformBegin [" + GetStateAsString() + "]\n" );
			return; 
		} 

	    QGetRenderContext() .BeginTransformModeBlock();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiTransformEnd
//	 Pop the previous transformation state.
//	 現在の変形状態をpopしてください。
	//
	public static void	RiTransformEnd()
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiTransformEndCache() ); 
			return;	
		}

		if(!ValidateState(1, Transform) ) 
		{
			logger.error("Invalid state for RiTransformEnd [" + GetStateAsString() + "]\n" );
			return; 
		} 

	    QGetRenderContext() .EndTransformModeBlock();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiAttribute
//	 Set a system specific attribute.
//	 システムの特定の属性を設定してください。
	//
	public static void	RiAttribute( String name, Object... pArgs )
	{

	    long hash = name.hashCode();
	      
	    if (hash == RIH_RENDER) return;
	    if (hash == RIH_INDIRECT) return;
	    if (hash == RIH_LIGHT) return;
	    if (hash == RIH_VISIBILITY) return;

	   STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiAttributeV( name, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiAttributeV
//	 List based version of above.
//	上のベースのバージョンを記載してください。
	//

	public static void	RiAttributeV( String name, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiAttributeCache(name, count, tokens, values) ); 
			return;	
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiAttribute [" + GetStateAsString() + "]\n");
			return; 
		}

	    long hash = name.hashCode();
	      
	    if (hash == RIH_RENDER) return;
	    if (hash == RIH_INDIRECT) return;
	    if (hash == RIH_LIGHT) return;
	    if (hash == RIH_VISIBILITY) return;

	    // Find the parameter on the current options.
	    CqNamedParameterList pAttr = QGetRenderContext() .pattrWriteCurrent() .pAttributeWrite( name );

	    int i;
	    for ( i = 0; i < count; ++i )
	    {
	        String	token = tokens[ i ];
	        Object	value = values[ i ];

	        int Type;
//	        int Class;
	        boolean bArray;
	        CqParameter pParam = pAttr.pParameter( token );
	        if ( pParam == null )
	        {
	            // Search for the parameter in the declarations.
	            // Note attributes can only be uniform.
	            SqParameterDeclaration Decl;
	            try
	            {
	                Decl = QGetRenderContext().FindParameterDecl( token );
	            }
	            catch( XqException e )
	            {
	            	logger.error(e.strReason());
	                continue;
	            }
//	            if ( Decl.m_strName != "" && Decl.m_Class.getValue() == class_uniform )
	            if ( (!Decl.m_strName.equals("")) && Decl.m_Class.getValue() == class_uniform )
	            {
	                try {
						pParam = createParameter( Decl );
					} catch (IllegalArgumentException e) {
						HimawariLogger.outputException( e );
					} catch (IllegalAccessException e) {
						HimawariLogger.outputException( e );
					} catch (InvocationTargetException e) {
						HimawariLogger.outputException( e );
					}
	                Type = Decl.m_Type.getValue();
//	                Class = Decl.m_Class.getValue();
//	                bArray = Decl.m_Count > 0;
	                bArray = Decl.m_Count > 1;
	                pAttr.AddParameter( pParam );
	            }
	            else
	            {
//	                if ( Decl.m_strName == "" )
	                if ( Decl.m_strName.equals("") )
	                	logger.warning("Unrecognised declaration \"" + token + "\"\n");
	                else
	                	logger.warning("Attributes can only be uniform\n");
	                return ;
	            }
	        }
	        else
	        {
	            Type = pParam.Type().getValue();
//	            Class = pParam.Class().getValue();
//	            bArray = pParam.Count() > 0;
	            bArray = pParam.Count() > 1;
	        }

	        switch ( Type )
	        {
	        case type_float:
	            {
	        		p_float[] pf = (p_float[])( value );
	                if ( bArray )
	                {
	                    int j;
	                    for ( j = 0; j < pParam.Count(); ++j )
	                    	((p_float)((CqParameterTypedUniformArray<p_float, p_float>)( pParam ) ).pValue_get( 0 , j )).value = pf[ j ].value;
	                }
	                else
	                	((p_float)((CqParameterTypedUniform<p_float, p_float>)( pParam )) .pValue_get( 0 , 0 )).value = pf[ 0 ].value;
	            }
	            break;

	        case type_integer:
	            {
	        		p_float[] pi = (p_float[])( value );
	        		
//	        		//CqParameterTyped.TClassを調べれば、事前にpValue()の実体クラスがわかる。
//	        		CqParameterTyped pParamTyped = (CqParameterTyped)pParam;
	        		
	        		if ( bArray )
	        		{
	        			int j;
	        			for ( j = 0; j < pParam.Count(); ++j )
	        				((p_int)((CqParameterTypedUniformArray<p_int,  p_float>)( pParam )) .pValue_get( 0 , j )).value = (int)pi[ j ].value;
	        		}
	        		else
	        			((p_int)((CqParameterTypedUniform<p_int,  p_float>)( pParam )) .pValue_get( 0 , 0 )).value = (int)pi[ 0 ].value;
	            }
	            break;

	        case type_string:
	            {
	        		p_String[] ps = (p_String[])( value );
	                if ( bArray )
	                {
	                    int j;
	                    for ( j = 0; j < pParam.Count(); ++j )
	                    {
	                        String str = ( ps[ j ].value );
	                        ((p_String)(( CqParameterTypedUniform<p_String, p_float>)( pParam ) ).pValue_get( 0 , j )).value = str;
	                    }
	                }
	                else
	                {
	                    String str = ( ps[ 0 ].value );
	                    ((p_String)((CqParameterTypedUniform<p_String,  p_float>)( pParam )) .pValue_get( 0 , 0 )).value = str;
	                    
						//*【改】 Aqsisver1.0.1で追加
	                   if( name.equals( "identifier" ) )
		                    	logger.info( "Identifier: " + ps[0] +"\n");
	                }
	            }
	            // TODO: Rest of parameter types.
	        }
	    }
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiPolygon
//	 Specify a coplanar, convex polygon.
//	 コプレーナ、凸状ポリゴンを指定してください。
	//
	public static void	RiPolygon( int nvertices, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiPolygonV( nvertices, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiPolygonV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiPolygonV( int nvertices, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiPolygonCache(nvertices, count, tokens, values) ); 
			return;	
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			
			logger.error( "Invalid state for RiPolygon [" + GetStateAsString() + "]\n" ); 
			return; 
		} 

	    // Create a new polygon surface primitive.
	    CqSurfacePolygon pSurface =  new CqSurfacePolygon( nvertices ) ;

		// Process any specified primitive variables.
	    if ( ProcessPrimitiveVariables( pSurface, count, tokens, values ) )
	    {
	        if ( !pSurface.CheckDegenerate() )
	        {
	            float time = QGetRenderContext().Time();
	            // Transform the points into camera space for processing,
	            pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
	            CreateGPrim( pSurface );
	        }
	        else
	        {
	        	logger.error("Found degenerate polygon\n");
	        }
	    }

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiGeneralPolygon
//	 Specify a nonconvex coplanar polygon.
//	 非凸コプレーナポリゴンを指定してください。
	//
	public static void	RiGeneralPolygon( int nloops, int nverts[], Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiGeneralPolygonV( nloops, nverts, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiGeneralPolygonV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiGeneralPolygonV( int nloops, int nverts[], int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject()!=null ) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiGeneralPolygonCache(nloops, nverts, count, tokens, values) ); 
			return;	
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error( "Invalid state for RiGeneralPolygon [" + GetStateAsString() + "]\n" );
			return; 
		} 

	    int iloop;

	    // Calcualte how many points there are.
	    int cVerts = 0;
	    for ( iloop = 0; iloop < nloops; ++iloop )
		{
	        cVerts += nverts[ iloop ];
			// Check for degenerate loops.
			if( nverts[ iloop ] < 3 )
			{
	            String objname = "unnamed";
	            String[] pattrName = QGetRenderContext().pattrCurrent().GetStringAttribute( "identifier", "name" );
	            if ( pattrName != null ) objname = pattrName[ 0 ];
	            logger.warning( "Degenerate loop in GeneralPolygon object \"" + objname + "\" \n" );
	            
	            if( nverts[ iloop ]==0 )
	            	return;
			}
		}
	    
		// Check "P" length
		for( int i=0; i<count; i++ ) {
			String param = tokens[i];
			int diff = cVerts*3 - Array.getLength(values[i]);

			if( param.equals("P") && diff > 0 ) {
				
				logger.error("Invalid \"P\" parameter length " +Array.getLength(values[i])+ " : \"P\" needs " +cVerts*3+ " float values \n");
				
				p_float[] filledP = new p_float[ cVerts*3 ];
				System.arraycopy( values[i], 0, filledP, 0, Array.getLength(values[i]) );
				for( int j=Array.getLength(values[i]); j<filledP.length; j++ ) {
					filledP[j] = new p_float(0);
				}
				values[i] = filledP;
			}
		}

	    // Create a storage class for all the points.
	    CqPolygonPoints pPointsClass =  new CqPolygonPoints( cVerts, 1, cVerts ) ;
	    // Process any specified primitive variables
	    if ( ProcessPrimitiveVariables( pPointsClass, count, tokens, values ) )
	    {
	        pPointsClass.SetDefaultPrimitiveVariables( RI_FALSE );

	        // Work out which plane to project to.
	        float	MinX, MaxX;
	        float	MinY, MaxY;
	        float	MinZ, MaxZ;
	        CqVector3D	vecTemp = new CqVector3D( (CqVector4D)pPointsClass.P().pValue_get( 0 ,0 ) );
	        MinX = MaxX = vecTemp.x;
	        MinY = MaxY = vecTemp.y;
	        MinZ = MaxZ = vecTemp.z;

	        // We need to take into account Orientation here.
	        boolean O = QGetRenderContext().pattrCurrent() .GetIntegerAttribute( "System", "Orientation" ) [ 0 ] != 0;

	        int iVert;
	        for ( iVert = 1; iVert < pPointsClass.P() .Size(); ++iVert )
	        {
	            vecTemp = new CqVector3D( (CqVector4D)pPointsClass.P().pValue_get( iVert , 0 ) );
	            MinX = ( MinX < vecTemp.x ) ? MinX : vecTemp.x;
	            MinY = ( MinY < vecTemp.y ) ? MinY : vecTemp.y;
	            MinZ = ( MinZ < vecTemp.z ) ? MinZ : vecTemp.z;
	            MaxX = ( MaxX > vecTemp.x ) ? MaxX : vecTemp.x;
	            MaxY = ( MaxY > vecTemp.y ) ? MaxY : vecTemp.y;
	            MaxZ = ( MaxZ > vecTemp.z ) ? MaxZ : vecTemp.z;
	        }
	        float	DiffX = MaxX - MinX;
	        float	DiffY = MaxY - MinY;
	        float	DiffZ = MaxZ - MinZ;

	        int Axis;
	        if ( DiffX < DiffY && DiffX < DiffZ )
	            Axis = CqPolygonGeneral2D.Axis_YZ;
	        else if ( DiffY < DiffX && DiffY < DiffZ )
	            Axis = CqPolygonGeneral2D.Axis_XZ;
	        else
	            Axis = CqPolygonGeneral2D.Axis_XY;

	        // Create a general 2D polygon using the points in each loop.
	        CqPolygonGeneral2D poly = new CqPolygonGeneral2D();
	        int ipoint = 0;
	        for ( iloop = 0; iloop < nloops; ++iloop )
	        {
	            CqPolygonGeneral2D polya = new CqPolygonGeneral2D();;
	            polya.SetAxis( Axis );
	            polya.SetpVertices( pPointsClass );
	            int ivert;
	            for ( ivert = 0; ivert < nverts[ iloop ]; ++ivert )
	            {
	                assert( ipoint < pPointsClass.P() .Size() );
	                polya.aiVertices().add( new p_int(ipoint++) );
	            }
	            if ( iloop == 0 )
	            {
					/// \note: We need to check here if the orientation of the projected poly matches the
					/// expected one, of not, we must swap the direction so that the triangulation routines can
					/// correctly determine the inside/outside nature of points. However, if doing so breaks the
					/// orientation as expected by the rest of the renderer, we need to flip the orientation
					/// attribute as well so that normals are correctly calculated.
	                if( O )
	                {
	                    if ( polya.CalcOrientation() != CqPolygonGeneral2D.Orientation_AntiClockwise )
						{
					        QGetRenderContext() .pattrWriteCurrent().GetIntegerAttributeWrite( "System", "Orientation" ) [ 0 ].value = 0;
	                        polya.SwapDirection();
						}
	                }
	                else
	                {
	                    if ( polya.CalcOrientation() != CqPolygonGeneral2D.Orientation_Clockwise )
						{
					        QGetRenderContext() .pattrWriteCurrent().GetIntegerAttributeWrite( "System", "Orientation" ) [ 0 ].value = 1;
	                        polya.SwapDirection();
						}
	                }
//	                poly = polya;
	                poly.assignment(polya);
	            }
	            else
	            {
	                if( O )
	                {
	                    if ( polya.CalcOrientation() != CqPolygonGeneral2D.Orientation_Clockwise )
	                        polya.SwapDirection();
	                }
	                else
	                {
	                    if ( polya.CalcOrientation() != CqPolygonGeneral2D.Orientation_AntiClockwise )
	                        polya.SwapDirection();
	                }
	                poly.Combine( polya );
	            }
	        }
	        // Now triangulate the general polygon

	        STLVector<p_int> aiTriangles = new STLVector<p_int>(p_int.class);
	        poly.CalcOrientation();
	        poly.Triangulate( aiTriangles );

	        int ctris = aiTriangles.size() / 3;
	        // Build an array of point counts (always 3 each).
	        STLVector<p_int> _nverts = new STLVector<p_int>(p_int.class);
//	        _nverts.resize( ctris, 3 );
			for( int i=0; i<ctris; i++ )	_nverts.add( new p_int(3) );

			//int[]へ変換
			int[] _nverts_ary		= new int[_nverts.size()];
			for( int i=0; i<_nverts_ary.length; i++ ){
				_nverts_ary[i] = _nverts.get(i).value;
			}
			int[] aiTriangles_ary	= new int[aiTriangles.size()];
			for( int i=0; i<aiTriangles_ary.length; i++ ){
				aiTriangles_ary[i] = aiTriangles.get(i).value;
			}

	        RiPointsPolygonsV( ctris, _nverts_ary, aiTriangles_ary, count, tokens, values );
	    }
	    return ;
	}

	public static void RiBlobby( int nleaf, int ncodes, int codes[], int nfloats, float floats[],
	                 int nstrings, String strings[], Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiBlobbyV( nleaf, ncodes, codes, nfloats, floats, nstrings, strings, count, aTokens.toArray(), aValues.toArray() );

	    return ;
	}

//	----------------------------------------------------------------------
	/** List based version of above.
	 * 上のベースのバージョンを記載してください。
	 *\return	nothing
	 **/
	public static void RiBlobbyV( int nleaf, int ncode, int code[], int nflt, float flt[],
	                  int nstr, String str[], int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiBlobbyCache(nleaf, ncode, code, nflt, flt, nstr, str, count, tokens, values) );
			return;	
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiBlobby [" + GetStateAsString() + "]\n"); 
			return; 
		} 

	    logger.warning ( "RiBlobby not supported\n" );

	    return ;
	}


//	----------------------------------------------------------------------
	/** Specify a small Points primitives
	 *  小さいPoints基関数を指定してください。
	 *\return	nothing
	 **/
	public static void	RiPoints( int nvertices, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiPointsV( nvertices, count, aTokens.toArray(), aValues.toArray() );

	    return ;
	}

//	----------------------------------------------------------------------
	/** List based version of above.
	 *  
	 *\return	nothing
	 **/
	public static void	RiPointsV( int npoints, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
			QGetRenderContext().pCurrentObject().AddCacheCommand(
					new RiPointsCache(npoints, count, tokens, values) );
			return;
		}
		
		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiPoints [" + GetStateAsString() + "]\n");
			return;
		}
		
		// Create a storage class for all the points.
		CqPolygonPoints pPointsClass = new CqPolygonPoints( npoints, 1, npoints ) ;
		
		// Create a new points storage class
		CqPoints pSurface;
		
		// read in the parameter list
		if ( ProcessPrimitiveVariables( pPointsClass, count, tokens, values ) )
		{
			// Transform the points into camera space for processing,
			// This needs to be done before initialising the KDTree as the tree must be formulated in 'current' (camera) space.
			pPointsClass.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pPointsClass.pTransform() .matObjectToWorld(pPointsClass.pTransform() .Time(0)), pPointsClass.pTransform() .Time(0) ),
					QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pPointsClass.pTransform() .matObjectToWorld(pPointsClass.pTransform() .Time(0)), pPointsClass.pTransform() .Time(0) ),
					QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pPointsClass.pTransform() .matObjectToWorld(pPointsClass.pTransform() .Time(0)), pPointsClass.pTransform() .Time(0) ) );
			
			pSurface =  new CqPoints( npoints, pPointsClass ) ;
			// Initialise the KDTree for the points to contain all.
			pSurface.InitialiseKDTree();
			pSurface.InitialiseMaxWidth();
			
			if ( QGetRenderContext() .pattrCurrent() .GetFloatAttribute( "System", "LevelOfDetailBounds" ) [ 1 ] < 0.0f )
			{
				// Cull this geometry for LOD reasons
				return ;
			}
			
			/// \note:	Have to duplicate the work of CreateGPrim here as we need a special type of CqDeformingSurface.
			///			Not happy about this, need to look at it.
			// If in a motion block, confirm that the current deformation surface can accept the passed one as a keyframe.
			if( QGetRenderContext() .pconCurrent() .fMotionBlock() )
			{
				CqMotionModeBlock pMMB = (CqMotionModeBlock)(QGetRenderContext() .pconCurrent());
				
				CqDeformingSurface pMS = pMMB.GetDeformingSurface();
				// If this is the first frame, then generate the appropriate CqDeformingSurface and fill in the first frame.
				// Then cache the pointer on the motion block.
				if( pMS == null)
				{
					CqDeformingPointsSurface pNewMS =  new CqDeformingPointsSurface( pSurface ) ;
					pNewMS.AddTimeSlot( QGetRenderContext().Time(), pSurface );
					
					pMMB.SetDeformingSurface( pNewMS );
				}
				else
				{
					pMS.AddTimeSlot( QGetRenderContext().Time(), pSurface );
				}
				QGetRenderContext() .AdvanceTime();
			}
			else
			{
				QGetRenderContext() .pImage() .PostSurface( pSurface );
				CqStats.STATS_INC( GPR_created );
			}
		}
		
		return ;
	}

//	----------------------------------------------------------------------
	/** Specify a small line primitives
	 *  小さい線のプリミティブを指定する。
	 *\param	type could be "linear" "bicubic"
	 *\param	ncurves : number of vertices
	 *\param	nvertices: vertices index
	 *\param	wrap could be "periodic" "nonperiodic"
	 *\return	nothing
	 **/

	public static void RiCurves( String type, int ncurves, int nvertices[], String wrap, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiCurvesV( type, ncurves, nvertices, wrap, count, aTokens.toArray(), aValues.toArray() );

	    return ;
	}

//	----------------------------------------------------------------------
	/** List based version of above.
	 *  
	 *\return	nothing
	 **/
	public static void RiCurvesV( String type, int ncurves, int nvertices[], String wrap, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiCurvesCache(type, ncurves, nvertices, wrap, count, tokens, values) );
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiCurves [" + GetStateAsString() + "]\n");
			return;
		}

	    // find out whether the curve is periodic or non-periodic
	    boolean periodic = false;
	    if ( wrap.equals( RI_PERIODIC ) )
	    {
	        periodic = true;
	    }
	    else if ( wrap.equals( RI_NONPERIODIC ) )
	    {
	        periodic = false;
	    }
	    else
	    {
	        // the wrap mode was neither "periodic" nor "nonperiodic"
	    	logger.error("RiCurves invalid wrap mode \"" + wrap + "\" \n");
	    }

	    // check ncurves
	    if( ncurves < 1 )
	    {
	    	logger.error("Invalid parameter " +ncurves+ " : ncurves > 0 \n");
	    	return;
	    }

		int i = 0, cVerts = 0;;
	    for( i = 0; i < nvertices.length; i++ )	cVerts += nvertices[ i ]; 

	    // check ncurves
	    if( cVerts < 1 )
	    {
	    	logger.error("Invalid parameter " + cVerts + " : nvertex > 0 \n");
	    	return;
	    }
	    
	    // Check "P" length
	    for( i = 0; i < count; i++ ) 
		{
			int diff = cVerts*3 - Array.getLength( values[ i ] );

			if( tokens[ i ].equals("P") && diff > 0 ) {
				
				logger.error("Invalid \"P\" parameter length " + Array.getLength( values[i] )+ " : \"P\" needs " +cVerts*3+ " float values \n");
				
				p_float[] filledP = new p_float[ cVerts*3 ];
				System.arraycopy( values[ i ], 0, filledP, 0, Array.getLength( values[ i ] ) );
				for( int j = Array.getLength( values[ i ] ); j < filledP.length; j++ ) {
					filledP[ j ] = new p_float( 0 );
				}
				values[ i ] = filledP;
			}
		}
	    
	    
	    // handle creation of linear and cubic curve groups separately
	    if ( type.equals( RI_CUBIC ) )
	    {
	        // create a new group of cubic curves
	    	CqCubicCurvesGroup pSurface = new CqCubicCurvesGroup( ncurves, nvertices, periodic );
	        // read in the parameter list
	        if ( ProcessPrimitiveVariables( pSurface, count, tokens, values ) )
	        {
	            // set the default primitive variables
	            pSurface.SetDefaultPrimitiveVariables();
				
				float time = QGetRenderContext().Time();
	            // Transform the points into camera space for processing,
	            pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
				
	            STLVector< CqBasicSurface > aSplits = new STLVector<CqBasicSurface>(CqBasicSurface.class);
	            pSurface.Split( aSplits );
//	            STLVector<boost::shared_ptr<CqBasicSurface> >::iterator iSS;
//	            for ( iSS = aSplits.begin(); iSS != aSplits.end(); ++iSS )
	            for( CqBasicSurface iSS : aSplits ) 
	            {
	                CreateGPrim( iSS );
	            }
	        }
	    }
	    else if ( type.equals( RI_LINEAR ))
	    {
	        // create a new group of linear curves
	    	CqLinearCurvesGroup pSurface = new CqLinearCurvesGroup( ncurves, nvertices, periodic );

	        // read in the parameter list
	        if ( ProcessPrimitiveVariables( pSurface, count, tokens, values ) )
	        {
	            // set the default primitive variables
	            pSurface.SetDefaultPrimitiveVariables();
	            float time = QGetRenderContext().Time();
	            // Transform the points into camera space for processing,
	            pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
	            CreateGPrim( pSurface );
	        }
	    }
	    else
	    {
	        // the type of curve was neither "linear" nor "cubic"
	    	logger.error( "RiCurves invalid type \"" + type + "\"");
	    }
	}


//	----------------------------------------------------------------------
//	 RiPointsPolygons
//	 Specify a list of convex coplanar polygons and their shared vertices.
//	 凸状コプレーナ多角形と彼らの共有された頭頂のリストを指定してください。
	//
	public static void	RiPointsPolygons( int npolys, int nverts[], int verts[], Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiPointsPolygonsV( npolys, nverts, verts, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiPointsPolygonsV
//	 List based version of above.
//	
	public static void	RiPointsPolygonsV( int npolys, int nverts[], int verts[], int count, String tokens[] ,Object values[] )
	{
		
		if( QGetRenderContext().pCurrentObject() != null)
		{
			QGetRenderContext().pCurrentObject().AddCacheCommand(
					new RiPointsPolygonsCache(npolys, nverts, verts, count, tokens, values) );
			return;
		}
		
		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiPointsPolygons [" + GetStateAsString() + "]\n");
			return;
		}
		
		// Calculate how many vertices there are.
		int cVerts = 0;
//		int[] pVerts = verts;	//2006.01.17. 配列の先頭アドレス→配列のインデックス と変更
		int pVerts = 0;
		int poly;
		int sumnVerts = 0;
		for ( poly = 0; poly < npolys; ++poly )
		{
			int v;
			sumnVerts += nverts[ poly ];
			
			// check verts length
			if( verts.length < pVerts + nverts[ poly ] ){
				logger.error("Invalid parameter length " +verts.length+ " : verts length = " +(pVerts+nverts[ poly ])+ " \n");
		    	return;
			}
			
			for ( v = 0; v < nverts[ poly ]; ++v )
			{
				//cVerts = Math.max( ( ( *pVerts ) + 1 ), cVerts );
				//cVerts = Math.max( verts[ pVerts ] + 1, cVerts );
				cVerts = (verts[ pVerts ] + 1 > cVerts )?verts[ pVerts ] + 1:cVerts;
				pVerts++;
			}
		}
		
		// Check "P" length
		for( int i=0; i<count; i++ ) {
			String param = tokens[i];
			int diff = cVerts*3 - Array.getLength(values[i]);

			if( param.equals("P") && diff > 0 ) {
				
				logger.error("Invalid \"P\" parameter length " +Array.getLength(values[i])+ " : \"P\" needs " +cVerts*3+ " float values \n");
				
				p_float[] filledP = new p_float[ cVerts*3 ];
				System.arraycopy( values[i], 0, filledP, 0, Array.getLength(values[i]) );
				for( int j=Array.getLength(values[i]); j<filledP.length; j++ ) {
					filledP[j] = new p_float(0);
				}
				values[i] = filledP;
			}
		}
		
		// Create a storage class for all the points.
		CqPolygonPoints pPointsClass = new CqPolygonPoints( cVerts, npolys, sumnVerts ) ;
		// Process any specified primitive variables
		if ( ProcessPrimitiveVariables( pPointsClass, count, tokens, values ) )
		{
			
			CqSurfacePointsPolygons pPsPs = new CqSurfacePointsPolygons(pPointsClass, npolys, nverts, verts ) ;
			
			float time = QGetRenderContext().Time();
			// Transform the points into camera space for processing,
			pPointsClass.Transform(	QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pPointsClass.pTransform() .matObjectToWorld(time), time ),
									QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pPointsClass.pTransform() .matObjectToWorld(time), time ),
									QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pPointsClass.pTransform() .matObjectToWorld(time), time ) );
			CreateGPrim(pPsPs);
		}
		
		return ;
	}


//	----------------------------------------------------------------------
//	 RiPointsGeneralPolygons
//	 Specify a list of coplanar, non-convex polygons and their shared vertices.
//	 コプレーナのリスト、非凸状なポリゴン、および彼らの共有された頭頂を指定してください。
	//
	public static void	RiPointsGeneralPolygons( int npolys, int nloops[], int nverts[], int verts[], Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiPointsGeneralPolygonsV( npolys, nloops, nverts, verts, count, aTokens.toArray(), aValues.toArray() );

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiPointsGeneralPolygonsV
//	 List based version of above.
//
	public static void	RiPointsGeneralPolygonsV( int npolys, int nloops[], int nverts[], int verts[], int count, String tokens[] ,Object values[] )
	{
    	
		if( QGetRenderContext().pCurrentObject()!=null )
		{
			QGetRenderContext().pCurrentObject().AddCacheCommand(
					new RiPointsGeneralPolygonsCache(npolys, nloops, nverts, verts, count, tokens, values) );
			return;
		}
		
		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiPointsGeneralPolygons [" + GetStateAsString() + "]\n" );
			return;
		}
		
		int ipoly;
		int iloop;
		int igloop = 0;
		int cVerts = 0;
		int igvert = 0;
		int initial_index;
		int sumnVerts = 0;
		
		// Calculate how many points overall.
//		int[] pVerts = verts;
		int pVerts = 0;
		for ( ipoly = 0; ipoly < npolys; ++ipoly )
		{
			
			// check nverts length
			if( nverts.length < igloop + nloops[ ipoly ] ){
				logger.error("Invalid parameter length " +nverts.length+ " : nverts length = " +(igloop+nloops[ ipoly ])+ " \n");
		    	return;
			}
			
			for ( iloop = 0; iloop < nloops[ ipoly ]; ++iloop, ++igloop )
			{
				int v;
				sumnVerts += nverts[ igloop ];
				
				// Check for degenerate loops.
				if( nverts[ igloop ] < 3 )
				{
					String objname = "unnamed" ;
					String[] pattrName = QGetRenderContext().pattrCurrent().GetStringAttribute( "identifier", "name" );
					if ( pattrName != null ) objname = pattrName[ 0 ];
					logger.warning( "Degenerate loop in PointsGeneralPolygons object \"" + objname + "\"" +" \n");
					
					if( nverts[ igloop ]==0 )
						return;
				}

				// check verts length
				if( verts.length < pVerts + nverts[ igloop ] ){
					logger.error("Invalid parameter length " +verts.length+ " : verts length = " +(pVerts+nverts[ igloop ])+ " \n");
			    	return;
				}

				for ( v = 0; v < nverts[ igloop ]; ++v )
				{
					//nttdata 高速化
					//cVerts = max( ( ( verts[pVerts] ) + 1 ), cVerts );
					cVerts = (verts[pVerts] ) + 1 > cVerts ?( verts[pVerts] ) + 1 : cVerts;
					pVerts++;
				}
			}
		}
		
		// Check "P" length
		for( int i=0; i<count; i++ ) {
			String param = tokens[i];
			int diff = cVerts*3 - Array.getLength(values[i]);

			if( param.equals("P") && diff > 0 ) {
				
				logger.error("Invalid \"P\" parameter length " +Array.getLength(values[i])+ " : \"P\" needs " +cVerts*3+ " float values \n");
				
				p_float[] filledP = new p_float[ cVerts*3 ];
				System.arraycopy( values[i], 0, filledP, 0, Array.getLength(values[i]) );
				for( int j=Array.getLength(values[i]); j<filledP.length; j++ ) {
					filledP[j] = new p_float(0);
				}
				values[i] = filledP;
			}
		}
		
		// We need to take into account Orientation here.
		boolean O = QGetRenderContext().pattrCurrent() .GetIntegerAttribute( "System", "Orientation" ) [ 0 ] != 0;
		
		// Create a storage class for all the points.
		CqPolygonPoints pPointsClass =  new CqPolygonPoints( cVerts, npolys, sumnVerts ) ;
		// Process any specified primitive variables
		if ( ProcessPrimitiveVariables( pPointsClass, count, tokens, values ) )
		{
			pPointsClass.SetDefaultPrimitiveVariables( false );
			
			// Reset loop counter.
			igloop = 0;
			int ctris = 0;
			STLVector<p_int> aiTriangles = new STLVector<p_int>(p_int.class);
			STLVector<p_int> aFVList = new STLVector<p_int>(p_int.class);
			STLVector<p_int> aUVList = new STLVector<p_int>(p_int.class);
			
			for ( ipoly = 0; ipoly < npolys; ++ipoly )
			{
				initial_index = igvert;
				// Create a general 2D polygon using the points in each loop.
				CqPolygonGeneral2D poly = new CqPolygonGeneral2D();
				int ipoint = 0;
				int imaxindex, iminindex;
				imaxindex = cVerts;
				iminindex = 0;
				for ( iloop = 0; iloop < nloops[ ipoly ]; ++iloop, ++igloop )
				{
//					iminindex = min( iminindex, verts[ igvert ] );
//					imaxindex = max( imaxindex, verts[ igvert ] );
					iminindex = ( iminindex < verts[ igvert ] )?iminindex:verts[ igvert ];
					imaxindex = ( imaxindex > verts[ igvert ] )?imaxindex:verts[ igvert ];
					float	MinX, MaxX;
					float	MinY, MaxY;
					float	MinZ, MaxZ;
					//CqVector3D	vecTemp = new CqVector3D( (CqVector4D)pPointsClass.P().pValue( verts[ igvert ] )[0] );
					CqVector3D	vecTemp = new CqVector3D( (CqVector4D)pPointsClass.P().pValue_get( verts[ igvert ] ,0 ));
					MinX = MaxX = vecTemp.x;
					MinY = MaxY = vecTemp.y;
					MinZ = MaxZ = vecTemp.z;
					
					CqPolygonGeneral2D polya = new CqPolygonGeneral2D();
					polya.SetpVertices( pPointsClass );
					int ivert;
					for ( ivert = 0; ivert < nverts[ igloop ]; ++ivert, ++igvert )
					{
						ipoint = verts[ igvert ];
						assert( ipoint < pPointsClass.P() .Size() );
						polya.aiVertices().add( new p_int(ipoint) );
						
						//vecTemp = new CqVector3D( (CqVector4D)pPointsClass.P().pValue( verts[ igvert ] )[0] );
						vecTemp = new CqVector3D( (CqVector4D)pPointsClass.P().pValue_get( verts[ igvert ] ,0 ) );
						MinX = ( MinX < vecTemp.x ) ? MinX : vecTemp.x;
						MinY = ( MinY < vecTemp.y ) ? MinY : vecTemp.y;
						MinZ = ( MinZ < vecTemp.z ) ? MinZ : vecTemp.z;
						MaxX = ( MaxX > vecTemp.x ) ? MaxX : vecTemp.x;
						MaxY = ( MaxY > vecTemp.y ) ? MaxY : vecTemp.y;
						MaxZ = ( MaxZ > vecTemp.z ) ? MaxZ : vecTemp.z;
					}
					
					// Work out which plane to project to.
					float	DiffX = MaxX - MinX;
					float	DiffY = MaxY - MinY;
					float	DiffZ = MaxZ - MinZ;
					
					int Axis;
					if ( DiffX < DiffY && DiffX < DiffZ )
						Axis = CqPolygonGeneral2D.Axis_YZ;
					else if ( DiffY < DiffX && DiffY < DiffZ )
						Axis = CqPolygonGeneral2D.Axis_XZ;
					else
						Axis = CqPolygonGeneral2D.Axis_XY;
					polya.SetAxis( Axis );
					
					if ( iloop == 0 )
					{
						/// \note: We need to check here if the orientation of the projected poly matches the
						/// expected one, of not, we must swap the direction so that the triangulation routines can
						/// correctly determine the inside/outside nature of points. However, if doing so breaks the
						/// orientation as expected by the rest of the renderer, we need to flip the orientation
						/// attribute as well so that normals are correctly calculated.
						if( !O )
						{
							if ( polya.CalcOrientation() != CqPolygonGeneral2D.Orientation_Clockwise )
								polya.SwapDirection();
						}
						else
						{
							if ( polya.CalcOrientation() != CqPolygonGeneral2D.Orientation_AntiClockwise )
								polya.SwapDirection();
						}
//						poly = polya;
						poly.assignment(polya);
					}
					else
					{
						if( !O )
						{
							if ( polya.CalcOrientation() != CqPolygonGeneral2D.Orientation_AntiClockwise )
								polya.SwapDirection();
						}
						else
						{
							if ( polya.CalcOrientation() != CqPolygonGeneral2D.Orientation_Clockwise )
								polya.SwapDirection();
						}
						poly.Combine( polya );
					}
				}
				// Now triangulate the general polygon
				poly.CalcOrientation();
				int iStartTri = aiTriangles.size();
				poly.Triangulate( aiTriangles );
				int iEndTri = aiTriangles.size();
				// Store the facevarying information
				/// \note This code relies on the fact that vertex indices cannot be duplicated
				/// within the loops of a single poly. Make sure this is a reasonable assumption.
				for( int ifv = iStartTri; ifv < iEndTri; ++ifv )
				{
					int ivaryingindex = aiTriangles.get( ifv ).value;
					boolean found = false;
					for( int iv = initial_index; iv != igvert; ++iv )
					{
						if( verts[ iv ] == ivaryingindex )
						{
							aFVList.add( new p_int(iv) );
							found = true;
						}
					}
					assert( found );
				}
				
				// Store the count of triangles generated for this general poly, so that we
				// can duplicate up the uniform values as appropriate.
				/// \note This code relies on the fact that vertex indices cannot be duplicated
				/// within the loops of a single poly. Make sure this is a reasonable assumption.
				aUVList.add( new p_int( ( iEndTri - iStartTri ) / 3 ) );
			}
			// Build an array of point counts (always 3 each).
			ctris = aiTriangles.size() / 3;
			STLVector<p_int> _nverts = new STLVector<p_int>(p_int.class);
//			_nverts.resize( ctris, 3 );
			for( int i=0; i<ctris; i++ )	_nverts.add( new p_int(3) );
			
			// Rebuild any facevarying or uniform variables.
			int iUserParam;
			int fvcount = ctris * 3;
			assert( aFVList.size() == fvcount );
			Vector<Object> aNewParams = new Vector<Object>();

			for( iUserParam = 0; iUserParam < count; ++iUserParam )
			{
				SqParameterDeclaration Decl;
			    try
		        {
		            Decl = QGetRenderContext().FindParameterDecl( tokens[ iUserParam ] );
		        }
		        catch( XqException e )
		        {
		        	logger.error( e.strReason() );
		            continue;
		        }
				int elem_size = 0;
				switch( Decl.m_Type.getValue() )
				{
				case type_float:
					elem_size = (Float.SIZE/8);//sizeof(float);	// ビット→バイトのために８で割る
					break;
//					***************************************************
//					【改】Aqsis1.0.1で追加されました。
					case type_integer:
					elem_size = (Integer.SIZE/8);
					break;
//					***************************************************
				case type_vector:
				case type_point:
				case type_normal:
					elem_size = (Float.SIZE/8)*3;//sizeof(RtPoint);
					break;
				case type_color:
					elem_size = (Float.SIZE/8)*3;//sizeof(RtColor);
					break;
				case type_matrix:
					elem_size = (Float.SIZE/8)*16;//sizeof(RtMatrix);
					break;
				}
				
				//Take into account array primitive variables.
				int array_size = Decl.m_Count;

				if( Decl.m_Class.getValue() == class_facevarying )
				{
//					 char* pNew = static_cast<char*>( malloc( elem_size * fvcount * array_size ) );
					elem_size /= 4; //float１つで４バイト
					p_float[] pNew = new p_float[ elem_size * fvcount * array_size ];
					p_float pval;
					int iElem;
					int idx = 0;
					for( iElem = 0; iElem < fvcount; ++iElem )
					{
//						const unsigned char* pval = static_cast<const unsigned char*>( values[ iUserParam ] ) + ( aFVList[ iElem ] * elem_size );
//						memcpy( pNew, pval, elem_size * array_size );
//						pNew += elem_size;

						for( int i=0; i<elem_size*array_size; i++ ){
							pval = (p_float)Array.get( values[ iUserParam ], aFVList.get( iElem ).value * elem_size * array_size + i );
							pNew[ idx++ ] = new p_float( pval.value );
						}
					}
					aNewParams.add( pNew );
					values[ iUserParam ] = aNewParams.lastElement();
				}
				else if( Decl.m_Class.getValue() == class_uniform )
				{
					// Allocate enough for 1 value per triangle, then duplicate values from the original list
					// accordingly.
//					 char* pNew = static_cast<char*>( malloc( elem_size * ctris * array_size) );
					elem_size /= 4; //float１つで４バイト
					p_float[] pNew = new p_float[ elem_size * ctris * array_size ];
					int iElem;
					p_float pval;
					int idx = 0;
					for( iElem = 0; iElem < npolys; ++iElem )
					{
						int dup_count = aUVList.get( iElem ).value; 
						int dup;
						for(dup=0; dup < dup_count; dup++)
						{
//							 memcpy( pNew, pval, elem_size * array_size );
							for( int i=0; i<elem_size; i++ ){
								pval = (p_float)Array.get( values[ iUserParam ], iElem * array_size + i );
								pNew[ idx++ ] = new p_float( pval.value );
							}
						}
						
					}
					aNewParams.add( pNew );
					values[ iUserParam ] = aNewParams.lastElement();
				}
				
			}
			
			//int[]へ変換
			int[] _nverts_ary		= new int[_nverts.size()];
			int[] aiTriangles_ary	= new int[aiTriangles.size()];
			for( int i=0; i<_nverts_ary.length; i++ ){
				_nverts_ary[i] = _nverts.get(i).value;
			}
			for( int i=0; i<aiTriangles_ary.length; i++ ){
				aiTriangles_ary[i] = aiTriangles.get(i).value;
			}

			RiPointsPolygonsV( ctris, _nverts_ary, aiTriangles_ary, count, tokens, values );
			
			
//			std::vector<void*>::iterator iNewParam;
//			for( iNewParam = aNewParams.begin(); iNewParam != aNewParams.end(); ++iNewParam )
//				free( *iNewParam );
		}
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiBasis
//	 Specify the patch basis matrices for the u and v directions, and the knot skip values.
//	 uとv対方向のためのパッチ基礎マトリクス、と結びのスキップ値を指定してください。
	//
	public static void	RiBasis( float[][] ubasis, int ustep, float[][] vbasis, int vstep )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiBasisCache(ubasis, ustep, vbasis, vstep) );
			return;
		}

		if(!ValidateState(8, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiBasis [" + GetStateAsString() + "]\n" );
			return;
		}

		// check ustep, vstep
		if( ustep < 1 )
		{
			logger.error( "Invalid parameter " + ustep + " : ustep > 0 \n" );
			return;
		}
		if( vstep < 1 )
		{
			logger.error( "Invalid parameter " + vstep + " : vstep > 0 \n" );
			return;
		}
		
	    CqMatrix u = new CqMatrix();
	    CqMatrix v = new CqMatrix();

	    // A good parser will use the Ri*Basis pointers so a quick comparison
	    //   can be done.
	    //if ( ubasis not same as before )
	    //{
	    //	// Save off the newly given basis.
	    //
	    //	// Calculate the (inverse Bezier Basis) * (given basis), but do
	    //	//   a quick check for RiPowerBasis since that is an identity
	    //	//   matrix requiring no math.
	    //	if ( ubasis!=RiPowerBasis )
	    //	{
	    //	}
	    //	else
	    //	{
	    //	}
	    //
	    // Do the above again for vbasis.
	    // Save off (InvBezier * VBasis) and (Transpose(InvBezier*UBasis)).
	    //}

	    int i;
	    for ( i = 0; i < 4; ++i )
	    {
	        int j;
	        for ( j = 0; j < 4; ++j )
	        {
	            u.m_aaElement[ i ][ j ] = ubasis[ i ][ j ] ;
	            v.m_aaElement[ i ][ j ] = vbasis[ i ][ j ] ;
	        }
	    }
	    u.SetfIdentity( false );
	    v.SetfIdentity( false );

	    QGetRenderContext() .pattrWriteCurrent() .GetMatrixAttributeWrite( "System", "Basis" ) [ 0 ].assignment( u );
	    QGetRenderContext() .pattrWriteCurrent() .GetMatrixAttributeWrite( "System", "Basis" ) [ 1 ].assignment( v );
	    QGetRenderContext() .pattrWriteCurrent() .GetIntegerAttributeWrite( "System", "BasisStep" ) [ 0 ].value = ustep;
	    QGetRenderContext() .pattrWriteCurrent() .GetIntegerAttributeWrite( "System", "BasisStep" ) [ 1 ].value = vstep;
	    QGetRenderContext() .AdvanceTime();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiPatch
//	 Specify a new patch primitive.
//	 新しいパッチプリミティブを指定してください。
	//
	public static void	RiPatch( String type, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiPatchV( type, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiPatchV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiPatchV( String type, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiPatchCache(type, count, tokens, values) );
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiPatch [" + GetStateAsString() + "]\n" );
			return;
		}
	    
	    // Check "P" length
		int cVerts = 0;
		if( type.equals( RI_BICUBIC ) )			cVerts = 16;//from CqSurfacePatchBicubic.cVertex()
		else if( type.equals( RI_BILINEAR ) )	cVerts = 4;	//from CqSurfacePatchBilinear.cVertex()
		for( int i = 0; i < count; i++ ) 
		{
			if( tokens[ i ].equals("P"))		cVerts *= 3;	
			else if( tokens[ i ].equals("Pw"))	cVerts *= 4;
			else if( tokens[ i ].equals("Pz") )	cVerts *= cVerts;
			else	continue;
				
			int diff = cVerts - Array.getLength( values[ i ] );
			if( diff > 0 ) 	
			{
				logger.error("Invalid \"" + tokens[ i ] + "\" parameter length " + Array.getLength( values[i] )+ " : \"" + tokens[ i ] + "\" needs " +cVerts*3+ " float values \n");
				
				p_float[] filledP = new p_float[ cVerts ];
				System.arraycopy( values[ i ], 0, filledP, 0, Array.getLength( values[ i ] ) );
				for( int j = Array.getLength( values[ i ] ); j < filledP.length; j++ ) 
					filledP[ j ] = new p_float( 0 );
				values[ i ] = filledP;
			}			
		}
		
	    
		
	    if ( type.compareTo( RI_BICUBIC ) == 0 )
	    {
	        // Create a surface patch
		CqSurfacePatchBicubic pSurface =  new CqSurfacePatchBicubic();
	        // Fill in primitive variables specified.
	        if ( ProcessPrimitiveVariables( pSurface, count, tokens, values ) )
	        {
	            // Fill in default values for all primitive variables not explicitly specified.
	            pSurface.SetDefaultPrimitiveVariables();
	            CqMatrix matuBasis = pSurface.pAttributes() .GetMatrixAttribute( "System", "Basis" ) [ 0 ];
	            CqMatrix matvBasis = pSurface.pAttributes() .GetMatrixAttribute( "System", "Basis" ) [ 1 ];
	            pSurface.ConvertToBezierBasis( matuBasis, matvBasis );

	            float time = QGetRenderContext().Time();
	            // Transform the points into camera space for processing,
	            pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );

	            CreateGPrim( pSurface );
	        }
	    }
	    else if ( type.compareTo( RI_BILINEAR ) == 0 )
	    {
	        // Create a surface patch
	    	CqSurfacePatchBilinear pSurface = new CqSurfacePatchBilinear() ;
	        // Fill in primitive variables specified.
	        if ( ProcessPrimitiveVariables( pSurface, count, tokens, values ) )
	        {
	            // Fill in default values for all primitive variables not explicitly specified.
	            pSurface.SetDefaultPrimitiveVariables();
	            float time = QGetRenderContext().Time();
	            // Transform the points into camera space for processing,
	            pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
	            CreateGPrim( pSurface );
	        }
	    }
	    else
	    {
	    	logger.error( "RiPatch invalid patch type \"" + type + "\"" );
	    }

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiPatchMesh
//	 Specify a quadrilaterla mesh of patches.
//	 パッチのquadrilaterlaメッシュを指定してください。
	//
	public static void	RiPatchMesh( String type, int nu, String uwrap, int nv, String vwrap, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiPatchMeshV( type, nu, uwrap, nv, vwrap, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiPatchMeshV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//

	public static void	RiPatchMeshV( String type, int nu, String uwrap, int nv, String vwrap, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiPatchMeshCache(type, nu, uwrap, nv, vwrap, count, tokens, values) );
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error( "Invalid state for RiPatchMesh [" + GetStateAsString() +"]\n" );
			return;
		}
		
		// check nu, nv
		if( nu < 1 ) {
			logger.error("Invalid parameter " + nu + " : nu > 0 \n");
			return;
		}
		else if( nv < 1 ) {
			logger.error("Invalid parameter " + nv + " : nv > 0 \n");
			return;
		}
		
		// check uwrap, vwrap
	    if( uwrap.compareTo( RI_PERIODIC ) != 0 && uwrap.compareTo( RI_NONPERIODIC ) != 0 )
	    	logger.error( "RiPatchMesh invalid u-wrap type: \"" + uwrap + "\"\n" );

	    if( vwrap.compareTo( RI_PERIODIC ) != 0 && vwrap.compareTo( RI_NONPERIODIC ) != 0)
	    	logger.error( "RiPatchMesh invalid v-wrap type: \"" + vwrap + "\"\n" );
	    
	    
	    // Check "P" length
		int cVerts = nu * nv;
		for( int i = 0; i < count; i++ ) 
		{
			if( tokens[ i ].equals("P"))		cVerts *= 3;	
			else if( tokens[ i ].equals("Pw"))	cVerts *= 4;
			else if( tokens[ i ].equals("Pz") )	cVerts *= cVerts;
			else	continue;
				
			int diff = cVerts - Array.getLength( values[ i ] );
			if( diff > 0 ) 	
			{
				logger.error("Invalid \"" + tokens[ i ] + "\" parameter length " + Array.getLength( values[i] )+ " : \"" + tokens[ i ] + "\" needs " +cVerts*3+ " float values \n");
				
				p_float[] filledP = new p_float[ cVerts ];
				System.arraycopy( values[ i ], 0, filledP, 0, Array.getLength( values[ i ] ) );
				for( int j = Array.getLength( values[ i ] ); j < filledP.length; j++ ) 
					filledP[ j ] = new p_float( 0 );
				values[ i ] = filledP;
			}			
		}
		
		
	    
	    if (  type.compareTo( RI_BICUBIC ) == 0 )
	    {
	        // Create a surface patch
	        boolean	uPeriodic = (  uwrap.compareTo( RI_PERIODIC ) == 0 ) ? true : false;
	        boolean	vPeriodic = (  vwrap.compareTo( RI_PERIODIC ) == 0 ) ? true : false;

		CqSurfacePatchMeshBicubic pSurface = new CqSurfacePatchMeshBicubic( nu, nv, uPeriodic, vPeriodic );
	        // Fill in primitive variables specified.
	        if ( ProcessPrimitiveVariables( pSurface, count, tokens, values ) )
	        {
	            // Fill in default values for all primitive variables not explicitly specified.
	            pSurface.SetDefaultPrimitiveVariables();
	            STLVector<CqBasicSurface> aSplits = new STLVector<CqBasicSurface>(CqBasicSurface.class);
	            pSurface.Split( aSplits );
	     
	            for ( CqBasicSurface iSS : aSplits)
	            {
	                CqMatrix matuBasis = pSurface.pAttributes() .GetMatrixAttribute( "System", "Basis" ) [ 0 ];
	                CqMatrix matvBasis = pSurface.pAttributes() .GetMatrixAttribute( "System", "Basis" ) [ 1 ];
	                (( CqSurfacePatchBicubic )( iSS ) ).ConvertToBezierBasis( matuBasis, matvBasis );
	                float time = QGetRenderContext().Time();
	                // Transform the points into camera space for processing,
	                (iSS).Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                   QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                   QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
	                CreateGPrim( iSS );
	            }
	        }
	    }
	    else if ( type.compareTo( RI_BILINEAR ) == 0 )
	    {
	        // Create a surface patch
	        boolean	uPeriodic = ( uwrap.compareTo( RI_PERIODIC ) == 0 ) ? true : false;
	        boolean	vPeriodic = ( vwrap.compareTo( RI_PERIODIC ) == 0 ) ? true : false;

	        CqSurfacePatchMeshBilinear pSurface = new CqSurfacePatchMeshBilinear( nu, nv, uPeriodic, vPeriodic ) ;
	        // Fill in primitive variables specified.
	        if ( ProcessPrimitiveVariables( pSurface, count, tokens, values ) )
	        {
	            // Fill in default values for all primitive variables not explicitly specified.
	            pSurface.SetDefaultPrimitiveVariables();
	            float time = QGetRenderContext().Time();
	            // Transform the points into camera space for processing,
	            pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                                 QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
	            CreateGPrim( pSurface );
	        }
	    }
	    else
	    {
	    	logger.error( "RiPatchMesh invalid type \"" + type + "\"" );
	    }

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiNuPatch
//	 Specify a new non uniform patch.
//	 新しい非のユニフォームパッチを指定してください。
	//
	public static void	RiNuPatch( int nu, int uorder, float uknot[], float umin, float umax,
	                  int nv, int vorder, float vknot[], float vmin, float vmax, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiNuPatchV( nu, uorder, uknot, umin, umax, nv, vorder, vknot, vmin, vmax, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiNuPatchV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiNuPatchV( int nu, int uorder, float uknot[], float umin, float umax,
	                   int nv, int vorder, float vknot[], float vmin, float vmax, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiNuPatchCache(nu, uorder, uknot, umin, umax, nv, vorder, vknot, vmin, vmax, count, tokens, values) );
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error( "Invalid state for RiNuPatch [" + GetStateAsString() + "]\n" ); 
			return; 
		}

	    // check n,v
		else if( uorder < 1){ logger.error("Invalid parameter " + uorder + " : " + "uorder" + " > 0 \n" ); return ;}
		else if( vorder < 1){ logger.error("Invalid parameter " + vorder + " : " + "vorder" + " > 0 \n" ); return ;}
		else if( nu < uorder ){ logger.error("Invalid parameter " + nu + " : " + "nu" + " > uorder = " + uorder + "\n"); return ; }
		else if( nv < vorder ){ logger.error("Invalid parameter " + nv + " : " + "nv" + " > vorder = " + vorder + "\n"); return ; }

		// check uknot, vknot 				
		if( nu + uorder != uknot.length ){ logger.error("Invalid \"uknot\" parameter length " + uknot.length + " : \"uknot\" needs " + (nu+uorder) + " float values \n" ); return ;}
		if( nv + vorder != vknot.length ){ logger.error("Invalid \"vknot\" parameter length " + vknot.length + " : \"vknot\" needs " + (nv+vorder) + " float values \n" ); return ;}
		
		  
	    // Check "P" length
		int cVerts = nu * nv;
		for( int i = 0; i < count; i++ ) 
		{
			if( tokens[ i ].equals("P"))		cVerts *= 3;	
			else if( tokens[ i ].equals("Pw"))	cVerts *= 4;
			else	continue;
				
			int diff = cVerts - Array.getLength( values[ i ] );
			if( diff > 0 ) 	
			{
				logger.error("Invalid \"" + tokens[ i ] + "\" parameter length " + Array.getLength( values[i] )+ " : \"" + tokens[ i ] + "\" needs " +cVerts*3+ " float values \n");
				
				p_float[] filledP = new p_float[ cVerts ];
				System.arraycopy( values[ i ], 0, filledP, 0, Array.getLength( values[ i ] ) );
				for( int j = Array.getLength( values[ i ] ); j < filledP.length; j++ ) 
					filledP[ j ] = new p_float( 0 );
				values[ i ] = filledP;
			}			
		}
		
		
	    // Create a NURBS patch
	    CqSurfaceNURBS pSurface = new CqSurfaceNURBS();
	    pSurface.SetfPatchMesh();
	    pSurface.Init( uorder, vorder, nu, nv );

	    pSurface.Setumin( umin );
	    pSurface.Setumax( umax );
	    pSurface.Setvmin( vmin );
	    pSurface.Setvmax( vmax );

	    // Copy the knot vectors.
	    int i;
	    for ( i = 0; i < nu + uorder; ++i ) pSurface.auKnots().get( i ).value = uknot[ i ];
	    for ( i = 0; i < nv + vorder; ++i ) pSurface.avKnots().get( i ).value = vknot[ i ];

	    // Process any specified parameters
	    if ( ProcessPrimitiveVariables( pSurface, count, tokens, values ) )
	    {
	        // Set up the default primitive variables.
	        pSurface.SetDefaultPrimitiveVariables();
	        // Clamp the surface to ensure non-periodic.
	        pSurface.Clamp();
	        float time = QGetRenderContext().Time();
	        // Transform the points into camera space for processing,
	        pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                             QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                             QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
	        CreateGPrim( pSurface );
	    }

	    return ;
	}

//	----------------------------------------------------------------------
//	 RiTrimCurve
//	 Specify curves which are used to trim NURBS surfaces.
//	 NURBSの表面を整えるのに使用されるカーブを指定してください。
	//
	public static void	RiTrimCurve( int nloops, int ncurves[], int order[], float knot[], float min[], float max[], int n[], float u[], float v[], float w[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiTrimCurveCache(nloops, ncurves, order, knot, min, max, n, u, v, w) );
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error("Invalid state for RiTrimCurve [" + GetStateAsString() + "]\n" );
			return;
		}
		
		// check ncurves
		for( int i = 0; i < nloops; i++ ){
			if( ncurves[i] < 0 ){
				logger.error("Invalid parameter " +ncurves[i]+ " at ncurves["+i+"] : all ncurves > 0 \n");
				return;
			}
		}
		// check order 
		if( order.length != n.length )	{
			logger.error("Invalid \"order\" parameter length and \"n\" parameter length \n");
			return ;
		}
		for( int i = 0; i < order.length; i++ )
		{
			if( order[i] < 1 ){
				logger.error("Invalid parameter " +order[i]+ " at order["+i+"] : all order > 0 \n");
				return;
			}
			if( n[i] < 1 ){
				logger.error("Invalid parameter " +n[i]+ " at n["+i+"] : all n > 0 \n");
				return;
			}
		}

		
	    // Clear the current loop array.
	    QGetRenderContext() .pattrWriteCurrent() .TrimLoops().Clear();

	    // Build an array of curves per specified loop.
	    int in = 0;
	    int iorder = 0;
	    int iknot = 0;
	    int ivert = 0;
	    int iloop;

	    for ( iloop = 0; iloop < nloops; ++iloop )
	    {
	        CqTrimLoop Loop = new CqTrimLoop();
	        int icurve;
	        for ( icurve = 0; icurve < ncurves[ iloop ]; ++icurve )
	        {
	            // Create a NURBS patch
	            CqTrimCurve Curve = new CqTrimCurve();
	            int o = order[ iorder++ ];
	            int cverts = n[ in++ ];
	            Curve.Init( o, cverts );
	            
	            // Copy the knot vectors.
	            int i;
	            boolean out = false;
	            for ( i = 0; i < o + cverts; ++i ) {
	            	if( i >= knot.length ) {
	            		Curve.aKnots().get( i ).value = 0.0f;
	            		out = true;
	            	}
	            	else
	            		Curve.aKnots().get( i ).value = knot[ iknot++ ] ;
	            }

	            // print knot values errmessage
	            if( out )
	            	logger.error("Invalid \"knot\" parameter length " + knot.length + " : \"knot\" needs " + ( o + cverts ) + " float values \n");
				
	            // Copy the vertices from the u,v,w arrays.
	            CqVector3D vec = new CqVector3D( 0, 0, 1 );
	            for ( i = 0; i < cverts; ++i )
	            {
	                vec.x( u[ ivert ] );
	                vec.y( v[ ivert ] );
	                vec.z( w[ ivert++ ] );
	                Curve.CP( i ).assignment( vec );
	            }
	            Loop.aCurves().add( Curve );
	        }
	        QGetRenderContext() .pattrWriteCurrent() .TrimLoops().aLoops().add( Loop );
	    }
	    return ;
	}



//	----------------------------------------------------------------------
//	 RiSphere
//	 Specify a sphere primitive.
//	 プリミティブの球を指定してください。
	//
	public static void	RiSphere( float radius, float zmin, float zmax, float thetamax, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiSphereV( radius, zmin, zmax, thetamax, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiSphereV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiSphereV( float radius, float zmin, float zmax, float thetamax, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiSphereCache(radius, zmin, zmax, thetamax, count, tokens, values) ); 
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiSphere [" + GetStateAsString() + "]\n" ); 
			return;
		}


	    // Check "P" length
		int cVerts = 4;
		for( int i = 0; i < count; i++ ) 
		{
			if( tokens[ i ].equals("P"))		cVerts *= 3;	
			else if( tokens[ i ].equals("Pw"))	cVerts *= 4;
			else if( tokens[ i ].equals("Pz") )	cVerts *= cVerts;
			else	continue;
				
			int diff = cVerts - Array.getLength( values[ i ] );
			if( diff > 0 ) 	{
				p_float[] filledP = new p_float[ cVerts ];
				System.arraycopy( values[ i ], 0, filledP, 0, Array.getLength( values[ i ] ) );
				for( int j = Array.getLength( values[ i ] ); j < filledP.length; j++ ) 
					filledP[ j ] = new p_float( 0 );
				values[ i ] = filledP;
			}			
		}
		
	    CqLogRangeCheckCallback rc = new CqLogRangeCheckCallback();

	    rc.set( "sphere zmin" );
	    CheckMinMax( zmin, Math.min(-radius, radius), Math.max(-radius,radius), rc );
	    rc.set( "sphere zmax" );
	    CheckMinMax( zmax, Math.min(-radius, radius), Math.max(-radius,radius), rc );

	    // Create a sphere
	    CqSphere pSurface = new CqSphere( radius, zmin, zmax, 0, thetamax );// ここで球を作成
	    ProcessPrimitiveVariables( pSurface, count, tokens, values );
	    pSurface.SetDefaultPrimitiveVariables();

	    float time = QGetRenderContext().Time();
	    // Transform the points into camera space for processing,
	    pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera",new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matNSpaceToSpace( "object", "camera",new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matVSpaceToSpace( "object", "camera",new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
	    CreateGPrim( pSurface );

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiCone
//	 Specify a cone primitive.
//	 特別な三角錐のプリミティブ
	//
	public static void	RiCone( float height, float radius, float thetamax, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiConeV( height, radius, thetamax, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiConeV
//	 List based version of above.
	//
	public static void	RiConeV( float height, float radius, float thetamax, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiConeCache(height, radius, thetamax, count, tokens, values) );
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{ 
			logger.error( "Invalid state for RiCone [" + GetStateAsString() + "]\n" ); 
			return; 
		} 

	    // XXX: This should be an exception and get caught further up.
	    if( thetamax == 0 )
	        return;

	    // Check "P" length
		int cVerts = 4;
		for( int i = 0; i < count; i++ ) 
		{
			if( tokens[ i ].equals("P"))		cVerts *= 3;	
			else if( tokens[ i ].equals("Pw"))	cVerts *= 4;
			else if( tokens[ i ].equals("Pz") )	cVerts *= cVerts;
			else	continue;
				
			int diff = cVerts - Array.getLength( values[ i ] );
			if( diff > 0 ) 	{
				p_float[] filledP = new p_float[ cVerts ];
				System.arraycopy( values[ i ], 0, filledP, 0, Array.getLength( values[ i ] ) );
				for( int j = Array.getLength( values[ i ] ); j < filledP.length; j++ ) 
					filledP[ j ] = new p_float( 0 );
				values[ i ] = filledP;
			}			
		}
		
	    // Create a cone
	    CqCone pSurface = new CqCone( height, radius, 0, thetamax, 0, 1.0f );
	    ProcessPrimitiveVariables( pSurface, count, tokens, values );
	    pSurface.SetDefaultPrimitiveVariables();

	    float time = QGetRenderContext().Time();
	    // Transform the points into camera space for processing,
	    pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
	    CreateGPrim( pSurface );

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiCylinder
//	 Specify a Cylinder primitive.
//	 円柱のプリミティブを指定する。
	//
	public static void	RiCylinder( float radius, float zmin, float zmax, float thetamax, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiCylinderV( radius, zmin, zmax, thetamax, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiCylinderV
//	 List based version of above.
	//
	public static void	RiCylinderV( float radius, float zmin, float zmax, float thetamax, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiCylinderCache(radius, zmin, zmax, thetamax, count, tokens, values) );
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) ) 
		{ 
			logger.error("Invalid state for RiCylinder [" + GetStateAsString() + "]\n" ); 
			return; 
		} 

	    // Check "P" length
		int cVerts = 4;
		for( int i = 0; i < count; i++ ) 
		{
			if( tokens[ i ].equals("P"))		cVerts *= 3;	
			else if( tokens[ i ].equals("Pw"))	cVerts *= 4;
			else if( tokens[ i ].equals("Pz") )	cVerts *= cVerts;
			else	continue;
				
			int diff = cVerts - Array.getLength( values[ i ] );
			if( diff > 0 ) 	{
				p_float[] filledP = new p_float[ cVerts ];
				System.arraycopy( values[ i ], 0, filledP, 0, Array.getLength( values[ i ] ) );
				for( int j = Array.getLength( values[ i ] ); j < filledP.length; j++ ) 
					filledP[ j ] = new p_float( 0 );
				values[ i ] = filledP;
			}			
		}
		
		
	    // Create a cylinder
	    CqCylinder pSurface =  new CqCylinder( radius, zmin, zmax, 0, thetamax ) ;
	    ProcessPrimitiveVariables( pSurface, count, tokens, values );
	    pSurface.SetDefaultPrimitiveVariables();

	    float time = QGetRenderContext().Time();
	    // Transform the points into camera space for processing,
	    pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
	    CreateGPrim( pSurface );

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiHyperboloid
//	 Specify a hyperboloid primitive.
//	 双曲面のプリミティブを指定する。
	//
	public static void	RiHyperboloid( float[] point1, float[] point2, float thetamax, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiHyperboloidV( point1, point2, thetamax, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiHyperboloidV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiHyperboloidV( float[] point1, float[] point2, float thetamax, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiHyperboloidCache(point1, point2, thetamax, count, tokens, values) );
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error( "Invalid state for RiHyperboloid [" + GetStateAsString() + "]\n" );
			return;
		}


	    // Check "P" length
		int cVerts = 4;
		for( int i = 0; i < count; i++ ) 
		{
			if( tokens[ i ].equals("P"))		cVerts *= 3;	
			else if( tokens[ i ].equals("Pw"))	cVerts *= 4;
			else if( tokens[ i ].equals("Pz") )	cVerts *= cVerts;
			else	continue;
				
			int diff = cVerts - Array.getLength( values[ i ] );
			if( diff > 0 ) 	{
				p_float[] filledP = new p_float[ cVerts ];
				System.arraycopy( values[ i ], 0, filledP, 0, Array.getLength( values[ i ] ) );
				for( int j = Array.getLength( values[ i ] ); j < filledP.length; j++ ) 
					filledP[ j ] = new p_float( 0 );
				values[ i ] = filledP;
			}			
		}
		
		
		
	    // Create a hyperboloid
	    CqVector3D v0 = new CqVector3D( point1[ 0 ], point1[ 1 ], point1[ 2 ] );
	    CqVector3D v1 = new CqVector3D( point2[ 0 ], point2[ 1 ], point2[ 2 ] );
	    CqHyperboloid pSurface =  new CqHyperboloid( v0, v1, 0, thetamax );
	    ProcessPrimitiveVariables( pSurface, count, tokens, values );
	    pSurface.SetDefaultPrimitiveVariables();

	    float time = QGetRenderContext().Time();
	    // Transform the points into camera space for processing,
	    pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
	    CreateGPrim( pSurface );

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiParaboloid
//	 Specify a paraboloid primitive.
//	 放物面プリミティブを指定してください。
	//
	public static void	RiParaboloid( float rmax, float zmin, float zmax, float thetamax, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiParaboloidV( rmax, zmin, zmax, thetamax, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiParaboloidV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiParaboloidV( float rmax, float zmin, float zmax, float thetamax, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiParaboloidCache(rmax, zmin, zmax, thetamax, count, tokens, values) );
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error( "Invalid state for RiParaboloid [" + GetStateAsString() + "]\n");
			return;
		}

		// check zmax,zmin
		if( zmin < 0 ) {
			logger.error( "Invalid parameter " + zmin + " : zmin > 0 \n" );
			return ; 
		}
		if( zmax < zmin ) {
			logger.error( "Invalid parameter " + zmax + " : zmax > zmin = " + zmin + "\n" );
			return ;
		}
		
	    // Check "P" length
		int cVerts = 4;
		for( int i = 0; i < count; i++ ) 
		{
			if( tokens[ i ].equals("P"))		cVerts *= 3;	
			else if( tokens[ i ].equals("Pw"))	cVerts *= 4;
			else if( tokens[ i ].equals("Pz") )	cVerts *= cVerts;
			else	continue;
				
			int diff = cVerts - Array.getLength( values[ i ] );
			if( diff > 0 ) 	{
				p_float[] filledP = new p_float[ cVerts ];
				System.arraycopy( values[ i ], 0, filledP, 0, Array.getLength( values[ i ] ) );
				for( int j = Array.getLength( values[ i ] ); j < filledP.length; j++ ) 
					filledP[ j ] = new p_float( 0 );
				values[ i ] = filledP;
			}			
		}
		
		
	    // Create a paraboloid
	    CqParaboloid pSurface =  new CqParaboloid( rmax, zmin, zmax, 0, thetamax ) ;
	    ProcessPrimitiveVariables( pSurface, count, tokens, values );
	    pSurface.SetDefaultPrimitiveVariables();

	    float time = QGetRenderContext().Time();
	    // Transform the points into camera space for processing,
	    pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );
	    CreateGPrim( pSurface );

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiDisk
//	 Specify a disk primitive.
//	 円形のプリミティブを指定する。
	//
	public static void	RiDisk( float height, float radius, float thetamax, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiDiskV( height, radius, thetamax, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiDiskV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiDiskV( float height, float radius, float thetamax, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiDiskCache(height, radius, thetamax, count, tokens, values) );
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error( "Invalid state for RiDisk [" + GetStateAsString() + "]\n" );
			return;
		}

	    // Check "P" length
		int cVerts = 4;
		for( int i = 0; i < count; i++ ) 
		{
			if( tokens[ i ].equals("P"))		cVerts *= 3;	
			else if( tokens[ i ].equals("Pw"))	cVerts *= 4;
			else if( tokens[ i ].equals("Pz") )	cVerts *= cVerts;
			else	continue;
				
			int diff = cVerts - Array.getLength( values[ i ] );
			if( diff > 0 ) 	{
				p_float[] filledP = new p_float[ cVerts ];
				System.arraycopy( values[ i ], 0, filledP, 0, Array.getLength( values[ i ] ) );
				for( int j = Array.getLength( values[ i ] ); j < filledP.length; j++ ) 
					filledP[ j ] = new p_float( 0 );
				values[ i ] = filledP;
			}			
		}
		
	    // Create a disk
	    CqDisk pSurface = new CqDisk( height, 0, radius, 0, thetamax ) ;
	    ProcessPrimitiveVariables( pSurface, count, tokens, values );
	    pSurface.SetDefaultPrimitiveVariables();

	    float time = QGetRenderContext().Time();
	    // Transform the points into camera space for processing,
	    pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera",new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matNSpaceToSpace( "object", "camera",new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matVSpaceToSpace( "object", "camera",new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );

	    CreateGPrim( pSurface );

	    return ;
	}


	//	----------------------------------------------------------------------
	//
	//
	public static void	RiTorus( float majorrad, float minorrad, float phimin, float phimax, float thetamax, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiTorusV( majorrad, minorrad, phimin, phimax, thetamax, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiTorus
//	 Specify a torus primitive.
//	 トーラスプリミティブを指定してください。
	//
	public static void	RiTorusV( float majorrad, float minorrad, float phimin, float phimax, float thetamax, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiTorusCache(majorrad, minorrad, phimin, phimax, thetamax, count, tokens, values) );
			return;
		}

		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{ 
			logger.error( "Invalid state for RiTorus [" + GetStateAsString() + "]\n" ); 
			return; 
		} 

	    // Check "P" length
		int cVerts = 4;
		for( int i = 0; i < count; i++ ) 
		{
			if( tokens[ i ].equals("P"))		cVerts *= 3;	
			else if( tokens[ i ].equals("Pw"))	cVerts *= 4;
			else if( tokens[ i ].equals("Pz") )	cVerts *= cVerts;
			else	continue;
				
			int diff = cVerts - Array.getLength( values[ i ] );
			if( diff > 0 ) 	{
				p_float[] filledP = new p_float[ cVerts ];
				System.arraycopy( values[ i ], 0, filledP, 0, Array.getLength( values[ i ] ) );
				for( int j = Array.getLength( values[ i ] ); j < filledP.length; j++ ) 
					filledP[ j ] = new p_float( 0 );
				values[ i ] = filledP;
			}			
		}
		

	    // Create a torus
	    CqTorus pSurface =  new CqTorus( majorrad, minorrad, phimin, phimax, 0, thetamax ) ;
	    ProcessPrimitiveVariables( pSurface, count, tokens, values );
	    pSurface.SetDefaultPrimitiveVariables();

	    float time = QGetRenderContext().Time();
	    // Transform the points into camera space for processing,
	    pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                         QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );

	    CreateGPrim( pSurface );

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiProcedural
//	 Implement the procedural type primitive.
//	 プリミティブに手続き上のタイプを与えてください。
//
	public static void RiProcedural( Object[] data, float[] bound, Method refineproc, Method freeproc )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiProceduralCache(data, bound, refineproc, freeproc) );
			return;
		}

		if(!ValidateState(5, World, Attribute, Transform, Solid, Object) )
		{
			logger.error( "Invalid state for RiProcedural [" + GetStateAsString() + "]\n" );
			return;
		}

	    CqBound B = new CqBound( bound );

	    //printf("bound(%f %f %f %f %f %f)\n", bound[0], bound[1], bound[2], bound[3], bound[4], bound[5]);

	    // I suspect that in order to handle the RtFreeProc correctly that we need to reference count
	    // the instances of CqProcedural so that FreeProc gets called on the final Release();

	    CqProcedural pProc = new CqProcedural(data, B, refineproc, freeproc );
		float time = QGetRenderContext().Time();
	    pProc.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pProc.pTransform() .matObjectToWorld(time), time ),
	                      QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pProc.pTransform() .matObjectToWorld(time), time ),
	                      QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pProc.pTransform() .matObjectToWorld(time), time ) );
	    CreateGPrim( pProc );

	    return ;
	}
	
	
	public static void RiProcRunProgram ( Object[] data, float detail )
	{
		//必要パラメタを取得
		String progName = ((p_String[])data[0])[0].value;
		String strParam = ((p_String[])data[0])[1].value;
		
		//拡張子未指定の場合はどうするか。
		if( !progName.contains(".") )	progName += ".exe";
		
		try{
			//Runtimeの取得
			Runtime runtime = Runtime.getRuntime();
			
			//genRegPoly.exeのProcessを取得
			Process process = runtime.exec( progName );
			
			//Processからストリームを取得
			BufferedInputStream  bis = new BufferedInputStream ( process.getInputStream() );
			BufferedOutputStream bos = new BufferedOutputStream( process.getOutputStream() );
			
			//こちらの情報をインプットする
			bos.write( ( detail + " " + strParam ).getBytes() );
			bos.flush();
			bos.close();
			
			//アウトプットをひろう。
			Parser parser = new Parser();
			parser.parse( progName, bis );
			
		}
		catch( Exception e ){
			HimawariLogger.outputException(e);
	        logger.error( "RiProcRunProgram: CreateProcess failed \n" );
		}
	}
	
	public static void RiProcDelayedReadArchive ( Object[] data, float detail )
	{
	    RiReadArchive( ((p_String[])data[0])[0].value, null );
	    STATS_INC( GEO_prc_created_dra );
	}
	
	public static void RiProcDynamicLoad ( Object[] data, float detail )
	{
		logger.warning( "RiProcDynamicLoad not supported\n" );
	}
	
	public static void RiProcFree ( Object[] data )
	{
		//Javaでは実装しない
		//free( data );
	}
	
	
//	----------------------------------------------------------------------
//	 RiGeometry
//	 Specify a special primitive.
//	 特別なプリミティブを指定する。
	//
	public static void	RiGeometry( String type, Object... pArgs )
	{

	   STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiGeometryV( type, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiGeometryV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiGeometryV( String type, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiGeometryCache(type, count, tokens, values) );
			return;
		}

		if(!ValidateState(5, World, Attribute, Transform, Solid, Object) )
		{
			logger.error( "Invalid state for RiGeometry [" + GetStateAsString() + "]\n" );
			return;
		}

	    if ( type.compareTo( "teapot" ) == 0 )
	    {

	        // Create a standard teapot
	    	CqTeapot pSurface =  new CqTeapot( true ) ; // add a bottom if true/false otherwise

	        pSurface.SetSurfaceParameters( pSurface );
	        ProcessPrimitiveVariables( pSurface, count, tokens, values );
	        pSurface.SetDefaultPrimitiveVariables();

	        // I don't use the original teapot primitives as defined by T. Burge
	        // but an array of Patch Bicubic (stolen from example from Pixar) and
	        // those (6 meshes) are registered as standards GPrims right here.
	        // Basically I kept the bound, transform and split, dice and diceable methods
	        // in teapot.cpp but I suspect they are never called since the work of
	        // dicing will rely on the registered Gprimitives (see below in the for loop).
	        // I suspect the 6/7 meshes are equivalent in size/definition as the T. Burge
	        // definition. The 7th is the bottom part of the teapot (see teapot.cpp).

	        for ( int i = 0; i < pSurface.cNbrPatchMeshBicubic; ++i )
	        {
	        	CqSurface pMesh = pSurface.pPatchMeshBicubic[ i ];

	            float time = QGetRenderContext().Time();
	            // Transform the points into camera space for processing,
	            pMesh.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                              QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                              QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );

	            CreateGPrim( (CqBasicSurface)( pMesh ) );
	        }
	    }
	    else if ( type.compareTo( "sphere" ) == 0 )
	    {
	        // Create a sphere
	    	CqSphere pSurface = new CqSphere( 1f,-1f, 1f, 0f, 360.0f );
	        ProcessPrimitiveVariables( pSurface, count, tokens, values );
	        pSurface.SetDefaultPrimitiveVariables();

	        float time = QGetRenderContext().Time();
	        // Transform the points into camera space for processing,
	        pSurface.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                             QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ),
	                             QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pSurface.pTransform() .matObjectToWorld(time), time ) );

	        CreateGPrim( pSurface );
	    }
	    else
	    {
	    	logger.warning( "RiGeometry unrecognised type \"" + type + "\"" + "\n" );
	    }

	    return ;
	}

//	----------------------------------------------------------------------
//	 RiSolidBegin
//	 Begin the definition of a CSG object.
//	 CSGオブジェクトの定義を始めてください。
	//
	public static void	RiSolidBegin( String type )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiSolidBeginCache(type) );
			return;
		}

		if(!ValidateState(5, World, Attribute, Transform, Solid, Object) )
		{
			logger.error( "Invalid state for RiSolidBegin [" + GetStateAsString() + "]\n" );
			return;
		}

		// check solid type
	    String strType = type;
	    if( !type.equals( "primitive" ) && !type.equals( "union" ) && !type.equals( "intersection" ) && !type.equals( "difference" ) ) {
	    	logger.error("Invalid Parameter \"" +type+ "\" : Solid Type is ( \"primitive\", \"union\", \"intersection\", \"difference\" ) \n");
	    	return;
	    }
	    
	    QGetRenderContext() .BeginSolidModeBlock( strType );

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiSolidEnd
//	 End the definition of a CSG object.
//	 CSGオブジェクトの定義を終わらせてください。
	//
	public static void	RiSolidEnd()
	{	
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiSolidEndCache() );
			return;
		}

		if(!ValidateState(1, Solid) )
		{
			logger.error( "Invalid state for RiSolidEnd [" + GetStateAsString() + "]\n" );
			return;
		}

	    QGetRenderContext() .EndSolidModeBlock();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiObjectBegin
//	 Begin the definition of a stored object for use by RiObjectInstance.
//	 RiObjectInstanceによる使用のために保存されたオブジェクトの定義を始めてください。
	//
	public static Object	RiObjectBegin()
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiObjectBeginCache() );
			return(null);
		}

		if(!ValidateState(6, BeginEnd, Frame, World, Attribute, Transform, Solid) )
		{
			logger.error( "Invalid state for RiObjectBegin [" + GetStateAsString() + "]\n" );
			return(null);
		}

	    QGetRenderContext() .BeginObjectModeBlock();
	    Object ObjectHandle = (Object)(QGetRenderContext() .OpenNewObjectInstance());

	    return ( ObjectHandle );
	}


//	----------------------------------------------------------------------
//	 RiObjectEnd
//	 End the defintion of a stored object for use by RiObjectInstance.
//	RiObjectInstanceによる使用のために保存されたオブジェクトの定義を終わらせてください。
	//
	public static void	RiObjectEnd()
	{
		if(!ValidateState(1, Object) )
		{
			logger.error( "Invalid state for RiObjectEnd [" + GetStateAsString() + "]\n");
			return;
		}

	    QGetRenderContext() .EndObjectModeBlock();
		QGetRenderContext() .CloseObjectInstance();

		if( QGetRenderContext().pCurrentObject() != null )
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiObjectEndCache() );
			return;	
		}

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiObjectInstance
//	 Instantiate a copt of a pre-stored geometric object.
//	 プレ保存された幾何学上オブジェクトのcoptを例示してください。
	//
	public static void	RiObjectInstance( Object handle )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiObjectInstanceCache(handle) );
			return;
		}

		if(!ValidateState(5, World, Attribute, Transform, Solid, Object) )
		{
			logger.error( "Invalid state for RiObjectInstance [" + GetStateAsString() + "]\n" );
			return;
		}

		QGetRenderContext() .InstantiateObject( (CqObjectInstance)( handle ) );
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiMotionBegin
//	 Begin the definition of the motion of an object for use by motion blur.
//	 使用のためにモーションブラーでオブジェクトの動きの定義を始めてください。
	//
	public static void	RiMotionBegin( int N, Object... pArgs )
	{

		float[] times = new float[ N ];
	    int i;
	    for ( i = 0; i < N; ++i )
	        times[ i ] = ((p_float) pArgs[i]).value;

	    RiMotionBeginV( N, times );

//	    delete[] ( times );
	    times = null;
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiBeginMotionV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiMotionBeginV( int N, float times[] )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiMotionBeginVCache(N, times) );
			return;
		}

		if(!ValidateState(7, BeginEnd, Frame, World, Attribute, Transform, Solid, Object) )
		{
			logger.error( "Invalid state for RiMotionBeginV [" + GetStateAsString() + "]\n" );
			return;
		}

	    QGetRenderContext() .BeginMotionModeBlock( N, times );

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiMotionEnd
//	 End the definition of the motion of an object.
//	 オブジェクトの動きの定義を終わらせてください。
	//
	public static void	RiMotionEnd()
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiMotionEndCache() );
			return;
		}

		if(!ValidateState(1, Motion) )
		{
			logger.error( "Invalid state for RiMotionEnd [" + GetStateAsString() + "]\n" );
			return; 
		}

	    QGetRenderContext() .EndMotionModeBlock();

	    return ;
	}


//	----------------------------------------------------------------------
//	 RiMakeTexture
//	 Convert a picture to a texture.
//	 絵をテクスチャに変換してください。
	//
	public static void RiMakeTexture ( String pic, String tex, String swrap, String twrap, Method filterfunc, float swidth, float twidth, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiMakeTextureV( pic, tex, swrap, twrap, filterfunc, swidth, twidth, count, aTokens.toArray(), aValues.toArray() );

	}


//	----------------------------------------------------------------------
//	 RiMakeTextureV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiMakeTextureV( String imagefile, String texturefile, String swrap, String twrap, Method filterfunc, float swidth, float twidth, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiMakeTextureCache(imagefile, texturefile, swrap, twrap, filterfunc, swidth, twidth, count, tokens, values) );
			return;
		}

		if(!ValidateState(2, BeginEnd, Frame) )
		{
			logger.error( "Invalid state for RiMakeTexture [" + GetStateAsString() + "]\n" );
			return;
		}

//	    char modes[ 1024 ];
		String modes;
	    assert( imagefile != null && texturefile != null && swrap != null && twrap != null && filterfunc != null );

	    //ファイル名が同じ場合はエラーログを出してreturnする
	    if(imagefile.equals(texturefile)){
			HimawariLogger.getLogger().error("ImageFile and TextureMapFile are the same names. \""+ imagefile + "\"\n");
			return;
	    }
	    QGetRenderContext() .Stats().MakeTextureTimer().Start();
	    // Get the wrap modes first.
//	    EqWrapMode smode = new EqWrapMode(EqWrapMode.WrapMode_Black);	//読み取られていない
//	    if ( swrap.compareTo(RI_PERIODIC ) == 0)
//	        smode = new EqWrapMode(EqWrapMode.WrapMode_Periodic);
//	    else if ( swrap.compareTo( RI_CLAMP ) == 0 )
//	        smode = new EqWrapMode(EqWrapMode.WrapMode_Clamp);
//	    else if ( swrap.compareTo(RI_BLACK ) == 0 )
//	        smode = new EqWrapMode(EqWrapMode.WrapMode_Black);
//
//	    EqWrapMode tmode = new EqWrapMode(EqWrapMode.WrapMode_Black);
//	    if ( twrap.compareTo( RI_PERIODIC ) == 0 )
//	        tmode = new EqWrapMode(EqWrapMode.WrapMode_Periodic);
//	    else if ( twrap.compareTo( RI_CLAMP ) == 0 )
//	        tmode = new EqWrapMode(EqWrapMode.WrapMode_Clamp);
//	    else if ( twrap.compareTo( RI_BLACK ) == 0 )
//	        tmode = new EqWrapMode(EqWrapMode.WrapMode_Black);

/*		2007/12/10 岩渕テクスチャ修正
	    modes = swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;
	    
	    if ( filterfunc.getName().equals("RiGaussianFilter") )
		    modes = swrap +" "+ twrap +" "+ "gaussian" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBoxFilter") )
		    modes = swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiTriangleFilter") )
		    modes = swrap +" "+ twrap +" "+ "triangle" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiCatmullRomFilter") )
		    modes = swrap +" "+ twrap +" "+ "catmull-rom" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiSincFilter") )
		    modes = swrap +" "+ twrap +" "+ "sinc" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiDiskFilter") )
		    modes = swrap +" "+ twrap +" "+ "disk" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBesselFilter") )
		    modes = swrap +" "+ twrap +" "+ "bessel" +" " + swidth +" "+ twidth;
*/
	    
	    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;
	    
	    if ( filterfunc.getName().equals("RiGaussianFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "gaussian" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBoxFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiTriangleFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "triangle" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiCatmullRomFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "catmull-rom" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiSincFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "sinc" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiDiskFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "disk" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBesselFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "bessel" +" " + swidth +" "+ twidth;
	    
	    // Now load the original image.
	    CqTextureMap Source = new CqTextureMap( imagefile );
	    Source.Open();
	    p_int comp = new p_int();
	    p_int qual = new p_int();
	    ProcessCompression( comp, qual, count, tokens, values );
	    Source.SetCompression( comp.value );
	    Source.SetQuality( qual.value );

	    if ( Source.IsValid() && Source.Format().getValue() == EqTexFormat.TexFormat_Plain )
	    {
	        // Hopefully CqTextureMap will take care of closing the tiff file after
	        // it has SAT mapped it so we can overwrite if needs be.
	        // Create a new image.
	        Source.Interpreted( modes );
//	        Source.CreateMIPMAP(); //MIPMAPを作成しない
//	        TIFF ptex = TIFFOpen( texturefile, "w" );
	        FileOutputStream fos = null;
	        //画像を保存する
	        try {
				fos = new FileOutputStream(new File(texturefile));
				ImageIO.write(Source.m_pImage,"png",fos);
      
				//メタ情報を付加する
				fos.write(modes.getBytes());
			} catch (FileNotFoundException e) {
				HimawariLogger.getLogger().error("Cannot open texture file \""+texturefile +"\"\n");
				HimawariLogger.outputException(e);
			} catch (IOException e) {
				HimawariLogger.outputException(e);
			}finally{
				try {
					if(fos != null)
						fos.close();
				} catch (IOException e) {
					HimawariLogger.outputException(e);
				}
			}
	        
//	        TIFFCreateDirectory( ptex );
//	        TIFFSetField( ptex, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB );
//	        TIFFSetField( ptex, TIFFTAG_PIXAR_TEXTUREFORMAT, MIPMAP_HEADER );
//	        TIFFSetField( ptex, TIFFTAG_PIXAR_WRAPMODES, modes );
//	        TIFFSetField( ptex, TIFFTAG_COMPRESSION, Source.Compression() ); /* COMPRESSION_DEFLATE */
//	        int log2 = (int)Math.min( Source.XRes(), Source.YRes() );
//	        log2 = ( int ) ( log( (float)(log2) ) / log( 2.0 ) );


//	        for ( int i = 0; i < log2; ++i )
//	        {
//	            // Write the floating point image to the directory.
//	            CqTextureMapBuffer pBuffer = Source.GetBuffer( 0, 0, i );
//	            if ( pBuffer == null )
//	            	break;
////	            Source.WriteTileImage( ptex, pBuffer, 64, 64, Source.Compression(), Source.Quality() );
//	        }
////	        TIFFClose( ptex );
	    }

	    Source.Close();
	    QGetRenderContext() .Stats().MakeTextureTimer().Stop();
	}


//	----------------------------------------------------------------------
//	 RiMakeBump
//	 Convert a picture to a bump map.
//	 画像をバンプマップに変換する。
	//
	public static void	RiMakeBump( String imagefile, String bumpfile, String swrap, String twrap, Method filterfunc, float swidth, float twidth, Object... pArgs )
	{
		logger.warning( "RiMakeBump not supported\n" );
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiMakeBumpV
//	 List based version of above.
	//
	public static void	RiMakeBumpV( String imagefile, String bumpfile, String swrap, String twrap, Method filterfunc, float swidth, float twidth, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null ) 
		{ 
				QGetRenderContext().pCurrentObject().AddCacheCommand( 
						new RiMakeBumpCache(imagefile, bumpfile, swrap, twrap, filterfunc, swidth, twidth, count, tokens, values) ); 
			return;	
		}

		if(!ValidateState(2, BeginEnd, Frame) ) 
		{
			logger.error( "Invalid state for RiMakeBump [" + GetStateAsString() + "]\n" ); 
			return; 
		} 
		
		logger.warning( "RiMakeBump not supported\n" );
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiMakeLatLongEnvironment
//	 Convert a picture to an environment map.
//	 絵を一つの環境マップに変換する。
	//
	public static void	RiMakeLatLongEnvironment( String imagefile, String reflfile, Method filterfunc, float swidth, float twidth, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiMakeLatLongEnvironmentV( imagefile, reflfile, filterfunc, swidth, twidth, count, aTokens.toArray(), aValues.toArray() );
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiMakeLatLongEnvironmentV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiMakeLatLongEnvironmentV( String imagefile, String reflfile, Method filterfunc, float swidth, float twidth, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiMakeLatLongEnvironmentCache(imagefile, reflfile, filterfunc, swidth, twidth, count, tokens, values) );
			return;
		}

		if(!ValidateState(2, BeginEnd, Frame) )
		{
			logger.error( "Invalid state for RiMakeLatLongEnvironment [" + GetStateAsString() + "]\n" );
			return;
		}

		//ファイル名が同じ場合はエラーを出して処理を終了する
		if(imagefile.equals(reflfile)){
			HimawariLogger.getLogger().error("ImageFile and LatLongMapFile are the same names. \""+ imagefile + "\"\n");
			return;
		}
		String modes;
	    String swrap = "periodic" ;
	    String twrap = "clamp";


	    assert( imagefile != null && reflfile != null && swrap != null && twrap != null && filterfunc != null );
	    
	    QGetRenderContext() .Stats().MakeEnvTimer().Start();

	    /*		2007/12/10 岩渕テクスチャ修正
	    modes = swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;
	    
	    if ( filterfunc.getName().equals("RiGaussianFilter") )
		    modes = swrap +" "+ twrap +" "+ "gaussian" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBoxFilter") )
		    modes = swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiTriangleFilter") )
		    modes = swrap +" "+ twrap +" "+ "triangle" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiCatmullRomFilter") )
		    modes = swrap +" "+ twrap +" "+ "catmull-rom" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiSincFilter") )
		    modes = swrap +" "+ twrap +" "+ "sinc" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiDiskFilter") )
		    modes = swrap +" "+ twrap +" "+ "disk" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBesselFilter") )
		    modes = swrap +" "+ twrap +" "+ "bessel" +" " + swidth +" "+ twidth;
	    */
	    
	    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;

	    if ( filterfunc.getName().equals("RiGaussianFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "gaussian" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBoxFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiTriangleFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "triangle" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiCatmullRomFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "catmull-rom" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiSincFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "sinc" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiDiskFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "disk" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBesselFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "bessel" +" " + swidth +" "+ twidth;
	    

	    // Now load the original image.
	    CqTextureMap Source = new CqTextureMap( imagefile );
	    Source.Open();
	    p_int comp = new p_int();
	    p_int qual = new p_int();
	    ProcessCompression( comp, qual, count, tokens, values );
	    Source.SetCompression( comp.value );
	    Source.SetQuality( qual.value );

	    if ( Source.IsValid() && Source.Format().getValue() == EqTexFormat.TexFormat_Plain )
	    {
	        // Hopefully CqTextureMap will take care of closing the tiff file after
	        // it has SAT mapped it so we can overwrite if needs be.
	        // Create a new image.
	        Source.Interpreted( modes );
//	        Source.CreateMIPMAP(); //MIPMAPを作成しない
//	        TIFF ptex = TIFFOpen( texturefile, "w" );
	        FileOutputStream fos = null;
	        //画像を保存する
	        try {
				fos = new FileOutputStream(new File(reflfile));
				ImageIO.write(Source.m_pImage,"png",fos);
      
				//メタ情報を付加する
				fos.write(modes.getBytes());
			} catch (FileNotFoundException e) {
				HimawariLogger.getLogger().error("Cannot open texture file \""+reflfile +"\"\n");
				HimawariLogger.outputException(e);
			} catch (IOException e) {
				HimawariLogger.outputException(e);
			}finally{
				try {
					if(fos != null)
						fos.close();
				} catch (IOException e) {
					HimawariLogger.outputException(e);
				}
			}
	    }

	    Source.Close();
	    QGetRenderContext() .Stats().MakeEnvTimer().Stop();



//
//	    // Now load the original image.
//	    CqTextureMap Source = new CqTextureMap( imagefile );
//	    Source.Open();
//	    TqInt comp, qual;
//	    ProcessCompression( comp, qual, count, tokens, values );
//	    Source.SetCompression( comp );
//	    Source.SetQuality( qual );
//
//	    if ( Source.IsValid() && Source.Format() == TexFormat_Plain )
//	    {
//	        // Hopefully CqTextureMap will take care of closing the tiff file after
//	        // it has SAT mapped it so we can overwrite if needs be.
//	        // Create a new image.
//	        Source.Interpreted( modes );
//	        Source.CreateMIPMAP();
//	        TIFF ptex = TIFFOpen( reflfile, "w" );
//
//	        TIFFCreateDirectory( ptex );
//	        TIFFSetField( ptex, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB );
//	        TIFFSetField( ptex, TIFFTAG_PIXAR_TEXTUREFORMAT, LATLONG_HEADER );
//	        TIFFSetField( ptex, TIFFTAG_PIXAR_WRAPMODES, modes );
//	        TIFFSetField( ptex, TIFFTAG_SAMPLESPERPIXEL, Source.SamplesPerPixel() );
//	        TIFFSetField( ptex, TIFFTAG_BITSPERSAMPLE, 8 );
//	        TIFFSetField( ptex, TIFFTAG_COMPRESSION, Source.Compression() ); /* COMPRESSION_DEFLATE */
//	        int log2 = MIN( Source.XRes(), Source.YRes() );
//	        log2 = ( int ) ( log( static_cast<float>(log2) ) / log( 2.0 ) );
//
//
//	        for ( int i = 0; i < log2; ++i )
//	        {
//	            // Write the floating point image to the directory.
//	            CqTextureMapBuffer pBuffer = Source.GetBuffer( 0, 0, i );
//	            if ( !pBuffer ) break;
//	            Source.WriteTileImage( ptex, pBuffer, 64, 64, Source.Compression(), Source.Quality() );
//	        }
//	        TIFFClose( ptex );
//	    }
//
//	    Source.Close();
//	    QGetRenderContext() .Stats().MakeEnvTimer().Stop();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiMakeCubeFaceEnvironment
//	 Convert a picture to a cubical environment map.
//	 絵を環境マップに変換する。
	//
	public static void	RiMakeCubeFaceEnvironment( String px, String nx, String py, String ny, String pz, String nz, String reflfile, float fov, Method filterfunc, float swidth, float twidth, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiMakeCubeFaceEnvironmentV( px, nx, py, ny, pz, nz, reflfile, fov, filterfunc, swidth, twidth, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiMakeCubeFaceEnvironment
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiMakeCubeFaceEnvironmentV( String px, String nx, String py, String ny, String pz, String nz, String reflfile, float fov, Method filterfunc, float swidth, float twidth, int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiMakeCubeFaceEnvironmentCache(px, nx, py, ny, pz, nz, reflfile, fov, filterfunc, swidth, twidth, count, tokens, values) );
			return;
		}

		if(!ValidateState(2, BeginEnd, Frame) )
		{
			logger.error( "Invalid state for RiMakeCubeFaceEnvironment [" + GetStateAsString() + "]\n" );
			return;
		}

		String modes;
	    String swrap = "black" ;
	    String twrap = "black";
	    QGetRenderContext() .Stats().MakeEnvTimer().Start();
	    assert( px != null && nx != null && py != null && ny != null && pz != null && nz != null &&
	            reflfile != null && filterfunc != null );
	    
//	    EqWrapMode smode = new EqWrapMode(EqWrapMode.WrapMode_Black);	//読み取られていない
//	    if ( swrap.compareTo(RI_PERIODIC ) == 0)
//	        smode = new EqWrapMode(EqWrapMode.WrapMode_Periodic);
//	    else if ( swrap.compareTo( RI_CLAMP ) == 0 )
//	        smode = new EqWrapMode(EqWrapMode.WrapMode_Clamp);
//	    else if ( swrap.compareTo(RI_BLACK ) == 0 )
//	        smode = new EqWrapMode(EqWrapMode.WrapMode_Black);
//
//	    EqWrapMode tmode = new EqWrapMode(EqWrapMode.WrapMode_Black);
//	    if ( twrap.compareTo( RI_PERIODIC ) == 0 )
//	        tmode = new EqWrapMode(EqWrapMode.WrapMode_Periodic);
//	    else if ( twrap.compareTo( RI_CLAMP ) == 0 )
//	        tmode = new EqWrapMode(EqWrapMode.WrapMode_Clamp);
//	    else if ( twrap.compareTo( RI_BLACK ) == 0 )
//	        tmode = new EqWrapMode(EqWrapMode.WrapMode_Black);

	    /*		2007/12/10 岩渕テクスチャ修正
	    modes = swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;
	    
	    if ( filterfunc.getName().equals("RiGaussianFilter") )
		    modes = swrap +" "+ twrap +" "+ "gaussian" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBoxFilter") )
		    modes = swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiTriangleFilter") )
		    modes = swrap +" "+ twrap +" "+ "triangle" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiCatmullRomFilter") )
		    modes = swrap +" "+ twrap +" "+ "catmull-rom" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiSincFilter") )
		    modes = swrap +" "+ twrap +" "+ "sinc" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiDiskFilter") )
		    modes = swrap +" "+ twrap +" "+ "disk" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBesselFilter") )
		    modes = swrap +" "+ twrap +" "+ "bessel" +" " + swidth +" "+ twidth;
        */
	    
	    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;
	    
	    if ( filterfunc.getName().equals("RiGaussianFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "gaussian" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBoxFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "box" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiTriangleFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "triangle" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiCatmullRomFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "catmull-rom" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiSincFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "sinc" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiDiskFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "disk" +" " + swidth +" "+ twidth;
	    if ( filterfunc.getName().equals("RiBesselFilter") )
		    modes = "TextureInfo " + swrap +" "+ twrap +" "+ "bessel" +" " + swidth +" "+ twidth;
	    
	    // Now load the original image.
	    CqTextureMap tpx = new CqTextureMap( px );
	    CqTextureMap tnx = new CqTextureMap( nx );
	    CqTextureMap tpy = new CqTextureMap( py );
	    CqTextureMap tny = new CqTextureMap( ny );
	    CqTextureMap tpz = new CqTextureMap( pz );
	    CqTextureMap tnz = new CqTextureMap( nz );

	    tpx.Open();
	    tnx.Open();
	    tpy.Open();
	    tny.Open();
	    tpz.Open();
	    tnz.Open();

//	    if ( tpx.Format().getValue() != EqTexFormat.TexFormat_MIPMAP ) tpx.CreateMIPMAP();
//	    if ( tnx.Format().getValue() != EqTexFormat.TexFormat_MIPMAP ) tnx.CreateMIPMAP();
//	    if ( tpy.Format().getValue() != EqTexFormat.TexFormat_MIPMAP ) tpy.CreateMIPMAP();
//	    if ( tny.Format().getValue() != EqTexFormat.TexFormat_MIPMAP ) tny.CreateMIPMAP();
//	    if ( tpz.Format().getValue() != EqTexFormat.TexFormat_MIPMAP ) tpz.CreateMIPMAP();
//	    if ( tnz.Format().getValue() != EqTexFormat.TexFormat_MIPMAP ) tnz.CreateMIPMAP();
	    if ( tpx.IsValid() && tnx.IsValid() && tpy.IsValid() && tny.IsValid() && tpz.IsValid() && tnz.IsValid() )
	    {
	        // Check all the same size;
	        boolean fValid = false;
	        if ( tpx.XRes() == tnx.XRes() && tpx.XRes() == tpy.XRes() && tpx.XRes() == tny.XRes() && tpx.XRes() == tpz.XRes() && tpx.XRes() == tnz.XRes() &&
	                tpx.XRes() == tnx.XRes() && tpx.XRes() == tpy.XRes() && tpx.XRes() == tny.XRes() && tpx.XRes() == tpz.XRes() && tpx.XRes() == tnz.XRes() ){
	            fValid = true;
	        }
	        
	        
	        if ( !fValid )
	        {
	        	logger.error( "RiMakeCubeFaceEnvironment all images must be the same size\n" );
	            return ;
	        }
	        
//	        //Textureの形式として不正な場合の処理
//        	if(!(tpx.IsValid() && tpy.IsValid() && tnx.IsValid()&&
//        			tpy.IsValid() && tpz.IsValid() && tnz.IsValid())){
////	        	logger.error( "RiMakeCubeFaceEnvironment all images must be the same size\n" );
//	            return ;        		
//        	}


	        // Now copy the images to the big map.
	        CqTextureMap[] Images = new CqTextureMap[ 6 ];
       		Images[0] = tpz;
    		Images[1] = tpx;
    		Images[2] = tpy;
    		Images[3] = tnx;
    		Images[4] = tny;
    		Images[5] = tnz;
	           

	        // Create a new image.
//	        TIFF ptex = TIFFOpen( reflfile, "w" );
//
//	        int ii;
	        int xRes = (int)tpx.XRes();
	        int yRes = (int)tpx.YRes();

	        //--独自実装
	        FileOutputStream fos = null;
	        //画像を保存する
	        try {
	        	//1枚の画像にまとめる
	        	int width = xRes *3;
	        	int height = yRes *2;
	        	BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
	        	Graphics g = image.getGraphics();
	        	g.drawImage(Images[0].m_pImage,0,0,null);
	        	g.drawImage(Images[1].m_pImage,xRes,0,null);
	        	g.drawImage(Images[2].m_pImage,xRes*2,0,null);
	        	g.drawImage(Images[3].m_pImage,0,yRes,null);
	        	g.drawImage(Images[4].m_pImage,xRes,yRes,null);
	        	g.drawImage(Images[5].m_pImage,xRes*2,yRes,null);

	        	fos = new FileOutputStream(new File(reflfile));
				ImageIO.write(image,"png",fos);
				g.dispose();
				image =null;
				//メタ情報を付加する
				fos.write(modes.getBytes());
			} catch (FileNotFoundException e) {
				HimawariLogger.getLogger().error("Cannot open texture file \""+reflfile +"\"\n");
				HimawariLogger.outputException(e);
			} catch (IOException e) {
				HimawariLogger.outputException(e);
			}finally{
				try {
					if(fos != null)
						fos.close();
				} catch (IOException e) {
					HimawariLogger.outputException(e);
				}
			}

	    }
	    QGetRenderContext() .Stats().MakeEnvTimer().Stop();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiMakeShadow
//	 Convert a depth map file to a shadow map.
//	 深度マップをシャドウマップに変換する。
	//
	public static void	RiMakeShadow( String picfile, String shadowfile, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiMakeShadowV( picfile, shadowfile, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiMakeShadowV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiMakeShadowV( String picfile, String shadowfile, int count, String tokens[] ,Object values[] )
	{
		//shadowFileをリネームする
		
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiMakeShadowCache(picfile, shadowfile, count, tokens, values) );
			return;
		}

		if(!ValidateState(2, BeginEnd, Frame) )
		{
			logger.error( "Invalid state for RiMakeShadow [" + GetStateAsString() + "]\n" );
			return;
		}
		if(picfile.equals( shadowfile))
			return;
	    QGetRenderContext() .Stats().MakeShadowTimer().Start();
	    
	    File src = new File(picfile);
	    File dest = new File(shadowfile);
	    
	    
	    FileInputStream in = null;
		FileOutputStream out = null;
		
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
	    
	    try {
			in = new FileInputStream(src);
			out = new FileOutputStream(dest);
			
			bis = new BufferedInputStream(in);
			bos = new BufferedOutputStream(out);
			byte[] buf = new byte[4096];
			while(bis.read(buf)!= -1){
				bos.write(buf);
			}
		} catch (FileNotFoundException e) {
			if(in == null)
				HimawariLogger.getLogger().error("Cannot open texture file \""+src +"\"\n");
			else
				HimawariLogger.getLogger().error("Cannot open texture file \""+dest +"\"\n");
			HimawariLogger.outputException(e);
		} catch (IOException e) {
//			e.printStackTrace();
			HimawariLogger.outputException(e);
		}finally{
			try {
				if(bis != null)
					bis.close();
				if(bos != null)
					bos.close();
				if(in != null)
					in.close();
				if(out != null)
					out.close();
			} catch (IOException e) {
//				e.printStackTrace();
				HimawariLogger.outputException(e);
			}
		}
	    
	    
	    //	    CqShadowMap ZFile = new CqShadowMap( picfile );
//	    ZFile.LoadZFile();
//
//	    TqInt comp, qual;
//	    ProcessCompression( comp, qual, count, tokens, values );
//	    ZFile.SetCompression( comp );
//	    ZFile.SetQuality( qual );
//
//	    ZFile.SaveShadowMap( shadowfile );
	    QGetRenderContext() .Stats().MakeShadowTimer().Stop();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiMakeOcclusion
//	 Convert a series of depth maps to an occlusion map.
//	 いちれんの深度マップを閉塞マップに変換してください。
	//
	public static void	RiMakeOcclusion( int npics, String picfiles[], String shadowfile, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiMakeOcclusionV( npics, picfiles, shadowfile, count, aTokens.toArray(), aValues.toArray() );
	}


//	----------------------------------------------------------------------
//	 RiMakeOcclusionV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiMakeOcclusionV( int npics, String picfiles[], String shadowfile, int count, String tokens[], Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiMakeOcclusionCache(npics, picfiles, shadowfile, count, tokens, values) );
			return;
		}

		if(!ValidateState(2, BeginEnd, Frame) )
		{
			logger.error( "Invalid state for RiMakeOcclusion [" + GetStateAsString() + "]\n" ); 
			return; 
		}

	    QGetRenderContext() .Stats().MakeShadowTimer().Start();

	    int index;
		FileOutputStream out = null;
		BufferedOutputStream bos = null;
	    FileInputStream in = null;
		BufferedInputStream bis = null;		    
	    File dest = null;
	    File src = null;
	    try {
		    dest = new File(shadowfile);
			out = new FileOutputStream(dest);
			bos = new BufferedOutputStream(out);
			

			for( index = 0; index < npics; ++index )
		    {

			    src = new File(picfiles[index]);

			    //--2007/06/11 check shadow header
				RandomAccessFile  rfile = new RandomAccessFile(src,"r");
				String str = rfile.readLine();
				if(str == null || !str.equals(ZFileRequest.START_SHADOW_HEADER)){
					HimawariLogger.getLogger().error("invalid image file \""+ picfiles[index]+"\"\n");
					rfile.close();
					continue;
				}
				if(rfile != null)
					rfile.close();
				//--

		    
				in = new FileInputStream(src);
				
				bis = new BufferedInputStream(in);
				byte[] buf = new byte[4096];
				while(bis.read(buf)!= -1){
					bos.write(buf);
				}
		    }
		} catch (FileNotFoundException e) {
			if(in == null)
				HimawariLogger.getLogger().error("Cannot open texture file \""+src +"\"\n");
			else
				HimawariLogger.getLogger().error("Cannot open texture file \""+dest +"\"\n");

		} catch (IOException e) {
//				e.printStackTrace();
			HimawariLogger.outputException(e);
		}finally{
			try {
				if(bis != null)
					bis.close();
				if(bos != null)
					bos.close();
				if(in != null)
					in.close();
				if(out != null)
					out.close();
			} catch (IOException e) {
//					e.printStackTrace();
				HimawariLogger.outputException(e);
			}
		}
		    
	    QGetRenderContext() .Stats().MakeShadowTimer().Stop();
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiErrorHandler
//	 Set the function used to report errors.
//	 エラーを報告するために使用される機能を設定する。
	//
	public static void	RiErrorHandler( Method handler )
	{
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiErrorHandlerCache(handler) );
			return;
		}

		if(!ValidateState(9, Outside, BeginEnd, Frame, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error( "Invalid state for RiErrorHandler [" + GetStateAsString() + "]\n");
			return;
		}

	    QGetRenderContext().SetpErrorHandler( handler );
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiErrorIgnore
//	 Function used by RiErrorHandler to continue after errors.
//	 RiErrorHandlerでエラーと停止を印刷するための機能
	//
	public static void	RiErrorIgnore( int code, int severity, String message )
	{
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiErrorPrint
//	 Function used by RiErrorHandler to print an error message to stdout and continue.
//	 RiErrorHandlerでエラーメッセージと続けるかを印刷するための機能
	//
	public static void	RiErrorPrint( int code, int severity, String message )
	{
	    // Don't use this!
//	    std::cerr << error << "RiError: " << code << " : " << severity << " : " << message << std::endl;
	    System.err.println( "RiError: " + code + " : " + severity + " : " + message );
	   
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiErrorAbort
//	 Function used by RiErrorHandler to print and error and stop.
//	 RiErrorHandlerでエラーと停止を印刷するための機能
	//
	public static void	RiErrorAbort( int code, int severity, String message )
	{
	    return ;
	}


//	----------------------------------------------------------------------
//	 RiSubdivisionMesh
//	 Specify a subdivision surface hull with tagging.
//	 タグ付けでサブディヴィジョンサーフェースを指定してください。
	//
	public static void	RiSubdivisionMesh( String scheme, int nfaces, int nvertices[], int vertices[], int ntags, String tags[], int nargs[], int intargs[], float floatargs[], Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiSubdivisionMeshV( scheme, nfaces, nvertices, vertices, ntags, tags, nargs, intargs, floatargs, count, aTokens.toArray(), aValues.toArray() );
	}

//	----------------------------------------------------------------------
//	 RiSubdivisionMeshV
//	 List based version of above.
//	 上のベースのバージョンを記載してください。
	//
	public static void	RiSubdivisionMeshV( String scheme, int nfaces, int nvertices[], int vertices[], int ntags, String tags[], int nargs[], int intargs[], float floatargs[], int count, String tokens[] ,Object values[] )
	{
		if( QGetRenderContext().pCurrentObject() != null )
		{
			QGetRenderContext().pCurrentObject().AddCacheCommand(
					new RiSubdivisionMeshCache(scheme, nfaces, nvertices, vertices, ntags, tags, nargs, intargs, floatargs, count, tokens, values) );
			return;
		}
		
		if(!ValidateState(6, World, Attribute, Transform, Solid, Object, Motion) )
		{
			logger.error( "Invalid state for RiSubdivisionMesh [" + GetStateAsString() + "]\n" );
			return;
		}
		
		// Calculate how many vertices there are.
		int cVerts = 0;
		int[] pVerts = vertices;
		int pVertsIdx = 0;
		int face;
		int sumnVerts = 0;
		for ( face = 0; face < nfaces; ++face )
		{
			int v;
			sumnVerts += nvertices[ face ];
			for ( v = 0; v < nvertices[ face ]; ++v )
			{
				//cVerts = MAX( ( ( *pVerts ) + 1 ), cVerts );
				//pVerts++;
				cVerts = Math.max( pVerts[ pVertsIdx ] + 1, cVerts );
				pVertsIdx++;
			}
		}
		
		// Create a storage class for all the points.
		CqPolygonPoints pPointsClass =  new CqPolygonPoints( cVerts, nfaces, sumnVerts );
		
//		STLVector<CqPolygonPoints>	apPoints = new STLVector<CqPolygonPoints>(CqPolygonPoints.class);
		// Process any specified primitive variables
		if ( ProcessPrimitiveVariables( pPointsClass, count, tokens, values ) )
		{
			// Create experimental version
			if ( scheme.compareTo( "catmull-clark" ) == 0 )
			{
				// Transform the points into camera space for processing,
				pPointsClass.Transform( QGetRenderContext() .matSpaceToSpace( "object", "camera", new CqMatrix(), pPointsClass.pTransform() .matObjectToWorld(pPointsClass.pTransform() .Time(0)), pPointsClass.pTransform() .Time(0) ),
						QGetRenderContext() .matNSpaceToSpace( "object", "camera", new CqMatrix(), pPointsClass.pTransform() .matObjectToWorld(pPointsClass.pTransform() .Time(0)), pPointsClass.pTransform() .Time(0) ),
						QGetRenderContext() .matVSpaceToSpace( "object", "camera", new CqMatrix(), pPointsClass.pTransform() .matObjectToWorld(pPointsClass.pTransform() .Time(0)), pPointsClass.pTransform() .Time(0) ) );
				
				CqSubdivision2 pSubd2 = new CqSubdivision2( pPointsClass );
				pSubd2.Prepare( cVerts );
				
				int	iP = 0;
				for ( face = 0; face < nfaces; ++face )
				{
					//配列の一部だけを切り取る
					int[] verticesSubAry = new int[ vertices.length - iP ];
					System.arraycopy( vertices, iP, verticesSubAry, 0, verticesSubAry.length );
					pSubd2.AddFacet( nvertices[ face ], verticesSubAry, iP );
					iP += nvertices[ face ];
				}
				if ( pSubd2.Finalise() )
				{
					// Process tags.
					int argcIndex = 0;
					int floatargIndex = 0;
					int intargIndex = 0;
					for ( int i = 0; i < ntags; ++i )
					{
						if ( tags[ i ].compareTo( "interpolateboundary" ) == 0 )
							pSubd2.SetInterpolateBoundary( true );
						else if ( tags [ i ].compareTo( "crease" ) == 0 )
						{
							float creaseSharpness = floatargs[ floatargIndex ];
							// convert pixars 0.infinity crease values to our 0.1
							if( creaseSharpness > 5.0f )
								creaseSharpness = 5.0f;
							creaseSharpness /= 5.0f;
							// bend the curve so values behave more like pixars algorithm
							creaseSharpness = (float) Math.pow(creaseSharpness, 0.2f);
							int iEdge = 0;
							while ( iEdge < nargs[ argcIndex ] - 1 )
							{
								if ( intargs[ iEdge + intargIndex ] < pSubd2.cVertices() &&
										intargs[ iEdge + intargIndex + 1 ] < pSubd2.cVertices() )
								{
									// Store the crease sharpness.
									CqLath pEdge = pSubd2.pVertex( intargs[ iEdge + intargIndex ] );
									STLVector<CqLath> aQve = new STLVector<CqLath>(CqLath.class);
									pEdge.Qve( aQve );
									//std::vector<CqLath*>::iterator iOpp;
									//for( iOpp = aQve.begin(); iOpp != aQve.end(); ++iOpp )
									for( CqLath iOpp : aQve )
									{
										if( ( null != (iOpp).ec() ) && (iOpp).ec().VertexIndex() == intargs[ iEdge + intargIndex + 1 ] )
										{
											pSubd2.AddSharpEdge( (iOpp), creaseSharpness );
											pSubd2.AddSharpEdge( (iOpp).ec(), creaseSharpness );
											break;
										}
									}
								}
								iEdge++;
							}
						}
						else if ( tags [ i ].compareTo( "corner" ) == 0 )
						{
							int iVertex = 0;
							while ( iVertex < nargs[ argcIndex ] )
							{
								if ( intargs[ iVertex + intargIndex ] < pSubd2.cVertices() )
								{
									// Store the corner sharpness.
									CqLath pVertex = pSubd2.pVertex( intargs[ iVertex + intargIndex ] );
									pSubd2.AddSharpCorner( pVertex, RI_INFINITY );
								}
								iVertex++;
							}
						}
						else if ( tags [ i ].compareTo( "hole" ) == 0 )
						{
							int iFace = 0;
							while ( iFace < nargs[ argcIndex ] )
							{
								pSubd2.SetHoleFace( intargs[ iFace + intargIndex ] );
								iFace++;
							}
						}
						
						intargIndex += nargs[ argcIndex++ ];
						floatargIndex += nargs[ argcIndex++ ];
					}
					
					CqSurfaceSubdivisionMesh pMesh = new CqSurfaceSubdivisionMesh(pSubd2, nfaces );
					CreateGPrim(pMesh);
				}
				else
				{
					logger.error( "RiSubdivisionMesh contains non-manifold data" );
				}
			}
			else
			{
				logger.error( "RiSubdivisionMesh invalid scheme \"" + scheme + "\"" );
			}
		}
		
		return ;
	}


	public static void RiReadArchive( String name, Method callback, Object... pArgs )
	{

	    STLVector<String> aTokens = new STLVector<String>(String.class);
	    STLVector<Object> aValues = new STLVector<Object>(Object.class);
	    int count = BuildParameterList( pArgs, aTokens, aValues );

	    RiReadArchiveV( name, callback, count, aTokens.toArray(), aValues.toArray() );
	}


	public static void	RiReadArchiveV( String name, Method callback, int count, String tokens[] ,Object values[] )
	{
		Parser parser = new Parser();
		if( QGetRenderContext().pCurrentObject() != null)
		{
				QGetRenderContext().pCurrentObject().AddCacheCommand(
						new RiReadArchiveCache(name, callback, count, tokens, values) );
			return;
		}

		//Validate_RiReadArchive
		
		CqRiFile fileArchive = new CqRiFile( name, "archive" );

	    if ( fileArchive.IsValid() )
	    {
	        String strRealName =  fileArchive.strRealName() ;
	        fileArchive.Close();
	        try
	        {
				parser.parse(strRealName);
				logger.info( "RiReadArchive: Reading archive \"" + strRealName + "\"\n" );
	        }
	        catch(Exception e)
	        {
	        	HimawariLogger.outputException( e );
	        }
	       	        
	    }
	    else
	    {
	    	logger.error("Archive \"" + name + "\" not found\n" );
	    }
	}


	public static void	RiArchiveRecord( String type, String val, Object... pArgs )
	{
		//Validate_RiArchiveRecord
	}

	Object	RiGetContext(  )
	{
		//Validate_RiGetContext

	    return( null );
	}

	public static void	RiContext( Object object )
	{
		//Validate_RiContext
	}

	public static void	RiClippingPlane( float a, float b, float c, float d, float e, float f)
	{
		//Validate_RiClippingPlane
		logger.warning("RiClippingPlane not supported\n");
	}


//	---------------------------------------------------------------------
//	---------------------------------------------------------------------
//	 Helper functions
//	 アシスタント機能
//	----------------------------------------------------------------------
//	 ProcessPrimitiveVariables
//	 Process and fill in any primitive variables.
//	 プロセスとあらゆるプリミティブの値を記入してください。
//	 return	:	RI_TRUE if position specified, RI_FALSE otherwise.

	static boolean ProcessPrimitiveVariables( CqSurface pSurface, int count, String tokens[] ,Object values[] )
	{
		//******iwabuchi 
		long start ,end ;
		start = System.currentTimeMillis();
		STLVector<p_int>	aUserParams = new STLVector<p_int>(p_int.class);

	    // Read recognised parameter values.
	    int	fP = RIL_NONE;

	    p_float[]	pPoints = null;

	    int i;
	    for (i = 0; i < count; ++i )
	    {
	        String	token = tokens[ i ];
	        Object	value = values[ i ];
	        //***************************************************************
	        //【改】Aqsis1.0.1で変更
		    //long hash = token.hashCode();  //ver1.0.1で削除
	        
	        SqParameterDeclaration Decl = new SqParameterDeclaration();
			try {
				Decl = QGetRenderContext().FindParameterDecl( token );
			} catch (XqException e) {
				HimawariLogger.outputException( e );
			}
			long hash = Decl.m_strName.hashCode(); // ver1.0.1で追加
			//***************************************************************


			if ( (hash == RIH_P) && (Decl.m_Class.getValue() == class_vertex ))
	        {
	            fP = RIL_P;
	            pPoints = (p_float[]) value;
	        }
			else if ( (hash == RIH_PZ) && (Decl.m_Class.getValue() == class_vertex ) )
	        {
	            fP = RIL_Pz;
	            pPoints = ( p_float[] ) value;
	        }
			else if ( (hash == RIH_PW) && (Decl.m_Class.getValue() == class_vertex ) )
	        {
	            fP = RIL_Pw;
	            pPoints = ( p_float[] ) value;
	        }
	        else
	        {
	            aUserParams.add( new p_int(i) );
	        }
	    }
		
	    // Fill in the position variable according to type.
	    if ( fP != RIL_NONE )
	    {
	        pSurface.AddPrimitiveVariable( new CqParameterTypedVertex<CqVector4D, CqVector3D>( "P", 1 ,new EqVariableType(type_hpoint),CqVector4D.class,CqVector3D.class) );
	        pSurface.P() .SetSize( (int)pSurface.cVertex() );
	        int j ;
	        switch ( fP )
	        {
	        case RIL_P:
	        	//頂点の値を設定する
	        	
	        	int cvert = pSurface.cVertex();
	            for ( j = 0; j < cvert; ++j )
	            {
//	                pSurface.P().pValue( j )[0] = new CqVector3D( pPoints[ (int) ( j * 3 ) ].value, pPoints[ (int) (( j * 3 ) + 1) ].value, pPoints[ (int) (( j * 3 ) + 2) ].value ); // 2005/12/22  Polygonのために修正 nttdata
	               
//	            	nttdata 高速化 start
	            	//((CqVector4D)(pSurface.P().pValue( j )[0])).assignment(pPoints[ (int) ( j * 3 ) ].value, pPoints[ (int) (( j * 3 ) + 1) ].value, pPoints[ (int) (( j * 3 ) + 2) ].value );
	            	((CqVector4D)(pSurface.P().pValue_get( j ,0 ))).assignment(pPoints[ (int) ( j * 3 ) ].value, pPoints[ (int) (( j * 3 ) + 1) ].value, pPoints[ (int) (( j * 3 ) + 2) ].value );

//	            	CqVector4D Temp = (CqVector4D)(pSurface.P().pValue( j )[0]);
//	            	Temp.x = pPoints[ (int) ( j * 3 ) ].value;
//	            	Temp.y = pPoints[ (int) (( j * 3 ) + 1) ].value; 
//	            	Temp.z = pPoints[ (int) (( j * 3 ) + 2) ].value;
//	            	Temp.w =1.0f;
	            	
	            	//nttdata 高速化のテスト end
	            	
	            }
	           
	        	break;

	        case RIL_Pz:
	            for ( j = 0; j < pSurface.cVertex(); ++j )
	            {
	                CqVector3D vecP = pSurface.SurfaceParametersAtVertex( j );
	                vecP.z( pPoints[ j ].value );
//	                pSurface.P().pValue( j )[0] = vecP; //変更前 2005/12/26 nttdata 
	                ((CqVector4D)pSurface.P().pValue_get( j ,0)).assignment(vecP);//変更後
	            }
	            break;

	        case RIL_Pw:
	            for ( j = 0; j < pSurface.cVertex(); ++j ){
//	                pSurface.P().pValue( j )[0] = new CqVector4D( pPoints[ ( j * 4 ) ].value, pPoints[ ( j * 4 ) + 1 ].value, pPoints[ ( j * 4 ) + 2 ].value, pPoints[ ( j * 4 ) + 3 ].value );//変更 2005/12/26 nttdata
	                //nttdata 高速化
	            	//((CqVector4D)pSurface.P().pValue( j )[0]).assignment(new CqVector4D( pPoints[ ( j * 4 ) ].value, pPoints[ ( j * 4 ) + 1 ].value, pPoints[ ( j * 4 ) + 2 ].value, pPoints[ ( j * 4 ) + 3 ].value ));//変更後
	            	((CqVector4D)pSurface.P().pValue_get( j , 0 )).assignment(new CqVector4D( pPoints[ ( j * 4 ) ].value, pPoints[ ( j * 4 ) + 1 ].value, pPoints[ ( j * 4 ) + 2 ].value, pPoints[ ( j * 4 ) + 3 ].value ));//変更後
	            }
	            break;
	        }
	    }

//		#########iwabuchi speed check #############
		end = System.currentTimeMillis();
//		System.out.println("K2 " + (end-start) +"ms");
		
	    // Now process any user defined paramter variables.
	    if ( aUserParams.size() > 0 )
	    {
//	        std::vector<TqInt>::iterator iUserParam;
//	        for ( iUserParam = aUserParams.begin(); iUserParam != aUserParams.end(); ++iUserParam )
	    	for ( p_int iUserParam : aUserParams)
	        {
	            SqParameterDeclaration Decl;
	            try
	            {
	                Decl = QGetRenderContext().FindParameterDecl( tokens[ iUserParam.value ] );
	            }
	            catch( XqException e )
	            {
	            	logger.error( e.strReason() );
	                continue;
	            }

				//---2006.02.28 add -----------------------//
	            Class valCls = values[ iUserParam.value ].getClass();
				if( 
						!( Decl.m_Type.getValue()==type_float   && valCls.equals(p_float[].class) )    &&
						!( Decl.m_Type.getValue()==type_integer && valCls.equals(p_float[].class) )      &&
						!( Decl.m_Type.getValue()==type_point   && valCls.equals(p_float[].class) )    &&
						!( Decl.m_Type.getValue()==type_normal  && valCls.equals(p_float[].class) )    &&
						!( Decl.m_Type.getValue()==type_vector  && valCls.equals(p_float[].class) )    &&
						!( Decl.m_Type.getValue()==type_string  && valCls.equals(p_String[].class) )   &&
						!( Decl.m_Type.getValue()==type_color   && valCls.equals(p_float[].class) )    &&
						!( Decl.m_Type.getValue()==type_hpoint  && valCls.equals(p_float[].class) )    &&
						!( Decl.m_Type.getValue()==type_matrix  && valCls.equals(p_float[].class) )
				) {
					logger.error("Undeclared! "+AbstractKeywordParser.paramToString( valCls )+" Parameter["+tokens[ iUserParam.value ]+"]\n");
					continue;
				}
				//---2006.02.28 add end -------------------//
	            
	            CqParameter pNewParam = null;
	            
				try {
					pNewParam = createParameter( Decl );
				} catch ( Exception e) {
					HimawariLogger.outputException( e );
					continue;
				}
				
				
				
	            // Now go across all values and fill in the parameter variable.
	            int cValues = 1;
	            switch ( Decl.m_Class.getValue() )
	            {
	            case class_uniform:
	                cValues = (int) pSurface.cUniform();
	                break;

	            case class_varying:
	                cValues = (int) pSurface.cVarying();
	                break;

	            case class_vertex:
	                cValues = (int) pSurface.cVertex();
	                break;

	            case class_facevarying:
	                cValues = (int) pSurface.cFaceVarying();
	                break;
	            }
	            pNewParam.SetSize( cValues );

//	    		#########iwabuchi speed check #############
	    		end = System.currentTimeMillis();
//	    		System.out.println("K3 " + (end-start) +"ms");
	            int j;
	            switch ( Decl.m_Type.getValue() )
	            {
	            case type_float:
	                {
	                    CqParameterTyped<p_float, p_float> pFloatParam = (CqParameterTyped<p_float, p_float>)( pNewParam );
//						float[] pValue = (float[])( values[ iUserParam.value ] );//変更前 2005/12/26 渡辺  
	                    p_float[] pValue = (p_float[])( values[ iUserParam.value ] );
	                    int iArrayIndex, iValIndex;
	                    j = 0;
	                    for ( iValIndex = 0; iValIndex < cValues; ++iValIndex )
	                        for ( iArrayIndex = 0; iArrayIndex < Decl.m_Count; ++iArrayIndex, ++j ){                      		
//ここから                    	pFloatParam.pValue( iValIndex ) [ iArrayIndex ] = pValue[ j ];//変更前 2005/12/26 nttdata       	
	                        	if(pValue.length > j)
	                        	{
//	                        		nttdata chenge 高速化
	                        		//((p_float)pFloatParam.pValue( iValIndex ) [ iArrayIndex ]).value = pValue[ j ].value;
	                        		((p_float)pFloatParam.pValue_get( iValIndex,iArrayIndex)).value = pValue[ j ].value;
	                        	}
                        		else
                        			//((p_float)pFloatParam.pValue( iValIndex ) [ iArrayIndex ]).value = 0;
                        			((p_float)pFloatParam.pValue_get( iValIndex , iArrayIndex )).value = 0;
	                        	//nttdata chenge 高速化 end
//ここまで                        		
	                        }
	                }
	                break;

	            case type_integer:
	                {
	                    CqParameterTyped<p_int, p_float> pIntParam = (CqParameterTyped<p_int, p_float>)( pNewParam );
//	                    int[] pValue = (int[])( values[ iUserParam.value ] );//変更前 2005/12/26
	                    //2006.03.28 ぶち　instanceofを追加
	                    if( values[ iUserParam.value ] instanceof p_int[] )
	                    {
		                    p_int[] pValue = (p_int[])( values[ iUserParam.value ] );
		                    int iArrayIndex, iValIndex;
		                    j = 0;
		                    for ( iValIndex = 0; iValIndex < cValues; ++iValIndex )
		                        for ( iArrayIndex = 0; iArrayIndex < Decl.m_Count; ++iArrayIndex, ++j ){
	//ここから		                pIntParam.pValue( iValIndex ) [ iArrayIndex ] = pValue[ j ];//変更前 2005/12/26 nttdata
		                        	if(pValue.length > j)
		                        		//nttdata chenge 高速化
		                        		//((p_int)pIntParam.pValue( iValIndex ) [ iArrayIndex ]).value = pValue[ j ].value;
		                        		((p_int)pIntParam.pValue_get( iValIndex ,iArrayIndex )).value = pValue[ j ].value;
		                        	else
//		                        		nttdata chenge 高速化
		                        		//((p_int)pIntParam.pValue( iValIndex ) [ iArrayIndex ]).value = 0;
		                        		((p_int)pIntParam.pValue_get( iValIndex, iArrayIndex)).value = 0;
	//ここまで
		                        }
	                    }
	                    else if( values[ iUserParam.value ] instanceof p_float[] )
	                    {
	                    	p_float[] pValue = (p_float[])( values[ iUserParam.value ] );
		                    int iArrayIndex, iValIndex;
		                    j = 0;
		                    for ( iValIndex = 0; iValIndex < cValues; ++iValIndex )
		                        for ( iArrayIndex = 0; iArrayIndex < Decl.m_Count; ++iArrayIndex, ++j ){
	//ここから		                pIntParam.pValue( iValIndex ) [ iArrayIndex ] = pValue[ j ];//変更前 2005/12/26 nttdata
		                        	if(pValue.length > j)
		                        		((p_int)pIntParam.pValue_get( iValIndex , iArrayIndex )).value = (int)pValue[ j ].value;
		                        	else
		                        		((p_int)pIntParam.pValue_get( iValIndex , iArrayIndex )).value = 0;
	//ここまで
		                        }
	                    }
	                }
	                break;

	            case type_point:
	            case type_normal:
	            case type_vector:
	                {
	                    CqParameterTyped<CqVector3D, CqVector3D> pVectorParam = (CqParameterTyped<CqVector3D, CqVector3D>)( pNewParam );
	                    //変更前 float[] pValue = (float[])( values[ iUserParam.value ] );
	                    p_float[] pValue = (p_float[])( values[ iUserParam.value ] );
	                    int iArrayIndex, iValIndex;
	                    j = 0;
	                    for ( iValIndex = 0; iValIndex < cValues; ++iValIndex )
	                        for ( iArrayIndex = 0; iArrayIndex < Decl.m_Count; ++iArrayIndex, ++j )
	                        {
	                        //pVectorParam.pValue( iValIndex ) [ iArrayIndex ] = new CqVector3D( pValue[ ( j * 3 ) ], pValue[ ( j * 3 ) + 1 ], pValue[ ( j * 3 ) + 2 ] );
	                        // 	--変更後 pValueにし、配列長以上のindexが指定された場合の対処を追加
	                        	if(pValue.length > j*3 +2)
	                        		//nttdata 高速化
                        			//((CqVector3D)(pVectorParam.pValue( iValIndex ) [ iArrayIndex ])).assignment(new CqVector3D( pValue[ ( j * 3 ) ].value, pValue[ ( j * 3 ) + 1 ].value, pValue[ ( j * 3 ) + 2 ].value ));
	                        		((CqVector3D)(pVectorParam.pValue_get( iValIndex , iArrayIndex ))).assignment( pValue[ ( j * 3 ) ].value, pValue[ ( j * 3 ) + 1 ].value, pValue[ ( j * 3 ) + 2 ].value );
                        		else if(j*3 < pValue.length){
                        			float[] tempArray = {0,0,0};
                        			for(int temp = 0 ; j*3+temp <pValue.length;temp++){
                        				tempArray[temp] = pValue[j * 3 + temp].value;
                        			}
                        			//nttdata 高速化
                        			//((CqVector3D)(pVectorParam.pValue( iValIndex ) [ iArrayIndex ])).assignment(new CqVector3D(tempArray[0],tempArray[1],tempArray[2] ));            
                        			((CqVector3D)(pVectorParam.pValue_get( iValIndex , iArrayIndex ))).assignment(tempArray[0],tempArray[1],tempArray[2] );
                        		}else{
//                        			nttdata 高速化
                        			//((CqVector3D)(pVectorParam.pValue( iValIndex ) [ iArrayIndex ])).assignment(new CqVector3D( 0,0,0));
                        			((CqVector3D)(pVectorParam.pValue_get( iValIndex , iArrayIndex ))).assignment( 0,0,0);
                        		}
	                        	//--ここまで
	                        }
	                
	                }
	                break;

	            case type_string:
	                {
	                    CqParameterTyped<p_String, p_String> pStringParam = (CqParameterTyped<p_String, p_String>)( pNewParam );
//	                    String[] pValue = (String[])( values[ iUserParam.value ] );//変更前 2005/12/26 nttdata
	                    p_String[] pValue = (p_String[])( values[ iUserParam.value ] );
	                    int iArrayIndex, iValIndex;
	                    j = 0;
	                    for ( iValIndex = 0; iValIndex < cValues; ++iValIndex )
	                        for ( iArrayIndex = 0; iArrayIndex < Decl.m_Count; ++iArrayIndex, ++j ){
//ここから		                  pStringParam.pValue( iValIndex ) [ iArrayIndex ] = new String( pValue[ j ] );//変更前 2005/12/26 nttdata
	                        	if(pValue.length > j)
	                        		((p_String)pStringParam.pValue_get( iValIndex , iArrayIndex )).value = pValue[ j ].value;
	                        	else
	                        		((p_String)pStringParam.pValue_get( iValIndex , iArrayIndex )).value = "";
	                        }
	                }
	                break;

	            case type_color:
	                {
	                    CqParameterTyped<CqColor, CqColor> pColorParam = (CqParameterTyped<CqColor, CqColor>)( pNewParam );
	                    //-- 2005/11/29 Csを指定した時に発生するClassCastExceptionを変更する
//変更前                float[] pValue = (float[])( values[ iUserParam.value ] );
	                    p_float[] pValue = (p_float[])( values[ iUserParam.value ] );
	                    int iArrayIndex, iValIndex;
	                    j = 0;
	                    for ( iValIndex = 0; iValIndex < cValues; ++iValIndex )
	                        for ( iArrayIndex = 0; iArrayIndex < Decl.m_Count; ++iArrayIndex, ++j ){
//変更前	                    pColorParam.pValue( iValIndex ) [ iArrayIndex ] = new CqColor( pValue[ ( j * 3 ) ], pValue[ ( j * 3 ) + 1 ], pValue[ ( j * 3 ) + 2 ] );
	                        	//--変更後 pValueにし、配列長以上のindexが指定された場合の対処を追加
	                        	if(pValue.length > j*3 +2)
                        			((CqColor)(pColorParam.pValue_get( iValIndex , iArrayIndex ))).assignment(new CqColor( pValue[ ( j * 3 ) ].value, pValue[ ( j * 3 ) + 1 ].value, pValue[ ( j * 3 ) + 2 ].value ));
                        		else if(j*3 < pValue.length){
                        			float[] tempArray = {0,0,0};
                        			for(int temp = 0 ; j*3+temp <pValue.length;temp++){
                        				tempArray[temp] = pValue[j * 3 + temp].value;
                        			}
                        			((CqColor)(pColorParam.pValue_get( iValIndex , iArrayIndex ))).assignment(new CqColor(tempArray[0],tempArray[1],tempArray[2] ));                        			
                        		}else{
                        			((CqColor)(pColorParam.pValue_get( iValIndex , iArrayIndex ))).assignment(new CqColor( 0,0,0));                        			
                        		}
	                        	//--ここまで
	                        }
	                        
	                }
	                break;

	            case type_hpoint:
	                {
	                    CqParameterTyped<CqVector4D, CqVector3D> pVectorParam = (CqParameterTyped<CqVector4D, CqVector3D>)( pNewParam );
//	                    float[] pValue = (float[])( values[ iUserParam.value ] );//変更前 2005/12/26 
	                    p_float[] pValue = (p_float[])( values[ iUserParam.value ] );
	                    int iArrayIndex, iValIndex;
	                    j = 0;
	                    for ( iValIndex = 0; iValIndex < cValues; ++iValIndex ){
	                        for ( iArrayIndex = 0; iArrayIndex < Decl.m_Count; ++iArrayIndex, ++j ){
//ここから						pVectorParam.pValue( iValIndex ) [ iArrayIndex ] = new CqVector4D( pValue[ ( j * 4 ) ], pValue[ ( j * 4 ) + 1 ], pValue[ ( j * 4 ) + 2 ], pValue[ ( j * 4 ) + 3 ] );//変更前 2005/12/26 nttdata
	                        	if(pValue.length > j*4 +3)
                        			((CqVector4D)(pVectorParam.pValue_get( iValIndex , iArrayIndex ))).assignment(new CqVector4D( pValue[ ( j * 4 ) ].value, pValue[ ( j * 4 ) + 1 ].value, pValue[ ( j * 4 ) + 2 ].value ,pValue[ ( j * 4 ) + 3 ].value ));
                        		else if(j*4 < pValue.length){
                        			float[] tempArray = {0,0,0,0};
                        			for(int temp = 0 ; j*4+temp <pValue.length;temp++){
                        				tempArray[temp] = pValue[j * 4 + temp].value;
                        			}
                        			((CqVector4D)(pVectorParam.pValue_get( iValIndex , iArrayIndex ))).assignment(new CqVector4D(tempArray[0],tempArray[1],tempArray[2],tempArray[3] ));                        			
                        		}else{
                        			((CqVector4D)(pVectorParam.pValue_get( iValIndex , iArrayIndex ))).assignment(new CqVector4D( 0,0,0,0));
                        		}
	                        }
	                    }
//--ここまで
	                }
	                break;

	            case type_matrix:
	                {
	                    CqParameterTyped<CqMatrix, CqMatrix> pMatrixParam = (CqParameterTyped<CqMatrix, CqMatrix>)( pNewParam );
//	                    float[] pValue = (float[])( values[ iUserParam.value ] ); //変更前 2005/12/26 
	                    p_float[] pValue = (p_float[])( values[ iUserParam.value ] ); //変更前 2005/12/26 
	                    int iArrayIndex, iValIndex;
	                    j = 0;
	                    for ( iValIndex = 0; iValIndex < cValues; ++iValIndex ){
	                        for ( iArrayIndex = 0; iArrayIndex < Decl.m_Count; ++iArrayIndex, ++j ){
//ここから 2005/12/26 nttdata           pMatrixParam.pValue( iValIndex ) [ iArrayIndex ] = new CqMatrix( pValue[ ( j * 16 ) ], pValue[ ( j * 16 ) + 1 ], pValue[ ( j * 16 ) + 2 ], pValue[ ( j * 16 ) + 3 ],
//	                                    pValue[ ( j * 16 ) + 4 ], pValue[ ( j * 16 ) + 5 ], pValue[ ( j * 16 ) + 6 ], pValue[ ( j * 16 ) + 7 ],
//	                                    pValue[ ( j * 16 ) + 8 ], pValue[ ( j * 16 ) + 9 ], pValue[ ( j * 16 ) + 10 ], pValue[ ( j * 16 ) + 11 ],
//	                                    pValue[ ( j * 16 ) + 12 ], pValue[ ( j * 16 ) + 13 ], pValue[ ( j * 16 ) + 14 ], pValue[ ( j * 16 ) + 15 ]
//	                                                                                        );
	                        	if(pValue.length > j*16 +15)
                        			((CqMatrix)(pMatrixParam.pValue_get( iValIndex , iArrayIndex ))).assignment(new CqMatrix( pValue[ ( j * 16 ) ].value, pValue[ ( j * 16 ) + 1 ].value, pValue[ ( j * 16 ) + 2 ].value ,pValue[ ( j * 16 ) + 3 ].value ,
                        					pValue[( j * 16 + 4 ) ].value, pValue[ ( j * 16 ) + 5 ].value, pValue[ ( j * 16 ) + 6 ].value ,pValue[ ( j * 16 ) + 7 ].value ,
                        					pValue[( j * 16 + 8) ].value, pValue[ ( j * 16 ) + 9 ].value, pValue[ ( j * 16 ) + 10 ].value ,pValue[ ( j * 16 ) + 11 ].value ,
                        					pValue[( j * 16 + 12) ].value, pValue[ ( j * 16 ) + 13 ].value, pValue[ ( j * 16 ) + 14 ].value ,pValue[ ( j * 16 ) + 15 ].value ));
                        		else if(j*16 < pValue.length){
                        			float[] tempArray = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
                        			for(int temp = 0 ; j*16+temp <pValue.length;temp++){
                        				tempArray[temp] = pValue[j * 16 + temp].value;
                        			}
                        			((CqMatrix)(pMatrixParam.pValue_get( iValIndex , iArrayIndex ))).assignment(new CqMatrix(tempArray ));                        			
                        		}else{
                        			((CqMatrix)(pMatrixParam.pValue_get( iValIndex , iArrayIndex ))).assignment(new CqMatrix( 0));
                        		}
//--ここまで
	                        }
	                    }
	                }
	                break;

	            default:
	                {
	                    // left blank to avoid compiler warnings about unhandled types
	                    break;
	                }
	            }
//	    		#########iwabuchi speed check #############
	    		end = System.currentTimeMillis();
//	    		System.out.println("K4 " + (end-start) +"ms");
	            pSurface.AddPrimitiveVariable( pNewParam );
//	            CqParameter pP = pSurface.P();
	        }
	    }
//		#########iwabuchi speed check #############
		end = System.currentTimeMillis();
//		System.out.println("K " + (end-start) +"ms");
	    return ( pSurface.P() != null );
	}


////	----------------------------------------------------------------------
////	 CreateGPrim
////	 Create and register a GPrim according to the current attributes/transform
////	 現在の属性/変換に従って、GPrimを作成して、登録してください。

	public static void	CreateGPrim( CqBasicSurface pSurface )
	{

	    if ( QGetRenderContext() .pattrCurrent() .GetFloatAttribute( "System", "LevelOfDetailBounds" ) [ 1 ] < 0.0f )
	    {
	        // Cull this geometry for LOD reasons.
	        return ;
	    }

	    // If in a motion block, confirm that the current deformation surface can accept the passed one as a keyframe.
	    if( QGetRenderContext() .pconCurrent() .fMotionBlock() )
	    {
	        pSurface.PrepareTrimCurve();

	        CqMotionModeBlock pMMB = (CqMotionModeBlock)(QGetRenderContext() .pconCurrent());

	        CqDeformingSurface pMS = pMMB.GetDeformingSurface();
	        // If this is the first frame, then generate the appropriate CqDeformingSurface and fill in the first frame.
	        // Then cache the pointer on the motion block.
	        if( pMS == null )
	        {
	        	CqDeformingSurface pNewMS = new CqDeformingSurface( pSurface );
	            pNewMS.AddTimeSlot( QGetRenderContext().Time(), pSurface );
	            pMMB.SetDeformingSurface( pNewMS );
	        }
	        else
	        {
	            pMS.AddTimeSlot( QGetRenderContext().Time(), pSurface );
	        }
	        QGetRenderContext() .AdvanceTime();
	    }
	    else
	    {
	        pSurface.PrepareTrimCurve();
	        QGetRenderContext() .pImage() .PostSurface( pSurface );
	        CqStats.STATS_INC( GPR_created );

	        // Add to the raytracer database also
	        if(QGetRenderContext().pRaytracer() != null )
	            QGetRenderContext().pRaytracer().AddPrimitive(pSurface);
	    }

	    return ;
	}

//----------------------------------------------------------------------
	
	/**
	 * Get the basis matrix given a standard basis name.
	 * 標準基礎名から与えられる規定行列を得てください。
	 * 
	 * @param b	Storage for basis matrix.
	 * @param strName	Name of basis.
	 * @return boolean	indicating the basis is valid.
	 */
	public static boolean BasisFromName( float[][] b, String strName )
	{
	    float[][] pVals = null;
	    
	    if ( strName.equals("bezier" ) )
	    	pVals = RiBezierBasis;
	    else if ( strName.equals("bspline" ) || strName.equals("b-spline" ) )	//2006.01.23. "-"を含んでもよいようにしました。nttdata
	    	pVals = RiBSplineBasis;
	    else if ( strName.equals("catmull-rom" ) )
	    	pVals = RiCatmullRomBasis;
	    else if ( strName.equals("hermite" ) )
	    	pVals = RiHermiteBasis;
	    else if ( strName.equals("power" ) )
	    	pVals = RiPowerBasis;
	    
	    if ( pVals != null)
	    {
	        int i, j;
	        for ( i = 0; i < 4; ++i )
	            for ( j = 0; j < 4; ++j )
	                ( b ) [ i ][ j ] = ( pVals ) [ i ][ j ];
	        return ( true );
	    }
	    return ( false );
	}


//	----------------------------------------------------------------------
	/** Set the function used to report progress.
	 *  経過を報告するのに使用される機能を設定してください。
	 *	\param	handler	Pointer to the new function to use.
	 */

	public static void	RiProgressHandler( Method handler )
	{
	    QGetRenderContext().SetpProgressHandler( handler );
	    return ;
	}


//	----------------------------------------------------------------------
	/** Set the function called just prior to rendering, after the world is complete.
	 	\param	function	Pointer to the new function to use.
	 	\return	Pointer to the old function.
		世界が完全になった後にレンダリングのすぐ前に呼ばれた機能を設定してください。
	 */

	public static Method	RiPreRenderFunction( Method function )
	{
	    Method pOldPreRenderFunction = QGetRenderContext().pPreRenderFunction();
	    QGetRenderContext().SetpPreRenderFunction( function );
	    return ( pOldPreRenderFunction );
	}

//	----------------------------------------------------------------------
	/** Set the function called just prior to world definition.
	 	\param	function	Pointer to the new function to use.
	 	\return	Pointer to the old function.
		世界定義のすぐ前に呼ばれた機能を設定してください。

	 */

	public static Method RiPreWorldFunction( Method function )
	{
		Method pOldPreWorldFunction = QGetRenderContext().pPreWorldFunction();
	    QGetRenderContext().SetpPreWorldFunction( function );
	    return ( pOldPreWorldFunction );
	}


	public static void SetShaderArgument( IqShader pShader, final String name, Object val )
	{
	    // Find the relevant variable.
	    SqParameterDeclaration Decl = new SqParameterDeclaration();
	    try
	    {
	        Decl = QGetRenderContext() .FindParameterDecl( name );
	    }
	    catch( XqException e )
	    {
	    	logger.error( e.strReason() );
	        return;
	    }

	    pShader.SetArgument( Decl.m_strName, Decl.m_Type, Decl.m_strSpace, val );
	}


//	----------------------------------------------------------------------
	/** Analyze the parameter list and figure what kind of compression is required for texturemapping output files.
	 パラメータ・リストを分析してください。そうすれば、図はどういう圧縮を分析するか。texturemapping出力ファイルのために、必要です。

		\param	compression	compression	Pointer to an integer to containing the TIFF compression
		\param	quality it is the quality of jpeg's compression
		\param	count list counter
		\param	tokens list of tokens
		\param	values list of values
	 
		\return	nothing
	 */

	static void ProcessCompression( p_int compression, p_int quality, int count, String[] tokens, Object[] values )
	{
		//XXX: 保留。tiffの圧縮の、種類や圧縮率を設定する。
//	    compression[0] = COMPRESSION_NONE;
//	    quality[0] = 70;
//
//	    for ( int i = 0; i < count; ++i )
//	    {
//	        String	token = tokens[ i ];
//	        String[] value = ( String [] ) values[ i ];
//
//	        if ( strstr( token, "compression" ) != 0 )
//	        {
//
//	            if ( strstr( *value, "none" ) != 0 )
//	                * compression = COMPRESSION_NONE;
//
//	            else if ( strstr( *value, "lzw" ) != 0 )
//	                * compression = COMPRESSION_LZW;
//
//	            else if ( strstr( *value, "deflate" ) != 0 )
//	                * compression = COMPRESSION_DEFLATE;
//
//	            else if ( strstr( *value, "jpeg" ) != 0 )
//	                * compression = COMPRESSION_JPEG;
//
//	            else if ( strstr( *value, "packbits" ) != 0 )
//	                * compression = COMPRESSION_PACKBITS;
//
//
//	        }
//	        else if ( strstr( token, "quality" ) != 0 )
//	        {
//
//	            *quality = ( int ) * ( float * ) value;
//	            if ( *quality < 0 ) * quality = 0;
//	            if ( *quality > 100 ) * quality = 100;
//	        }
//	    }
	}
	
	private static CqParameter createParameter( SqParameterDeclaration Decl ) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		
		CqParameter pParam = null;
		
		if( Decl == null )	return null;
		
		switch( Decl.m_Type.getValue() )
		{
		case type_invalid :
			break;
		case type_float :
			pParam = (CqParameter)(Decl.m_pCreate.invoke( null, Decl.m_strName, Decl.m_Count , Decl.m_Type ,p_float.class,p_float.class));
			break;
		case type_integer :
			pParam = (CqParameter)(Decl.m_pCreate.invoke( null, Decl.m_strName, Decl.m_Count , Decl.m_Type ,p_int.class,p_float.class));
			break;
		case type_point  :
			pParam = (CqParameter)(Decl.m_pCreate.invoke( null, Decl.m_strName, Decl.m_Count , Decl.m_Type ,CqVector3D.class,CqVector3D.class));
			break;
		case type_string :
			pParam = (CqParameter)(Decl.m_pCreate.invoke( null, Decl.m_strName, Decl.m_Count , Decl.m_Type ,p_String.class,p_String.class));
			break;
		case type_color :
			pParam = (CqParameter)(Decl.m_pCreate.invoke( null, Decl.m_strName, Decl.m_Count , Decl.m_Type ,CqColor.class,CqColor.class));
			break;
		case type_triple :
			break;
		case type_hpoint :
			pParam = (CqParameter)(Decl.m_pCreate.invoke( null, Decl.m_strName, Decl.m_Count , Decl.m_Type ,CqVector4D.class,CqVector4D.class));
			break;
		case type_normal :
			pParam = (CqParameter)(Decl.m_pCreate.invoke( null, Decl.m_strName, Decl.m_Count , Decl.m_Type ,CqVector3D.class,CqVector3D.class));
			break;
		case type_vector :
			pParam = (CqParameter)(Decl.m_pCreate.invoke( null, Decl.m_strName, Decl.m_Count , Decl.m_Type ,CqVector3D.class,CqVector3D.class));
			break;
		case type_void :
			break;
		case type_matrix :
			pParam = (CqParameter)(Decl.m_pCreate.invoke( null, Decl.m_strName, Decl.m_Count , Decl.m_Type ,CqMatrix.class,CqMatrix.class));
			break;
		case type_sixteentuple :
		case type_bool :
		case type_last :
		default :
			break;
		
		}
		
		return pParam;
	}
	
}
